Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bus compare #345

Merged
merged 3 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## Unreleased
### Added
- `axi_sim_mem`: Increase number of request ports, add multiport interface variant.
- `axi_bus_compare`: Optionally consider AXI `size` field to only compare used data.

### Fixed
- `axi_bus_compare`: Fix mismatch detection.

## 0.39.3 - 2024-05-08
### Added
Expand Down
149 changes: 144 additions & 5 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;
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;
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;
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
Loading