diff --git a/dv/uvm/core_ibex/ibex_dv.f b/dv/uvm/core_ibex/ibex_dv.f index c8ec489eb..3f8eb825a 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 15fb32786..095505a94 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 cde47fca2..3986fb3ca 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 d3ca14ca0..057b6bb80 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 000000000..45b88ca05 --- /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 000000000..7d4ca1b0a --- /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 3149b3be7..3560033f8 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,