From 764f31463e9c54bc39e4df1e526873b2f82a3a7d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 22 Oct 2018 11:40:05 +0200 Subject: [PATCH] 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 --- library/axi_dmac/tb/axi_read_slave.v | 18 +++++---- library/axi_dmac/tb/axi_slave.v | 3 +- library/axi_dmac/tb/axi_write_slave.v | 25 ++++++++++--- library/axi_dmac/tb/dma_read_tb.v | 54 +++++++++++++++++---------- library/axi_dmac/tb/dma_write_tb.v | 41 +++++++++++++------- 5 files changed, 94 insertions(+), 47 deletions(-) diff --git a/library/axi_dmac/tb/axi_read_slave.v b/library/axi_dmac/tb/axi_read_slave.v index 281418bc3..9d5ed0383 100644 --- a/library/axi_dmac/tb/axi_read_slave.v +++ b/library/axi_dmac/tb/axi_read_slave.v @@ -62,18 +62,20 @@ module axi_read_slave #( reg [DATA_WIDTH-1:0] data = 'h00; -assign rresp = 2'b00; -//assign rdata = data; +wire [31:0] beat_addr; -always @(posedge clk) begin - if (reset == 1'b1) begin - data <= 'h00; - end else if (rvalid == 1'b1 && rready == 1'b1) begin - data <= data + 1'b1; +assign rresp = 2'b00; +assign rdata = data; + +always @(*) begin: gen_data + integer i; + for (i = 0; i < DATA_WIDTH; i = i + 8) begin + data[i+:8] <= beat_addr[7:0] + i / 8; end end axi_slave #( + .DATA_WIDTH(DATA_WIDTH), .ACCEPTANCE(READ_ACCEPTANCE), .MIN_LATENCY(MIN_LATENCY), .MAX_LATENCY(MAX_LATENCY) @@ -93,7 +95,7 @@ axi_slave #( .beat_stb(rvalid), .beat_ack(rvalid & rready), .beat_last(rlast), - .beat_addr(rdata) + .beat_addr(beat_addr) ); endmodule diff --git a/library/axi_dmac/tb/axi_slave.v b/library/axi_dmac/tb/axi_slave.v index c60b225a8..4d1003285 100644 --- a/library/axi_dmac/tb/axi_slave.v +++ b/library/axi_dmac/tb/axi_slave.v @@ -36,6 +36,7 @@ `timescale 1ns/100ps module axi_slave #( + parameter DATA_WIDTH = 32, parameter ACCEPTANCE = 3, parameter MIN_LATENCY = 16, 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_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 if (reset == 1'b1) begin diff --git a/library/axi_dmac/tb/axi_write_slave.v b/library/axi_dmac/tb/axi_write_slave.v index 06de2f188..e8595edec 100644 --- a/library/axi_dmac/tb/axi_write_slave.v +++ b/library/axi_dmac/tb/axi_write_slave.v @@ -115,15 +115,30 @@ always @(posedge clk) begin 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 - data_cmp <= 'h00; + for (i = 0; i < DATA_WIDTH; i = i + 8) begin + data_cmp[i+:8] <= i/8; + end failed <= 'b0; end else if (wvalid & wready) begin - if (data_cmp !== wdata) begin - failed <= 1'b1; + for (i = 0; i < DATA_WIDTH; i = i + 8) begin + 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 - data_cmp <= data_cmp + 'h4; end end diff --git a/library/axi_dmac/tb/dma_read_tb.v b/library/axi_dmac/tb/dma_read_tb.v index 18075e782..6e3f4a430 100644 --- a/library/axi_dmac/tb/dma_read_tb.v +++ b/library/axi_dmac/tb/dma_read_tb.v @@ -37,15 +37,18 @@ module dmac_dma_read_tb; 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" localparam TRANSFER_ADDR = 32'h80000000; - localparam TRANSFER_LEN = 24'h203; reg req_valid = 1'b1; wire req_ready; - reg [23:0] req_length = 'h03; + reg [23:0] req_length = REQ_LEN_INIT - 1; wire awvalid; wire awready; @@ -60,18 +63,18 @@ module dmac_dma_read_tb; wire rvalid; wire rready; wire [1:0] rresp; - wire [31:0] rdata; + wire [WIDTH_SRC-1:0] rdata; always @(posedge clk) begin if (reset != 1'b1 && req_ready == 1'b1) begin req_valid <= 1'b1; - req_length <= req_length + 4; + req_length <= req_length + REQ_LEN_INC; end end axi_read_slave #( - .DATA_WIDTH(32) - ) i_write_slave ( + .DATA_WIDTH(WIDTH_SRC) + ) i_read_slave ( .clk(clk), .reset(reset), @@ -94,16 +97,17 @@ module dmac_dma_read_tb; wire fifo_rd_en = 1'b1; wire fifo_rd_valid; wire fifo_rd_underflow; - wire [31:0] fifo_rd_dout; - reg [31:0] fifo_rd_dout_cmp = TRANSFER_ADDR; + wire [WIDTH_DEST-1:0] fifo_rd_dout; + reg [WIDTH_DEST-1:0] fifo_rd_dout_cmp = 'h00; 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 #( .DMA_TYPE_SRC(0), .DMA_TYPE_DEST(2), - .DMA_DATA_WIDTH_SRC(32), - .DMA_DATA_WIDTH_DEST(32), + .DMA_DATA_WIDTH_SRC(WIDTH_SRC), + .DMA_DATA_WIDTH_DEST(WIDTH_DEST), .FIFO_SIZE(8) ) transfer ( .m_src_axi_aclk(clk), @@ -134,8 +138,8 @@ module dmac_dma_read_tb; .req_valid(req_valid), .req_ready(req_ready), - .req_dest_address(TRANSFER_ADDR[31:2]), - .req_src_address(TRANSFER_ADDR[31:2]), + .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_y_length(24'h00), .req_dest_stride(24'h00), @@ -149,19 +153,31 @@ module dmac_dma_read_tb; .fifo_rd_dout(fifo_rd_dout) ); - always @(posedge clk) begin + always @(posedge clk) begin: dout + integer i; + 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_req_length <= REQ_LEN_INIT; + fifo_rd_beat_counter <= 'h00; end else begin fifo_rd_dout_mismatch <= 1'b0; if (fifo_rd_valid == 1'b1) begin - if (fifo_rd_dout_cmp < TRANSFER_ADDR + fifo_rd_dout_limit) begin - fifo_rd_dout_cmp <= (fifo_rd_dout_cmp + 'h4); + if (fifo_rd_beat_counter + WIDTH_DEST / 8 < fifo_rd_req_length) begin + 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 - fifo_rd_dout_cmp <= TRANSFER_ADDR; - fifo_rd_dout_limit <= fifo_rd_dout_limit + 'h4; + 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_beat_counter <= 'h00; + fifo_rd_req_length <= fifo_rd_req_length + REQ_LEN_INC; end if (fifo_rd_dout_cmp != fifo_rd_dout) begin fifo_rd_dout_mismatch <= 1'b1; diff --git a/library/axi_dmac/tb/dma_write_tb.v b/library/axi_dmac/tb/dma_write_tb.v index 90164525b..6497327e7 100644 --- a/library/axi_dmac/tb/dma_write_tb.v +++ b/library/axi_dmac/tb/dma_write_tb.v @@ -37,12 +37,18 @@ module dmac_dma_write_tb; 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" + localparam TRANSFER_ADDR = 32'h80000000; + reg req_valid = 1'b1; wire req_ready; - reg [23:0] req_length = 'h03; + reg [23:0] req_length = REQ_LEN_INIT - 1; wire awvalid; wire awready; wire [31:0] awaddr; @@ -55,10 +61,10 @@ module dmac_dma_write_tb; wire wlast; wire wvalid; wire wready; - wire [3:0] wstrb; - wire [31:0] wdata; + wire [WIDTH_DEST/8-1:0] wstrb; + 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; wire fifo_wr_xfer_req; @@ -69,12 +75,12 @@ module dmac_dma_write_tb; always @(posedge clk) begin if (reset != 1'b1 && req_ready == 1'b1) begin req_valid <= 1'b1; - req_length <= req_length + 'h4; + req_length <= req_length + REQ_LEN_INC; end end axi_write_slave #( - .DATA_WIDTH(32) + .DATA_WIDTH(WIDTH_DEST) ) i_write_slave ( .clk(clk), .reset(reset), @@ -100,8 +106,8 @@ module dmac_dma_write_tb; ); axi_dmac_transfer #( - .DMA_DATA_WIDTH_SRC(32), - .DMA_DATA_WIDTH_DEST(32) + .DMA_DATA_WIDTH_SRC(WIDTH_SRC), + .DMA_DATA_WIDTH_DEST(WIDTH_DEST) ) i_transfer ( .m_dest_axi_aclk (clk), .m_dest_axi_aresetn(resetn), @@ -136,7 +142,8 @@ module dmac_dma_write_tb; .req_valid(req_valid), .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_y_length(24'h00), .req_dest_stride(24'h00), @@ -151,13 +158,19 @@ module dmac_dma_write_tb; .fifo_wr_xfer_req(fifo_wr_xfer_req) ); - always @(posedge clk) begin - if (reset) begin - fifo_wr_din <= 'b0; + always @(posedge clk) begin: fifo_wr + integer i; + + 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; end else begin - if (fifo_wr_en) begin - fifo_wr_din <= fifo_wr_din + 'h4; + if (fifo_wr_en == 1'b1) begin + 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 fifo_wr_rq <= (($random % 4) == 0); end