Skip to content

Commit

Permalink
bus_compare: consider size field for comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
micprog committed Jul 16, 2024
1 parent fe2ece8 commit 416adf2
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 2 deletions.
143 changes: 141 additions & 2 deletions src/axi_bus_compare.sv
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ module axi_bus_compare #(
parameter int unsigned AxiIdWidth = 32'd0,
/// FIFO depth
parameter int unsigned FifoDepth = 32'd0,
/// Consider size field in comparison
parameter bit UseSize = 1'b0,
/// Data width of the AXI4+ATOP interface
parameter int unsigned DataWidth = 32'd8,
/// AW channel type of the AXI4+ATOP interface
parameter type axi_aw_chan_t = logic,
/// W channel type of the AXI4+ATOP interface
Expand Down Expand Up @@ -151,6 +155,12 @@ module axi_bus_compare #(
axi_r_chan_t [2**AxiIdWidth-1:0] fifo_cmp_data_r_b;


// Size alignment signals
logic [2:0] w_size;
logic [$clog2(DataWidth/8)-1:0] w_lower, w_offset, w_increment;
logic [2**AxiIdWidth-1:0][2:0] r_size;
logic [2**AxiIdWidth-1:0][$clog2(DataWidth/8)-1:0] r_lower, r_offset, r_increment;

//-----------------------------------
// Channel A stream forks
//-----------------------------------
Expand Down Expand Up @@ -272,6 +282,46 @@ module axi_bus_compare #(
.ready_i ( fifo_cmp_valid_ar_a [id] & fifo_cmp_valid_ar_b [id] )
);

