From ec5bedbe908ea0a339aabfecb0cf116fce588d66 Mon Sep 17 00:00:00 2001 From: Pascal Nasahl Date: Fri, 29 Nov 2024 18:58:35 +0100 Subject: [PATCH] [rtl] Fix non-DSP reset in ibex_counter When targeting Xilinx FPGAs, we utilize a DSP for counters with a width of less than 49-bit. In this case, a sync. reset is needed. However, currently, there is a bug in the RTL where also a sync. reset is used for the non-DSP counters on the FPGA. Signed-off-by: Pascal Nasahl --- rtl/ibex_counter.sv | 46 +++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/rtl/ibex_counter.sv b/rtl/ibex_counter.sv index c78e510ee4..a31dddc4fe 100644 --- a/rtl/ibex_counter.sv +++ b/rtl/ibex_counter.sv @@ -51,26 +51,39 @@ module ibex_counter #( end `ifdef FPGA_XILINX - // Set DSP pragma for supported xilinx FPGAs - localparam int DspPragma = CounterWidth < 49 ? "yes" : "no"; - (* use_dsp = DspPragma *) logic [CounterWidth-1:0] counter_q; - - // DSP output register requires synchronous reset. - `define COUNTER_FLOP_RST posedge clk_i + // On Xilinx FPGAs, 48-bit DSPs are available that can be used for the + // counter. Hence, use Xilinx specific flop implementation. The datatype for + // UseDsp is on purpose int as with string Xilinx throws an error for the + // use_dsp pragma. + localparam int UseDsp = CounterWidth < 49 ? "yes" : "no"; + (* use_dsp = UseDsp *) logic [CounterWidth-1:0] counter_q; `else + localparam string UseDsp = "no"; logic [CounterWidth-1:0] counter_q; - - `define COUNTER_FLOP_RST posedge clk_i or negedge rst_ni `endif - // Counter flop - always_ff @(`COUNTER_FLOP_RST) begin - if (!rst_ni) begin - counter_q <= '0; - end else begin - counter_q <= counter_d; + generate + if (UseDsp == "yes") begin : g_cnt_dsp + // Use sync. reset for DSP. + always_ff @(posedge clk_i) begin + if (!rst_ni) begin + counter_q <= '0; + end else begin + counter_q <= counter_d; + end + end + end else begin : g_cnt_no_dsp + // Use async. reset for flop. + 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 end - end + endgenerate + if (CounterWidth < 64) begin : g_counter_narrow logic [63:CounterWidth] unused_counter_load; @@ -98,6 +111,3 @@ module ibex_counter #( assign counter_val_o = counter; endmodule - -// Keep helper defines file-local. -`undef COUNTER_FLOP_RST