URL
https://opencores.org/ocsvn/axi_master/axi_master/trunk
Subversion Repositories axi_master
Compare Revisions
- This comparison shows the changes necessary to convert path
/axi_master/trunk
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/src/base/def_axi_master_static.txt
26,62 → 26,63
//// details. http://www.gnu.org/licenses/lgpl.html //// |
//// //// |
//////////////////////////////////////////////////////////////////##> |
|
VERIFY (DATA_BITS <= 64) else stub supports 32 or 64 bits data bus |
VERIFY (SIZE_BITS <= 3) else stub supports 32 or 64 bits data bus |
|
GROUP STUB_AXI_A is { |
ID ID_BITS output |
ADDR ADDR_BITS output |
LEN LEN_BITS output |
SIZE SIZE_BITS output |
BURST 2 output |
CACHE 4 output |
PROT 3 output |
LOCK 2 output |
VALID 1 output |
READY 1 input |
} |
|
GROUP STUB_AXI_W is { |
ID ID_BITS output |
DATA DATA_BITS output |
STRB DATA_BITS/8 output |
LAST 1 output |
VALID 1 output |
READY 1 input |
} |
|
GROUP STUB_AXI_B is { |
ID ID_BITS input |
RESP 2 input |
VALID 1 input |
READY 1 output |
} |
|
GROUP STUB_AXI_R is { |
ID ID_BITS input |
DATA DATA_BITS input |
RESP 2 input |
LAST 1 input |
VALID 1 input |
READY 1 output |
} |
|
GROUP STUB_AXI joins { |
GROUP STUB_AXI_A prefix_AW |
GROUP STUB_AXI_W prefix_W |
GROUP STUB_AXI_B prefix_B |
GROUP STUB_AXI_A prefix_AR |
GROUP STUB_AXI_R prefix_R |
} |
|
GROUP AXI_MASTER_RAND is { |
len_min SON(DEFAULT 0) |
len_max SON(DEFAULT 15) |
size_min SON(DEFAULT 0) |
size_max SON(DEFAULT 3) |
addr_min SON(DEFAULT 0) |
addr_max SON(DEFAULT {DATA_BITS{1'b1}}) |
} |
|
VERIFY (DATA_BITS <= 64) else stub supports 32 or 64 bits data bus |
VERIFY (SIZE_BITS <= 3) else stub supports 32 or 64 bits data bus |
|
GROUP STUB_AXI_A is { |
ID ID_BITS output |
ADDR ADDR_BITS output |
LEN LEN_BITS output |
SIZE SIZE_BITS output |
BURST 2 output |
CACHE 4 output |
PROT 3 output |
LOCK 2 output |
VALID 1 output |
READY 1 input |
} |
|
GROUP STUB_AXI_W is { |
ID ID_BITS output |
DATA DATA_BITS output |
STRB DATA_BITS/8 output |
LAST 1 output |
VALID 1 output |
READY 1 input |
} |
|
GROUP STUB_AXI_B is { |
ID ID_BITS input |
RESP 2 input |
VALID 1 input |
READY 1 output |
} |
|
GROUP STUB_AXI_R is { |
ID ID_BITS input |
DATA DATA_BITS input |
RESP 2 input |
LAST 1 input |
VALID 1 input |
READY 1 output |
} |
|
GROUP STUB_AXI joins { |
GROUP STUB_AXI_A prefix_AW |
GROUP STUB_AXI_W prefix_W |
GROUP STUB_AXI_B prefix_B |
GROUP STUB_AXI_A prefix_AR |
GROUP STUB_AXI_R prefix_R |
} |
|
GROUP AXI_MASTER_RAND is { |
use_addr_base SON(DEFAULT 0) |
len_min SON(DEFAULT 0) |
len_max SON(DEFAULT 15) |
size_min SON(DEFAULT 0) |
size_max SON(DEFAULT 3) |
addr_min SON(DEFAULT 0) |
addr_max SON(DEFAULT {DATA_BITS{1'b1}}) |
} |
|
/src/base/axi_master.v
26,276 → 26,311
//// details. http://www.gnu.org/licenses/lgpl.html //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
OUTFILE PREFIX.v |
|
INCLUDE def_axi_master.txt |
|
|
////////////////////////////////////// |
// |
// General: |
// The AXI master has an internal master per ID. |
// These internal masters work simultaniously and an interconnect matrix connets them. |
// |
// |
// I/F : |
// idle - all internal masters emptied their command FIFOs |
// scrbrd_empty - all scoreboard checks have been completed (for random testing) |
// |
// |
// Tasks: |
// |
// enable(input master_num) |
// Description: Enables master |
// Parameters: master_num - number of internal master |
// |
// enable_all() |
// Description: Enables all masters |
// |
// write_single(input master_num, input addr, input wdata) |
// Description: write a single AXI burst (1 data cycle) |
// Parameters: master_num - number of internal master |
// addr - address |
// wdata - write data |
// |
// read_single(input master_num, input addr, output rdata) |
// Description: read a single AXI burst (1 data cycle) |
// Parameters: master_num - number of internal master |
// addr - address |
// rdata - return read data |
// |
// insert_wr_cmd(input master_num, input addr, input len, input size) |
// Description: add an AXI write burst to command FIFO |
// Parameters: master_num - number of internal master |
// addr - address |
// len - AXI LEN (data strobe number) |
// size - AXI SIZE (data width) |
// |
// insert_rd_cmd(input master_num, input addr, input len, input size) |
// Description: add an AXI read burst to command FIFO |
// Parameters: master_num - number of internal master |
// addr - address |
// len - AXI LEN (data strobe number) |
// size - AXI SIZE (data width) |
// |
// insert_wr_data(input master_num, input wdata) |
// Description: add a single data to data FIFO (to be used in write bursts) |
// Parameters: master_num - number of internal master |
// wdata - write data |
// |
// insert_wr_incr_data(input master_num, input addr, input len, input size) |
// Description: add an AXI write burst to command FIFO will use incremental data (no need to use insert_wr_data) |
// Parameters: master_num - number of internal master |
// addr - address |
// len - AXI LEN (data strobe number) |
// size - AXI SIZE (data width) |
// |
// insert_rand_chk(input master_num, input burst_num) |
// Description: add multiple commands to command FIFO. Each command writes incremental data to a random address, reads the data back and checks the data. Useful for random testing. |
// Parameters: master_num - number of internal master |
// burst_num - total number of bursts to check |
// |
|
// |
// Parameters: |
// |
// For random testing: (changing these values automatically update interanl masters) |
// len_min - minimum burst LEN (length) |
// len_max - maximum burst LEN (length) |
// size_min - minimum burst SIZE (length) |
// size_max - maximum burst SIZE (length) |
// addr_min - minimum address (in bytes) |
// addr_max - maximum address (in bytes) |
// |
////////////////////////////////////// |
|
|
ITER IX ID_NUM |
module PREFIX(PORTS); |
|
input clk; |
input reset; |
|
port GROUP_STUB_AXI; |
|
output idle; |
output scrbrd_empty; |
|
|
//random parameters |
integer GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND.DEFAULT; |
|
wire GROUP_STUB_AXI_IX; |
wire idle_IX; |
wire scrbrd_empty_IX; |
|
|
always @(*) |
begin |
#FFD; |
PREFIX_singleIX.GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND; |
end |
|
assign idle = CONCAT(idle_IX &); |
assign scrbrd_empty = CONCAT(scrbrd_empty_IX &); |
|
|
CREATE axi_master_single.v |
|
LOOP IX ID_NUM |
PREFIX_single #(IX, IDIX_VAL, CMD_DEPTH) |
PREFIX_singleIX( |
.clk(clk), |
.reset(reset), |
.GROUP_STUB_AXI(GROUP_STUB_AXI_IX), |
.idle(idle_IX), |
.scrbrd_empty(scrbrd_empty_IX) |
); |
ENDLOOP IX |
|
IFDEF TRUE(ID_NUM==1) |
|
assign GROUP_STUB_AXI.OUT = GROUP_STUB_AXI_0.OUT; |
assign GROUP_STUB_AXI_0.IN = GROUP_STUB_AXI.IN; |
|
ELSE TRUE(ID_NUM==1) |
|
CREATE ic.v DEFCMD(SWAP.GLOBAL PARENT PREFIX) DEFCMD(SWAP.GLOBAL MASTER_NUM ID_NUM) DEFCMD(SWAP.GLOBAL CONST(ID_BITS) ID_BITS) DEFCMD(SWAP.GLOBAL CONST(CMD_DEPTH) CMD_DEPTH) DEFCMD(SWAP.GLOBAL CONST(DATA_BITS) DATA_BITS) DEFCMD(SWAP.GLOBAL CONST(ADDR_BITS) ADDR_BITS) |
LOOP IX ID_NUM |
STOMP NEWLINE |
DEFCMD(LOOP.GLOBAL MIX_IDX 1) |
STOMP NEWLINE |
DEFCMD(SWAP.GLOBAL ID_MIX_ID0 IDIX_VAL) |
ENDLOOP IX |
|
PREFIX_ic PREFIX_ic( |
.clk(clk), |
.reset(reset), |
.MIX_GROUP_STUB_AXI(GROUP_STUB_AXI_IX), |
.S0_GROUP_STUB_AXI(GROUP_STUB_AXI), |
STOMP , |
|
); |
|
ENDIF TRUE(ID_NUM==1) |
|
|
|
task check_master_num; |
input [24*8-1:0] task_name; |
input [31:0] master_num; |
begin |
if (master_num >= ID_NUM) |
begin |
$display("FATAL ERROR: task %0s called for master %0d that does not exist.\tTime: %0d ns.", task_name, master_num, $time); |
end |
end |
endtask |
|
task enable; |
input [31:0] master_num; |
begin |
check_master_num("enable", master_num); |
case (master_num) |
IX : PREFIX_singleIX.enable = 1; |
endcase |
end |
endtask |
|
task enable_all; |
begin |
PREFIX_singleIX.enable = 1; |
end |
endtask |
|
task write_single; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
begin |
check_master_num("write_single", master_num); |
case (master_num) |
IX : PREFIX_singleIX.write_single(addr, wdata); |
endcase |
end |
endtask |
|
task read_single; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
output [DATA_BITS-1:0] rdata; |
begin |
check_master_num("read_single", master_num); |
case (master_num) |
IX : PREFIX_singleIX.read_single(addr, rdata); |
endcase |
end |
endtask |
|
task insert_wr_cmd; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
begin |
check_master_num("insert_wr_cmd", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_wr_cmd(addr, len, size); |
endcase |
end |
endtask |
|
task insert_rd_cmd; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
begin |
check_master_num("insert_rd_cmd", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_rd_cmd(addr, len, size); |
endcase |
end |
endtask |
|
task insert_wr_data; |
input [31:0] master_num; |
input [DATA_BITS-1:0] wdata; |
begin |
check_master_num("insert_wr_data", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_wr_data(wdata); |
endcase |
end |
endtask |
|
task insert_wr_incr_data; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
begin |
check_master_num("insert_wr_incr_data", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_wr_incr_data(addr, len, size); |
endcase |
end |
endtask |
|
task insert_rand_chk; |
input [31:0] master_num; |
input [31:0] burst_num; |
begin |
check_master_num("insert_rand_chk", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_rand_chk(burst_num); |
endcase |
end |
endtask |
|
|
|
endmodule |
|
|
|
////////////////////////////////////// |
// |
// General: |
// The AXI master has an internal master per ID. |
// These internal masters work simultaniously and an interconnect matrix connets them. |
// |
// |
// I/F : |
// idle - all internal masters emptied their command FIFOs |
// scrbrd_empty - all scoreboard checks have been completed (for random testing) |
// |
// |
// Tasks: |
// |
// enable(input master_num) |
// Description: Enables master |
// Parameters: master_num - number of internal master |
// |
// enable_all() |
// Description: Enables all masters |
// |
// write_single(input master_num, input addr, input wdata) |
// Description: write a single AXI burst (1 data cycle) |
// Parameters: master_num - number of internal master |
// addr - address |
// wdata - write data |
// |
// read_single(input master_num, input addr, output rdata) |
// Description: read a single AXI burst (1 data cycle) |
// Parameters: master_num - number of internal master |
// addr - address |
// rdata - return read data |
// |
// check_single(input master_num, input addr, input expected) |
// Description: read a single AXI burst and gives an error if the data read does not match expected |
// Parameters: master_num - number of internal master |
// addr - address |
// expected - expected read data |
// |
// write_and_check_single(input master_num, input addr, input data) |
// Description: write a single AXI burst read it back and compare the write and read data |
// Parameters: master_num - number of internal master |
// addr - address |
// data - data to write and expect on read |
// |
// insert_wr_cmd(input master_num, input addr, input len, input size) |
// Description: add an AXI write burst to command FIFO |
// Parameters: master_num - number of internal master |
// addr - address |
// len - AXI LEN (data strobe number) |
// size - AXI SIZE (data width) |
// |
// insert_rd_cmd(input master_num, input addr, input len, input size) |
// Description: add an AXI read burst to command FIFO |
// Parameters: master_num - number of internal master |
// addr - address |
// len - AXI LEN (data strobe number) |
// size - AXI SIZE (data width) |
// |
// insert_wr_data(input master_num, input wdata) |
// Description: add a single data to data FIFO (to be used in write bursts) |
// Parameters: master_num - number of internal master |
// wdata - write data |
// |
// insert_wr_incr_data(input master_num, input addr, input len, input size) |
// Description: add an AXI write burst to command FIFO will use incremental data (no need to use insert_wr_data) |
// Parameters: master_num - number of internal master |
// addr - address |
// len - AXI LEN (data strobe number) |
// size - AXI SIZE (data width) |
// |
// insert_rand_chk(input master_num, input burst_num) |
// Description: add multiple commands to command FIFO. Each command writes incremental data to a random address, reads the data back and checks the data. Useful for random testing. |
// Parameters: master_num - number of internal master |
// burst_num - total number of bursts to check |
// |
|
// |
// Parameters: |
// |
// For random testing: (changing these values automatically update interanl masters) |
// len_min - minimum burst AXI LEN (length) |
// len_max - maximum burst AXI LEN (length) |
// size_min - minimum burst AXI SIZE (width) |
// size_max - maximum burst AXI SIZE (width) |
// addr_min - minimum address (in bytes) |
// addr_max - maximum address (in bytes) |
// |
////////////////////////////////////// |
|
OUTFILE PREFIX.v |
|
INCLUDE def_axi_master.txt |
|
|
ITER IX ID_NUM |
module PREFIX(PORTS); |
|
input clk; |
input reset; |
|
port GROUP_STUB_AXI; |
|
output idle; |
output scrbrd_empty; |
|
|
//random parameters |
integer GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND.DEFAULT; |
|
wire GROUP_STUB_AXI_IX; |
wire idle_IX; |
wire scrbrd_empty_IX; |
|
|
always @(*) |
begin |
#FFD; |
PREFIX_singleIX.GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND; |
end |
|
assign idle = CONCAT(idle_IX &); |
assign scrbrd_empty = CONCAT(scrbrd_empty_IX &); |
|
|
CREATE axi_master_single.v |
|
LOOP IX ID_NUM |
PREFIX_single #(IX, IDIX_VAL, CMD_DEPTH) |
PREFIX_singleIX( |
.clk(clk), |
.reset(reset), |
.GROUP_STUB_AXI(GROUP_STUB_AXI_IX), |
.idle(idle_IX), |
.scrbrd_empty(scrbrd_empty_IX) |
); |
ENDLOOP IX |
|
IFDEF TRUE(ID_NUM==1) |
|
assign GROUP_STUB_AXI.OUT = GROUP_STUB_AXI_0.OUT; |
assign GROUP_STUB_AXI_0.IN = GROUP_STUB_AXI.IN; |
|
ELSE TRUE(ID_NUM==1) |
|
CREATE ic.v DEFCMD(SWAP.GLOBAL PARENT PREFIX) DEFCMD(SWAP.GLOBAL MASTER_NUM ID_NUM) DEFCMD(SWAP.GLOBAL CONST(ID_BITS) ID_BITS) DEFCMD(SWAP.GLOBAL CONST(CMD_DEPTH) CMD_DEPTH) DEFCMD(SWAP.GLOBAL CONST(DATA_BITS) DATA_BITS) DEFCMD(SWAP.GLOBAL CONST(ADDR_BITS) ADDR_BITS) |
LOOP IX ID_NUM |
STOMP NEWLINE |
DEFCMD(LOOP.GLOBAL MIX_IDX 1) |
STOMP NEWLINE |
DEFCMD(SWAP.GLOBAL ID_MIX_ID0 IDIX_VAL) |
ENDLOOP IX |
|
PREFIX_ic PREFIX_ic( |
.clk(clk), |
.reset(reset), |
.MIX_GROUP_STUB_AXI(GROUP_STUB_AXI_IX), |
.S0_GROUP_STUB_AXI(GROUP_STUB_AXI), |
STOMP , |
|
); |
|
ENDIF TRUE(ID_NUM==1) |
|
|
|
task check_master_num; |
input [24*8-1:0] task_name; |
input [31:0] master_num; |
begin |
if (master_num >= ID_NUM) |
begin |
$display("FATAL ERROR: task %0s called for master %0d that does not exist.\tTime: %0d ns.", task_name, master_num, $time); |
end |
end |
endtask |
|
task enable; |
input [31:0] master_num; |
begin |
check_master_num("enable", master_num); |
case (master_num) |
IX : PREFIX_singleIX.enable = 1; |
endcase |
end |
endtask |
|
task enable_all; |
begin |
PREFIX_singleIX.enable = 1; |
end |
endtask |
|
task write_single; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
begin |
check_master_num("write_single", master_num); |
case (master_num) |
IX : PREFIX_singleIX.write_single(addr, wdata); |
endcase |
end |
endtask |
|
task read_single; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
output [DATA_BITS-1:0] rdata; |
begin |
check_master_num("read_single", master_num); |
case (master_num) |
IX : PREFIX_singleIX.read_single(addr, rdata); |
endcase |
end |
endtask |
|
task check_single; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] expected; |
begin |
check_master_num("check_single", master_num); |
case (master_num) |
IX : PREFIX_singleIX.check_single(addr, expected); |
endcase |
end |
endtask |
|
task write_and_check_single; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] data; |
begin |
check_master_num("write_and_check_single", master_num); |
case (master_num) |
IX : PREFIX_singleIX.write_and_check_single(addr, data); |
endcase |
end |
endtask |
|
task insert_wr_cmd; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
begin |
check_master_num("insert_wr_cmd", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_wr_cmd(addr, len, size); |
endcase |
end |
endtask |
|
task insert_rd_cmd; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
begin |
check_master_num("insert_rd_cmd", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_rd_cmd(addr, len, size); |
endcase |
end |
endtask |
|
task insert_wr_data; |
input [31:0] master_num; |
input [DATA_BITS-1:0] wdata; |
begin |
check_master_num("insert_wr_data", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_wr_data(wdata); |
endcase |
end |
endtask |
|
task insert_wr_incr_data; |
input [31:0] master_num; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
begin |
check_master_num("insert_wr_incr_data", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_wr_incr_data(addr, len, size); |
endcase |
end |
endtask |
|
task insert_rand_chk; |
input [31:0] master_num; |
input [31:0] burst_num; |
begin |
check_master_num("insert_rand_chk", master_num); |
case (master_num) |
IX : PREFIX_singleIX.insert_rand_chk(burst_num); |
endcase |
end |
endtask |
|
|
|
endmodule |
|
|
/src/base/axi_master_single.v
26,807 → 26,830
//// details. http://www.gnu.org/licenses/lgpl.html //// |
//// //// |
///////////////////////////////////////////////////////////////////// |
|
OUTFILE PREFIX_single.v |
|
INCLUDE def_axi_master.txt |
|
module PREFIX_single(PORTS); |
|
parameter MASTER_NUM = 0; |
parameter MASTER_ID = 0; |
parameter MASTER_PEND = 0; |
|
`include "prgen_rand.v" |
|
parameter MAX_CMDS = 16; //Depth of command FIFO |
parameter DATA_LOG = LOG2(EXPR(DATA_BITS/8)); |
parameter PEND_BITS = |
(MAX_CMDS <= 16) ? 4 : |
(MAX_CMDS <= 32) ? 5 : |
(MAX_CMDS <= 64) ? 6 : |
(MAX_CMDS <= 128) ? 7 : |
(MAX_CMDS <= 256) ? 8 : |
(MAX_CMDS <= 512) ? 9 : 0; //0 is ilegal |
|
|
|
input clk; |
input reset; |
|
port GROUP_STUB_AXI; |
|
output idle; |
output scrbrd_empty; |
|
|
|
//random parameters |
integer GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND.DEFAULT; |
|
reg AWVALID_pre; |
reg WVALID_pre; |
wire BREADY_pre; |
reg ARVALID_pre; |
wire RREADY_pre; |
|
reg enable = 0; |
reg rd_enable = 0; |
reg wr_enable = 0; |
reg wait_for_write = 0; |
|
reg scrbrd_enable = 0; |
reg [LEN_BITS-1:0] wvalid_cnt; |
|
reg rd_cmd_push = 0; |
wire rd_cmd_pop; |
wire [PEND_BITS:0] rd_cmd_fullness; |
wire rd_cmd_empty; |
wire rd_cmd_full; |
reg [ADDR_BITS-1:0] rd_cmd_addr_in; |
reg [LEN_BITS-1:0] rd_cmd_len_in; |
reg [SIZE_BITS-1:0] rd_cmd_size_in; |
wire [ADDR_BITS-1:0] rd_cmd_addr; |
wire [LEN_BITS-1:0] rd_cmd_len; |
wire [SIZE_BITS-1:0] rd_cmd_size; |
|
reg rd_resp_push = 0; |
wire rd_resp_pop; |
wire rd_resp_empty; |
wire rd_resp_full; |
reg [ADDR_BITS-1:0] rd_resp_addr_in; |
reg [SIZE_BITS-1:0] rd_resp_size_in; |
wire [ADDR_BITS-1:0] rd_resp_addr; |
wire [SIZE_BITS-1:0] rd_resp_size; |
|
reg wr_cmd_push = 0; |
wire wr_cmd_pop; |
wire [PEND_BITS:0] wr_cmd_fullness; |
wire wr_cmd_empty; |
wire wr_cmd_full; |
reg [ADDR_BITS-1:0] wr_cmd_addr_in; |
reg [LEN_BITS-1:0] wr_cmd_len_in; |
reg [SIZE_BITS-1:0] wr_cmd_size_in; |
wire [ADDR_BITS-1:0] wr_cmd_addr; |
wire [LEN_BITS-1:0] wr_cmd_len; |
wire [SIZE_BITS-1:0] wr_cmd_size; |
|
reg wr_data_push = 0; |
wire wr_data_pop; |
wire [PEND_BITS:0] wr_data_fullness; |
wire wr_data_empty; |
wire wr_data_full; |
reg [ADDR_BITS-1:0] wr_data_addr_in; |
reg [LEN_BITS-1:0] wr_data_len_in; |
reg [SIZE_BITS-1:0] wr_data_size_in; |
wire [ADDR_BITS-1:0] wr_data_addr; |
wire [LEN_BITS-1:0] wr_data_len; |
wire [SIZE_BITS-1:0] wr_data_size; |
wire [DATA_BITS/8-1:0] wr_data_strb; |
wire [7:0] wr_data_bytes; |
wire [ADDR_BITS-1:0] wr_data_addr_prog; |
wire [7:0] wr_data_offset; |
|
wire wr_resp_push; |
reg wr_resp_pop = 0; |
wire wr_resp_empty; |
wire wr_resp_full; |
wire [1:0] wr_resp_resp_in; |
wire [1:0] wr_resp_resp; |
|
reg wr_fifo_push = 0; |
wire wr_fifo_pop; |
wire wr_fifo_empty; |
wire wr_fifo_full; |
reg [DATA_BITS-1:0] wr_fifo_data_in; |
wire [DATA_BITS-1:0] wr_fifo_data; |
|
wire rd_fifo_push; |
reg rd_fifo_pop = 0; |
wire rd_fifo_empty; |
wire rd_fifo_full; |
wire [DATA_BITS-1:0] rd_fifo_data_in; |
wire [1:0] rd_fifo_resp_in; |
wire [DATA_BITS-1:0] rd_fifo_data; |
wire [1:0] rd_fifo_resp; |
|
reg scrbrd_push = 0; |
reg scrbrd_pop = 0; |
wire scrbrd_empty; |
wire scrbrd_full; |
reg [ADDR_BITS-1:0] scrbrd_addr_in; |
reg [DATA_BITS-1:0] scrbrd_data_in; |
reg [DATA_BITS-1:0] scrbrd_mask_in; |
wire [ADDR_BITS-1:0] scrbrd_addr; |
wire [DATA_BITS-1:0] scrbrd_data; |
wire [DATA_BITS-1:0] scrbrd_mask; |
|
integer wr_fullness; |
integer rd_fullness; |
integer rd_completed; |
integer wr_completed; |
integer wr_pend_max = MASTER_PEND; |
integer rd_pend_max = MASTER_PEND; |
wire wr_hold; |
wire rd_hold; |
|
integer rand_chk_num = 0; |
|
|
assign idle = rd_cmd_empty & rd_resp_empty & wr_cmd_empty & wr_data_empty & wr_resp_empty; |
|
always @(rand_chk_num) |
if (rand_chk_num > 0) |
insert_rand_chk_loop(rand_chk_num); |
|
always @(posedge enable) |
begin |
@(posedge clk); |
wr_enable = 1; |
repeat (50) @(posedge clk); |
rd_enable = 1; |
end |
|
//for incremental data |
reg [DATA_BITS-1:0] base_data = 0; |
integer ww; |
initial |
begin |
ww=0; |
while (ww < DATA_BITS/8) |
begin |
base_data = base_data + ((MASTER_NUM + ww) << (ww*8)); |
ww = ww + 1; |
end |
end |
|
assign rd_cmd_pop = ARVALID & ARREADY; |
assign rd_resp_pop = RVALID & RREADY & RLAST; |
assign rd_fifo_push = RVALID & RREADY; |
assign wr_cmd_pop = AWVALID & AWREADY; |
assign wr_data_pop = WVALID & WREADY & WLAST; |
assign wr_fifo_pop = WVALID & WREADY; |
assign wr_resp_push = BVALID & BREADY; |
|
assign RREADY_pre = 1; |
assign BREADY_pre = 1; |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
AWVALID_pre <= #FFD 1'b0; |
else if ((wr_cmd_fullness == 1) & wr_cmd_pop) |
AWVALID_pre <= #FFD 1'b0; |
else if ((!wr_cmd_empty) & wr_enable) |
AWVALID_pre <= #FFD 1'b1; |
|
|
assign AWADDR = wr_cmd_addr; |
assign AWLEN = wr_cmd_len; |
assign AWSIZE = wr_cmd_size; |
assign AWID = MASTER_ID; |
assign AWBURST = 2'd1; //INCR only |
assign AWCACHE = 4'd0; //not supported |
assign AWPROT = 4'd0; //not supported |
assign AWLOCK = 2'd0; //not supported |
|
always @(posedge clk or posedge reset) |
if (reset) |
ARVALID_pre <= #FFD 1'b0; |
else if (((rd_cmd_fullness == 1)) & rd_cmd_pop) |
ARVALID_pre <= #FFD 1'b0; |
else if ((!rd_cmd_empty) & rd_enable) |
ARVALID_pre <= #FFD 1'b1; |
|
assign ARADDR = rd_cmd_addr; |
assign ARLEN = rd_cmd_len; |
assign ARSIZE = rd_cmd_size; |
assign ARID = MASTER_ID; |
assign ARBURST = 2'd1; //INCR only |
assign ARCACHE = 4'd0; //not supported |
assign ARPROT = 4'd0; //not supported |
assign ARLOCK = 2'd0; //not supported |
|
assign rd_fifo_data_in = RDATA; |
assign rd_fifo_resp_in = BRESP; |
|
assign wr_data_bytes = 1'b1 << wr_data_size; |
|
assign wr_data_strb = |
wr_data_size == 'd0 ? 1'b1 : |
wr_data_size == 'd1 ? 2'b11 : |
wr_data_size == 'd2 ? 4'b1111 : |
wr_data_size == 'd3 ? {8{1'b1}} : |
wr_data_size == 'd4 ? {16{1'b1}} : 'd0; |
|
assign wr_data_addr_prog = wr_data_addr + (wvalid_cnt * wr_data_bytes); |
|
always @(posedge clk or posedge reset) |
if (reset) |
WVALID_pre <= #FFD 1'b0; |
else if ((wr_data_fullness == 1) & wr_data_pop) |
WVALID_pre <= #FFD 1'b0; |
else if ((!wr_data_empty) & wr_enable) |
WVALID_pre <= #FFD 1'b1; |
|
|
assign wr_data_offset = wr_data_addr_prog[DATA_LOG-1:0]; |
|
assign WID = MASTER_ID; |
assign WDATA = wr_fifo_empty ? 0 : wr_fifo_data; |
assign WSTRB = wr_data_strb << wr_data_offset; |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
wvalid_cnt <= #FFD {LEN_BITS{1'b0}}; |
else if (wr_data_pop) |
wvalid_cnt <= #FFD {LEN_BITS{1'b0}}; |
else if (WVALID & WREADY) |
wvalid_cnt <= #FFD wvalid_cnt + 1'b1; |
|
assign WLAST = WVALID & (wvalid_cnt == wr_data_len); |
|
assign wr_resp_resp_in = BRESP; |
|
always @(posedge clk or posedge reset) |
if (reset) |
begin |
wr_fullness <= #FFD 0; |
rd_fullness <= #FFD 0; |
rd_completed <= #FFD 0; |
wr_completed <= #FFD 0; |
end |
else |
begin |
wr_fullness <= #FFD wr_fullness + wr_cmd_pop - wr_resp_push; |
rd_fullness <= #FFD rd_fullness + rd_cmd_pop - rd_resp_pop; |
rd_completed <= #FFD rd_completed + rd_resp_pop; |
wr_completed <= #FFD wr_completed + wr_resp_push; |
end |
|
assign wr_hold = wr_fullness >= wr_pend_max; |
assign rd_hold = (rd_fullness >= rd_pend_max) | (wait_for_write & (wr_completed <= rd_completed + rd_fullness)); |
|
|
|
task insert_rd_cmd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
begin |
rd_cmd_addr_in = addr; |
rd_cmd_len_in = len; |
rd_cmd_size_in = size; |
rd_resp_addr_in = addr; |
rd_resp_size_in = size; |
|
if (rd_cmd_full) enable = 1; //start stub not started yet |
|
wait ((!rd_cmd_full) & (!rd_resp_full)); |
@(negedge clk); #FFD; |
rd_cmd_push = 1; |
rd_resp_push = 1; |
@(posedge clk); #FFD; |
rd_cmd_push = 0; |
rd_resp_push = 0; |
end |
endtask |
|
task insert_wr_cmd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
begin |
wr_cmd_addr_in = addr; |
wr_cmd_len_in = len; |
wr_cmd_size_in = size; |
wr_data_addr_in = addr; |
wr_data_len_in = len; |
wr_data_size_in = size; |
|
if (wr_cmd_full) enable = 1; //start stub not started yet |
|
wait ((!wr_cmd_full) & (!wr_data_full)); |
@(negedge clk); #FFD; |
wr_cmd_push = 1; |
wr_data_push = 1; |
@(posedge clk); #FFD; |
wr_cmd_push = 0; |
wr_data_push = 0; |
end |
endtask |
|
task insert_wr_data; |
input [DATA_BITS-1:0] wdata; |
|
begin |
wr_fifo_data_in = wdata; |
|
wait (!wr_fifo_full); |
@(negedge clk); #FFD; |
wr_fifo_push = 1; |
@(posedge clk); #FFD; |
wr_fifo_push = 0; |
end |
endtask |
|
task insert_wr_incr_data; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
integer valid_cnt; |
integer wdata_cnt; |
reg [7:0] data_cnt; |
integer bytes; |
reg [DATA_BITS-1:0] add_data; |
reg [DATA_BITS-1:0] next_data; |
begin |
//insert data |
valid_cnt = 0; |
while (valid_cnt <= len) |
begin |
bytes = 1'b1 << size; |
wdata_cnt = valid_cnt+(addr[DATA_LOG-1:0]/bytes); |
data_cnt = ((wdata_cnt)/(DATA_BITS/(bytes*8))) * (DATA_BITS/8); |
add_data = {DATA_BITS/8{data_cnt}}; |
next_data = base_data + add_data; |
insert_wr_data(next_data); |
valid_cnt = valid_cnt+1; |
end |
//insert command |
insert_wr_cmd(addr, len, size); |
end |
endtask |
|
task insert_scrbrd; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] data; |
input [DATA_BITS-1:0] mask; |
begin |
scrbrd_enable = 1; |
scrbrd_addr_in = addr; |
scrbrd_data_in = data; |
scrbrd_mask_in = mask; |
|
wait (!scrbrd_full); |
@(negedge clk); #FFD; |
scrbrd_push = 1; |
@(posedge clk); #FFD; |
scrbrd_push = 0; |
end |
endtask |
|
task insert_scrbrd_incr_data; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
integer valid_cnt; |
integer wdata_cnt; |
reg [7:0] data_cnt; |
integer bytes; |
reg [DATA_BITS-1:0] add_data; |
reg [DATA_BITS-1:0] next_data; |
reg [DATA_BITS:0] strb; |
reg [DATA_BITS-1:0] mask; |
reg [ADDR_BITS-1:0] next_addr; |
begin |
valid_cnt = 0; |
while (valid_cnt <= len) |
begin |
bytes = 1'b1 << size; |
wdata_cnt = valid_cnt+(addr[DATA_LOG-1:0]/bytes); |
data_cnt = ((wdata_cnt)/(DATA_BITS/(bytes*8))) * (DATA_BITS/8); |
add_data = {DATA_BITS/8{data_cnt}}; |
next_data = base_data + add_data; |
next_addr = addr + (bytes * valid_cnt); |
strb = (1 << (bytes*8)) - 1; |
mask = strb << (next_addr[DATA_LOG-1:0]*8); |
insert_scrbrd(next_addr, next_data, mask); |
valid_cnt = valid_cnt+1; |
end |
end |
endtask |
|
task insert_rd_scrbrd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
begin |
insert_scrbrd_incr_data(addr, len, size); |
insert_rd_cmd(addr, len, size); |
end |
endtask |
|
task insert_wr_rd_scrbrd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
begin |
wait_for_write=1; |
insert_wr_incr_data(addr, len, size); |
insert_rd_scrbrd(addr, len, size); |
end |
endtask |
|
task insert_wr_rd_scrbrd_rand; |
reg [ADDR_BITS-1:0] addr; |
reg [LEN_BITS-1:0] len; |
reg [SIZE_BITS-1:0] size; |
|
begin |
len = rand(len_min, len_max); |
size = rand(size_min, size_max); |
addr = rand_align(addr_min, addr_max, 1 << size); |
insert_wr_rd_scrbrd(addr, len, size); |
end |
endtask |
|
task insert_rand_chk; |
input [31:0] num; |
|
rand_chk_num = num; |
endtask |
|
task insert_rand_chk_loop; |
input [31:0] num; |
|
integer i; |
begin |
i = 0; |
while (i < num) |
begin |
insert_wr_rd_scrbrd_rand; |
i = i + 1; |
end |
end |
endtask |
|
task insert_wr_single; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
|
reg [SIZE_BITS-1:0] size; |
begin |
size = EXPR((DATA_BITS/32)+1); |
insert_wr_data(wdata); |
insert_wr_cmd(addr, 0, size); |
end |
endtask |
|
task get_rd_resp; |
output [DATA_BITS-1:0] rdata; |
output [1:0] resp; |
|
reg [DATA_BITS-1:0] rdata; |
reg [1:0] resp; |
begin |
wait (!rd_fifo_empty); |
rdata = rd_fifo_data; |
resp = rd_fifo_resp; |
@(negedge clk); #FFD; |
rd_fifo_pop = 1; |
@(posedge clk); #FFD; |
rd_fifo_pop = 0; |
end |
endtask |
|
task get_scrbrd; |
output [ADDR_BITS-1:0] addr; |
output [DATA_BITS-1:0] rdata; |
output [DATA_BITS-1:0] mask; |
|
reg [ADDR_BITS-1:0] addr; |
reg [DATA_BITS-1:0] rdata; |
reg [DATA_BITS-1:0] mask; |
begin |
wait (!scrbrd_empty); |
addr = scrbrd_addr; |
rdata = scrbrd_data; |
mask = scrbrd_mask; |
@(negedge clk); #FFD; |
scrbrd_pop = 1; |
@(posedge clk); #FFD; |
scrbrd_pop = 0; |
end |
endtask |
|
task get_wr_resp; |
output [1:0] resp; |
|
reg [1:0] resp; |
begin |
wait (!wr_resp_empty); |
resp = wr_resp_resp; |
@(negedge clk); #FFD; |
wr_resp_pop = 1; |
@(posedge clk); #FFD; |
wr_resp_pop = 0; |
end |
endtask |
|
task insert_rd_single; |
input [ADDR_BITS-1:0] addr; |
|
reg [SIZE_BITS-1:0] size; |
begin |
size = EXPR((DATA_BITS/32)+1); |
insert_rd_cmd(addr, 0, size); |
end |
endtask |
|
task read_single_ack; |
input [ADDR_BITS-1:0] addr; |
output [DATA_BITS-1:0] rdata; |
output [1:0] resp; |
|
reg [1:0] resp; |
begin |
insert_rd_single(addr); |
get_rd_resp(rdata, resp); |
end |
endtask |
|
task write_single_ack; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
output [1:0] resp; |
|
reg [1:0] resp; |
begin |
insert_wr_single(addr, wdata); |
get_wr_resp(resp); |
end |
endtask |
|
task read_single; |
input [ADDR_BITS-1:0] addr; |
output [DATA_BITS-1:0] rdata; |
|
reg [1:0] resp; |
begin |
read_single_ack(addr, rdata, resp); |
end |
endtask |
|
task write_single; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
|
reg [1:0] resp; |
begin |
write_single_ack(addr, wdata, resp); |
end |
endtask |
|
task chk_scrbrd; |
reg [ADDR_BITS-1:0] addr; |
reg [DATA_BITS-1:0] mask; |
reg [DATA_BITS-1:0] expected_data; |
reg [DATA_BITS-1:0] rdata; |
reg [DATA_BITS-1:0] rdata_masked; |
reg [1:0] resp; |
|
begin |
if (!wr_resp_empty) get_wr_resp(resp); |
get_scrbrd(addr, expected_data, mask); |
get_rd_resp(rdata, resp); |
expected_data = expected_data & mask; //TBD insert z as dontcare (for print) |
rdata_masked = rdata & mask; |
|
if (expected_data !== rdata_masked) |
$display("MASTER%0d: SCRBRD_ERROR: Address: 0x%0h, Expected: 0x%0h, Received: 0x%0h.\tTime: %0d ns.", MASTER_NUM, addr, expected_data, rdata, $time); |
end |
endtask |
|
always @(posedge scrbrd_enable) |
begin |
while (scrbrd_enable) |
begin |
chk_scrbrd; |
end |
end |
|
|
CREATE prgen_fifo.v DEFCMD(DEFINE STUB) |
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS) |
rd_cmd_list( |
.clk(clk), |
.reset(reset), |
.push(rd_cmd_push), |
.pop(rd_cmd_pop), |
.din({ |
rd_cmd_size_in, |
rd_cmd_len_in, |
rd_cmd_addr_in |
}), |
.dout({ |
rd_cmd_size, |
rd_cmd_len, |
rd_cmd_addr |
}), |
.fullness(rd_cmd_fullness), |
.empty(rd_cmd_empty), |
.full(rd_cmd_full) |
); |
|
prgen_fifo_stub #(ADDR_BITS+SIZE_BITS, MAX_CMDS) |
rd_resp_list( |
.clk(clk), |
.reset(reset), |
.push(rd_resp_push), |
.pop(rd_resp_pop), |
.din({ |
rd_resp_addr_in, |
rd_resp_size_in |
}), |
.dout({ |
rd_resp_addr, |
rd_resp_size |
}), |
.empty(rd_resp_empty), |
.full(rd_resp_full) |
); |
|
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS) |
wr_cmd_list( |
.clk(clk), |
.reset(reset), |
.push(wr_cmd_push), |
.pop(wr_cmd_pop), |
.din({ |
wr_cmd_size_in, |
wr_cmd_len_in, |
wr_cmd_addr_in |
}), |
.dout({ |
wr_cmd_size, |
wr_cmd_len, |
wr_cmd_addr |
}), |
.fullness(wr_cmd_fullness), |
.empty(wr_cmd_empty), |
.full(wr_cmd_full) |
); |
|
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS) |
wr_data_list( |
.clk(clk), |
.reset(reset), |
.push(wr_data_push), |
.pop(wr_data_pop), |
.din({ |
wr_data_size_in, |
wr_data_len_in, |
wr_data_addr_in |
}), |
.dout({ |
wr_data_size, |
wr_data_len, |
wr_data_addr |
}), |
.fullness(wr_data_fullness), |
.empty(wr_data_empty), |
.full(wr_data_full) |
); |
|
prgen_fifo_stub #(2, MAX_CMDS) |
wr_resp_list( |
.clk(clk), |
.reset(reset), |
.push(wr_resp_push), |
.pop(wr_resp_pop), |
.din(wr_resp_resp_in), |
.dout(wr_resp_resp), |
.empty(wr_resp_empty), |
.full(wr_resp_full) |
); |
|
|
prgen_fifo_stub #(DATA_BITS, MAX_CMDS*EXPR(2^LEN_BITS)) |
wr_data_fifo( |
.clk(clk), |
.reset(reset), |
.push(wr_fifo_push), |
.pop(wr_fifo_pop), |
.din(wr_fifo_data_in), |
.dout(wr_fifo_data), |
.empty(wr_fifo_empty), |
.full(wr_fifo_full) |
); |
|
prgen_fifo_stub #(DATA_BITS+2, MAX_CMDS*EXPR(2^LEN_BITS)) |
rd_data_fifo( |
.clk(clk), |
.reset(reset), |
.push(rd_fifo_push), |
.pop(rd_fifo_pop), |
.din({ |
rd_fifo_data_in, |
rd_fifo_resp_in |
}), |
.dout({ |
rd_fifo_data, |
rd_fifo_resp |
}), |
.empty(rd_fifo_empty), |
.full(rd_fifo_full) |
); |
|
prgen_fifo_stub #(ADDR_BITS+2*DATA_BITS, MAX_CMDS*EXPR(2^LEN_BITS)) |
scrbrd_fifo( |
.clk(clk), |
.reset(reset), |
.push(scrbrd_push), |
.pop(scrbrd_pop), |
.din({ |
scrbrd_addr_in, |
scrbrd_data_in, |
scrbrd_mask_in |
}), |
.dout({ |
scrbrd_addr, |
scrbrd_data, |
scrbrd_mask |
}), |
.empty(scrbrd_empty), |
.full(scrbrd_full) |
); |
|
|
CREATE axi_master_stall.v |
PREFIX_stall |
PREFIX_stall ( |
.clk(clk), |
.reset(reset), |
|
.rd_hold(rd_hold), |
.wr_hold(wr_hold), |
|
.ARVALID_pre(ARVALID_pre), |
.RREADY_pre(RREADY_pre), |
.AWVALID_pre(AWVALID_pre), |
.WVALID_pre(WVALID_pre), |
.BREADY_pre(BREADY_pre), |
|
.ARREADY(ARREADY), |
.AWREADY(AWREADY), |
.WREADY(WREADY), |
|
.ARVALID(ARVALID), |
.RREADY(RREADY), |
.AWVALID(AWVALID), |
.WVALID(WVALID), |
.BREADY(BREADY) |
); |
|
|
endmodule |
|
|
|
OUTFILE PREFIX_single.v |
|
INCLUDE def_axi_master.txt |
|
module PREFIX_single(PORTS); |
|
parameter MASTER_NUM = 0; |
parameter MASTER_ID = 0; |
parameter MASTER_PEND = 0; |
|
`include "prgen_rand.v" |
|
parameter MAX_CMDS = 16; //Depth of command FIFO |
parameter DATA_LOG = LOG2(EXPR(DATA_BITS/8)); |
parameter PEND_BITS = |
(MAX_CMDS <= 16) ? 4 : |
(MAX_CMDS <= 32) ? 5 : |
(MAX_CMDS <= 64) ? 6 : |
(MAX_CMDS <= 128) ? 7 : |
(MAX_CMDS <= 256) ? 8 : |
(MAX_CMDS <= 512) ? 9 : 0; //0 is ilegal |
|
|
|
input clk; |
input reset; |
|
port GROUP_STUB_AXI; |
|
output idle; |
output scrbrd_empty; |
|
|
|
//random parameters |
integer GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND.DEFAULT; |
|
reg AWVALID_pre; |
reg WVALID_pre; |
wire BREADY_pre; |
reg ARVALID_pre; |
wire RREADY_pre; |
|
reg enable = 0; |
reg rd_enable = 0; |
reg wr_enable = 0; |
reg wait_for_write = 0; |
|
reg scrbrd_enable = 0; |
reg [LEN_BITS-1:0] wvalid_cnt; |
|
reg rd_cmd_push = 0; |
wire rd_cmd_pop; |
wire [PEND_BITS:0] rd_cmd_fullness; |
wire rd_cmd_empty; |
wire rd_cmd_full; |
reg [ADDR_BITS-1:0] rd_cmd_addr_in; |
reg [LEN_BITS-1:0] rd_cmd_len_in; |
reg [SIZE_BITS-1:0] rd_cmd_size_in; |
wire [ADDR_BITS-1:0] rd_cmd_addr; |
wire [LEN_BITS-1:0] rd_cmd_len; |
wire [SIZE_BITS-1:0] rd_cmd_size; |
|
reg rd_resp_push = 0; |
wire rd_resp_pop; |
wire rd_resp_empty; |
wire rd_resp_full; |
reg [ADDR_BITS-1:0] rd_resp_addr_in; |
reg [SIZE_BITS-1:0] rd_resp_size_in; |
wire [ADDR_BITS-1:0] rd_resp_addr; |
wire [SIZE_BITS-1:0] rd_resp_size; |
|
reg wr_cmd_push = 0; |
wire wr_cmd_pop; |
wire [PEND_BITS:0] wr_cmd_fullness; |
wire wr_cmd_empty; |
wire wr_cmd_full; |
reg [ADDR_BITS-1:0] wr_cmd_addr_in; |
reg [LEN_BITS-1:0] wr_cmd_len_in; |
reg [SIZE_BITS-1:0] wr_cmd_size_in; |
wire [ADDR_BITS-1:0] wr_cmd_addr; |
wire [LEN_BITS-1:0] wr_cmd_len; |
wire [SIZE_BITS-1:0] wr_cmd_size; |
|
reg wr_data_push = 0; |
wire wr_data_pop; |
wire [PEND_BITS:0] wr_data_fullness; |
wire wr_data_empty; |
wire wr_data_full; |
reg [ADDR_BITS-1:0] wr_data_addr_in; |
reg [LEN_BITS-1:0] wr_data_len_in; |
reg [SIZE_BITS-1:0] wr_data_size_in; |
wire [ADDR_BITS-1:0] wr_data_addr; |
wire [LEN_BITS-1:0] wr_data_len; |
wire [SIZE_BITS-1:0] wr_data_size; |
wire [DATA_BITS/8-1:0] wr_data_strb; |
wire [7:0] wr_data_bytes; |
wire [ADDR_BITS-1:0] wr_data_addr_prog; |
wire [7:0] wr_data_offset; |
|
wire wr_resp_push; |
reg wr_resp_pop = 0; |
wire wr_resp_empty; |
wire wr_resp_full; |
wire [1:0] wr_resp_resp_in; |
wire [1:0] wr_resp_resp; |
|
reg wr_fifo_push = 0; |
wire wr_fifo_pop; |
wire wr_fifo_empty; |
wire wr_fifo_full; |
reg [DATA_BITS-1:0] wr_fifo_data_in; |
wire [DATA_BITS-1:0] wr_fifo_data; |
|
wire rd_fifo_push; |
reg rd_fifo_pop = 0; |
wire rd_fifo_empty; |
wire rd_fifo_full; |
wire [DATA_BITS-1:0] rd_fifo_data_in; |
wire [1:0] rd_fifo_resp_in; |
wire [DATA_BITS-1:0] rd_fifo_data; |
wire [1:0] rd_fifo_resp; |
|
reg scrbrd_push = 0; |
reg scrbrd_pop = 0; |
wire scrbrd_empty; |
wire scrbrd_full; |
reg [ADDR_BITS-1:0] scrbrd_addr_in; |
reg [DATA_BITS-1:0] scrbrd_data_in; |
reg [DATA_BITS-1:0] scrbrd_mask_in; |
wire [ADDR_BITS-1:0] scrbrd_addr; |
wire [DATA_BITS-1:0] scrbrd_data; |
wire [DATA_BITS-1:0] scrbrd_mask; |
|
integer wr_fullness; |
integer rd_fullness; |
integer rd_completed; |
integer wr_completed; |
integer wr_pend_max = MASTER_PEND; |
integer rd_pend_max = MASTER_PEND; |
wire wr_hold; |
wire rd_hold; |
|
integer rand_chk_num = 0; |
|
|
assign idle = rd_cmd_empty & rd_resp_empty & wr_cmd_empty & wr_data_empty & wr_resp_empty; |
|
always @(rand_chk_num) |
if (rand_chk_num > 0) |
insert_rand_chk_loop(rand_chk_num); |
|
always @(posedge enable) |
begin |
@(posedge clk); |
wr_enable = 1; |
repeat (50) @(posedge clk); |
rd_enable = 1; |
end |
|
//for incremental data |
reg [DATA_BITS-1:0] base_data = 0; |
integer ww; |
initial |
begin |
ww=0; |
while (ww < DATA_BITS/8) |
begin |
base_data = base_data + ((MASTER_NUM + ww) << (ww*8)); |
ww = ww + 1; |
end |
end |
|
assign rd_cmd_pop = ARVALID & ARREADY; |
assign rd_resp_pop = RVALID & RREADY & RLAST; |
assign rd_fifo_push = RVALID & RREADY; |
assign wr_cmd_pop = AWVALID & AWREADY; |
assign wr_data_pop = WVALID & WREADY & WLAST; |
assign wr_fifo_pop = WVALID & WREADY; |
assign wr_resp_push = BVALID & BREADY; |
|
assign RREADY_pre = 1; |
assign BREADY_pre = 1; |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
AWVALID_pre <= #FFD 1'b0; |
else if ((wr_cmd_fullness == 1) & wr_cmd_pop) |
AWVALID_pre <= #FFD 1'b0; |
else if ((!wr_cmd_empty) & wr_enable) |
AWVALID_pre <= #FFD 1'b1; |
|
|
assign AWADDR = wr_cmd_addr; |
assign AWLEN = wr_cmd_len; |
assign AWSIZE = wr_cmd_size; |
assign AWID = MASTER_ID; |
assign AWBURST = 2'd1; //INCR only |
assign AWCACHE = 4'd0; //not supported |
assign AWPROT = 4'd0; //not supported |
assign AWLOCK = 2'd0; //not supported |
|
always @(posedge clk or posedge reset) |
if (reset) |
ARVALID_pre <= #FFD 1'b0; |
else if (((rd_cmd_fullness == 1)) & rd_cmd_pop) |
ARVALID_pre <= #FFD 1'b0; |
else if ((!rd_cmd_empty) & rd_enable) |
ARVALID_pre <= #FFD 1'b1; |
|
assign ARADDR = rd_cmd_addr; |
assign ARLEN = rd_cmd_len; |
assign ARSIZE = rd_cmd_size; |
assign ARID = MASTER_ID; |
assign ARBURST = 2'd1; //INCR only |
assign ARCACHE = 4'd0; //not supported |
assign ARPROT = 4'd0; //not supported |
assign ARLOCK = 2'd0; //not supported |
|
assign rd_fifo_data_in = RDATA; |
assign rd_fifo_resp_in = BRESP; |
|
assign wr_data_bytes = 1'b1 << wr_data_size; |
|
assign wr_data_strb = |
wr_data_size == 'd0 ? 1'b1 : |
wr_data_size == 'd1 ? 2'b11 : |
wr_data_size == 'd2 ? 4'b1111 : |
wr_data_size == 'd3 ? {8{1'b1}} : |
wr_data_size == 'd4 ? {16{1'b1}} : 'd0; |
|
assign wr_data_addr_prog = wr_data_addr + (wvalid_cnt * wr_data_bytes); |
|
always @(posedge clk or posedge reset) |
if (reset) |
WVALID_pre <= #FFD 1'b0; |
else if ((wr_data_fullness == 1) & wr_data_pop) |
WVALID_pre <= #FFD 1'b0; |
else if ((!wr_data_empty) & wr_enable) |
WVALID_pre <= #FFD 1'b1; |
|
|
assign wr_data_offset = wr_data_addr_prog[DATA_LOG-1:0]; |
|
assign WID = MASTER_ID; |
assign WDATA = wr_fifo_empty ? 0 : wr_fifo_data; |
assign WSTRB = wr_data_strb << wr_data_offset; |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
wvalid_cnt <= #FFD {LEN_BITS{1'b0}}; |
else if (wr_data_pop) |
wvalid_cnt <= #FFD {LEN_BITS{1'b0}}; |
else if (WVALID & WREADY) |
wvalid_cnt <= #FFD wvalid_cnt + 1'b1; |
|
assign WLAST = WVALID & (wvalid_cnt == wr_data_len); |
|
assign wr_resp_resp_in = BRESP; |
|
always @(posedge clk or posedge reset) |
if (reset) |
begin |
wr_fullness <= #FFD 0; |
rd_fullness <= #FFD 0; |
rd_completed <= #FFD 0; |
wr_completed <= #FFD 0; |
end |
else |
begin |
wr_fullness <= #FFD wr_fullness + wr_cmd_pop - wr_resp_push; |
rd_fullness <= #FFD rd_fullness + rd_cmd_pop - rd_resp_pop; |
rd_completed <= #FFD rd_completed + rd_resp_pop; |
wr_completed <= #FFD wr_completed + wr_resp_push; |
end |
|
assign wr_hold = wr_fullness >= wr_pend_max; |
assign rd_hold = (rd_fullness >= rd_pend_max) | (wait_for_write & (wr_completed <= rd_completed + rd_fullness)); |
|
|
|
task insert_rd_cmd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
begin |
rd_cmd_addr_in = addr; |
rd_cmd_len_in = len; |
rd_cmd_size_in = size; |
rd_resp_addr_in = addr; |
rd_resp_size_in = size; |
|
if (rd_cmd_full) enable = 1; //start stub not started yet |
|
wait ((!rd_cmd_full) & (!rd_resp_full)); |
@(negedge clk); #FFD; |
rd_cmd_push = 1; |
rd_resp_push = 1; |
@(posedge clk); #FFD; |
rd_cmd_push = 0; |
rd_resp_push = 0; |
end |
endtask |
|
task insert_wr_cmd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
begin |
wr_cmd_addr_in = addr; |
wr_cmd_len_in = len; |
wr_cmd_size_in = size; |
wr_data_addr_in = addr; |
wr_data_len_in = len; |
wr_data_size_in = size; |
|
if (wr_cmd_full) enable = 1; //start stub not started yet |
|
wait ((!wr_cmd_full) & (!wr_data_full)); |
@(negedge clk); #FFD; |
wr_cmd_push = 1; |
wr_data_push = 1; |
@(posedge clk); #FFD; |
wr_cmd_push = 0; |
wr_data_push = 0; |
end |
endtask |
|
task insert_wr_data; |
input [DATA_BITS-1:0] wdata; |
|
begin |
wr_fifo_data_in = wdata; |
|
wait (!wr_fifo_full); |
@(negedge clk); #FFD; |
wr_fifo_push = 1; |
@(posedge clk); #FFD; |
wr_fifo_push = 0; |
end |
endtask |
|
task insert_wr_incr_data; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
integer valid_cnt; |
integer wdata_cnt; |
reg [7:0] data_cnt; |
integer bytes; |
reg [DATA_BITS-1:0] add_data; |
reg [DATA_BITS-1:0] next_data; |
begin |
//insert data |
valid_cnt = 0; |
while (valid_cnt <= len) |
begin |
bytes = 1'b1 << size; |
wdata_cnt = valid_cnt+(addr[DATA_LOG-1:0]/bytes); |
data_cnt = ((wdata_cnt)/(DATA_BITS/(bytes*8))) * (DATA_BITS/8); |
add_data = {DATA_BITS/8{data_cnt}}; |
next_data = (use_addr_base ? addr : base_data) + add_data; |
insert_wr_data(next_data); |
valid_cnt = valid_cnt+1; |
end |
//insert command |
insert_wr_cmd(addr, len, size); |
end |
endtask |
|
task insert_scrbrd; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] data; |
input [DATA_BITS-1:0] mask; |
begin |
scrbrd_enable = 1; |
scrbrd_addr_in = addr; |
scrbrd_data_in = data; |
scrbrd_mask_in = mask; |
|
wait (!scrbrd_full); |
@(negedge clk); #FFD; |
scrbrd_push = 1; |
@(posedge clk); #FFD; |
scrbrd_push = 0; |
end |
endtask |
|
task insert_scrbrd_incr_data; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
integer valid_cnt; |
integer wdata_cnt; |
reg [7:0] data_cnt; |
integer bytes; |
reg [DATA_BITS-1:0] add_data; |
reg [DATA_BITS-1:0] next_data; |
reg [DATA_BITS:0] strb; |
reg [DATA_BITS-1:0] mask; |
reg [ADDR_BITS-1:0] next_addr; |
begin |
valid_cnt = 0; |
while (valid_cnt <= len) |
begin |
bytes = 1'b1 << size; |
wdata_cnt = valid_cnt+(addr[DATA_LOG-1:0]/bytes); |
data_cnt = ((wdata_cnt)/(DATA_BITS/(bytes*8))) * (DATA_BITS/8); |
add_data = {DATA_BITS/8{data_cnt}}; |
next_data = (use_addr_base ? addr : base_data) + add_data; |
next_addr = addr + (bytes * valid_cnt); |
strb = (1 << (bytes*8)) - 1; |
mask = strb << (next_addr[DATA_LOG-1:0]*8); |
insert_scrbrd(next_addr, next_data, mask); |
valid_cnt = valid_cnt+1; |
end |
end |
endtask |
|
task insert_rd_scrbrd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
begin |
insert_scrbrd_incr_data(addr, len, size); |
insert_rd_cmd(addr, len, size); |
end |
endtask |
|
task insert_wr_rd_scrbrd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
|
begin |
wait_for_write=1; |
insert_wr_incr_data(addr, len, size); |
insert_rd_scrbrd(addr, len, size); |
end |
endtask |
|
task insert_wr_rd_scrbrd_rand; |
reg [ADDR_BITS-1:0] addr; |
reg [LEN_BITS-1:0] len; |
reg [SIZE_BITS-1:0] size; |
|
begin |
len = rand(len_min, len_max); |
size = rand(size_min, size_max); |
addr = rand_align(addr_min, addr_max, 1 << size); |
insert_wr_rd_scrbrd(addr, len, size); |
end |
endtask |
|
task insert_rand_chk; |
input [31:0] num; |
|
rand_chk_num = num; |
endtask |
|
task insert_rand_chk_loop; |
input [31:0] num; |
|
integer i; |
begin |
i = 0; |
while (i < num) |
begin |
insert_wr_rd_scrbrd_rand; |
i = i + 1; |
end |
end |
endtask |
|
task insert_wr_single; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
|
reg [SIZE_BITS-1:0] size; |
begin |
size = EXPR((DATA_BITS/32)+1); |
insert_wr_data(wdata); |
insert_wr_cmd(addr, 0, size); |
end |
endtask |
|
task get_rd_resp; |
output [DATA_BITS-1:0] rdata; |
output [1:0] resp; |
|
reg [DATA_BITS-1:0] rdata; |
reg [1:0] resp; |
begin |
wait (!rd_fifo_empty); |
rdata = rd_fifo_data; |
resp = rd_fifo_resp; |
@(negedge clk); #FFD; |
rd_fifo_pop = 1; |
@(posedge clk); #FFD; |
rd_fifo_pop = 0; |
end |
endtask |
|
task get_scrbrd; |
output [ADDR_BITS-1:0] addr; |
output [DATA_BITS-1:0] rdata; |
output [DATA_BITS-1:0] mask; |
|
reg [ADDR_BITS-1:0] addr; |
reg [DATA_BITS-1:0] rdata; |
reg [DATA_BITS-1:0] mask; |
begin |
wait (!scrbrd_empty); |
addr = scrbrd_addr; |
rdata = scrbrd_data; |
mask = scrbrd_mask; |
@(negedge clk); #FFD; |
scrbrd_pop = 1; |
@(posedge clk); #FFD; |
scrbrd_pop = 0; |
end |
endtask |
|
task get_wr_resp; |
output [1:0] resp; |
|
reg [1:0] resp; |
begin |
wait (!wr_resp_empty); |
resp = wr_resp_resp; |
@(negedge clk); #FFD; |
wr_resp_pop = 1; |
@(posedge clk); #FFD; |
wr_resp_pop = 0; |
end |
endtask |
|
task insert_rd_single; |
input [ADDR_BITS-1:0] addr; |
|
reg [SIZE_BITS-1:0] size; |
begin |
size = EXPR((DATA_BITS/32)+1); |
insert_rd_cmd(addr, 0, size); |
end |
endtask |
|
task read_single_ack; |
input [ADDR_BITS-1:0] addr; |
output [DATA_BITS-1:0] rdata; |
output [1:0] resp; |
|
reg [1:0] resp; |
begin |
insert_rd_single(addr); |
get_rd_resp(rdata, resp); |
end |
endtask |
|
task write_single_ack; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
output [1:0] resp; |
|
reg [1:0] resp; |
begin |
insert_wr_single(addr, wdata); |
get_wr_resp(resp); |
end |
endtask |
|
task read_single; |
input [ADDR_BITS-1:0] addr; |
output [DATA_BITS-1:0] rdata; |
|
reg [1:0] resp; |
begin |
read_single_ack(addr, rdata, resp); |
end |
endtask |
|
task check_single; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] expected; |
|
reg [1:0] resp; |
reg [DATA_BITS-1:0] rdata; |
begin |
read_single_ack(addr, rdata, resp); |
if (rdata !== expected) |
$display("MASTER%0d: CHK_SINGLE_ERROR: Address: 0x%0h, Expected: 0x%0h, Received: 0x%0h.\tTime: %0d ns.", MASTER_NUM, addr, expected, rdata, $time); |
end |
endtask |
|
task write_and_check_single; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] data; |
|
begin |
write_single(addr, data); |
check_single(addr, data); |
end |
endtask |
|
task write_single; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
|
reg [1:0] resp; |
begin |
write_single_ack(addr, wdata, resp); |
end |
endtask |
|
task chk_scrbrd; |
reg [ADDR_BITS-1:0] addr; |
reg [DATA_BITS-1:0] mask; |
reg [DATA_BITS-1:0] expected_data; |
reg [DATA_BITS-1:0] rdata; |
reg [DATA_BITS-1:0] rdata_masked; |
reg [1:0] resp; |
|
begin |
if (!wr_resp_empty) get_wr_resp(resp); |
get_scrbrd(addr, expected_data, mask); |
get_rd_resp(rdata, resp); |
expected_data = expected_data & mask; //TBD insert z as dontcare (for print) |
rdata_masked = rdata & mask; |
|
if (expected_data !== rdata_masked) |
$display("MASTER%0d: SCRBRD_ERROR: Address: 0x%0h, Expected: 0x%0h, Received: 0x%0h.\tTime: %0d ns.", MASTER_NUM, addr, expected_data, rdata, $time); |
end |
endtask |
|
always @(posedge scrbrd_enable) |
begin |
while (scrbrd_enable) |
begin |
chk_scrbrd; |
end |
end |
|
|
CREATE prgen_fifo.v DEFCMD(DEFINE STUB) |
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS) |
rd_cmd_list( |
.clk(clk), |
.reset(reset), |
.push(rd_cmd_push), |
.pop(rd_cmd_pop), |
.din({ |
rd_cmd_size_in, |
rd_cmd_len_in, |
rd_cmd_addr_in |
}), |
.dout({ |
rd_cmd_size, |
rd_cmd_len, |
rd_cmd_addr |
}), |
.fullness(rd_cmd_fullness), |
.empty(rd_cmd_empty), |
.full(rd_cmd_full) |
); |
|
prgen_fifo_stub #(ADDR_BITS+SIZE_BITS, MAX_CMDS) |
rd_resp_list( |
.clk(clk), |
.reset(reset), |
.push(rd_resp_push), |
.pop(rd_resp_pop), |
.din({ |
rd_resp_addr_in, |
rd_resp_size_in |
}), |
.dout({ |
rd_resp_addr, |
rd_resp_size |
}), |
.empty(rd_resp_empty), |
.full(rd_resp_full) |
); |
|
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS) |
wr_cmd_list( |
.clk(clk), |
.reset(reset), |
.push(wr_cmd_push), |
.pop(wr_cmd_pop), |
.din({ |
wr_cmd_size_in, |
wr_cmd_len_in, |
wr_cmd_addr_in |
}), |
.dout({ |
wr_cmd_size, |
wr_cmd_len, |
wr_cmd_addr |
}), |
.fullness(wr_cmd_fullness), |
.empty(wr_cmd_empty), |
.full(wr_cmd_full) |
); |
|
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS) |
wr_data_list( |
.clk(clk), |
.reset(reset), |
.push(wr_data_push), |
.pop(wr_data_pop), |
.din({ |
wr_data_size_in, |
wr_data_len_in, |
wr_data_addr_in |
}), |
.dout({ |
wr_data_size, |
wr_data_len, |
wr_data_addr |
}), |
.fullness(wr_data_fullness), |
.empty(wr_data_empty), |
.full(wr_data_full) |
); |
|
prgen_fifo_stub #(2, MAX_CMDS) |
wr_resp_list( |
.clk(clk), |
.reset(reset), |
.push(wr_resp_push), |
.pop(wr_resp_pop), |
.din(wr_resp_resp_in), |
.dout(wr_resp_resp), |
.empty(wr_resp_empty), |
.full(wr_resp_full) |
); |
|
|
prgen_fifo_stub #(DATA_BITS, MAX_CMDS*EXPR(2^LEN_BITS)) |
wr_data_fifo( |
.clk(clk), |
.reset(reset), |
.push(wr_fifo_push), |
.pop(wr_fifo_pop), |
.din(wr_fifo_data_in), |
.dout(wr_fifo_data), |
.empty(wr_fifo_empty), |
.full(wr_fifo_full) |
); |
|
prgen_fifo_stub #(DATA_BITS+2, MAX_CMDS*EXPR(2^LEN_BITS)) |
rd_data_fifo( |
.clk(clk), |
.reset(reset), |
.push(rd_fifo_push), |
.pop(rd_fifo_pop), |
.din({ |
rd_fifo_data_in, |
rd_fifo_resp_in |
}), |
.dout({ |
rd_fifo_data, |
rd_fifo_resp |
}), |
.empty(rd_fifo_empty), |
.full(rd_fifo_full) |
); |
|
prgen_fifo_stub #(ADDR_BITS+2*DATA_BITS, MAX_CMDS*EXPR(2^LEN_BITS)) |
scrbrd_fifo( |
.clk(clk), |
.reset(reset), |
.push(scrbrd_push), |
.pop(scrbrd_pop), |
.din({ |
scrbrd_addr_in, |
scrbrd_data_in, |
scrbrd_mask_in |
}), |
.dout({ |
scrbrd_addr, |
scrbrd_data, |
scrbrd_mask |
}), |
.empty(scrbrd_empty), |
.full(scrbrd_full) |
); |
|
|
CREATE axi_master_stall.v |
PREFIX_stall |
PREFIX_stall ( |
.clk(clk), |
.reset(reset), |
|
.rd_hold(rd_hold), |
.wr_hold(wr_hold), |
|
.ARVALID_pre(ARVALID_pre), |
.RREADY_pre(RREADY_pre), |
.AWVALID_pre(AWVALID_pre), |
.WVALID_pre(WVALID_pre), |
.BREADY_pre(BREADY_pre), |
|
.ARREADY(ARREADY), |
.AWREADY(AWREADY), |
.WREADY(WREADY), |
|
.ARVALID(ARVALID), |
.RREADY(RREADY), |
.AWVALID(AWVALID), |
.WVALID(WVALID), |
.BREADY(BREADY) |
); |
|
|
endmodule |
|
|