if (UseSize) begin : gen_r_size
stream_fifo #(
.FALL_THROUGH ( 1'b0 ),
.DATA_WIDTH ( $clog2(DataWidth/8)+3 ),
// .DATA_WIDTH ( 7+3 ),
.DEPTH ( 2*FifoDepth )
) i_stream_fifo_w_size (
.clk_i,
.rst_ni,
.testmode_i,
.flush_i ( 1'b0 ),
.usage_o (),
.data_i ( {axi_a_req_i.ar.addr[$clog2(DataWidth/8)-1:0], axi_a_req_i.ar.size} ),
.valid_i ( fifo_valid_ar_a [id] & fifo_ready_ar_a [id] ),
.ready_o (),
.data_o ( {r_offset[id], r_size[id]} ),
.valid_o (),
.ready_i ( fifo_cmp_valid_r_a[id] & fifo_cmp_valid_r_b[id] & fifo_cmp_data_r_a[id].last )
);
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_r_increment
if(!rst_ni) begin
r_increment[id] <= '0;
end else begin
if (fifo_cmp_valid_r_a[id] && fifo_cmp_valid_r_b[id]) begin
if (fifo_cmp_data_r_a[id].last) begin
r_increment[id] <= '0;
end else begin
r_increment[id] <= r_increment[id] + 2**r_size[id] - ((r_offset[id]+r_increment[id])%(2**r_size[id]));
end
end
end
end
assign r_lower[id] = r_offset[id] + r_increment[id];
end else begin : gen_no_size
assign r_offset[id] = '0;
assign r_size[id] = '1;
assign r_lower[id] = '0;
end


stream_fifo #(
.FALL_THROUGH ( 1'b0 ),
.DATA_WIDTH ( 1'b0 ),
Expand All @@ -292,6 +342,45 @@ module axi_bus_compare #(
);
end

if (UseSize) begin : gen_w_size
stream_fifo #(
.FALL_THROUGH ( 1'b0 ),
.DATA_WIDTH ( $clog2(DataWidth/8)+3 ),
// .DATA_WIDTH ( 7+3 ),
.DEPTH ( FifoDepth )
) i_stream_fifo_w_size (
.clk_i,
.rst_ni,
.testmode_i,
.flush_i ( 1'b0 ),
.usage_o (),
.data_i ( {axi_a_req_i.aw.addr[$clog2(DataWidth/8)-1:0], axi_a_req_i.aw.size} ),
.valid_i ( axi_a_req_i.aw_valid & axi_a_rsp_o.aw_ready ),
.ready_o (),
.data_o ( {w_offset, w_size} ),
.valid_o (),
.ready_i ( fifo_cmp_valid_w_a & fifo_cmp_valid_w_b & fifo_cmp_data_w_a.last )
);
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_w_increment
if(!rst_ni) begin
w_increment <= '0;
end else begin
if (fifo_cmp_valid_w_a && fifo_cmp_valid_w_b) begin
if (fifo_cmp_data_w_a.last) begin
w_increment <= '0;
end else begin
w_increment <= (w_increment + 2**w_size) - ((w_offset+w_increment)%(2**w_size));
end
end
end
end
assign w_lower = w_offset + w_increment;
end else begin : gen_no_size
assign w_offset = '0;
assign w_size = '1;
assign w_lower = '0;
end

stream_fifo #(
.FALL_THROUGH ( 1'b0 ),
.DATA_WIDTH ( 1'b0 ),
Expand Down Expand Up @@ -555,18 +644,68 @@ module axi_bus_compare #(
// Comparison
//-----------------------------------
for (genvar id = 0; id < 2**AxiIdWidth; id++) begin : gen_cmp
logic [DataWidth/8-1:0] r_data_partial_mismatch;
logic r_data_mismatch;

if (UseSize) begin : gen_r_mismatch_sized
for (genvar j = 0; j < DataWidth/8; j++) begin : gen_r_partial_mismatch
assign r_data_partial_mismatch[j] = fifo_cmp_data_r_a[id].data[8*j+:8] != fifo_cmp_data_r_b[id].data[8*j+:8];
end

always_comb begin : proc_r_data_mismatch
r_data_mismatch = '0;
for (int unsigned j = 0; j < DataWidth/8; j++) begin
if (j >= r_lower[id] && j < (r_lower[id] + 2**r_size[id])-((r_lower[id] + 2**r_size[id])%(2**r_size[id])) ) begin
r_data_mismatch |= r_data_partial_mismatch[j];
end
end
end
end else begin : gen_r_mismatch_unsized
assign r_data_mismatch = fifo_cmp_data_r_a[id].data != fifo_cmp_data_r_b[id].data;
end

assign aw_mismatch_o [id] = (fifo_cmp_valid_aw_a [id] & fifo_cmp_valid_aw_b [id]) ?
fifo_cmp_data_aw_a [id] != fifo_cmp_data_aw_b [id] : '0;
assign b_mismatch_o [id] = (fifo_cmp_valid_b_a [id] & fifo_cmp_valid_b_b [id]) ?
fifo_cmp_data_b_a [id] != fifo_cmp_data_b_b [id] : '0;
assign ar_mismatch_o [id] = (fifo_cmp_valid_ar_a [id] & fifo_cmp_valid_ar_b [id]) ?
fifo_cmp_data_ar_a [id] != fifo_cmp_data_ar_b [id] : '0;
assign r_mismatch_o [id] = (fifo_cmp_valid_r_a [id] & fifo_cmp_valid_r_b [id]) ?
fifo_cmp_data_r_a [id] != fifo_cmp_data_r_b [id] : '0;
( fifo_cmp_data_r_a[id].id != fifo_cmp_data_r_b[id].id |
r_data_mismatch |
fifo_cmp_data_r_a[id].resp != fifo_cmp_data_r_b[id].resp |
fifo_cmp_data_r_a[id].last != fifo_cmp_data_r_b[id].last |
fifo_cmp_data_r_a[id].user != fifo_cmp_data_r_b[id].user )
: '0;
end

logic [DataWidth/8-1:0] w_data_partial_mismatch;
logic w_data_mismatch;

if (UseSize) begin : gen_w_mismatch_sized
for (genvar j = 0; j < DataWidth/8; j++) begin : gen_w_partial_mismatch
assign w_data_partial_mismatch[j] = fifo_cmp_data_w_a.data[8*j+:8] != fifo_cmp_data_w_b.data[8*j+:8] |
fifo_cmp_data_w_a.strb[ j ] != fifo_cmp_data_w_b.strb[ j ];
end

always_comb begin : proc_w_data_mismatch
w_data_mismatch = '0;
for (int unsigned j = 0; j < DataWidth/8; j++) begin
if (j >= w_lower && j < (w_lower + 2**w_size)-((w_lower + 2**w_size)%(2**w_size)) ) begin
w_data_mismatch |= w_data_partial_mismatch[j];
end
end
end
end else begin : gen_w_mismatch_unsized
assign w_data_mismatch = fifo_cmp_data_w_a.data != fifo_cmp_data_w_b.data |
fifo_cmp_data_w_a.strb != fifo_cmp_data_w_b.strb;
end

assign w_mismatch_o = (fifo_cmp_valid_w_a & fifo_cmp_valid_w_b ) ?
fifo_cmp_data_w_a != fifo_cmp_data_w_b : '0;
( w_data_mismatch |
fifo_cmp_data_w_a.last != fifo_cmp_data_w_b.last |
fifo_cmp_data_w_a.user != fifo_cmp_data_w_b.user )
: '0;


//-----------------------------------
Expand Down
6 changes: 6 additions & 0 deletions src/axi_slave_compare.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ module axi_slave_compare #(
parameter int unsigned AxiIdWidth = 32'd0,
/// FIFO depth
parameter int unsigned FifoDepth = 32'd0,
/// Consider size field in comparison
parameter bit UseSize = 1'b0,
/// Data width of the AXI4+ATOP interface
parameter int unsigned DataWidth = 32'd8,
/// AW channel type of the AXI4+ATOP interface
parameter type axi_aw_chan_t = logic,
/// W channel type of the AXI4+ATOP interface
Expand Down Expand Up @@ -154,6 +158,8 @@ module axi_slave_compare #(
axi_bus_compare #(
.AxiIdWidth ( AxiIdWidth ),
.FifoDepth ( FifoDepth ),
.UseSize ( UseSize ),
.DataWidth ( DataWidth ),
.axi_aw_chan_t ( axi_aw_chan_t ),
.axi_w_chan_t ( axi_w_chan_t ),
.axi_b_chan_t ( axi_b_chan_t ),
Expand Down

0 comments on commit 416adf2

Please sign in to comment.