axi_dmac: tb: Allow testing asymmetric interface widths
One of the major features of the DMAC is being able to handle non matching interface widths for the destination and source side. Currently the test benches only support the case where the width for the source and the destination side are the same. Extend them so that it is possible to also test and verify setups where the width is not the same. To accomplish this each byte memory location is treated as if it contained the lower 8 bytes of its address. And then the written/read data is compared to the expected data based on that. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>main
parent
29e6bbde88
commit
764f31463e
|
@ -62,18 +62,20 @@ module axi_read_slave #(
|
||||||
|
|
||||||
reg [DATA_WIDTH-1:0] data = 'h00;
|
reg [DATA_WIDTH-1:0] data = 'h00;
|
||||||
|
|
||||||
assign rresp = 2'b00;
|
wire [31:0] beat_addr;
|
||||||
//assign rdata = data;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
assign rresp = 2'b00;
|
||||||
if (reset == 1'b1) begin
|
assign rdata = data;
|
||||||
data <= 'h00;
|
|
||||||
end else if (rvalid == 1'b1 && rready == 1'b1) begin
|
always @(*) begin: gen_data
|
||||||
data <= data + 1'b1;
|
integer i;
|
||||||
|
for (i = 0; i < DATA_WIDTH; i = i + 8) begin
|
||||||
|
data[i+:8] <= beat_addr[7:0] + i / 8;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
axi_slave #(
|
axi_slave #(
|
||||||
|
.DATA_WIDTH(DATA_WIDTH),
|
||||||
.ACCEPTANCE(READ_ACCEPTANCE),
|
.ACCEPTANCE(READ_ACCEPTANCE),
|
||||||
.MIN_LATENCY(MIN_LATENCY),
|
.MIN_LATENCY(MIN_LATENCY),
|
||||||
.MAX_LATENCY(MAX_LATENCY)
|
.MAX_LATENCY(MAX_LATENCY)
|
||||||
|
@ -93,7 +95,7 @@ axi_slave #(
|
||||||
.beat_stb(rvalid),
|
.beat_stb(rvalid),
|
||||||
.beat_ack(rvalid & rready),
|
.beat_ack(rvalid & rready),
|
||||||
.beat_last(rlast),
|
.beat_last(rlast),
|
||||||
.beat_addr(rdata)
|
.beat_addr(beat_addr)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
`timescale 1ns/100ps
|
`timescale 1ns/100ps
|
||||||
|
|
||||||
module axi_slave #(
|
module axi_slave #(
|
||||||
|
parameter DATA_WIDTH = 32,
|
||||||
parameter ACCEPTANCE = 3,
|
parameter ACCEPTANCE = 3,
|
||||||
parameter MIN_LATENCY = 16,
|
parameter MIN_LATENCY = 16,
|
||||||
parameter MAX_LATENCY = 32
|
parameter MAX_LATENCY = 32
|
||||||
|
@ -91,7 +92,7 @@ reg [7:0] beat_counter = 'h00;
|
||||||
|
|
||||||
assign beat_stb = req_fifo_level != 0 && timestamp > req_fifo[req_fifo_rd][71:40];
|
assign beat_stb = req_fifo_level != 0 && timestamp > req_fifo[req_fifo_rd][71:40];
|
||||||
assign beat_last = beat_stb ? beat_counter == req_fifo[req_fifo_rd][0+:8] : 1'b0;
|
assign beat_last = beat_stb ? beat_counter == req_fifo[req_fifo_rd][0+:8] : 1'b0;
|
||||||
assign beat_addr = req_fifo[req_fifo_rd][8+:32] + beat_counter * 4;
|
assign beat_addr = req_fifo[req_fifo_rd][8+:32] + beat_counter * DATA_WIDTH / 8;
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (reset == 1'b1) begin
|
if (reset == 1'b1) begin
|
||||||
|
|
|
@ -115,15 +115,30 @@ always @(posedge clk) begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge clk) begin
|
integer byte_count;
|
||||||
|
|
||||||
|
always @(*) begin: count
|
||||||
|
integer i;
|
||||||
|
byte_count = 0;
|
||||||
|
for (i = 0; i < DATA_WIDTH / 8; i = i + 1) begin
|
||||||
|
byte_count = byte_count + wstrb[i];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin: gen_data_cmp
|
||||||
|
integer i;
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
data_cmp <= 'h00;
|
for (i = 0; i < DATA_WIDTH; i = i + 8) begin
|
||||||
|
data_cmp[i+:8] <= i/8;
|
||||||
|
end
|
||||||
failed <= 'b0;
|
failed <= 'b0;
|
||||||
end else if (wvalid & wready) begin
|
end else if (wvalid & wready) begin
|
||||||
if (data_cmp !== wdata) begin
|
for (i = 0; i < DATA_WIDTH; i = i + 8) begin
|
||||||
failed <= 1'b1;
|
if (data_cmp[i+:8] !== wdata[i+:8] && wstrb[i/8] == 1'b1) begin
|
||||||
|
failed <= 1'b1;
|
||||||
|
end
|
||||||
|
data_cmp[i+:8] <= data_cmp[i+:8] + byte_count;
|
||||||
end
|
end
|
||||||
data_cmp <= data_cmp + 'h4;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -37,15 +37,18 @@
|
||||||
|
|
||||||
module dmac_dma_read_tb;
|
module dmac_dma_read_tb;
|
||||||
parameter VCD_FILE = {`__FILE__,"cd"};
|
parameter VCD_FILE = {`__FILE__,"cd"};
|
||||||
|
parameter WIDTH_DEST = 32;
|
||||||
|
parameter WIDTH_SRC = 32;
|
||||||
|
parameter REQ_LEN_INC = 4;
|
||||||
|
parameter REQ_LEN_INIT = 4;
|
||||||
|
|
||||||
`include "tb_base.v"
|
`include "tb_base.v"
|
||||||
|
|
||||||
localparam TRANSFER_ADDR = 32'h80000000;
|
localparam TRANSFER_ADDR = 32'h80000000;
|
||||||
localparam TRANSFER_LEN = 24'h203;
|
|
||||||
|
|
||||||
reg req_valid = 1'b1;
|
reg req_valid = 1'b1;
|
||||||
wire req_ready;
|
wire req_ready;
|
||||||
reg [23:0] req_length = 'h03;
|
reg [23:0] req_length = REQ_LEN_INIT - 1;
|
||||||
|
|
||||||
wire awvalid;
|
wire awvalid;
|
||||||
wire awready;
|
wire awready;
|
||||||
|
@ -60,18 +63,18 @@ module dmac_dma_read_tb;
|
||||||
wire rvalid;
|
wire rvalid;
|
||||||
wire rready;
|
wire rready;
|
||||||
wire [1:0] rresp;
|
wire [1:0] rresp;
|
||||||
wire [31:0] rdata;
|
wire [WIDTH_SRC-1:0] rdata;
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (reset != 1'b1 && req_ready == 1'b1) begin
|
if (reset != 1'b1 && req_ready == 1'b1) begin
|
||||||
req_valid <= 1'b1;
|
req_valid <= 1'b1;
|
||||||
req_length <= req_length + 4;
|
req_length <= req_length + REQ_LEN_INC;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
axi_read_slave #(
|
axi_read_slave #(
|
||||||
.DATA_WIDTH(32)
|
.DATA_WIDTH(WIDTH_SRC)
|
||||||
) i_write_slave (
|
) i_read_slave (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
|
|
||||||
|
@ -94,16 +97,17 @@ module dmac_dma_read_tb;
|
||||||
wire fifo_rd_en = 1'b1;
|
wire fifo_rd_en = 1'b1;
|
||||||
wire fifo_rd_valid;
|
wire fifo_rd_valid;
|
||||||
wire fifo_rd_underflow;
|
wire fifo_rd_underflow;
|
||||||
wire [31:0] fifo_rd_dout;
|
wire [WIDTH_DEST-1:0] fifo_rd_dout;
|
||||||
reg [31:0] fifo_rd_dout_cmp = TRANSFER_ADDR;
|
reg [WIDTH_DEST-1:0] fifo_rd_dout_cmp = 'h00;
|
||||||
reg fifo_rd_dout_mismatch = 1'b0;
|
reg fifo_rd_dout_mismatch = 1'b0;
|
||||||
reg [31:0] fifo_rd_dout_limit = 'h0;
|
reg [23:0] fifo_rd_req_length = REQ_LEN_INIT;
|
||||||
|
reg [23:0] fifo_rd_beat_counter = 'h00;
|
||||||
|
|
||||||
axi_dmac_transfer #(
|
axi_dmac_transfer #(
|
||||||
.DMA_TYPE_SRC(0),
|
.DMA_TYPE_SRC(0),
|
||||||
.DMA_TYPE_DEST(2),
|
.DMA_TYPE_DEST(2),
|
||||||
.DMA_DATA_WIDTH_SRC(32),
|
.DMA_DATA_WIDTH_SRC(WIDTH_SRC),
|
||||||
.DMA_DATA_WIDTH_DEST(32),
|
.DMA_DATA_WIDTH_DEST(WIDTH_DEST),
|
||||||
.FIFO_SIZE(8)
|
.FIFO_SIZE(8)
|
||||||
) transfer (
|
) transfer (
|
||||||
.m_src_axi_aclk(clk),
|
.m_src_axi_aclk(clk),
|
||||||
|
@ -134,8 +138,8 @@ module dmac_dma_read_tb;
|
||||||
|
|
||||||
.req_valid(req_valid),
|
.req_valid(req_valid),
|
||||||
.req_ready(req_ready),
|
.req_ready(req_ready),
|
||||||
.req_dest_address(TRANSFER_ADDR[31:2]),
|
.req_dest_address(TRANSFER_ADDR[31:$clog2(WIDTH_DEST/8)]),
|
||||||
.req_src_address(TRANSFER_ADDR[31:2]),
|
.req_src_address(TRANSFER_ADDR[31:$clog2(WIDTH_SRC/8)]),
|
||||||
.req_x_length(req_length),
|
.req_x_length(req_length),
|
||||||
.req_y_length(24'h00),
|
.req_y_length(24'h00),
|
||||||
.req_dest_stride(24'h00),
|
.req_dest_stride(24'h00),
|
||||||
|
@ -149,19 +153,31 @@ module dmac_dma_read_tb;
|
||||||
.fifo_rd_dout(fifo_rd_dout)
|
.fifo_rd_dout(fifo_rd_dout)
|
||||||
);
|
);
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin: dout
|
||||||
|
integer i;
|
||||||
|
|
||||||
if (reset == 1'b1) begin
|
if (reset == 1'b1) begin
|
||||||
fifo_rd_dout_cmp <= TRANSFER_ADDR;
|
for (i = 0; i < WIDTH_DEST; i = i + 8) begin
|
||||||
|
fifo_rd_dout_cmp[i+:8] <= TRANSFER_ADDR[7:0] + i / 8;
|
||||||
|
end
|
||||||
fifo_rd_dout_mismatch <= 1'b0;
|
fifo_rd_dout_mismatch <= 1'b0;
|
||||||
|
fifo_rd_req_length <= REQ_LEN_INIT;
|
||||||
|
fifo_rd_beat_counter <= 'h00;
|
||||||
end else begin
|
end else begin
|
||||||
fifo_rd_dout_mismatch <= 1'b0;
|
fifo_rd_dout_mismatch <= 1'b0;
|
||||||
|
|
||||||
if (fifo_rd_valid == 1'b1) begin
|
if (fifo_rd_valid == 1'b1) begin
|
||||||
if (fifo_rd_dout_cmp < TRANSFER_ADDR + fifo_rd_dout_limit) begin
|
if (fifo_rd_beat_counter + WIDTH_DEST / 8 < fifo_rd_req_length) begin
|
||||||
fifo_rd_dout_cmp <= (fifo_rd_dout_cmp + 'h4);
|
for (i = 0; i < WIDTH_DEST; i = i + 8) begin
|
||||||
|
fifo_rd_dout_cmp[i+:8] <= fifo_rd_dout_cmp[i+:8] + WIDTH_DEST / 8;
|
||||||
|
end
|
||||||
|
fifo_rd_beat_counter <= fifo_rd_beat_counter + WIDTH_DEST / 8;
|
||||||
end else begin
|
end else begin
|
||||||
fifo_rd_dout_cmp <= TRANSFER_ADDR;
|
for (i = 0; i < WIDTH_DEST; i = i + 8) begin
|
||||||
fifo_rd_dout_limit <= fifo_rd_dout_limit + 'h4;
|
fifo_rd_dout_cmp[i+:8] <= TRANSFER_ADDR[7:0] + i / 8;
|
||||||
|
end
|
||||||
|
fifo_rd_beat_counter <= 'h00;
|
||||||
|
fifo_rd_req_length <= fifo_rd_req_length + REQ_LEN_INC;
|
||||||
end
|
end
|
||||||
if (fifo_rd_dout_cmp != fifo_rd_dout) begin
|
if (fifo_rd_dout_cmp != fifo_rd_dout) begin
|
||||||
fifo_rd_dout_mismatch <= 1'b1;
|
fifo_rd_dout_mismatch <= 1'b1;
|
||||||
|
|
|
@ -37,12 +37,18 @@
|
||||||
|
|
||||||
module dmac_dma_write_tb;
|
module dmac_dma_write_tb;
|
||||||
parameter VCD_FILE = {`__FILE__,"cd"};
|
parameter VCD_FILE = {`__FILE__,"cd"};
|
||||||
|
parameter WIDTH_DEST = 32;
|
||||||
|
parameter WIDTH_SRC = 32;
|
||||||
|
parameter REQ_LEN_INC = 4;
|
||||||
|
parameter REQ_LEN_INIT = 4;
|
||||||
|
|
||||||
`include "tb_base.v"
|
`include "tb_base.v"
|
||||||
|
|
||||||
|
localparam TRANSFER_ADDR = 32'h80000000;
|
||||||
|
|
||||||
reg req_valid = 1'b1;
|
reg req_valid = 1'b1;
|
||||||
wire req_ready;
|
wire req_ready;
|
||||||
reg [23:0] req_length = 'h03;
|
reg [23:0] req_length = REQ_LEN_INIT - 1;
|
||||||
wire awvalid;
|
wire awvalid;
|
||||||
wire awready;
|
wire awready;
|
||||||
wire [31:0] awaddr;
|
wire [31:0] awaddr;
|
||||||
|
@ -55,10 +61,10 @@ module dmac_dma_write_tb;
|
||||||
wire wlast;
|
wire wlast;
|
||||||
wire wvalid;
|
wire wvalid;
|
||||||
wire wready;
|
wire wready;
|
||||||
wire [3:0] wstrb;
|
wire [WIDTH_DEST/8-1:0] wstrb;
|
||||||
wire [31:0] wdata;
|
wire [WIDTH_DEST-1:0] wdata;
|
||||||
|
|
||||||
reg [31:0] fifo_wr_din = 'b0;
|
reg [WIDTH_SRC-1:0] fifo_wr_din = 'b0;
|
||||||
reg fifo_wr_rq = 'b0;
|
reg fifo_wr_rq = 'b0;
|
||||||
wire fifo_wr_xfer_req;
|
wire fifo_wr_xfer_req;
|
||||||
|
|
||||||
|
@ -69,12 +75,12 @@ module dmac_dma_write_tb;
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (reset != 1'b1 && req_ready == 1'b1) begin
|
if (reset != 1'b1 && req_ready == 1'b1) begin
|
||||||
req_valid <= 1'b1;
|
req_valid <= 1'b1;
|
||||||
req_length <= req_length + 'h4;
|
req_length <= req_length + REQ_LEN_INC;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
axi_write_slave #(
|
axi_write_slave #(
|
||||||
.DATA_WIDTH(32)
|
.DATA_WIDTH(WIDTH_DEST)
|
||||||
) i_write_slave (
|
) i_write_slave (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.reset(reset),
|
.reset(reset),
|
||||||
|
@ -100,8 +106,8 @@ module dmac_dma_write_tb;
|
||||||
);
|
);
|
||||||
|
|
||||||
axi_dmac_transfer #(
|
axi_dmac_transfer #(
|
||||||
.DMA_DATA_WIDTH_SRC(32),
|
.DMA_DATA_WIDTH_SRC(WIDTH_SRC),
|
||||||
.DMA_DATA_WIDTH_DEST(32)
|
.DMA_DATA_WIDTH_DEST(WIDTH_DEST)
|
||||||
) i_transfer (
|
) i_transfer (
|
||||||
.m_dest_axi_aclk (clk),
|
.m_dest_axi_aclk (clk),
|
||||||
.m_dest_axi_aresetn(resetn),
|
.m_dest_axi_aresetn(resetn),
|
||||||
|
@ -136,7 +142,8 @@ module dmac_dma_write_tb;
|
||||||
|
|
||||||
.req_valid(req_valid),
|
.req_valid(req_valid),
|
||||||
.req_ready(req_ready),
|
.req_ready(req_ready),
|
||||||
.req_dest_address(30'h7e09000),
|
.req_dest_address(TRANSFER_ADDR[31:$clog2(WIDTH_DEST/8)]),
|
||||||
|
.req_src_address(TRANSFER_ADDR[31:$clog2(WIDTH_SRC/8)]),
|
||||||
.req_x_length(req_length),
|
.req_x_length(req_length),
|
||||||
.req_y_length(24'h00),
|
.req_y_length(24'h00),
|
||||||
.req_dest_stride(24'h00),
|
.req_dest_stride(24'h00),
|
||||||
|
@ -151,13 +158,19 @@ module dmac_dma_write_tb;
|
||||||
.fifo_wr_xfer_req(fifo_wr_xfer_req)
|
.fifo_wr_xfer_req(fifo_wr_xfer_req)
|
||||||
);
|
);
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin: fifo_wr
|
||||||
if (reset) begin
|
integer i;
|
||||||
fifo_wr_din <= 'b0;
|
|
||||||
|
if (reset == 1'b1) begin
|
||||||
|
for (i = 0; i < WIDTH_SRC; i = i + 8) begin
|
||||||
|
fifo_wr_din[i+:8] <= i / 8;
|
||||||
|
end
|
||||||
fifo_wr_rq <= 'b0;
|
fifo_wr_rq <= 'b0;
|
||||||
end else begin
|
end else begin
|
||||||
if (fifo_wr_en) begin
|
if (fifo_wr_en == 1'b1) begin
|
||||||
fifo_wr_din <= fifo_wr_din + 'h4;
|
for (i = 0; i < WIDTH_SRC; i = i + 8) begin
|
||||||
|
fifo_wr_din[i+:8] <= fifo_wr_din[i+:8] + WIDTH_SRC / 8;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
fifo_wr_rq <= (($random % 4) == 0);
|
fifo_wr_rq <= (($random % 4) == 0);
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue