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
Lars-Peter Clausen 2018-10-22 11:40:05 +02:00 committed by Laszlo Nagy
parent 29e6bbde88
commit 764f31463e
5 changed files with 94 additions and 47 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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