From 2f56e30e9725236de3905cd4fa4a9a2c03ed820a Mon Sep 17 00:00:00 2001 From: Andreas Kurth Date: Wed, 30 Mar 2022 16:54:40 +0200 Subject: [PATCH 1/5] axi_mux: Add missing spill registers for single-slave-port configuration --- CHANGELOG.md | 1 + src/axi_mux.sv | 68 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 475b8afd4..575abc0b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - `axi_demux_intf`: Add missing parameter (`ATOP_SUPPORT`) to optionally disable support for atomic operations. +- `axi_mux`: Add missing spill registers for configurations with a single slave port. - `axi_lite_mux_intf`: Add missing parameter values on the internal `axi_lite_mux` instance (`axi_req_t` and `axi_resp_t`). - `axi_sim_mem`: Propagate the AR channel's user signal correctly to the monitor. diff --git a/src/axi_mux.sv b/src/axi_mux.sv index 59ee3ec46..083b5d06e 100644 --- a/src/axi_mux.sv +++ b/src/axi_mux.sv @@ -69,8 +69,72 @@ module axi_mux #( // pass through if only one slave port if (NoSlvPorts == 32'h1) begin : gen_no_mux - assign mst_req_o = slv_reqs_i[0]; - assign slv_resps_o[0] = mst_resp_i; + spill_register #( + .T ( mst_aw_chan_t ), + .Bypass ( ~SpillAw ) + ) i_aw_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_reqs_i[0].aw_valid ), + .ready_o ( slv_resps_o[0].aw_ready ), + .data_i ( slv_reqs_i[0].aw ), + .valid_o ( mst_req_o.aw_valid ), + .ready_i ( mst_resp_i.aw_ready ), + .data_o ( mst_req_o.aw ) + ); + spill_register #( + .T ( w_chan_t ), + .Bypass ( ~SpillW ) + ) i_w_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_reqs_i[0].w_valid ), + .ready_o ( slv_resps_o[0].w_ready ), + .data_i ( slv_reqs_i[0].w ), + .valid_o ( mst_req_o.w_valid ), + .ready_i ( mst_resp_i.w_ready ), + .data_o ( mst_req_o.w ) + ); + spill_register #( + .T ( mst_b_chan_t ), + .Bypass ( ~SpillB ) + ) i_b_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( mst_resp_i.b_valid ), + .ready_o ( mst_req_o.b_ready ), + .data_i ( mst_resp_i.b ), + .valid_o ( slv_resps_o[0].b_valid ), + .ready_i ( slv_reqs_i[0].b_ready ), + .data_o ( slv_resps_o[0].b ) + ); + spill_register #( + .T ( mst_ar_chan_t ), + .Bypass ( ~SpillAr ) + ) i_ar_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_reqs_i[0].ar_valid ), + .ready_o ( slv_resps_o[0].ar_ready ), + .data_i ( slv_reqs_i[0].ar ), + .valid_o ( mst_req_o.ar_valid ), + .ready_i ( mst_resp_i.ar_ready ), + .data_o ( mst_req_o.ar ) + ); + spill_register #( + .T ( mst_r_chan_t ), + .Bypass ( ~SpillR ) + ) i_r_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( mst_resp_i.r_valid ), + .ready_o ( mst_req_o.r_ready ), + .data_i ( mst_resp_i.r ), + .valid_o ( slv_resps_o[0].r_valid ), + .ready_i ( slv_reqs_i[0].r_ready ), + .data_o ( slv_resps_o[0].r ) + ); + // other non degenerate cases end else begin : gen_mux From 0c1344cd34b3d99ad281dcc491c1e1c0e9e5fc60 Mon Sep 17 00:00:00 2001 From: Andreas Kurth Date: Wed, 30 Mar 2022 17:22:08 +0200 Subject: [PATCH 2/5] axi_demux: Add missing spill register for single-master-port configurations --- CHANGELOG.md | 1 + src/axi_demux.sv | 68 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 575abc0b5..933b2dece 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed ### Fixed +- `axi_demux`: Add missing spill registers for configurations with a single master port. - `axi_demux_intf`: Add missing parameter (`ATOP_SUPPORT`) to optionally disable support for atomic operations. - `axi_mux`: Add missing spill registers for configurations with a single slave port. diff --git a/src/axi_demux.sv b/src/axi_demux.sv index 47ab00409..9ba3ef360 100644 --- a/src/axi_demux.sv +++ b/src/axi_demux.sv @@ -76,8 +76,72 @@ module axi_demux #( // pass through if only one master port if (NoMstPorts == 32'h1) begin : gen_no_demux - assign mst_reqs_o[0] = slv_req_i; - assign slv_resp_o = mst_resps_i; + spill_register #( + .T ( aw_chan_t ), + .Bypass ( ~SpillAw ) + ) i_aw_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_req_i.aw_valid ), + .ready_o ( slv_resp_o.aw_ready ), + .data_i ( slv_req_i.aw ), + .valid_o ( mst_reqs_o[0].aw_valid ), + .ready_i ( mst_resps_i[0].aw_ready ), + .data_o ( mst_reqs_o[0].aw ) + ); + spill_register #( + .T ( w_chan_t ), + .Bypass ( ~SpillW ) + ) i_w_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_req_i.w_valid ), + .ready_o ( slv_resp_o.w_ready ), + .data_i ( slv_req_i.w ), + .valid_o ( mst_reqs_o[0].w_valid ), + .ready_i ( mst_resps_i[0].w_ready ), + .data_o ( mst_reqs_o[0].w ) + ); + spill_register #( + .T ( b_chan_t ), + .Bypass ( ~SpillB ) + ) i_b_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( mst_resps_i[0].b_valid ), + .ready_o ( mst_reqs_o[0].b_ready ), + .data_i ( mst_resps_i[0].b ), + .valid_o ( slv_resp_o.b_valid ), + .ready_i ( slv_req_i.b_ready ), + .data_o ( slv_resp_o.b ) + ); + spill_register #( + .T ( ar_chan_t ), + .Bypass ( ~SpillAr ) + ) i_ar_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_req_i.ar_valid ), + .ready_o ( slv_resp_o.ar_ready ), + .data_i ( slv_req_i.ar ), + .valid_o ( mst_reqs_o[0].ar_valid ), + .ready_i ( mst_resps_i[0].ar_ready ), + .data_o ( mst_reqs_o[0].ar ) + ); + spill_register #( + .T ( r_chan_t ), + .Bypass ( ~SpillR ) + ) i_r_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( mst_resps_i[0].r_valid ), + .ready_o ( mst_reqs_o[0].r_ready ), + .data_i ( mst_resps_i[0].r ), + .valid_o ( slv_resp_o.r_valid ), + .ready_i ( slv_req_i.r_ready ), + .data_o ( slv_resp_o.r ) + ); + // other non degenerate cases end else begin : gen_demux From 7c064733a6559f895b7aab053f4a32f213f46324 Mon Sep 17 00:00:00 2001 From: Andreas Kurth Date: Wed, 30 Mar 2022 17:25:49 +0200 Subject: [PATCH 3/5] axi_lite_mux: Add missing spill registers for single-slave-port configuration --- CHANGELOG.md | 3 +- src/axi_lite_mux.sv | 68 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 933b2dece..9e0b8ad49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `axi_demux`: Add missing spill registers for configurations with a single master port. - `axi_demux_intf`: Add missing parameter (`ATOP_SUPPORT`) to optionally disable support for atomic operations. -- `axi_mux`: Add missing spill registers for configurations with a single slave port. +- `axi_mux` and `axi_lite_mux`: Add missing spill registers for configurations with a single slave + port. - `axi_lite_mux_intf`: Add missing parameter values on the internal `axi_lite_mux` instance (`axi_req_t` and `axi_resp_t`). - `axi_sim_mem`: Propagate the AR channel's user signal correctly to the monitor. diff --git a/src/axi_lite_mux.sv b/src/axi_lite_mux.sv index 37544373d..7aba411ac 100644 --- a/src/axi_lite_mux.sv +++ b/src/axi_lite_mux.sv @@ -54,8 +54,72 @@ module axi_lite_mux #( ); // pass through if only one slave port if (NoSlvPorts == 32'h1) begin : gen_no_mux - assign mst_req_o = slv_reqs_i[0]; - assign slv_resps_o[0] = mst_resp_i; + spill_register #( + .T ( aw_chan_t ), + .Bypass ( ~SpillAw ) + ) i_aw_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_reqs_i[0].aw_valid ), + .ready_o ( slv_resps_o[0].aw_ready ), + .data_i ( slv_reqs_i[0].aw ), + .valid_o ( mst_req_o.aw_valid ), + .ready_i ( mst_resp_i.aw_ready ), + .data_o ( mst_req_o.aw ) + ); + spill_register #( + .T ( w_chan_t ), + .Bypass ( ~SpillW ) + ) i_w_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_reqs_i[0].w_valid ), + .ready_o ( slv_resps_o[0].w_ready ), + .data_i ( slv_reqs_i[0].w ), + .valid_o ( mst_req_o.w_valid ), + .ready_i ( mst_resp_i.w_ready ), + .data_o ( mst_req_o.w ) + ); + spill_register #( + .T ( b_chan_t ), + .Bypass ( ~SpillB ) + ) i_b_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( mst_resp_i.b_valid ), + .ready_o ( mst_req_o.b_ready ), + .data_i ( mst_resp_i.b ), + .valid_o ( slv_resps_o[0].b_valid ), + .ready_i ( slv_reqs_i[0].b_ready ), + .data_o ( slv_resps_o[0].b ) + ); + spill_register #( + .T ( ar_chan_t ), + .Bypass ( ~SpillAr ) + ) i_ar_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_reqs_i[0].ar_valid ), + .ready_o ( slv_resps_o[0].ar_ready ), + .data_i ( slv_reqs_i[0].ar ), + .valid_o ( mst_req_o.ar_valid ), + .ready_i ( mst_resp_i.ar_ready ), + .data_o ( mst_req_o.ar ) + ); + spill_register #( + .T ( r_chan_t ), + .Bypass ( ~SpillR ) + ) i_r_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( mst_resp_i.r_valid ), + .ready_o ( mst_req_o.r_ready ), + .data_i ( mst_resp_i.r ), + .valid_o ( slv_resps_o[0].r_valid ), + .ready_i ( slv_reqs_i[0].r_ready ), + .data_o ( slv_resps_o[0].r ) + ); + // other non degenerate cases end else begin : gen_mux // typedef for the FIFO types From 914db6a154bee611cbe86598add430632a6b30b3 Mon Sep 17 00:00:00 2001 From: Andreas Kurth Date: Wed, 30 Mar 2022 17:27:50 +0200 Subject: [PATCH 4/5] axi_lite_demux: Add missing spill registers for single-master-port configuration --- CHANGELOG.md | 3 +- src/axi_lite_demux.sv | 69 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e0b8ad49..46a6cf242 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed ### Fixed -- `axi_demux`: Add missing spill registers for configurations with a single master port. +- `axi_demux` and `axi_lite_demux`: Add missing spill registers for configurations with a single + master port. - `axi_demux_intf`: Add missing parameter (`ATOP_SUPPORT`) to optionally disable support for atomic operations. - `axi_mux` and `axi_lite_mux`: Add missing spill registers for configurations with a single slave diff --git a/src/axi_lite_demux.sv b/src/axi_lite_demux.sv index ec5658fbd..a4e8fdd20 100644 --- a/src/axi_lite_demux.sv +++ b/src/axi_lite_demux.sv @@ -70,9 +70,72 @@ module axi_lite_demux #( if (NoMstPorts == 32'd1) begin : gen_no_demux // degenerate case, connect slave to master port - // AW channel - assign mst_reqs_o[0] = slv_req_i; - assign slv_resp_o = mst_resps_i[0]; + spill_register #( + .T ( aw_chan_t ), + .Bypass ( ~SpillAw ) + ) i_aw_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_req_i.aw_valid ), + .ready_o ( slv_resp_o.aw_ready ), + .data_i ( slv_req_i.aw ), + .valid_o ( mst_reqs_o[0].aw_valid ), + .ready_i ( mst_resps_i[0].aw_ready ), + .data_o ( mst_reqs_o[0].aw ) + ); + spill_register #( + .T ( w_chan_t ), + .Bypass ( ~SpillW ) + ) i_w_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_req_i.w_valid ), + .ready_o ( slv_resp_o.w_ready ), + .data_i ( slv_req_i.w ), + .valid_o ( mst_reqs_o[0].w_valid ), + .ready_i ( mst_resps_i[0].w_ready ), + .data_o ( mst_reqs_o[0].w ) + ); + spill_register #( + .T ( b_chan_t ), + .Bypass ( ~SpillB ) + ) i_b_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( mst_resps_i[0].b_valid ), + .ready_o ( mst_reqs_o[0].b_ready ), + .data_i ( mst_resps_i[0].b ), + .valid_o ( slv_resp_o.b_valid ), + .ready_i ( slv_req_i.b_ready ), + .data_o ( slv_resp_o.b ) + ); + spill_register #( + .T ( ar_chan_t ), + .Bypass ( ~SpillAr ) + ) i_ar_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( slv_req_i.ar_valid ), + .ready_o ( slv_resp_o.ar_ready ), + .data_i ( slv_req_i.ar ), + .valid_o ( mst_reqs_o[0].ar_valid ), + .ready_i ( mst_resps_i[0].ar_ready ), + .data_o ( mst_reqs_o[0].ar ) + ); + spill_register #( + .T ( r_chan_t ), + .Bypass ( ~SpillR ) + ) i_r_spill_reg ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .valid_i ( mst_resps_i[0].r_valid ), + .ready_o ( mst_reqs_o[0].r_ready ), + .data_i ( mst_resps_i[0].r ), + .valid_o ( slv_resp_o.r_valid ), + .ready_i ( slv_req_i.r_ready ), + .data_o ( slv_resp_o.r ) + ); + end else begin : gen_demux // normal non degenerate case From b91f44080ffb5d36d4f504617f02a1c821cb6048 Mon Sep 17 00:00:00 2001 From: Andreas Kurth Date: Wed, 30 Mar 2022 17:28:22 +0200 Subject: [PATCH 5/5] axi_mux: Add assertions for ID width in passthrough case A mismatch of the ID width between the parameter and the master port or the slave port would result in the wrong bits being connected through the `spill_register`s. Without these assertions, this could go unnoticed, which would likely corrupt the connections to an unusable state. --- src/axi_mux.sv | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/axi_mux.sv b/src/axi_mux.sv index 083b5d06e..da17e2b8c 100644 --- a/src/axi_mux.sv +++ b/src/axi_mux.sv @@ -22,6 +22,7 @@ // a response with ID `6'b100110` will be forwarded to slave port 2 (`2'b10`). // register macros +`include "common_cells/assertions.svh" `include "common_cells/registers.svh" module axi_mux #( @@ -134,6 +135,17 @@ module axi_mux #( .ready_i ( slv_reqs_i[0].r_ready ), .data_o ( slv_resps_o[0].r ) ); +// Validate parameters. +// pragma translate_off + `ASSERT_INIT(CorrectIdWidthSlvAw, $bits(slv_reqs_i[0].aw.id) == SlvAxiIDWidth) + `ASSERT_INIT(CorrectIdWidthSlvB, $bits(slv_resps_o[0].b.id) == SlvAxiIDWidth) + `ASSERT_INIT(CorrectIdWidthSlvAr, $bits(slv_reqs_i[0].ar.id) == SlvAxiIDWidth) + `ASSERT_INIT(CorrectIdWidthSlvR, $bits(slv_resps_o[0].r.id) == SlvAxiIDWidth) + `ASSERT_INIT(CorrectIdWidthMstAw, $bits(mst_req_o.aw.id) == SlvAxiIDWidth) + `ASSERT_INIT(CorrectIdWidthMstB, $bits(mst_resp_i.b.id) == SlvAxiIDWidth) + `ASSERT_INIT(CorrectIdWidthMstAr, $bits(mst_req_o.ar.id) == SlvAxiIDWidth) + `ASSERT_INIT(CorrectIdWidthMstR, $bits(mst_resp_i.r.id) == SlvAxiIDWidth) +// pragma translate_on // other non degenerate cases end else begin : gen_mux