From c4f62d769a7ccfe5a823e33ff773dda9ebeea032 Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Tue, 18 Jan 2022 16:49:58 +0100 Subject: [PATCH 1/6] Add rr_distributor --- Bender.yml | 2 ++ ci/install-verilator.sh | 2 +- src/rr_distributor.sv | 70 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/rr_distributor.sv diff --git a/Bender.yml b/Bender.yml index 6f3e06f2..04de422b 100644 --- a/Bender.yml +++ b/Bender.yml @@ -8,6 +8,7 @@ package: - "Manuel Eggimann " - "Stefan Mach " - "Wolfgang Roenninger " + - "Thomas Benz " dependencies: common_verification: { git: "https://github.com/pulp-platform/common_verification.git", version: 0.2.0 } @@ -44,6 +45,7 @@ sources: - src/plru_tree.sv - src/popcount.sv - src/rr_arb_tree.sv + - src/rr_distributor.sv - src/rstgen_bypass.sv - src/serial_deglitch.sv - src/shift_reg.sv diff --git a/ci/install-verilator.sh b/ci/install-verilator.sh index 31f72f74..2587f6fe 100755 --- a/ci/install-verilator.sh +++ b/ci/install-verilator.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e -ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +ROOT=$(cd "$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")/.." && pwd) cd $ROOT/tmp if [ -z ${NUM_JOBS} ]; then diff --git a/src/rr_distributor.sv b/src/rr_distributor.sv new file mode 100644 index 00000000..9775fe73 --- /dev/null +++ b/src/rr_distributor.sv @@ -0,0 +1,70 @@ +// Copyright 2019 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. +// +// Author: Thomas Benz , ETH Zurich +// Date: 12.01.2021 +// Description: round robin distributor + +module rr_distributor # ( + parameter int unsigned NumOut = 1, + parameter int unsigned Width = 1, + parameter type payload_t = logic [Width-1:0], + parameter int unsigned IdxWidth = (NumOut > 32'd1) ? unsigned'($clog2(NumOut)) : 32'd1, + parameter type idx_t = logic [IdxWidth-1:0] +) ( + // input stream + input logic clk_i, + input logic rst_ni, + input logic valid_i, + output logic ready_o, + input payload_t payload_i, + // output stream + output logic [NumOut-1:0] valid_o, + input logic [NumOut-1:0] ready_i, + output payload_t [NumOut-1:0] payload_o, + output idx_t sel_o +); + + if (NumOut == 1) begin : gen_bypass + assign valid_o[0] = valid_i; + assign ready_o = ready_i[0]; + assign sel_o = 1'b0; + end else begin : gen_arb + + idx_t rr_d, rr_q; + logic one_ready; + + assign rr_d = (valid_i & one_ready) ? ((rr_q == idx_t'(NumOut-1)) ? '0 : rr_q + 1'b1) : rr_q; + + assign one_ready = |ready_i; + + always_comb begin : proc_arbitration + valid_o = '0; + ready_o = 1'b0; + if (ready_i[rr_q]) begin + valid_o[rr_q] = valid_i; + ready_o = 1'b1; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : proc_prio_regs + if(~rst_ni) begin + rr_q <= 0; + end else begin + rr_q <= rr_d; + end + end + + assign sel_o = rr_q; + end + + assign payload_o = {{NumOut}{payload_i}}; + +endmodule : rr_distributor From f0edaf8089aff6aaaaa8ab498727032087b9aa7f Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Tue, 18 Jan 2022 18:02:44 +0100 Subject: [PATCH 2/6] Add description for round-robin distributor --- src/rr_distributor.sv | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/rr_distributor.sv b/src/rr_distributor.sv index 9775fe73..b0c8e390 100644 --- a/src/rr_distributor.sv +++ b/src/rr_distributor.sv @@ -12,19 +12,27 @@ // Date: 12.01.2021 // Description: round robin distributor +/// The rr_distributor forwards requests to individual outputs in a round robin fashion. module rr_distributor # ( - parameter int unsigned NumOut = 1, - parameter int unsigned Width = 1, - parameter type payload_t = logic [Width-1:0], - parameter int unsigned IdxWidth = (NumOut > 32'd1) ? unsigned'($clog2(NumOut)) : 32'd1, - parameter type idx_t = logic [IdxWidth-1:0] + /// Number of outputs to distribute to. + parameter int unsigned NumOut = 1, + /// Data width of the payload in bits. Not needed if `payload_t` is overwritten. + parameter int unsigned Width = 1, + /// Data type of the payload, can be overwritten with a custom type. Only use of `Width`. + parameter type payload_t = logic [Width-1:0], + /// Dependent parameter, do **not** overwrite. + /// Width of the selected index + parameter int unsigned IdxWidth = (NumOut > 32'd1) ? unsigned'($clog2(NumOut)) : 32'd1, + /// Dependent parameter, do **not** overwrite. + /// type of the selected index + parameter type idx_t = logic [IdxWidth-1:0] ) ( + input logic clk_i, + input logic rst_ni, // input stream - input logic clk_i, - input logic rst_ni, - input logic valid_i, - output logic ready_o, - input payload_t payload_i, + input logic valid_i, + output logic ready_o, + input payload_t payload_i, // output stream output logic [NumOut-1:0] valid_o, input logic [NumOut-1:0] ready_i, From 061cc72278e9c1e21c769f754828b227bdc04d91 Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Tue, 18 Jan 2022 18:08:04 +0100 Subject: [PATCH 3/6] Fix lint error --- src/rr_distributor.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rr_distributor.sv b/src/rr_distributor.sv index b0c8e390..52dc8187 100644 --- a/src/rr_distributor.sv +++ b/src/rr_distributor.sv @@ -49,7 +49,8 @@ module rr_distributor # ( idx_t rr_d, rr_q; logic one_ready; - assign rr_d = (valid_i & one_ready) ? ((rr_q == idx_t'(NumOut-1)) ? '0 : rr_q + 1'b1) : rr_q; + assign rr_d = (valid_i & one_ready) ? + ((rr_q == idx_t'(NumOut-1)) ? '0 : rr_q + 1'b1) : rr_q; assign one_ready = |ready_i; From ebe83fef19df3baea19d662da2113e1ccda106a9 Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Tue, 25 Jan 2022 08:52:52 +0100 Subject: [PATCH 4/6] Add comments from reviewer - change `payload_t` to `data_t` - replace inline if with always comb block - add rr_distributor to src_files --- src/rr_distributor.sv | 36 ++++++++++++++++++++++-------------- src_files.yml | 1 + 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/rr_distributor.sv b/src/rr_distributor.sv index 52dc8187..8347dbed 100644 --- a/src/rr_distributor.sv +++ b/src/rr_distributor.sv @@ -16,28 +16,28 @@ module rr_distributor # ( /// Number of outputs to distribute to. parameter int unsigned NumOut = 1, - /// Data width of the payload in bits. Not needed if `payload_t` is overwritten. + /// Data width of the payload in bits. Not needed if `data_t` is overwritten. parameter int unsigned Width = 1, /// Data type of the payload, can be overwritten with a custom type. Only use of `Width`. - parameter type payload_t = logic [Width-1:0], + parameter type data_t = logic [Width-1:0], /// Dependent parameter, do **not** overwrite. /// Width of the selected index - parameter int unsigned IdxWidth = (NumOut > 32'd1) ? unsigned'($clog2(NumOut)) : 32'd1, + parameter int unsigned IdxWidth = cf_math_pkg::idx_width(NumOut), /// Dependent parameter, do **not** overwrite. /// type of the selected index parameter type idx_t = logic [IdxWidth-1:0] ) ( - input logic clk_i, - input logic rst_ni, + input logic clk_i, + input logic rst_ni, // input stream - input logic valid_i, - output logic ready_o, - input payload_t payload_i, + input logic valid_i, + output logic ready_o, + input data_t payload_i, // output stream - output logic [NumOut-1:0] valid_o, - input logic [NumOut-1:0] ready_i, - output payload_t [NumOut-1:0] payload_o, - output idx_t sel_o + output logic [NumOut-1:0] valid_o, + input logic [NumOut-1:0] ready_i, + output data_t [NumOut-1:0] payload_o, + output idx_t sel_o ); if (NumOut == 1) begin : gen_bypass @@ -49,8 +49,16 @@ module rr_distributor # ( idx_t rr_d, rr_q; logic one_ready; - assign rr_d = (valid_i & one_ready) ? - ((rr_q == idx_t'(NumOut-1)) ? '0 : rr_q + 1'b1) : rr_q; + always_comb begin : rr_next + rr_d = rr_q; + if (valid_i && one_ready) begin + if (rr_q == idx_t'(NumOut - 1)) begin + rr_d = '0; + end else begin + rr_d = rr_q + 1'b1; + end + end + end assign one_ready = |ready_i; diff --git a/src_files.yml b/src_files.yml index f00937cd..cf82b5af 100644 --- a/src_files.yml +++ b/src_files.yml @@ -27,6 +27,7 @@ common_cells_all: - src/plru_tree.sv - src/popcount.sv - src/rr_arb_tree.sv + - src/rr_distributor.sv - src/rstgen_bypass.sv - src/serial_deglitch.sv - src/shift_reg.sv From 5635be989d072cf970f8abd9f5e1e2c1d82675a4 Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Wed, 26 Jan 2022 17:17:02 +0100 Subject: [PATCH 5/6] rr_distributor: add StrictRR parameter, clarify distribution --- src/rr_distributor.sv | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/rr_distributor.sv b/src/rr_distributor.sv index 8347dbed..6c617565 100644 --- a/src/rr_distributor.sv +++ b/src/rr_distributor.sv @@ -19,7 +19,16 @@ module rr_distributor # ( /// Data width of the payload in bits. Not needed if `data_t` is overwritten. parameter int unsigned Width = 1, /// Data type of the payload, can be overwritten with a custom type. Only use of `Width`. - parameter type data_t = logic [Width-1:0], + parameter type data_t = logic [Width-1:0], + /// Setting StrictRR enforces a strict round-robin distribution + /// If set to 1'b1, the rr_distributor will distribute the requests to the next output + /// in line, irrespective if this output is ready or not, irrespective if another + /// output could accept the request. The transaction will wait until the next one in + /// line accepts the handshake. + /// If set to 1'b0, the rr_distributor will step through the outputs if one is ready + /// but the current one is not. This can reduce wait time for the input. + /// **THIS IS NOT COMPLIANT AS IT MAY DE-ASSERT VALID WITHOUT A PROPER HANDSHAKE** + parameter bit StrictRR = 1'b0, /// Dependent parameter, do **not** overwrite. /// Width of the selected index parameter int unsigned IdxWidth = cf_math_pkg::idx_width(NumOut), @@ -51,7 +60,7 @@ module rr_distributor # ( always_comb begin : rr_next rr_d = rr_q; - if (valid_i && one_ready) begin + if (valid_i && ( ready_i[rr_q] || (one_ready && !StrictRR))) begin if (rr_q == idx_t'(NumOut - 1)) begin rr_d = '0; end else begin @@ -64,12 +73,9 @@ module rr_distributor # ( always_comb begin : proc_arbitration valid_o = '0; - ready_o = 1'b0; - if (ready_i[rr_q]) begin - valid_o[rr_q] = valid_i; - ready_o = 1'b1; - end + valid_o[rr_q] = valid_i; end + assign ready_o = ready_i[rr_q]; always_ff @(posedge clk_i or negedge rst_ni) begin : proc_prio_regs if(~rst_ni) begin From 3e433be23a022467a33bebc6c8ef7a6effb5b93e Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Thu, 27 Jan 2022 10:55:36 +0100 Subject: [PATCH 6/6] rr_distributor: default to compliant behavior --- src/rr_distributor.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rr_distributor.sv b/src/rr_distributor.sv index 6c617565..d9bb779f 100644 --- a/src/rr_distributor.sv +++ b/src/rr_distributor.sv @@ -28,7 +28,7 @@ module rr_distributor # ( /// If set to 1'b0, the rr_distributor will step through the outputs if one is ready /// but the current one is not. This can reduce wait time for the input. /// **THIS IS NOT COMPLIANT AS IT MAY DE-ASSERT VALID WITHOUT A PROPER HANDSHAKE** - parameter bit StrictRR = 1'b0, + parameter bit StrictRR = 1'b1, /// Dependent parameter, do **not** overwrite. /// Width of the selected index parameter int unsigned IdxWidth = cf_math_pkg::idx_width(NumOut),