Skip to content

Commit

Permalink
[rtl] Fix non-DSP reset in ibex_counter
Browse files Browse the repository at this point in the history
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 <nasahlpa@lowrisc.org>
  • Loading branch information
nasahlpa committed Dec 4, 2024
1 parent 0945aa8 commit d249e50
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 18 deletions.
1 change: 1 addition & 0 deletions dv/uvm/core_ibex/ibex_dv.f
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
${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_xilinx.sv
${PRJ_DIR}/rtl/ibex_decoder.sv
${PRJ_DIR}/rtl/ibex_dummy_instr.sv
${PRJ_DIR}/rtl/ibex_ex_block.sv
Expand Down
1 change: 1 addition & 0 deletions ibex_core.core
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ filesets:
- rtl/ibex_cs_registers.sv
- rtl/ibex_csr.sv
- rtl/ibex_counter.sv
- rtl/ibex_counter_flop_xilinx.sv
- rtl/ibex_decoder.sv
- rtl/ibex_ex_block.sv
- rtl/ibex_fetch_fifo.sv
Expand Down
1 change: 1 addition & 0 deletions rtl/ibex_core.f
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
ibex_compressed_decoder.sv
ibex_controller.sv
ibex_counter.sv
ibex_counter_flop_xilinx.sv
ibex_cs_registers.sv
ibex_decoder.sv
ibex_ex_block.sv
Expand Down
44 changes: 26 additions & 18 deletions rtl/ibex_counter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,37 @@ 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.
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;
Expand Down Expand Up @@ -98,6 +109,3 @@ module ibex_counter #(
assign counter_val_o = counter;

endmodule

// Keep helper defines file-local.
`undef COUNTER_FLOP_RST
43 changes: 43 additions & 0 deletions rtl/ibex_counter_flop_xilinx.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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,
parameter logic [CounterWidth-1:0] ResetValue = 0
) (
input logic clk_i,
input logic rst_ni,
input logic [CounterWidth-1:0] d_i,
output logic [CounterWidth-1:0] q_o
);
// On Xilinx FPGAs, 48-bit DSPs are available that can be used for the
// counter. When using a DSP, a sync. reset is needed for the flop.
localparam string ResetType = CounterWidth < 49 ? "SYNC" : "ASYNC";

generate
if(ResetType == "ASYNC") begin : g_async_reset_ff
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
q_o <= ResetValue;
end else begin
q_o <= d_i;
end
end
end else begin : g_sync_reset_ff
always_ff @(posedge clk_i) begin
if (!rst_ni) begin
q_o <= ResetValue;
end else begin
q_o <= d_i;
end
end
end
endgenerate

endmodule
1 change: 1 addition & 0 deletions src_files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ibex:
rtl/ibex_controller.sv,
rtl/ibex_cs_registers.sv,
rtl/ibex_counters.sv,
rtl/ibex_counter_flop_xilinx.sv,
rtl/ibex_decoder.sv,
rtl/ibex_ex_block.sv,
rtl/ibex_id_stage.sv,
Expand Down

0 comments on commit d249e50

Please sign in to comment.