?? pci_mast.tf
字號:
//------------------------------------------------------------------------------
//
// File : pci_mast.tf
// Last Modification: 06/26/2001
//
// Created In SpDE Version: SpDE 8.22
// Author : Richard Yuan, QuickLogic Corporation
// Copyright (C) 2001, Licensed customers of QuickLogic may copy and modify
// this file for use in designing with QuickLogic devices only.
//
// Description :
// This is a PCI master model.
// Please see "The QL5064 PCI Bus Simulation Environment" for detailed informaiton.
//
// Hierarchy:
// This file is to be included by pci5(3/4)32_208.tf.
//
// History:
// Date Author Version
// 06/26/01 Richard Yuan 1.0
// - Header reorganized to conform to coding standard.
//
//------------------------------------------------------------------------------
`timescale 1ns/1ns
// ----------------------------------------------------------------------------
// PCI bus commands:
// ----------------------------------------------------------------------------
`define COMMAND_INTERRUPT_ACK 4'b0000
`define COMMAND_SPECIAL_CYCLE 4'b0001
`define COMMAND_IO_READ 4'b0010
`define COMMAND_IO_WRITE 4'b0011
`define COMMAND_CMD_RESERVED_1 4'b0100
`define COMMAND_CMD_RESERVED_2 4'b0101
`define COMMAND_MEM_READ 4'b0110
`define COMMAND_MEM_WRITE 4'b0111
`define COMMAND_CMD_RESERVED_3 4'b1000
`define COMMAND_CMD_RESERVED_4 4'b1001
`define COMMAND_CONFIG_READ 4'b1010
`define COMMAND_CONFIG_WRITE 4'b1011
`define COMMAND_MEM_READ_MULT 4'b1100
`define COMMAND_DUAL_ADDR 4'b1101
`define COMMAND_MEM_READ_LINE 4'b1110
`define COMMAND_MEM_WR_INVALID 4'b1111
module tf_pci_master (
pci_clk,
pci_ad,
pci_cbe,
par,
par_64,
frame_l,
irdy_l,
trdy_l,
stop_l,
devsel_l,
idsel,
req64_l,
ack64_l,
req_l,
gnt_l,
reset_l
);
parameter OutDly = 2; // 2ns clock to out (PCI Min)
parameter RW_BUFF_SIZE_ADDR_BITS = 8;
parameter RW_BUFF_SIZE = (1<<RW_BUFF_SIZE_ADDR_BITS);
input pci_clk;
inout [63:0] pci_ad;
output [7:0] pci_cbe;
inout par;
inout par_64;
inout frame_l;
inout irdy_l;
input trdy_l;
input stop_l;
input devsel_l;
inout idsel;
output req64_l;
input ack64_l;
output req_l;
input gnt_l;
input reset_l;
reg [63:0] pci_ad_reg;
reg pci_ad_oe;
wire [63:0] #4 pci_ad;
assign pci_ad[63:0] = (pci_ad_oe ? pci_ad_reg[63:0] : 64'hzzzzzzzzzzzzzzzz);
reg [7:0] pci_cbe_reg;
reg pci_cbe_oe;
wire [7:0] #4 pci_cbe;
assign pci_cbe[7:0] = (pci_cbe_oe ? pci_cbe_reg[7:0] : 8'hzz);
reg frame_reg;
reg frame_oe;
wire #4 frame_l;
assign frame_l = (frame_oe ? ~frame_reg : 1'bz); // Added delay BDS
reg irdy_reg;
reg irdy_oe;
wire #4 irdy_l;
assign irdy_l = (irdy_oe ? ~irdy_reg : 1'bz); // Added delay BDS
reg idsel_reg;
reg idsel_oe;
wire #4 idsel;
assign idsel = (idsel_oe ? idsel_reg : 1'bz); // Error, this is wrong...
reg req_reg;
reg req64_oe;
reg par_oe_reg;
reg par64_oe_reg;
reg par_reg;
reg par64_reg;
integer bad_parity_phase;
integer bad_parity_phase_dly;
reg bad_par;
reg bad_par64;
integer phase_count;
reg frame_dly;
reg irdy_dly;
reg irdy_oe_dly;
wire frame; assign frame = ~frame_l;
wire irdy; assign irdy = ~irdy_l;
wire trdy; assign trdy = ~trdy_l;
wire devsel; assign devsel = ~devsel_l;
wire stop; assign stop = ~stop_l;
wire reset; assign reset = ~reset_l;
wire gnt; assign gnt = ~gnt_l;
assign req_l = (reset) ? 1'b1 : (~req_reg);
initial begin
pci_ad_oe <= 1'b0;
pci_cbe_oe <= 1'b0;
frame_oe <= 1'b0;
idsel_oe <= 1'b0;
irdy_oe <= 1'b0;
req64_oe <= 1'b0;
req_reg <= 1'b0;
end
// ----------------------------
// registers set by test fixture
// to force 32/64 bit behavior
// ----------------------------
// Two ways of getting 32 bit access:
// a) not asserting req64
// b) asserting req64 but not getting ack64
// (ie. disconnect req64 between here and bus)
//
reg force_32;
reg disconnect_req64;
wire local_req64_l;
assign local_req64_l = (req64_oe & frame_oe ? 1'b0 : 1'bz);
assign req64_l = disconnect_req64 ? 1'b1 : local_req64_l;
// --
reg m64_local;
initial begin
force_32 <= 1'b0;
disconnect_req64 <= 1'b0;
end
//If bus is 32bit, NEVER assert req64!!!
always @(negedge reset) begin
if (req64_l == 1'b1) force_32 = 1'b1;
end
// ----------------------------
// tasks called by test fixture
// to force parity errors on bus
// ----------------------------
wire par_reg_with_error = (((bad_parity_phase_dly == phase_count) & bad_par) ? ~par_reg : par_reg); // mess up parity if we're supposed to
wire par64_reg_with_error = (((bad_parity_phase_dly == phase_count) & bad_par64) ? ~par64_reg : par64_reg); // mess up parity if we're supposed to
wire perr_injected = par_reg_with_error ^ par_reg;
wire perr64_injected = par64_reg_with_error ^ par64_reg;
assign par = (par_oe_reg ? par_reg_with_error : 1'bz);
assign par_64 = (par64_oe_reg ? par64_reg_with_error : 1'bz);
initial bad_parity_phase = 0;
//task generate_bad_parity(phase);
task generate_bad_parity;
input phase;
integer phase;
begin
bad_parity_phase <= phase;
bad_par <= 1'b1;
bad_par64 <= 1'b0;
end
endtask
//task generate_bad_parity64(phase);
task generate_bad_parity64;
input phase;
integer phase;
begin
bad_parity_phase <= phase;
bad_par <= 1'b0;
bad_par64 <= 1'b1;
end
endtask
// --------------------------
always @(posedge pci_clk or negedge reset_l)
if ( ~reset_l ) begin
par_reg <= 1'b0;
par_oe_reg <= 1'b0;
par64_reg <= 1'b0;
par64_oe_reg <= 1'b0;
frame_dly <= 1'b0;
irdy_dly <= 1'b0;
irdy_oe_dly <= 1'b0;
end else begin
par_oe_reg <= pci_ad_oe;
par64_oe_reg <= pci_ad_oe;
bad_parity_phase_dly <= bad_parity_phase; // we use a delayed version because when the
// user sets the b_p_p to 1, we're at 1 coming
// into the transaction. Its either this or
// have a special case that checks for b_p_p = 1
frame_dly <= frame;
irdy_dly <= irdy;
irdy_oe_dly <= irdy_oe;
if ((frame && !frame_dly) || (!frame && !irdy)) phase_count <= 1;
// else if (irdy && (phase_count == 1)) phase_count <= phase_count + 1;
// else if (irdy && trdy) phase_count <= phase_count + 1;
else if (trdy || irdy) phase_count <= phase_count + 1; // count address phases and others
if ((phase_count == bad_parity_phase_dly)) begin
bad_parity_phase <= 0;
bad_parity_phase_dly <= 0;
//$display ("Injected parity error at %0t", $time);
end
par_reg <= (^pci_ad[31:0]) ^ (^pci_cbe[3:0]);
par64_reg <= (^pci_ad[63:32]) ^ (^pci_cbe[7:4]);
end
// **********************************************
reg fake_a_DAC;
initial fake_a_DAC = 1'b0;
task set_fake_a_DAC;
begin
fake_a_DAC = 1'b1;
end
endtask
task clear_fake_a_DAC;
begin
fake_a_DAC = 1'b0;
end
endtask
// **********************************************
reg [31:0] data_array[RW_BUFF_SIZE-1:0];
reg [3:0] be_array[RW_BUFF_SIZE-1:0];
reg [63:0] start_address; // field for use in qlpci_target.tf to store individual master's info
reg [63:0] burst_count; // field for use in qlpci_target.tf to store individual master's info
reg [63:0] command; // field for use in qlpci_target.tf to store individual master's info
reg burst;
reg [15:0] timeout;
reg [RW_BUFF_SIZE_ADDR_BITS:0] countleft;
reg [5:0] timeleft;
reg got_devsel;
reg quit;
reg [RW_BUFF_SIZE_ADDR_BITS:0] dwords_transmitted;
//task compare64 (addr, expected, actual, be, pass_fail, quiet, last_data);
task compare64;
input [63:0] addr;
input [63:0] expected;
input [63:0] actual;
input [7:0] be;
inout pass_fail;
input quiet;
output [63:0] last_data;
reg [63:0] be_mask;
begin
be_mask = {(be[7] ? 8'hFF: 8'h00),
(be[6] ? 8'hFF: 8'h00),
(be[5] ? 8'hFF: 8'h00),
(be[4] ? 8'hFF: 8'h00),
(be[3] ? 8'hFF: 8'h00),
(be[2] ? 8'hFF: 8'h00),
(be[1] ? 8'hFF: 8'h00),
(be[0] ? 8'hFF: 8'h00)};
if ((expected & be_mask) !== (actual & be_mask)) begin
pass_fail = 1'b0;
if (!quiet) begin
$display ("FAILURE: PCI side quad word data read mismatch at address %0h at time %0t. Expected: %h, Actual: %h",
addr,
$time,
expected & be_mask,
actual & be_mask);
$stop;
end
end
//$display (" COMPARE64 SAYS:");
//$display (" addr = %0h at %0t", addr, $time);
//$display (" actual = %0h at %0t", actual, $time);
//$display (" be = %0h", be);
//$display (" be_mask = %0h", be_mask);
last_data = actual & be_mask;
end
endtask
//task compare (addr, expected, actual, be, pass_fail, quiet, last_data);
task compare;
input [63:0] addr;
input [31:0] expected;
input [31:0] actual;
input [3:0] be;
inout pass_fail;
input quiet;
output [63:0] last_data;
reg [31:0] be_mask;
begin
be_mask = {(be[3] ? 8'hFF: 8'h00),
(be[2] ? 8'hFF: 8'h00),
(be[1] ? 8'hFF: 8'h00),
(be[0] ? 8'hFF: 8'h00)};
if ((expected & be_mask) !== (actual & be_mask)) begin
pass_fail = 1'b0;
if (!quiet) begin
$display ("FAILURE: PCI side double word data read mismatch at address %0h at time %0t. Expected: %h, Actual: %h",
addr,
$time,
expected & be_mask,
actual & be_mask);
$stop;
end
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -