From 52ba52aabc77e2905ed18e2dc34c3e2aa6810f30 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Fri, 29 Nov 2024 18:58:35 +0100 Subject: [PATCH] [rtl] Dedicated ibex_counter_flop modules Depending on whether we are targeting a Xilinx FPGA or a generic target, we use a Xilinx specifc flop implementation for the Ibex counters. To increase readability, this commit creates two new modules containing a Xilinx specific flop implementation or a generic flop implementation. In the Xilinx specific version, a DSP is used when the CounterWidth is below 49-bits. Signed-off-by: Pascal Nasahl --- dv/uvm/core_ibex/ibex_dv.f | 2 ++ ibex_core.core | 2 ++ rtl/ibex_core.f | 2 ++ rtl/ibex_counter.sv | 42 ++++++++++------------ rtl/ibex_counter_flop_generic.sv | 31 +++++++++++++++++ rtl/ibex_counter_flop_xilinx.sv | 60 ++++++++++++++++++++++++++++++++ src_files.yml | 2 ++ 7 files changed, 117 insertions(+), 24 deletions(-) create mode 100644 rtl/ibex_counter_flop_generic.sv create mode 100644 rtl/ibex_counter_flop_xilinx.sv diff --git a/dv/uvm/core_ibex/ibex_dv.f b/dv/uvm/core_ibex/ibex_dv.f index c8ec489eb2..3f8eb825a6 100644 --- a/dv/uvm/core_ibex/ibex_dv.f +++ b/dv/uvm/core_ibex/ibex_dv.f @@ -84,6 +84,8 @@ ${PRJ_DIR}/rtl/ibex_csr.sv ${PRJ_DIR}/rtl/ibex_cs_registers.sv ${PRJ_DIR}/rtl/ibex_counter.sv +${PRJ_DIR}/rtl/ibex_counter_flop_generic.sv +${PRJ_DIR}/rtl/ibex_counter_flop_xilinx.sv ${PRJ_DIR}/rtl/ibex_decoder.sv ${PRJ_DIR}/rtl/ibex_dummy_instr.sv ${PRJ_DIR}/rtl/ibex_ex_block.sv diff --git a/ibex_core.core b/ibex_core.core index 15fb327869..095505a941 100644 --- a/ibex_core.core +++ b/ibex_core.core @@ -23,6 +23,8 @@ filesets: - rtl/ibex_cs_registers.sv - rtl/ibex_csr.sv - rtl/ibex_counter.sv + - rtl/ibex_counter_flop_generic.sv + - rtl/ibex_counter_flop_xilinx.sv - rtl/ibex_decoder.sv - rtl/ibex_ex_block.sv - rtl/ibex_fetch_fifo.sv diff --git a/rtl/ibex_core.f b/rtl/ibex_core.f index cde47fca2c..3986fb3ca3 100644 --- a/rtl/ibex_core.f +++ b/rtl/ibex_core.f @@ -7,6 +7,8 @@ ibex_compressed_decoder.sv ibex_controller.sv ibex_counter.sv +ibex_counter_flop_generic.sv +ibex_counter_flop_xilinx.sv ibex_cs_registers.sv ibex_decoder.sv ibex_ex_block.sv diff --git a/rtl/ibex_counter.sv b/rtl/ibex_counter.sv index d3ca14ca02..057b6bb80f 100644 --- a/rtl/ibex_counter.sv +++ b/rtl/ibex_counter.sv @@ -24,7 +24,7 @@ module ibex_counter #( logic [CounterWidth-1:0] counter_upd; logic [63:0] counter_load; logic we; - logic [CounterWidth-1:0] counter_d; + logic [CounterWidth-1:0] counter_d, counter_q; // Increment assign counter_upd = counter[CounterWidth-1:0] + {{CounterWidth - 1{1'b0}}, 1'b1}; @@ -52,32 +52,26 @@ module ibex_counter #( `ifdef FPGA_XILINX // On Xilinx FPGAs, 48-bit DSPs are available that can be used for the - // counter. - if (CounterWidth < 49) begin : g_dsp_counter - // Set DSP pragma for supported xilinx FPGAs - (* use_dsp = "yes" *) logic [CounterWidth-1:0] counter_q; - // DSP output register requires synchronous reset. - `define COUNTER_FLOP_RST posedge clk_i - end else begin : g_no_dsp_counter - (* use_dsp = "no" *) logic [CounterWidth-1:0] counter_q; - `define COUNTER_FLOP_RST posedge clk_i or negedge rst_ni - end + // counter. Hence, use Xilinx specific flop implementation. + ibex_counter_flop_xilinx #( + .CounterWidth (CounterWidth) + ) u_ibex_cnt_ff_xilinx ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .counter_i (counter_d), + .counter_o (counter_q) + ); `else - logic [CounterWidth-1:0] counter_q; - - `define COUNTER_FLOP_RST posedge clk_i or negedge rst_ni + ibex_counter_flop_generic #( + .CounterWidth (CounterWidth) + ) u_ibex_cnt_ff_generic ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .counter_i (counter_d), + .counter_o (counter_q) + ); `endif - // Counter flop - always_ff @(`COUNTER_FLOP_RST) begin - `undef COUNTER_FLOP_RST - if (!rst_ni) begin - counter_q <= '0; - end else begin - counter_q <= counter_d; - end - end - if (CounterWidth < 64) begin : g_counter_narrow logic [63:CounterWidth] unused_counter_load; diff --git a/rtl/ibex_counter_flop_generic.sv b/rtl/ibex_counter_flop_generic.sv new file mode 100644 index 0000000000..45b88ca05f --- /dev/null +++ b/rtl/ibex_counter_flop_generic.sv @@ -0,0 +1,31 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +/** + * Generic Counter Flop + * + * Counter flop implementation for non-Xilinx targets + */ +module ibex_counter_flop_generic #( + parameter int CounterWidth = 32 +) ( + input logic clk_i, + input logic rst_ni, + + input logic [CounterWidth-1:0] counter_i, + output logic [CounterWidth-1:0] counter_o +); + logic [CounterWidth-1:0] counter_q, counter_d; + assign counter_o = counter_q; + assign counter_d = counter_i; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + counter_q <= '0; + end else begin + counter_q <= counter_d; + end + end + +endmodule diff --git a/rtl/ibex_counter_flop_xilinx.sv b/rtl/ibex_counter_flop_xilinx.sv new file mode 100644 index 0000000000..7d4ca1b0af --- /dev/null +++ b/rtl/ibex_counter_flop_xilinx.sv @@ -0,0 +1,60 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +/** + * Generic Counter Flop + * + * Counter flop implementation for non-Xilinx targets + */ +module ibex_counter_flop_xilinx #( + parameter int CounterWidth = 32 +) ( + input logic clk_i, + input logic rst_ni, + + input logic [CounterWidth-1:0] counter_i, + output logic [CounterWidth-1:0] counter_o +); + // On Xilinx FPGAs, 48-bit DSPs are available that can be used for the + // counter. + localparam int DspPragma = CounterWidth < 49 ? "yes" : "no"; + (* use_dsp = DspPragma *) logic [CounterWidth-1:0] counter_q; + // When using a DSP, a sync. reset is needed for the flop. + localparam string ResetType = CounterWidth < 49 ? "SYNC" : "ASYNC"; + + // Flop with async. reset. + `define ASYNC_RST_FF(CLK, RST_NI, Q, D) \ + always_ff @(posedge CLK or negedge RST_NI) begin \ + if (!RST_NI) begin \ + Q <= '0; \ + end else begin \ + Q <= D; \ + end \ + end + + // Flop with sync. reset. + `define SYNC_RST_FF(CLK, RST_NI, Q, D) \ + always_ff @(posedge CLK) begin \ + if (!RST_NI) begin \ + Q <= '0; \ + end else begin \ + Q <= D; \ + end \ + end + + logic [CounterWidth-1:0] counter_d; + assign counter_o = counter_q; + assign counter_d = counter_i; + + generate + if(ResetType == "ASYNC") begin : g_async_reset_ff + `ASYNC_RST_FF(clk_i, rst_ni, counter_q, counter_d); + `undef ASYNC_RST_FF + end else begin : g_sync_reset_ff + `SYNC_RST_FF(clk_i, rst_ni, counter_q, counter_d); + `undef SYNC_RST_FF + end + endgenerate + +endmodule diff --git a/src_files.yml b/src_files.yml index 3149b3be71..3560033f89 100644 --- a/src_files.yml +++ b/src_files.yml @@ -10,6 +10,8 @@ ibex: rtl/ibex_controller.sv, rtl/ibex_cs_registers.sv, rtl/ibex_counters.sv, + rtl/ibex_counter_flop_generic.sv, + rtl/ibex_counter_flop_xilinx.sv, rtl/ibex_decoder.sv, rtl/ibex_ex_block.sv, rtl/ibex_id_stage.sv,