added converted verilog file with top wrapper
diff --git a/verilog/rtl/PWM.v b/verilog/rtl/PWM.v
deleted file mode 100644
index 44078a0..0000000
--- a/verilog/rtl/PWM.v
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
-control register [7:0]ctrl:
-bit 0: When set, external clock is chosen for PWM/timer. When cleared, wb clock is used for PWM/timer.
-bit 1: When set, PWM is enabled. When cleared, timer is enabled.
-bit 2: When set, PWM/timer starts. When cleared, PWM/timer stops.
-bit 3: When set, timer runs continuously. When cleared, timer runs one time.
-bit 4: When set, o_pwm enabled.
-bit 5: timer interrupt bit When it is written with 0, interrupt request is cleared.
-bit 6: When set, a 16-bit external signal i_DC is used as duty cycle. When cleared, register DC is used.
-bit 7: When set, counter reset for PWM/timer, it's output and bit 5 will also be cleared. When changing from PWM mode to timer mode reset is needed before timer starts.
-*/
-module PWM(
-//tlul interface
- input clk_i,
- input rst_ni,
-
- input re_i,
- input we_i,
- input [7:0] addr_i,
- input [31:0] wdata_i,
- input [3:0] be_i,
- output [31:0] rdata_o,
- //output error_o,
-
- input i_extclk,
- input [15:0] i_DC,
- input i_valid_DC,
- output o_pwm,
- output o_pwm_2,
- output reg oe_pwm1,
- output reg oe_pwm2
-
-);
-
-////////////////////control logic////////////////////////////
-parameter adr_ctrl_1 = 0,
- adr_divisor_1= 4,
- adr_period_1 = 8,
- adr_DC_1 = 12;
-
-parameter adr_ctrl_2 = 16,
- adr_divisor_2= 20,
- adr_period_2 = 24,
- adr_DC_2 = 28;
-
-
-
-
-reg [7:0] ctrl;
-reg [15:0] period;
-reg [15:0] DC;
-reg [15:0] divisor;
-
-reg [7:0] ctrl_2;
-reg [15:0] period_2;
-reg [15:0] DC_2;
-reg [15:0] divisor_2;
-
-wire write;
-
-assign write = we_i & ~re_i;
-
-always@(posedge clk_i)
- if(~rst_ni)begin
- ctrl[4:2] <= 0;
- ctrl[0] <= 0;
- ctrl[7:6] <= 0;
- DC <= 0;
- period <= 0;
- divisor <= 0;
-
-
- ctrl_2[4:2] <= 0;
- ctrl_2[0] <= 0;
- ctrl_2[7:6] <= 0;
- DC_2 <= 0;
- period_2 <= 0;
- divisor_2 <= 0;
- end
- else if(write)begin
- case(addr_i)
- adr_ctrl_1:begin
- ctrl[0] <= wdata_i[0];
- ctrl[4:2] <= wdata_i[4:2];
- ctrl[7:6] <= wdata_i[7:6];
- end
-
- adr_ctrl_2:begin
- ctrl_2[0] <= wdata_i[0];
- ctrl_2[4:2] <= wdata_i[4:2];
- ctrl_2[7:6] <= wdata_i[7:6];
- end
-
- adr_divisor_1 : divisor <= wdata_i[15:0];
- adr_period_1 : period <= wdata_i[15:0];
- adr_DC_1 : DC <= wdata_i[15:0];
-
- adr_divisor_2 : divisor_2 <= wdata_i[15:0];
- adr_period_2 : period_2 <= wdata_i[15:0];
- adr_DC_2 : DC_2 <= wdata_i[15:0];
- endcase
- end
-
-
-
-wire pwm;
-always @(posedge clk_i) begin
- ctrl[1] <= 1'b1;
-end
-
-
-assign pwm = ctrl[1];
-
-wire pwm_1;
-always @(posedge clk_i) begin
- ctrl_2[1] <= 1'b1;
-end
-
-assign pwm_1 = ctrl_2[1];
-wire eclk_2,oclk_2;
-///////////////////////////////////////////////////////////
-
-//////down clocking for pwm///////////////////
-wire clk_source;
-wire eclk,oclk;
-assign clk_source = clk_i;
-down_clocking_even clock_div_ev(
- .clk_i (clk_source) ,
- .rst_ni (rst_ni),
- .i_divisor ({1'b0,divisor[15:1]}),
- .o_clk (eclk)
-);
-down_clocking_odd clock_div_od(
- .clk_i (clk_source),
- .rst_ni (rst_ni),
- .i_divisor ({1'b0,divisor[15:1]}),
- .o_clk (oclk)
-);
-wire clk;
-assign clk = divisor[0]? oclk: eclk;
-
-
-
-
-down_clocking_even clock_div_ev_2(
- .clk_i (clk_source) ,
- .rst_ni (rst_ni),
- .i_divisor ({1'b0,divisor_2[15:1]}),
- .o_clk (eclk_2)
-);
-down_clocking_odd clock_div_od_2(
- .clk_i (clk_source),
- .rst_ni (rst_ni),
- .i_divisor ({1'b0,divisor_2[15:1]}),
- .o_clk (oclk_2)
-);
-wire clk_2;
-assign clk_2 = divisor_2[0]? oclk_2: eclk_2;
-
-///////////////////////////////////////////////////////
-
-/////////////////main counter //////////////////////////
-reg [15:0] ct;
-reg pts; //PWM signal
-reg [15:0] extDC;
-wire [15:0] DC_1;
-assign DC_1 = ctrl[6]? extDC: DC; //external or internal duty cycle toggle
-wire [15:0] period_1;
-assign period_1 = (period==0)? 0: (period-1);
-
-wire rst_ct;
-assign rst_ct = ~rst_ni|ctrl[7];
-
-
-reg [15:0] ct_2;
-reg pts_2; //PWM signal
-reg [15:0] extDC_2;
-wire [15:0] DCw_2;
-assign DCw_2 = ctrl_2[6]? extDC_2: DC_2; //external or internal duty cycle toggle
-wire [15:0] period_P2;
-assign period_P2 = (period_2==0)? 0: (period_2-1);
-
-wire rst_ct_2;
-assign rst_ct_2 = ~rst_ni|ctrl_2[7];
-
-always@(posedge clk )
- if(rst_ct)begin
- pts <= 0;
- ct <= 0;
- extDC <= 0;
- end
- else begin
- if(i_valid_DC) extDC <= i_DC;
- if(ctrl[2])begin
- if(pwm) begin
- oe_pwm1 <= 1'b1;
- if(ct >= period_1) ct <= 0;
- else ct <= ct+1;
-
- if(ct < DC_1) pts <= 1'b1;
- else pts <= 1'b0;
- end
- end
- else begin
- pts <= 1'b0;
- ct <= 0;
- oe_pwm1 <= 0;
- end
-end
-
-
-
-always@(posedge clk_2 )
- if(rst_ct_2)begin
- pts_2 <= 0;
- ct_2 <= 0;
- extDC_2 <= 0;
- end
- else begin
- if(i_valid_DC) extDC_2 <= i_DC;
- if(ctrl_2[2])begin
- if(pwm_1) begin
- oe_pwm2 <= 1'b1;
- if(ct_2 >= period_P2) ct_2 <= 0;
- else ct_2 <= ct_2+1;
-
- if(ct_2 < DCw_2) pts_2 <= 1'b1;
- else pts_2 <= 1'b0;
- end
- end
- else begin
- pts_2 <= 1'b0;
- ct_2 <= 0;
- oe_pwm2 <= 1'b0;
- end
-end
-//////////////////////////////////////////////////////////
-
-assign o_pwm = ctrl[4]? pts: 0;
-assign o_pwm_2 = ctrl_2[4]? pts_2: 0;
-assign rdata_o = (addr_i == adr_ctrl_1) ? {8'h0,ctrl} :
- (addr_i == adr_divisor_1)? divisor :
- (addr_i == adr_period_1) ? period :
- (addr_i == adr_DC_1) ? DC :
- (addr_i == adr_DC_2) ? DC_2 :
- (addr_i == adr_period_2) ? period_2 :
- (addr_i == adr_divisor_2)? divisor_2 :
- (addr_i == adr_ctrl_2) ? {8'h0,ctrl_2}:0;
-
-
-endmodule
diff --git a/verilog/rtl/azadi_soc_top.sv b/verilog/rtl/azadi_soc_top.sv
deleted file mode 100644
index aaad2b5..0000000
--- a/verilog/rtl/azadi_soc_top.sv
+++ /dev/null
@@ -1,498 +0,0 @@
-// Designed by a Team at Micro Electronics Research Lab, Usman Institute of Technology.
-// https://www.merledupk.org
-
-
-module azadi_soc_top (
-`ifdef USE_POWER_PINS
- inout vccd1,
- inout vssd1,
-`endif
- input logic clk_i,
- input logic rst_ni,
- input logic prog,
- //output system_rst_ni,
- // output prog_rst_ni,
- input logic [15:0] clks_per_bit,
- input logic [31:0] gpio_i,
- output logic [31:0] gpio_o,
- output logic [31:0] gpio_oe,
-
- // jtag interface
- input logic jtag_tck_i,
- input logic jtag_tms_i,
- input logic jtag_trst_ni,
- input logic jtag_tdi_i,
- output logic jtag_tdo_o,
- output logic jtag_tdo_oe_o,
-
- // uart-periph interface
- output logic uart_tx,
- input logic uart_rx,
-
- // PWM interface
-
- output logic pwm_o,
- output logic pwm_o_2,
- output logic pwm1_oe,
- output logic pwm2_oe,
-
- // SPI interface
-
- output logic [`SPI_SS_NB-1:0] ss_o,
- output logic sclk_o,
- output logic sd_o,
- output logic sd_oe,
- input logic sd_i
-);
-
-localparam logic [31:0] JTAG_ID = {
- 4'h0, // Version
- 16'h4F54, // Part Number: "OT"
- 11'h426, // Manufacturer Identity: Google
- 1'b1 // (fixed)
-};
-
-// logic clk_ni;
-// assign clk_ni = ~clk_i;
- logic prog_rst_n;
- logic system_rst_ni;
- logic [31:0] gpio_in;
- logic [31:0] gpio_out;
-
- assign gpio_in = gpio_i;
- assign gpio_o = gpio_out;
-
- logic instr_valid;
- logic [11:0] tlul_addr;
- logic req_i;
- logic [31:0] tlul_data;
- logic dbg_req;
- logic dbg_rst;
-
-
- // instruction sram interface
- logic instr_csb;
- logic [11:0] instr_addr;
- logic [31:0] instr_wdata;
- logic [3:0] instr_wmask;
- logic instr_we;
- logic [31:0] instr_rdata;
-
- // data sram interface
- logic data_csb;
- logic [11:0] data_addr;
- logic [31:0] data_wdata;
- logic [3:0] data_wmask;
- logic data_we;
- logic [31:0] data_rdata;
-
- logic [31:0] iccm_ctrl_data;
- logic iccm_ctrl_we;
- logic [11:0] iccm_ctrl_addr_o;
-
-
- tlul_pkg::tl_h2d_t ifu_to_xbar;
- tlul_pkg::tl_d2h_t xbar_to_ifu;
- tlul_pkg::tl_h2d_t xbar_to_iccm;
- tlul_pkg::tl_d2h_t iccm_to_xbar;
-
- tlul_pkg::tl_h2d_t lsu_to_xbar;
- tlul_pkg::tl_d2h_t xbar_to_lsu;
-
- tlul_pkg::tl_h2d_t xbar_to_dccm;
- tlul_pkg::tl_d2h_t dccm_to_xbar;
-
- tlul_pkg::tl_h2d_t xbarp_to_gpio;
- tlul_pkg::tl_d2h_t gpio_to_xbarp;
-
- tlul_pkg::tl_h2d_t dm_to_xbar;
- tlul_pkg::tl_d2h_t xbar_to_dm;
-
- tlul_pkg::tl_h2d_t dbgrom_to_xbar;
- tlul_pkg::tl_d2h_t xbar_to_dbgrom;
-
- tlul_pkg::tl_h2d_t plic_req;
- tlul_pkg::tl_d2h_t plic_resp;
-
- tlul_pkg::tl_h2d_t xbar_to_uart;
- tlul_pkg::tl_d2h_t uart_to_xbar;
-
- tlul_pkg::tl_h2d_t xbar_to_timer;
- tlul_pkg::tl_d2h_t timer_to_xbar;
-
- tlul_pkg::tl_h2d_t xbar_to_pwm;
- tlul_pkg::tl_d2h_t pwm_to_xbar;
-
- tlul_pkg::tl_h2d_t xbar_to_spi;
- tlul_pkg::tl_d2h_t spi_to_xbar;
-
- // interrupt vector
- logic [35:0] intr_vector;
-
- // Interrupt source list
- logic [31:0] intr_gpio;
- logic intr_uart0_tx_watermark;
- logic intr_uart0_rx_watermark;
- logic intr_uart0_tx_empty;
- logic intr_uart0_rx_overflow;
- logic intr_uart0_rx_frame_err;
- logic intr_uart0_rx_break_err;
- logic intr_uart0_rx_timeout;
- logic intr_uart0_rx_parity_err;
- logic intr_req;
- logic intr_srx;
- logic intr_stx;
- logic intr_timer;
- logic intr_u_tx;
-
- assign intr_vector = {
- intr_srx,
- intr_stx,
- intr_u_tx,
- intr_gpio,
- 1'b0
- };
-
-// jtag interface
-
- jtag_pkg::jtag_req_t jtag_req;
- jtag_pkg::jtag_rsp_t jtag_rsp;
-
-
- assign jtag_req.tck = jtag_tck_i;
- assign jtag_req.tms = jtag_tms_i;
- assign jtag_req.trst_n = jtag_trst_ni;
- assign jtag_req.tdi = jtag_tdi_i;
- assign jtag_tdo_o = jtag_rsp.tdo;
- assign jtag_tdo_oe_o = jtag_rsp.tdo_oe;
-
-
-brq_core_top #(
- .PMPEnable (1'b0),
- .PMPGranularity (0),
- .PMPNumRegions (4),
- .MHPMCounterNum (0),
- .MHPMCounterWidth (40),
- .RV32E (1'b0),
- .RV32M (brq_pkg::RV32MSlow),
- .RV32B (brq_pkg::RV32BNone),
- .RegFile (brq_pkg::RegFileFF),
- .BranchTargetALU (1'b0),
- .WritebackStage (1'b1),
- .ICache (1'b0),
- .ICacheECC (1'b0),
- .BranchPredictor (1'b0),
- .DbgTriggerEn (1'b1),
- .DbgHwBreakNum (1),
- .Securebrq (1'b0),
- .DmHaltAddr (tl_main_pkg::ADDR_SPACE_DEBUG_ROM + 32'h 800),
- .DmExceptionAddr (tl_main_pkg::ADDR_SPACE_DEBUG_ROM + dm::ExceptionAddress)
-) u_top (
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
- // instruction memory interface
- .tl_i_i (xbar_to_ifu),
- .tl_i_o (ifu_to_xbar),
-
- // data memory interface
- .tl_d_i (xbar_to_lsu),
- .tl_d_o (lsu_to_xbar),
-
- //.test_en_i (1'b0), // enable all clk_i gates for testing
-
- .hart_id_i (32'b0),
- .boot_addr_i (32'h20000000),
-
- // Interrupt inputs
- .irq_software_i (1'b0),
- .irq_timer_i (intr_timer),
- .irq_external_i (intr_req),
- .irq_fast_i ('0),
- .irq_nm_i (1'b0), // non-maskeable interrupt
-
- // Debug Interface
- .debug_req_i (dbg_req),
- // CPU Control Signals
- .fetch_enable_i (1'b1),
- .alert_minor_o (),
- .alert_major_o (),
- .core_sleep_o ()
-);
-
-// Debug module
-rv_dm #(
- .NrHarts(1),
- .IdcodeValue(JTAG_ID)
- // .DirectDmiTap (DirectDmiTap)
-) debug_module (
- .clk_i(clk_i), // clk_i
- .rst_ni(rst_ni), // asynchronous reset active low, connect PoR
- // here, not the system reset
- .testmode_i('0),
- .ndmreset_o(dbg_rst), // non-debug module reset
- .dmactive_o(), // debug module is active
- .debug_req_o(dbg_req), // async debug request
- .unavailable_i(1'b0), // communicate whether the hart is unavailable
- // (e.g.: power down)
-
- // bus device with debug memory, for an execution based technique
- .tl_d_i(dbgrom_to_xbar),
- .tl_d_o(xbar_to_dbgrom),
-
- // bus host, for system bus accesses
- .tl_h_o(dm_to_xbar),
- .tl_h_i(xbar_to_dm),
-
- .jtag_req_i(jtag_req),
- .jtag_rsp_o(jtag_rsp)
-);
-
-
-
-// main xbar module
- tl_xbar_main main_swith (
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
- // Host interfaces
- .tl_brqif_i (ifu_to_xbar),
- .tl_brqif_o (xbar_to_ifu),
- .tl_brqlsu_i (lsu_to_xbar),
- .tl_brqlsu_o (xbar_to_lsu),
- .tl_dm_sba_i (dm_to_xbar),
- .tl_dm_sba_o (xbar_to_dm),
-
- // Device interfaces
- .tl_iccm_o (xbar_to_iccm),
- .tl_iccm_i (iccm_to_xbar),
- .tl_debug_rom_o (dbgrom_to_xbar),
- .tl_debug_rom_i (xbar_to_dbgrom),
- .tl_dccm_o (xbar_to_dccm),
- .tl_dccm_i (dccm_to_xbar),
- .tl_timer0_o (xbar_to_timer),
- .tl_timer0_i (timer_to_xbar),
- .tl_uart_o (xbar_to_uart),
- .tl_uart_i (uart_to_xbar),
- .tl_spi_o (xbar_to_spi),
- .tl_spi_i (spi_to_xbar),
- .tl_pwm_o (xbar_to_pwm),
- .tl_pwm_i (pwm_to_xbar),
- .tl_gpio_o (xbarp_to_gpio),
- .tl_gpio_i (gpio_to_xbarp),
- .tl_plic_o (plic_req),
- .tl_plic_i (plic_resp)
-);
-
-
-// timer
-rv_timer timer0(
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
- .tl_i (xbar_to_timer),
- .tl_o (timer_to_xbar),
-
- .intr_timer_expired_0_0_o (intr_timer)
-);
-
-// PWM module
-
-pwm_top u_pwm(
-
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
- .tl_i (xbar_to_pwm),
- .tl_o (pwm_to_xbar),
-
-
- .pwm_o (pwm_o),
- .pwm_o_2 (pwm_o_2),
- .pwm1_oe (pwm1_oe),
- .pwm2_oe (pwm2_oe)
-);
-
-
-// spi module
-
-spi_top u_spi_host(
-
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
- .tl_i (xbar_to_spi),
- .tl_o (spi_to_xbar),
-
- // SPI signals
- .intr_rx_o (intr_srx),
- .intr_tx_o (intr_stx),
- .ss_o (ss_o),
- .sclk_o (sclk_o),
- .sd_o (sd_o),
- .sd_oe (sd_oe),
- .sd_i (sd_i)
-);
-
-
-//GPIO module
-gpio GPIO (
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
- // Below Regster interface can be changed
- .tl_i (xbarp_to_gpio),
- .tl_o (gpio_to_xbarp),
-
- .cio_gpio_i (gpio_in),
- .cio_gpio_o (gpio_out),
- .cio_gpio_en_o (gpio_oe),
-
- .intr_gpio_o (intr_gpio )
-);
-
-
-rstmgr reset_manager(
- .clk_i(clk_i),
- .rst_ni(rst_ni),
- .ndmreset (dbg_rst),
- .prog_rst_ni(prog_rst_ni),
- .sys_rst_ni(system_rst_ni)
-);
-
-rv_plic intr_controller (
- .clk_i(clk_i),
- .rst_ni(system_rst_ni),
-
- // Bus Interface (device)
- .tl_i (plic_req),
- .tl_o (plic_resp),
-
- // Interrupt Sources
- .intr_src_i (intr_vector),
-
- // Interrupt notification to targets
- .irq_o (intr_req),
- .msip_o()
-);
-
- uart_top u_uart(
-
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
- .tl_i (xbar_to_uart),
- .tl_o (uart_to_xbar),
-
- .tx_o (uart_tx),
- .rx_i (uart_rx),
-
- .intr_tx (intr_u_tx)
-);
-
-logic rx_dv_i;
-logic [7:0] rx_byte_i;
-
-iccm_controller u_dut(
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .prog_i (prog),
- .rx_dv_i (rx_dv_i),
- .rx_byte_i (rx_byte_i),
- .we_o (iccm_ctrl_we),
- .addr_o (iccm_ctrl_addr_o),
- .wdata_o (iccm_ctrl_data),
- .reset_o (prog_rst_ni)
-);
-
-uart_rx_prog u_uart_rx_prog(
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .i_Rx_Serial (uart_rx),
- .CLKS_PER_BIT (clks_per_bit),
- .o_Rx_DV (rx_dv_i),
- .o_Rx_Byte (rx_byte_i)
-);
-
-
-// dummy instruction memory
-instr_mem_top iccm_adapter(
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
- .tl_i (xbar_to_iccm),
- .tl_o (iccm_to_xbar),
-// iccm controller interface
- .iccm_ctrl_addr (iccm_ctrl_addr_o),
- .iccm_ctrl_wdata (iccm_ctrl_data),
- .iccm_ctrl_we (iccm_ctrl_we),
- .prog_rst_ni (prog_rst_ni),
-
-
-// instruction sram interface
- .csb (instr_csb),
- .addr_o (instr_addr),
- .wdata_o (instr_wdata),
- .wmask_o (instr_wmask),
- .we_o (instr_we),
- .rdata_i (instr_rdata)
-);
-
- logic [31:0] unused_data1;
- logic [31:0] unused_data2;
-
- sky130_sram_4kbyte_1rw1r_32x1024_8 u_iccm (
- `ifdef USE_POWER_PINS
- .vccd1(vccd1),
- .vssd1(vssd1),
- `endif
- .clk0 (clk_i), // clock
- .csb0 (instr_csb), // active low chip select
- .web0 (instr_we), // active low write control
- .wmask0 (instr_wmask), // write mask
- .addr0 (instr_addr[9:0]),
- .din0 (instr_wdata),
- .dout0 (instr_rdata),
- .clk1 (1'b0),
- .csb1 (1'b1),
- .addr1 (10'b0),
- .dout1 (unused_data1)
- );
-// dummy data memory
-
-data_mem_top dccm_adapter(
- .clk_i (clk_i),
- .rst_ni (system_rst_ni),
-
-// tl-ul insterface
- .tl_d_i (xbar_to_dccm),
- .tl_d_o (dccm_to_xbar),
-
- // sram interface
- .csb (data_csb),
- .addr_o (data_addr),
- .wdata_o (data_wdata),
- .wmask_o (data_wmask),
- .we_o (data_we),
- .rdata_i (data_rdata)
-);
-
-
-sky130_sram_4kbyte_1rw1r_32x1024_8 u_dccm (
-`ifdef USE_POWER_PINS
- .vccd1(vccd1),
- .vssd1(vssd1),
-`endif
- .clk0 (clk_i), // clock
- .csb0 (data_csb), // active low chip select
- .web0 (data_we), // active low write control
- .wmask0 (data_wmask), // write mask
- .addr0 (data_addr[9:0]),
- .din0 (data_wdata),
- .dout0 (data_rdata),
- .clk1 (1'b0),
- .csb1 (1'b1),
- .addr1 (10'b0),
- .dout1 (unused_data2)
- );
-endmodule
diff --git a/verilog/rtl/azadi_soc_top.v b/verilog/rtl/azadi_soc_top.v
new file mode 100644
index 0000000..0b0cbd4
--- /dev/null
+++ b/verilog/rtl/azadi_soc_top.v
@@ -0,0 +1,26121 @@
+`default_nettype wire
+
+module azadi_soc_top (
+ `ifdef USE_POWER_PINS
+ inout VPWR, // User area 1 1.8V supply
+ inout VGND, // User area 1 digital ground
+ `endif
+ clk_i,
+ rst_ni,
+ prog,
+ clks_per_bit,
+ gpio_i,
+ gpio_o,
+ gpio_oe,
+ jtag_tck_i,
+ jtag_tms_i,
+ jtag_trst_ni,
+ jtag_tdi_i,
+ jtag_tdo_o,
+ jtag_tdo_oe_o,
+ uart_tx,
+ uart_rx,
+ pwm_o,
+ pwm_o_2,
+ pwm1_oe,
+ pwm2_oe,
+ ss_o,
+ sclk_o,
+ sd_o,
+ sd_oe,
+ sd_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire prog;
+ input wire [15:0] clks_per_bit;
+ input wire [31:0] gpio_i;
+ output wire [31:0] gpio_o;
+ output wire [31:0] gpio_oe;
+ input wire jtag_tck_i;
+ input wire jtag_tms_i;
+ input wire jtag_trst_ni;
+ input wire jtag_tdi_i;
+ output wire jtag_tdo_o;
+ output wire jtag_tdo_oe_o;
+ output wire uart_tx;
+ input wire uart_rx;
+ output wire pwm_o;
+ output wire pwm_o_2;
+ output wire pwm1_oe;
+ output wire pwm2_oe;
+ output wire [3:0] ss_o;
+ output wire sclk_o;
+ output wire sd_o;
+ output wire sd_oe;
+ input wire sd_i;
+ localparam [31:0] JTAG_ID = 32'b00000100111101010100100001001101;
+ wire prog_rst_n;
+ wire system_rst_ni;
+ wire [31:0] gpio_in;
+ wire [31:0] gpio_out;
+ assign gpio_in = gpio_i;
+ assign gpio_o = gpio_out;
+ wire instr_valid;
+ wire [11:0] tlul_addr;
+ wire req_i;
+ wire [31:0] tlul_data;
+ wire dbg_req;
+ wire dbg_rst;
+ wire instr_csb;
+ wire [11:0] instr_addr;
+ wire [31:0] instr_wdata;
+ wire [3:0] instr_wmask;
+ wire instr_we;
+ wire [31:0] instr_rdata;
+ wire data_csb;
+ wire [11:0] data_addr;
+ wire [31:0] data_wdata;
+ wire [3:0] data_wmask;
+ wire data_we;
+ wire [31:0] data_rdata;
+ wire [31:0] iccm_ctrl_data;
+ wire iccm_ctrl_we;
+ wire [11:0] iccm_ctrl_addr_o;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ wire [85:0] ifu_to_xbar;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ wire [51:0] xbar_to_ifu;
+ wire [85:0] xbar_to_iccm;
+ wire [51:0] iccm_to_xbar;
+ wire [85:0] lsu_to_xbar;
+ wire [51:0] xbar_to_lsu;
+ wire [85:0] xbar_to_dccm;
+ wire [51:0] dccm_to_xbar;
+ wire [85:0] xbarp_to_gpio;
+ wire [51:0] gpio_to_xbarp;
+ wire [85:0] dm_to_xbar;
+ wire [51:0] xbar_to_dm;
+ wire [85:0] dbgrom_to_xbar;
+ wire [51:0] xbar_to_dbgrom;
+ wire [85:0] plic_req;
+ wire [51:0] plic_resp;
+ wire [85:0] xbar_to_uart;
+ wire [51:0] uart_to_xbar;
+ wire [85:0] xbar_to_timer;
+ wire [51:0] timer_to_xbar;
+ wire [85:0] xbar_to_pwm;
+ wire [51:0] pwm_to_xbar;
+ wire [85:0] xbar_to_spi;
+ wire [51:0] spi_to_xbar;
+ wire [35:0] intr_vector;
+ wire [31:0] intr_gpio;
+ wire intr_uart0_tx_watermark;
+ wire intr_uart0_rx_watermark;
+ wire intr_uart0_tx_empty;
+ wire intr_uart0_rx_overflow;
+ wire intr_uart0_rx_frame_err;
+ wire intr_uart0_rx_break_err;
+ wire intr_uart0_rx_timeout;
+ wire intr_uart0_rx_parity_err;
+ wire intr_req;
+ wire intr_srx;
+ wire intr_stx;
+ wire intr_timer;
+ wire intr_u_tx;
+ assign intr_vector = {intr_srx, intr_stx, intr_u_tx, intr_gpio, 1'b0};
+ wire [3:0] jtag_req;
+ wire [1:0] jtag_rsp;
+ assign jtag_req[3] = jtag_tck_i;
+ assign jtag_req[2] = jtag_tms_i;
+ assign jtag_req[1] = jtag_trst_ni;
+ assign jtag_req[0] = jtag_tdi_i;
+ assign jtag_tdo_o = jtag_rsp[1];
+ assign jtag_tdo_oe_o = jtag_rsp[0];
+ localparam [63:0] dm_HaltAddress = 64'h0000000000000800;
+ localparam [63:0] dm_ExceptionAddress = dm_HaltAddress + 8;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_DEBUG_ROM = 32'h10040000;
+ localparam integer brq_pkg_RV32BNone = 0;
+ localparam integer brq_pkg_RV32MSlow = 1;
+ localparam integer brq_pkg_RegFileFF = 0;
+ brq_core_top #(
+ .PMPEnable(1'b0),
+ .PMPGranularity(0),
+ .PMPNumRegions(4),
+ .MHPMCounterNum(0),
+ .MHPMCounterWidth(40),
+ .RV32E(1'b0),
+ .RV32M(brq_pkg_RV32MSlow),
+ .RV32B(brq_pkg_RV32BNone),
+ .RegFile(brq_pkg_RegFileFF),
+ .BranchTargetALU(1'b0),
+ .WritebackStage(1'b1),
+ .ICache(1'b0),
+ .ICacheECC(1'b0),
+ .BranchPredictor(1'b0),
+ .DbgTriggerEn(1'b1),
+ .DbgHwBreakNum(1),
+ .Securebrq(1'b0),
+ .DmHaltAddr(tl_main_pkg_ADDR_SPACE_DEBUG_ROM + 32'h00000800),
+ .DmExceptionAddr(tl_main_pkg_ADDR_SPACE_DEBUG_ROM + dm_ExceptionAddress)
+ ) u_top(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_i_i(xbar_to_ifu),
+ .tl_i_o(ifu_to_xbar),
+ .tl_d_i(xbar_to_lsu),
+ .tl_d_o(lsu_to_xbar),
+ .hart_id_i(32'b00000000000000000000000000000000),
+ .boot_addr_i(32'h20000000),
+ .irq_software_i(1'b0),
+ .irq_timer_i(intr_timer),
+ .irq_external_i(intr_req),
+ .irq_fast_i({15 {1'sb0}}),
+ .irq_nm_i(1'b0),
+ .debug_req_i(dbg_req),
+ .fetch_enable_i(1'b1),
+ .alert_minor_o(),
+ .alert_major_o(),
+ .core_sleep_o()
+ );
+ rv_dm #(
+ .NrHarts(1),
+ .IdcodeValue(JTAG_ID)
+ ) debug_module(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .testmode_i(1'b0),
+ .ndmreset_o(dbg_rst),
+ .dmactive_o(),
+ .debug_req_o(dbg_req),
+ .unavailable_i(1'b0),
+ .tl_d_i(dbgrom_to_xbar),
+ .tl_d_o(xbar_to_dbgrom),
+ .tl_h_o(dm_to_xbar),
+ .tl_h_i(xbar_to_dm),
+ .jtag_req_i(jtag_req),
+ .jtag_rsp_o(jtag_rsp)
+ );
+ tl_xbar_main main_swith(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_brqif_i(ifu_to_xbar),
+ .tl_brqif_o(xbar_to_ifu),
+ .tl_brqlsu_i(lsu_to_xbar),
+ .tl_brqlsu_o(xbar_to_lsu),
+ .tl_dm_sba_i(dm_to_xbar),
+ .tl_dm_sba_o(xbar_to_dm),
+ .tl_iccm_o(xbar_to_iccm),
+ .tl_iccm_i(iccm_to_xbar),
+ .tl_debug_rom_o(dbgrom_to_xbar),
+ .tl_debug_rom_i(xbar_to_dbgrom),
+ .tl_dccm_o(xbar_to_dccm),
+ .tl_dccm_i(dccm_to_xbar),
+ .tl_timer0_o(xbar_to_timer),
+ .tl_timer0_i(timer_to_xbar),
+ .tl_uart_o(xbar_to_uart),
+ .tl_uart_i(uart_to_xbar),
+ .tl_spi_o(xbar_to_spi),
+ .tl_spi_i(spi_to_xbar),
+ .tl_pwm_o(xbar_to_pwm),
+ .tl_pwm_i(pwm_to_xbar),
+ .tl_gpio_o(xbarp_to_gpio),
+ .tl_gpio_i(gpio_to_xbarp),
+ .tl_plic_o(plic_req),
+ .tl_plic_i(plic_resp)
+ );
+ rv_timer timer0(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_i(xbar_to_timer),
+ .tl_o(timer_to_xbar),
+ .intr_timer_expired_0_0_o(intr_timer)
+ );
+ pwm_top u_pwm(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_i(xbar_to_pwm),
+ .tl_o(pwm_to_xbar),
+ .pwm_o(pwm_o),
+ .pwm_o_2(pwm_o_2),
+ .pwm1_oe(pwm1_oe),
+ .pwm2_oe(pwm2_oe)
+ );
+ spi_top u_spi_host(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_i(xbar_to_spi),
+ .tl_o(spi_to_xbar),
+ .intr_rx_o(intr_srx),
+ .intr_tx_o(intr_stx),
+ .ss_o(ss_o),
+ .sclk_o(sclk_o),
+ .sd_o(sd_o),
+ .sd_oe(sd_oe),
+ .sd_i(sd_i)
+ );
+ gpio GPIO(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_i(xbarp_to_gpio),
+ .tl_o(gpio_to_xbarp),
+ .cio_gpio_i(gpio_in),
+ .cio_gpio_o(gpio_out),
+ .cio_gpio_en_o(gpio_oe),
+ .intr_gpio_o(intr_gpio)
+ );
+ wire prog_rst_ni;
+ rstmgr reset_manager(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .ndmreset(dbg_rst),
+ .prog_rst_ni(prog_rst_ni),
+ .sys_rst_ni(system_rst_ni)
+ );
+ rv_plic intr_controller(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_i(plic_req),
+ .tl_o(plic_resp),
+ .intr_src_i(intr_vector),
+ .irq_o(intr_req),
+ .msip_o()
+ );
+ uart_top u_uart(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_i(xbar_to_uart),
+ .tl_o(uart_to_xbar),
+ .tx_o(uart_tx),
+ .rx_i(uart_rx),
+ .intr_tx(intr_u_tx)
+ );
+ wire rx_dv_i;
+ wire [7:0] rx_byte_i;
+ iccm_controller u_dut(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .prog_i(prog),
+ .rx_dv_i(rx_dv_i),
+ .rx_byte_i(rx_byte_i),
+ .we_o(iccm_ctrl_we),
+ .addr_o(iccm_ctrl_addr_o),
+ .wdata_o(iccm_ctrl_data),
+ .reset_o(prog_rst_ni)
+ );
+ uart_rx_prog u_uart_rx_prog(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .i_Rx_Serial(uart_rx),
+ .CLKS_PER_BIT(clks_per_bit),
+ .o_Rx_DV(rx_dv_i),
+ .o_Rx_Byte(rx_byte_i)
+ );
+ instr_mem_top iccm_adapter(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_i(xbar_to_iccm),
+ .tl_o(iccm_to_xbar),
+ .iccm_ctrl_addr(iccm_ctrl_addr_o),
+ .iccm_ctrl_wdata(iccm_ctrl_data),
+ .iccm_ctrl_we(iccm_ctrl_we),
+ .prog_rst_ni(prog_rst_ni),
+ .csb(instr_csb),
+ .addr_o(instr_addr),
+ .wdata_o(instr_wdata),
+ .wmask_o(instr_wmask),
+ .we_o(instr_we),
+ .rdata_i(instr_rdata)
+ );
+ wire [31:0] unused_data1;
+ wire [31:0] unused_data2;
+ sky130_sram_4kbyte_1rw1r_32x1024_8 u_iccm(
+ `ifdef USE_POWER_PINS
+ .vccd1(VPWR),
+ .vssd1(VGND),
+ `endif
+ .clk0(clk_i),
+ .csb0(instr_csb),
+ .web0(instr_we),
+ .wmask0(instr_wmask),
+ .addr0(instr_addr[9:0]),
+ .din0(instr_wdata),
+ .dout0(instr_rdata),
+ .clk1(1'b0),
+ .csb1(1'b1),
+ .addr1(10'b0000000000),
+ .dout1(unused_data1)
+ );
+ data_mem_top dccm_adapter(
+ .clk_i(clk_i),
+ .rst_ni(system_rst_ni),
+ .tl_d_i(xbar_to_dccm),
+ .tl_d_o(dccm_to_xbar),
+ .csb(data_csb),
+ .addr_o(data_addr),
+ .wdata_o(data_wdata),
+ .wmask_o(data_wmask),
+ .we_o(data_we),
+ .rdata_i(data_rdata)
+ );
+ sky130_sram_4kbyte_1rw1r_32x1024_8 u_dccm(
+ `ifdef USE_POWER_PINS
+ .vccd1(VPWR),
+ .vssd1(VGND),
+ `endif
+ .clk0(clk_i),
+ .csb0(data_csb),
+ .web0(data_we),
+ .wmask0(data_wmask),
+ .addr0(data_addr[9:0]),
+ .din0(data_wdata),
+ .dout0(data_rdata),
+ .clk1(1'b0),
+ .csb1(1'b1),
+ .addr1(10'b0000000000),
+ .dout1(unused_data2)
+ );
+endmodule
+module brq_core (
+ clk_i,
+ rst_ni,
+ hart_id_i,
+ boot_addr_i,
+ instr_req_o,
+ instr_gnt_i,
+ instr_rvalid_i,
+ instr_addr_o,
+ instr_rdata_i,
+ instr_err_i,
+ data_req_o,
+ data_gnt_i,
+ data_rvalid_i,
+ data_we_o,
+ data_be_o,
+ data_addr_o,
+ data_wdata_o,
+ data_rdata_i,
+ data_err_i,
+ irq_software_i,
+ irq_timer_i,
+ irq_external_i,
+ irq_fast_i,
+ irq_nm_i,
+ debug_req_i,
+ fetch_enable_i,
+ alert_minor_o,
+ alert_major_o,
+ core_sleep_o
+);
+ parameter [0:0] PMPEnable = 1'b0;
+ parameter [31:0] PMPGranularity = 0;
+ parameter [31:0] PMPNumRegions = 0;
+ parameter [31:0] MHPMCounterNum = 0;
+ parameter [31:0] MHPMCounterWidth = 40;
+ parameter [0:0] RV32E = 1'b0;
+ localparam integer brq_pkg_RV32MFast = 2;
+ parameter integer RV32M = brq_pkg_RV32MFast;
+ localparam integer brq_pkg_RV32BNone = 0;
+ parameter integer RV32B = brq_pkg_RV32BNone;
+ localparam integer brq_pkg_RegFileFF = 0;
+ parameter integer RegFile = brq_pkg_RegFileFF;
+ localparam integer brq_pkg_RV32FSingle = 1;
+ parameter integer RVF = brq_pkg_RV32FSingle;
+ parameter [31:0] FloatingPoint = 1'b1;
+ parameter [0:0] BranchTargetALU = 1'b0;
+ parameter [0:0] WritebackStage = 1'b1;
+ parameter [0:0] ICache = 1'b0;
+ parameter [0:0] ICacheECC = 1'b0;
+ parameter [0:0] BranchPredictor = 1'b0;
+ parameter [0:0] DbgTriggerEn = 1'b0;
+ parameter [31:0] DbgHwBreakNum = 1;
+ parameter [0:0] Securebrq = 1'b0;
+ parameter [31:0] DmHaltAddr = 32'h1a110800;
+ parameter [31:0] DmExceptionAddr = 32'h1a110808;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [31:0] hart_id_i;
+ input wire [31:0] boot_addr_i;
+ output wire instr_req_o;
+ input wire instr_gnt_i;
+ input wire instr_rvalid_i;
+ output wire [31:0] instr_addr_o;
+ input wire [31:0] instr_rdata_i;
+ input wire instr_err_i;
+ output wire data_req_o;
+ input wire data_gnt_i;
+ input wire data_rvalid_i;
+ output wire data_we_o;
+ output wire [3:0] data_be_o;
+ output wire [31:0] data_addr_o;
+ output wire [31:0] data_wdata_o;
+ input wire [31:0] data_rdata_i;
+ input wire data_err_i;
+ input wire irq_software_i;
+ input wire irq_timer_i;
+ input wire irq_external_i;
+ input wire [14:0] irq_fast_i;
+ input wire irq_nm_i;
+ input wire debug_req_i;
+ input wire fetch_enable_i;
+ output wire alert_minor_o;
+ output wire alert_major_o;
+ output wire core_sleep_o;
+ wire test_en_i;
+ assign test_en_i = 1'b0;
+ localparam [31:0] W = 32;
+ wire fp_flush;
+ wire in_ready_c2fpu;
+ wire in_valid_c2fpu;
+ wire out_ready_fpu2c;
+ wire out_valid_fpu2c;
+ wire valid_id_fpu;
+ wire fp_rm_dynamic;
+ wire fp_alu_op_mod;
+ wire [4:0] fp_rf_raddr_a;
+ wire [4:0] fp_rf_raddr_b;
+ wire [4:0] fp_rf_raddr_c;
+ wire [31:0] fp_rf_rdata_a;
+ wire [31:0] fp_rf_rdata_b;
+ wire [31:0] fp_rf_rdata_c;
+ wire fp_rf_wen_id;
+ wire is_fp_instr;
+ wire [95:0] fp_operands;
+ wire fp_busy;
+ wire fpu_busy_idu;
+ wire [31:0] fp_result;
+ wire [31:0] data_wb;
+ wire [4:0] fp_rf_waddr_id;
+ wire [4:0] fp_rf_waddr_wb;
+ wire fp_rf_we;
+ wire fp_rf_wen_wb;
+ wire use_fp_rs1;
+ wire use_fp_rs2;
+ wire use_fp_rd;
+ wire fp_rf_write_wb;
+ wire [31:0] rf_int_fp_lsu;
+ wire fp_swap_oprnds;
+ wire fpu_is_busy;
+ wire fp_load;
+ wire [31:0] fp_rf_wdata_wb;
+ wire [4:0] fp_status;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ wire [3:0] fp_operation;
+ wire [2:0] fp_rounding_mode;
+ wire [2:0] fp_frm_csr;
+ wire [2:0] fp_frm_fpnew;
+ wire [3:0] fp_alu_operator;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] fp_src_fmt;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] fp_dst_fmt;
+ localparam [31:0] PMP_NUM_CHAN = 2;
+ localparam [0:0] DataIndTiming = Securebrq;
+ localparam [0:0] DummyInstructions = Securebrq;
+ localparam [0:0] PCIncrCheck = Securebrq;
+ localparam [0:0] ShadowCSR = Securebrq;
+ localparam [0:0] SpecBranch = PMPEnable & (PMPNumRegions == 16);
+ localparam [0:0] RegFileECC = Securebrq;
+ localparam [31:0] RegFileDataWidth = (RegFileECC ? 39 : 32);
+ wire dummy_instr_id;
+ wire instr_valid_id;
+ wire instr_new_id;
+ wire [31:0] instr_rdata_id;
+ wire [31:0] instr_rdata_alu_id;
+ wire [15:0] instr_rdata_c_id;
+ wire instr_is_compressed_id;
+ wire instr_perf_count_id;
+ wire instr_fetch_err;
+ wire instr_fetch_err_plus2;
+ wire illegal_c_insn_id;
+ wire [31:0] pc_if;
+ wire [31:0] pc_id;
+ wire [31:0] pc_wb;
+ wire [67:0] imd_val_d_ex;
+ wire [67:0] imd_val_q_ex;
+ wire [1:0] imd_val_we_ex;
+ wire data_ind_timing;
+ wire dummy_instr_en;
+ wire [2:0] dummy_instr_mask;
+ wire dummy_instr_seed_en;
+ wire [31:0] dummy_instr_seed;
+ wire icache_enable;
+ wire icache_inval;
+ wire pc_mismatch_alert;
+ wire csr_shadow_err;
+ wire instr_first_cycle_id;
+ wire instr_valid_clear;
+ wire pc_set;
+ wire pc_set_spec;
+ wire [2:0] pc_mux_id;
+ wire [1:0] exc_pc_mux_id;
+ wire [5:0] exc_cause;
+ wire lsu_load_err;
+ wire lsu_store_err;
+ wire lsu_addr_incr_req;
+ wire [31:0] lsu_addr_last;
+ wire [31:0] branch_target_ex;
+ wire branch_decision;
+ wire ctrl_busy;
+ wire if_busy;
+ wire lsu_busy;
+ wire core_busy_d;
+ reg core_busy_q;
+ wire [4:0] rf_raddr_a;
+ wire [31:0] rf_rdata_a;
+ wire [4:0] rf_raddr_b;
+ wire [31:0] rf_rdata_b;
+ wire rf_ren_a;
+ wire rf_ren_b;
+ wire [4:0] rf_waddr_wb;
+ wire [31:0] rf_wdata_wb;
+ wire [31:0] rf_wdata_fwd_wb;
+ wire [31:0] rf_wdata_lsu;
+ wire rf_we_wb;
+ wire rf_we_lsu;
+ wire [4:0] rf_waddr_id;
+ wire [31:0] rf_wdata_id;
+ wire rf_we_id;
+ wire rf_rd_a_wb_match;
+ wire rf_rd_b_wb_match;
+ wire [5:0] alu_operator_ex;
+ wire [31:0] alu_operand_a_ex;
+ wire [31:0] alu_operand_b_ex;
+ wire [31:0] bt_a_operand;
+ wire [31:0] bt_b_operand;
+ wire [31:0] alu_adder_result_ex;
+ wire [31:0] result_ex;
+ wire mult_en_ex;
+ wire div_en_ex;
+ wire mult_sel_ex;
+ wire div_sel_ex;
+ wire [1:0] multdiv_operator_ex;
+ wire [1:0] multdiv_signed_mode_ex;
+ wire [31:0] multdiv_operand_a_ex;
+ wire [31:0] multdiv_operand_b_ex;
+ wire multdiv_ready_id;
+ wire csr_access;
+ wire [1:0] csr_op;
+ wire csr_op_en;
+ wire [11:0] csr_addr;
+ wire [31:0] csr_rdata;
+ wire [31:0] csr_wdata;
+ wire illegal_csr_insn_id;
+ wire lsu_we;
+ wire [1:0] lsu_type;
+ wire lsu_sign_ext;
+ wire lsu_req;
+ wire [31:0] lsu_wdata;
+ wire lsu_req_done;
+ wire id_in_ready;
+ wire ex_valid;
+ wire lsu_resp_valid;
+ wire lsu_resp_err;
+ wire instr_req_int;
+ wire en_wb;
+ wire [1:0] instr_type_wb;
+ wire ready_wb;
+ wire rf_write_wb;
+ wire outstanding_load_wb;
+ wire outstanding_store_wb;
+ wire irq_pending;
+ wire nmi_mode;
+ wire [17:0] irqs;
+ wire csr_mstatus_mie;
+ wire [31:0] csr_mepc;
+ wire [31:0] csr_depc;
+ wire [(0 >= (PMPNumRegions - 1) ? ((2 - PMPNumRegions) * 34) + (((PMPNumRegions - 1) * 34) - 1) : (PMPNumRegions * 34) - 1):(0 >= (PMPNumRegions - 1) ? (PMPNumRegions - 1) * 34 : 0)] csr_pmp_addr;
+ wire [(0 >= (PMPNumRegions - 1) ? ((2 - PMPNumRegions) * 6) + (((PMPNumRegions - 1) * 6) - 1) : (PMPNumRegions * 6) - 1):(0 >= (PMPNumRegions - 1) ? (PMPNumRegions - 1) * 6 : 0)] csr_pmp_cfg;
+ wire [0:1] pmp_req_err;
+ wire instr_req_out;
+ wire data_req_out;
+ wire csr_save_if;
+ wire csr_save_id;
+ wire csr_save_wb;
+ wire csr_restore_mret_id;
+ wire csr_restore_dret_id;
+ wire csr_save_cause;
+ wire csr_mtvec_init;
+ wire [31:0] csr_mtvec;
+ wire [31:0] csr_mtval;
+ wire csr_mstatus_tw;
+ wire [1:0] priv_mode_id;
+ wire [1:0] priv_mode_if;
+ wire [1:0] priv_mode_lsu;
+ wire debug_mode;
+ wire [2:0] debug_cause;
+ wire debug_csr_save;
+ wire debug_single_step;
+ wire debug_ebreakm;
+ wire debug_ebreaku;
+ wire trigger_match;
+ wire instr_id_done;
+ wire instr_done_wb;
+ wire perf_instr_ret_wb;
+ wire perf_instr_ret_compressed_wb;
+ wire perf_iside_wait;
+ wire perf_dside_wait;
+ wire perf_mul_wait;
+ wire perf_div_wait;
+ wire perf_jump;
+ wire perf_branch;
+ wire perf_tbranch;
+ wire perf_load;
+ wire perf_store;
+ wire illegal_insn_id;
+ wire unused_illegal_insn_id;
+ wire clk;
+ wire clock_en;
+ assign core_busy_d = ((ctrl_busy | if_busy) | lsu_busy) | fp_busy;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ core_busy_q <= 1'b0;
+ else
+ core_busy_q <= core_busy_d;
+ reg fetch_enable_q;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ fetch_enable_q <= 1'b0;
+ else if (fetch_enable_i)
+ fetch_enable_q <= 1'b1;
+ assign clock_en = fetch_enable_q & (((core_busy_q | debug_req_i) | irq_pending) | irq_nm_i);
+ assign core_sleep_o = ~clock_en;
+ prim_clock_gating core_clock_gate_i(
+ .clk_i(clk_i),
+ .en_i(clock_en),
+ .test_en_i(test_en_i),
+ .clk_o(clk)
+ );
+ localparam [31:0] brq_pkg_PMP_I = 0;
+ brq_ifu #(
+ .DmHaltAddr(DmHaltAddr),
+ .DmExceptionAddr(DmExceptionAddr),
+ .DummyInstructions(DummyInstructions),
+ .ICache(ICache),
+ .ICacheECC(ICacheECC),
+ .PCIncrCheck(PCIncrCheck),
+ .BranchPredictor(BranchPredictor)
+ ) if_stage_i(
+ .clk_i(clk),
+ .rst_ni(rst_ni),
+ .boot_addr_i(boot_addr_i),
+ .req_i(instr_req_int),
+ .instr_req_o(instr_req_out),
+ .instr_addr_o(instr_addr_o),
+ .instr_gnt_i(instr_gnt_i),
+ .instr_rvalid_i(instr_rvalid_i),
+ .instr_rdata_i(instr_rdata_i),
+ .instr_err_i(instr_err_i),
+ .instr_pmp_err_i(pmp_req_err[brq_pkg_PMP_I]),
+ .instr_valid_id_o(instr_valid_id),
+ .instr_new_id_o(instr_new_id),
+ .instr_rdata_id_o(instr_rdata_id),
+ .instr_rdata_alu_id_o(instr_rdata_alu_id),
+ .instr_rdata_c_id_o(instr_rdata_c_id),
+ .instr_is_compressed_id_o(instr_is_compressed_id),
+ .instr_fetch_err_o(instr_fetch_err),
+ .instr_fetch_err_plus2_o(instr_fetch_err_plus2),
+ .illegal_c_insn_id_o(illegal_c_insn_id),
+ .pc_if_o(pc_if),
+ .pc_id_o(pc_id),
+ .instr_valid_clear_i(instr_valid_clear),
+ .pc_set_i(pc_set),
+ .pc_set_spec_i(pc_set_spec),
+ .pc_mux_i(pc_mux_id),
+ .exc_pc_mux_i(exc_pc_mux_id),
+ .branch_target_ex_i(branch_target_ex),
+ .csr_mepc_i(csr_mepc),
+ .csr_depc_i(csr_depc),
+ .csr_mtvec_i(csr_mtvec),
+ .csr_mtvec_init_o(csr_mtvec_init),
+ .id_in_ready_i(id_in_ready),
+ .pc_mismatch_alert_o(pc_mismatch_alert),
+ .if_busy_o(if_busy)
+ );
+ assign perf_iside_wait = id_in_ready & ~instr_valid_id;
+ assign instr_req_o = instr_req_out & ~pmp_req_err[brq_pkg_PMP_I];
+ wire use_fp_rs3;
+ brq_idu #(
+ .RV32E(RV32E),
+ .RV32M(RV32M),
+ .RV32B(RV32B),
+ .BranchTargetALU(BranchTargetALU),
+ .DataIndTiming(DataIndTiming),
+ .SpecBranch(SpecBranch),
+ .WritebackStage(WritebackStage),
+ .BranchPredictor(BranchPredictor),
+ .FloatingPoint(FloatingPoint)
+ ) id_stage_i(
+ .clk_i(clk),
+ .rst_ni(rst_ni),
+ .ctrl_busy_o(ctrl_busy),
+ .illegal_insn_o(illegal_insn_id),
+ .instr_valid_i(instr_valid_id),
+ .instr_rdata_i(instr_rdata_id),
+ .instr_rdata_alu_i(instr_rdata_alu_id),
+ .instr_rdata_c_i(instr_rdata_c_id),
+ .instr_is_compressed_i(instr_is_compressed_id),
+ .branch_decision_i(branch_decision),
+ .instr_first_cycle_id_o(instr_first_cycle_id),
+ .instr_valid_clear_o(instr_valid_clear),
+ .id_in_ready_o(id_in_ready),
+ .instr_req_o(instr_req_int),
+ .pc_set_o(pc_set),
+ .pc_set_spec_o(pc_set_spec),
+ .pc_mux_o(pc_mux_id),
+ .exc_pc_mux_o(exc_pc_mux_id),
+ .exc_cause_o(exc_cause),
+ .icache_inval_o(icache_inval),
+ .instr_fetch_err_i(instr_fetch_err),
+ .instr_fetch_err_plus2_i(instr_fetch_err_plus2),
+ .illegal_c_insn_i(illegal_c_insn_id),
+ .pc_id_i(pc_id),
+ .ex_valid_i(valid_id_fpu),
+ .lsu_resp_valid_i(lsu_resp_valid),
+ .alu_operator_ex_o(alu_operator_ex),
+ .alu_operand_a_ex_o(alu_operand_a_ex),
+ .alu_operand_b_ex_o(alu_operand_b_ex),
+ .imd_val_q_ex_o(imd_val_q_ex),
+ .imd_val_d_ex_i(imd_val_d_ex),
+ .imd_val_we_ex_i(imd_val_we_ex),
+ .bt_a_operand_o(bt_a_operand),
+ .bt_b_operand_o(bt_b_operand),
+ .mult_en_ex_o(mult_en_ex),
+ .div_en_ex_o(div_en_ex),
+ .mult_sel_ex_o(mult_sel_ex),
+ .div_sel_ex_o(div_sel_ex),
+ .multdiv_operator_ex_o(multdiv_operator_ex),
+ .multdiv_signed_mode_ex_o(multdiv_signed_mode_ex),
+ .multdiv_operand_a_ex_o(multdiv_operand_a_ex),
+ .multdiv_operand_b_ex_o(multdiv_operand_b_ex),
+ .multdiv_ready_id_o(multdiv_ready_id),
+ .csr_access_o(csr_access),
+ .csr_op_o(csr_op),
+ .csr_op_en_o(csr_op_en),
+ .csr_save_if_o(csr_save_if),
+ .csr_save_id_o(csr_save_id),
+ .csr_save_wb_o(csr_save_wb),
+ .csr_restore_mret_id_o(csr_restore_mret_id),
+ .csr_restore_dret_id_o(csr_restore_dret_id),
+ .csr_save_cause_o(csr_save_cause),
+ .csr_mtval_o(csr_mtval),
+ .priv_mode_i(priv_mode_id),
+ .csr_mstatus_tw_i(csr_mstatus_tw),
+ .illegal_csr_insn_i(illegal_csr_insn_id),
+ .data_ind_timing_i(data_ind_timing),
+ .lsu_req_o(lsu_req),
+ .lsu_we_o(lsu_we),
+ .lsu_type_o(lsu_type),
+ .lsu_sign_ext_o(lsu_sign_ext),
+ .lsu_wdata_o(lsu_wdata),
+ .lsu_req_done_i(lsu_req_done),
+ .lsu_addr_incr_req_i(lsu_addr_incr_req),
+ .lsu_addr_last_i(lsu_addr_last),
+ .lsu_load_err_i(lsu_load_err),
+ .lsu_store_err_i(lsu_store_err),
+ .csr_mstatus_mie_i(csr_mstatus_mie),
+ .irq_pending_i(irq_pending),
+ .irqs_i(irqs),
+ .irq_nm_i(irq_nm_i),
+ .nmi_mode_o(nmi_mode),
+ .debug_mode_o(debug_mode),
+ .debug_cause_o(debug_cause),
+ .debug_csr_save_o(debug_csr_save),
+ .debug_req_i(debug_req_i),
+ .debug_single_step_i(debug_single_step),
+ .debug_ebreakm_i(debug_ebreakm),
+ .debug_ebreaku_i(debug_ebreaku),
+ .trigger_match_i(trigger_match),
+ .result_ex_i(data_wb),
+ .csr_rdata_i(csr_rdata),
+ .rf_raddr_a_o(rf_raddr_a),
+ .rf_rdata_a_i(rf_rdata_a),
+ .rf_raddr_b_o(rf_raddr_b),
+ .rf_rdata_b_i(rf_int_fp_lsu),
+ .rf_ren_a_o(rf_ren_a),
+ .rf_ren_b_o(rf_ren_b),
+ .rf_waddr_id_o(rf_waddr_id),
+ .rf_wdata_id_o(rf_wdata_id),
+ .rf_we_id_o(rf_we_id),
+ .rf_rd_a_wb_match_o(rf_rd_a_wb_match),
+ .rf_rd_b_wb_match_o(rf_rd_b_wb_match),
+ .rf_waddr_wb_i(rf_waddr_wb),
+ .rf_wdata_fwd_wb_i(rf_wdata_fwd_wb),
+ .rf_write_wb_i(rf_write_wb),
+ .en_wb_o(en_wb),
+ .instr_type_wb_o(instr_type_wb),
+ .instr_perf_count_id_o(instr_perf_count_id),
+ .ready_wb_i(ready_wb),
+ .outstanding_load_wb_i(outstanding_load_wb),
+ .outstanding_store_wb_i(outstanding_store_wb),
+ .perf_jump_o(perf_jump),
+ .perf_branch_o(perf_branch),
+ .perf_tbranch_o(perf_tbranch),
+ .perf_dside_wait_o(perf_dside_wait),
+ .perf_mul_wait_o(perf_mul_wait),
+ .perf_div_wait_o(perf_div_wait),
+ .instr_id_done_o(instr_id_done),
+ .fp_rounding_mode_o(fp_rounding_mode),
+ .fp_rf_rdata_a_i(fp_rf_rdata_a),
+ .fp_rf_rdata_b_i(fp_rf_rdata_b),
+ .fp_rf_rdata_c_i(fp_rf_rdata_c),
+ .fp_rf_raddr_a_o(fp_rf_raddr_a),
+ .fp_rf_raddr_b_o(fp_rf_raddr_b),
+ .fp_rf_raddr_c_o(fp_rf_raddr_c),
+ .fp_rf_waddr_o(fp_rf_waddr_id),
+ .fp_rf_we_o(fp_rf_wen_id),
+ .fp_alu_operator_o(fp_alu_operator),
+ .fp_alu_op_mod_o(fp_alu_op_mod),
+ .fp_src_fmt_o(fp_src_fmt),
+ .fp_dst_fmt_o(fp_dst_fmt),
+ .fp_rm_dynamic_o(fp_rm_dynamic),
+ .fp_flush_o(fp_flush),
+ .is_fp_instr_o(is_fp_instr),
+ .use_fp_rs1_o(use_fp_rs1),
+ .use_fp_rs2_o(use_fp_rs2),
+ .use_fp_rs3_o(use_fp_rs3),
+ .use_fp_rd_o(use_fp_rd),
+ .fpu_busy_i(fpu_busy_idu),
+ .fp_rf_write_wb_i(fp_rf_write_wb),
+ .fp_rf_wdata_fwd_wb_i(fp_rf_wdata_wb),
+ .fp_operands_o(fp_operands),
+ .fp_load_o(fp_load)
+ );
+ assign unused_illegal_insn_id = illegal_insn_id;
+ brq_exu #(
+ .RV32M(RV32M),
+ .RV32B(RV32B),
+ .BranchTargetALU(BranchTargetALU)
+ ) ex_block_i(
+ .clk_i(clk),
+ .rst_ni(rst_ni),
+ .alu_operator_i(alu_operator_ex),
+ .alu_operand_a_i(alu_operand_a_ex),
+ .alu_operand_b_i(alu_operand_b_ex),
+ .alu_instr_first_cycle_i(instr_first_cycle_id),
+ .bt_a_operand_i(bt_a_operand),
+ .bt_b_operand_i(bt_b_operand),
+ .multdiv_operator_i(multdiv_operator_ex),
+ .mult_en_i(mult_en_ex),
+ .div_en_i(div_en_ex),
+ .mult_sel_i(mult_sel_ex),
+ .div_sel_i(div_sel_ex),
+ .multdiv_signed_mode_i(multdiv_signed_mode_ex),
+ .multdiv_operand_a_i(multdiv_operand_a_ex),
+ .multdiv_operand_b_i(multdiv_operand_b_ex),
+ .multdiv_ready_id_i(multdiv_ready_id),
+ .data_ind_timing_i(data_ind_timing),
+ .imd_val_we_o(imd_val_we_ex),
+ .imd_val_d_o(imd_val_d_ex),
+ .imd_val_q_i(imd_val_q_ex),
+ .alu_adder_result_ex_o(alu_adder_result_ex),
+ .result_ex_o(result_ex),
+ .branch_target_o(branch_target_ex),
+ .branch_decision_o(branch_decision),
+ .ex_valid_o(ex_valid)
+ );
+ localparam [31:0] brq_pkg_PMP_D = 1;
+ assign data_req_o = data_req_out & ~pmp_req_err[brq_pkg_PMP_D];
+ assign lsu_resp_err = lsu_load_err | lsu_store_err;
+ brq_lsu load_store_unit_i(
+ .clk_i(clk),
+ .rst_ni(rst_ni),
+ .data_req_o(data_req_out),
+ .data_gnt_i(data_gnt_i),
+ .data_rvalid_i(data_rvalid_i),
+ .data_err_i(data_err_i),
+ .data_pmp_err_i(pmp_req_err[brq_pkg_PMP_D]),
+ .data_addr_o(data_addr_o),
+ .data_we_o(data_we_o),
+ .data_be_o(data_be_o),
+ .data_wdata_o(data_wdata_o),
+ .data_rdata_i(data_rdata_i),
+ .lsu_we_i(lsu_we),
+ .lsu_type_i(lsu_type),
+ .lsu_wdata_i(lsu_wdata),
+ .lsu_sign_ext_i(lsu_sign_ext),
+ .lsu_rdata_o(rf_wdata_lsu),
+ .lsu_rdata_valid_o(rf_we_lsu),
+ .lsu_req_i(lsu_req),
+ .lsu_req_done_o(lsu_req_done),
+ .adder_result_ex_i(alu_adder_result_ex),
+ .addr_incr_req_o(lsu_addr_incr_req),
+ .addr_last_o(lsu_addr_last),
+ .lsu_resp_valid_o(lsu_resp_valid),
+ .load_err_o(lsu_load_err),
+ .store_err_o(lsu_store_err),
+ .busy_o(lsu_busy),
+ .perf_load_o(perf_load),
+ .perf_store_o(perf_store)
+ );
+ brq_wbu #(.WritebackStage(WritebackStage)) wb_stage_i(
+ .clk_i(clk),
+ .rst_ni(rst_ni),
+ .en_wb_i(en_wb),
+ .instr_type_wb_i(instr_type_wb),
+ .pc_id_i(pc_id),
+ .instr_is_compressed_id_i(instr_is_compressed_id),
+ .instr_perf_count_id_i(instr_perf_count_id),
+ .ready_wb_o(ready_wb),
+ .rf_write_wb_o(rf_write_wb),
+ .outstanding_load_wb_o(outstanding_load_wb),
+ .outstanding_store_wb_o(outstanding_store_wb),
+ .pc_wb_o(pc_wb),
+ .perf_instr_ret_wb_o(perf_instr_ret_wb),
+ .perf_instr_ret_compressed_wb_o(perf_instr_ret_compressed_wb),
+ .rf_waddr_id_i(rf_waddr_id),
+ .rf_wdata_id_i(rf_wdata_id),
+ .rf_we_id_i(rf_we_id),
+ .rf_wdata_lsu_i(rf_wdata_lsu),
+ .rf_we_lsu_i(rf_we_lsu),
+ .rf_wdata_fwd_wb_o(rf_wdata_fwd_wb),
+ .rf_waddr_wb_o(rf_waddr_wb),
+ .rf_wdata_wb_o(rf_wdata_wb),
+ .rf_we_wb_o(rf_we_wb),
+ .lsu_resp_valid_i(lsu_resp_valid),
+ .lsu_resp_err_i(lsu_resp_err),
+ .instr_done_wb_o(instr_done_wb),
+ .fp_rf_write_wb_o(fp_rf_write_wb),
+ .fp_rf_wen_wb_o(fp_rf_wen_wb),
+ .fp_rf_waddr_wb_o(fp_rf_waddr_wb),
+ .fp_rf_wen_id_i(fp_rf_wen_id),
+ .fp_rf_waddr_id_i(fp_rf_waddr_id),
+ .fp_rf_wdata_wb_o(fp_rf_wdata_wb),
+ .fp_load_i(fp_load)
+ );
+ wire [RegFileDataWidth - 1:0] rf_wdata_wb_ecc;
+ wire [RegFileDataWidth - 1:0] rf_rdata_a_ecc;
+ wire [RegFileDataWidth - 1:0] rf_rdata_b_ecc;
+ wire rf_ecc_err_comb;
+ generate
+ if (RegFileECC) begin : gen_regfile_ecc
+ wire [1:0] rf_ecc_err_a;
+ wire [1:0] rf_ecc_err_b;
+ wire rf_ecc_err_a_id;
+ wire rf_ecc_err_b_id;
+ prim_secded_39_32_enc regfile_ecc_enc(
+ .in(rf_wdata_wb),
+ .out(rf_wdata_wb_ecc)
+ );
+ prim_secded_39_32_dec regfile_ecc_dec_a(
+ .in(rf_rdata_a_ecc),
+ .d_o(),
+ .syndrome_o(),
+ .err_o(rf_ecc_err_a)
+ );
+ prim_secded_39_32_dec regfile_ecc_dec_b(
+ .in(rf_rdata_b_ecc),
+ .d_o(),
+ .syndrome_o(),
+ .err_o(rf_ecc_err_b)
+ );
+ assign rf_rdata_a = rf_rdata_a_ecc[31:0];
+ assign rf_rdata_b = rf_rdata_b_ecc[31:0];
+ assign rf_ecc_err_a_id = (|rf_ecc_err_a & rf_ren_a) & ~rf_rd_a_wb_match;
+ assign rf_ecc_err_b_id = (|rf_ecc_err_b & rf_ren_b) & ~rf_rd_b_wb_match;
+ assign rf_ecc_err_comb = instr_valid_id & (rf_ecc_err_a_id | rf_ecc_err_b_id);
+ end
+ else begin : gen_no_regfile_ecc
+ wire unused_rf_ren_a;
+ wire unused_rf_ren_b;
+ wire unused_rf_rd_a_wb_match;
+ wire unused_rf_rd_b_wb_match;
+ assign unused_rf_ren_a = rf_ren_a;
+ assign unused_rf_ren_b = rf_ren_b;
+ assign unused_rf_rd_a_wb_match = rf_rd_a_wb_match;
+ assign unused_rf_rd_b_wb_match = rf_rd_b_wb_match;
+ assign rf_wdata_wb_ecc = rf_wdata_wb;
+ assign rf_rdata_a = rf_rdata_a_ecc;
+ assign rf_rdata_b = rf_rdata_b_ecc;
+ assign rf_ecc_err_comb = 1'b0;
+ end
+ endgenerate
+ assign rf_int_fp_lsu = (is_fp_instr & use_fp_rs2 ? fp_rf_rdata_b : rf_rdata_b);
+ localparam integer brq_pkg_RegFileFPGA = 1;
+ localparam integer brq_pkg_RegFileLatch = 2;
+ generate
+ if (RegFile == brq_pkg_RegFileFF) begin : gen_regfile_ff
+ brq_register_file_ff #(
+ .RV32E(RV32E),
+ .DataWidth(RegFileDataWidth),
+ .DummyInstructions(DummyInstructions)
+ ) register_file_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .dummy_instr_id_i(dummy_instr_id),
+ .raddr_a_i(rf_raddr_a),
+ .rdata_a_o(rf_rdata_a_ecc),
+ .raddr_b_i(rf_raddr_b),
+ .rdata_b_o(rf_rdata_b_ecc),
+ .waddr_a_i(rf_waddr_wb),
+ .wdata_a_i(rf_wdata_wb_ecc),
+ .we_a_i(rf_we_wb)
+ );
+ end
+ else if (RegFile == brq_pkg_RegFileFPGA) begin : gen_regfile_fpga
+ brq_register_file_fpga #(
+ .RV32E(RV32E),
+ .DataWidth(RegFileDataWidth),
+ .DummyInstructions(DummyInstructions)
+ ) register_file_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .test_en_i(test_en_i),
+ .dummy_instr_id_i(dummy_instr_id),
+ .raddr_a_i(rf_raddr_a),
+ .rdata_a_o(rf_rdata_a_ecc),
+ .raddr_b_i(rf_raddr_b),
+ .rdata_b_o(rf_rdata_b_ecc),
+ .waddr_a_i(rf_waddr_wb),
+ .wdata_a_i(rf_wdata_wb_ecc),
+ .we_a_i(rf_we_wb)
+ );
+ end
+ else if (RegFile == brq_pkg_RegFileLatch) begin : gen_regfile_latch
+ brq_register_file_latch #(
+ .RV32E(RV32E),
+ .DataWidth(RegFileDataWidth),
+ .DummyInstructions(DummyInstructions)
+ ) register_file_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .test_en_i(test_en_i),
+ .dummy_instr_id_i(dummy_instr_id),
+ .raddr_a_i(rf_raddr_a),
+ .rdata_a_o(rf_rdata_a_ecc),
+ .raddr_b_i(rf_raddr_b),
+ .rdata_b_o(rf_rdata_b_ecc),
+ .waddr_a_i(rf_waddr_wb),
+ .wdata_a_i(rf_wdata_wb_ecc),
+ .we_a_i(rf_we_wb)
+ );
+ end
+ endgenerate
+ generate
+ if (FloatingPoint) begin : gen_fp_regfile
+ brq_fp_register_file_ff #(
+ .RVF(RVF),
+ .DataWidth(W)
+ ) fp_register_file(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .raddr_a_i(fp_rf_raddr_a),
+ .rdata_a_o(fp_rf_rdata_a),
+ .raddr_b_i(fp_rf_raddr_b),
+ .rdata_b_o(fp_rf_rdata_b),
+ .raddr_c_i(fp_rf_raddr_c),
+ .rdata_c_o(fp_rf_rdata_c),
+ .waddr_a_i(fp_rf_waddr_wb),
+ .wdata_a_i(fp_rf_wdata_wb),
+ .we_a_i(fp_rf_wen_wb)
+ );
+ end
+ endgenerate
+ assign alert_minor_o = 1'b0;
+ assign alert_major_o = (rf_ecc_err_comb | pc_mismatch_alert) | csr_shadow_err;
+ assign csr_wdata = alu_operand_a_ex;
+ function automatic [11:0] sv2v_cast_12;
+ input reg [11:0] inp;
+ sv2v_cast_12 = inp;
+ endfunction
+ assign csr_addr = sv2v_cast_12((csr_access ? alu_operand_b_ex[11:0] : 12'b000000000000));
+ brq_cs_registers #(
+ .DbgTriggerEn(DbgTriggerEn),
+ .DbgHwBreakNum(DbgHwBreakNum),
+ .DataIndTiming(DataIndTiming),
+ .DummyInstructions(DummyInstructions),
+ .ShadowCSR(ShadowCSR),
+ .ICache(ICache),
+ .MHPMCounterNum(MHPMCounterNum),
+ .MHPMCounterWidth(MHPMCounterWidth),
+ .PMPEnable(PMPEnable),
+ .PMPGranularity(PMPGranularity),
+ .PMPNumRegions(PMPNumRegions),
+ .RV32E(RV32E),
+ .RV32M(RV32M)
+ ) cs_registers_i(
+ .clk_i(clk),
+ .rst_ni(rst_ni),
+ .hart_id_i(hart_id_i),
+ .priv_mode_id_o(priv_mode_id),
+ .priv_mode_if_o(priv_mode_if),
+ .priv_mode_lsu_o(priv_mode_lsu),
+ .csr_mtvec_o(csr_mtvec),
+ .csr_mtvec_init_i(csr_mtvec_init),
+ .boot_addr_i(boot_addr_i),
+ .csr_access_i(csr_access),
+ .csr_addr_i(csr_addr),
+ .csr_wdata_i(csr_wdata),
+ .csr_op_i(csr_op),
+ .csr_op_en_i(csr_op_en),
+ .csr_rdata_o(csr_rdata),
+ .irq_software_i(irq_software_i),
+ .irq_timer_i(irq_timer_i),
+ .irq_external_i(irq_external_i),
+ .irq_fast_i(irq_fast_i),
+ .nmi_mode_i(nmi_mode),
+ .irq_pending_o(irq_pending),
+ .irqs_o(irqs),
+ .csr_mstatus_mie_o(csr_mstatus_mie),
+ .csr_mstatus_tw_o(csr_mstatus_tw),
+ .csr_mepc_o(csr_mepc),
+ .csr_pmp_cfg_o(csr_pmp_cfg),
+ .csr_pmp_addr_o(csr_pmp_addr),
+ .csr_depc_o(csr_depc),
+ .debug_mode_i(debug_mode),
+ .debug_cause_i(debug_cause),
+ .debug_csr_save_i(debug_csr_save),
+ .debug_single_step_o(debug_single_step),
+ .debug_ebreakm_o(debug_ebreakm),
+ .debug_ebreaku_o(debug_ebreaku),
+ .trigger_match_o(trigger_match),
+ .pc_if_i(pc_if),
+ .pc_id_i(pc_id),
+ .pc_wb_i(pc_wb),
+ .data_ind_timing_o(data_ind_timing),
+ .csr_shadow_err_o(csr_shadow_err),
+ .csr_save_if_i(csr_save_if),
+ .csr_save_id_i(csr_save_id),
+ .csr_save_wb_i(csr_save_wb),
+ .csr_restore_mret_i(csr_restore_mret_id),
+ .csr_restore_dret_i(csr_restore_dret_id),
+ .csr_save_cause_i(csr_save_cause),
+ .csr_mcause_i(exc_cause),
+ .csr_mtval_i(csr_mtval),
+ .illegal_csr_insn_o(illegal_csr_insn_id),
+ .instr_ret_i(perf_instr_ret_wb),
+ .instr_ret_compressed_i(perf_instr_ret_compressed_wb),
+ .iside_wait_i(perf_iside_wait),
+ .jump_i(perf_jump),
+ .branch_i(perf_branch),
+ .branch_taken_i(perf_tbranch),
+ .mem_load_i(perf_load),
+ .mem_store_i(perf_store),
+ .dside_wait_i(perf_dside_wait),
+ .mul_wait_i(perf_mul_wait),
+ .div_wait_i(perf_div_wait),
+ .fp_rm_dynamic_i(fp_rm_dynamic),
+ .fp_frm_o(fp_frm_csr),
+ .fp_status_i(fp_status),
+ .is_fp_instr_i(is_fp_instr)
+ );
+ assign fp_frm_fpnew = (fp_rm_dynamic ? fp_frm_csr : fp_rounding_mode);
+ assign in_ready_c2fpu = id_in_ready;
+ assign in_valid_c2fpu = instr_valid_id & is_fp_instr;
+ assign valid_id_fpu = (is_fp_instr ? out_valid_fpu2c : ex_valid);
+ localparam [31:0] fpnew_pkg_NUM_OPGROUPS = 4;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ localparam [1:0] fpnew_pkg_MERGED = 2;
+ localparam [1:0] fpnew_pkg_PARALLEL = 1;
+ function automatic [31:0] sv2v_cast_CC116;
+ input reg [31:0] inp;
+ sv2v_cast_CC116 = inp;
+ endfunction
+ function automatic [127:0] sv2v_cast_128;
+ input reg [127:0] inp;
+ sv2v_cast_128 = inp;
+ endfunction
+ function automatic [7:0] sv2v_cast_8;
+ input reg [7:0] inp;
+ sv2v_cast_8 = inp;
+ endfunction
+ localparam [137:0] fpnew_pkg_DEFAULT_NOREGS = {sv2v_cast_128({fpnew_pkg_NUM_OPGROUPS {sv2v_cast_CC116(0)}}), sv2v_cast_8({{fpnew_pkg_PARALLEL}, {fpnew_pkg_MERGED}, {fpnew_pkg_PARALLEL}, {fpnew_pkg_MERGED}}), fpnew_pkg_BEFORE};
+ localparam [31:0] fpnew_pkg_NUM_INT_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_INT_FORMAT_BITS = 0;
+ function automatic [0:0] sv2v_cast_1;
+ input reg [0:0] inp;
+ sv2v_cast_1 = inp;
+ endfunction
+ localparam [35:0] fpnew_pkg_RV32F = {34'b0000000000000000000000000010000001, sv2v_cast_1(5'b10000), sv2v_cast_1(4'b0010)};
+ localparam [fpnew_pkg_INT_FORMAT_BITS - 1:0] fpnew_pkg_INT32 = 0;
+ fpnew_top_F1920 #(
+ .Features(fpnew_pkg_RV32F),
+ .Implementation(fpnew_pkg_DEFAULT_NOREGS)
+ ) i_fpnew_top(
+ .clk_i(clk),
+ .rst_ni(rst_ni),
+ .operands_i(fp_operands),
+ .rnd_mode_i(fp_frm_fpnew),
+ .op_i(fp_alu_operator),
+ .op_mod_i(fp_alu_op_mod),
+ .src_fmt_i(fp_src_fmt),
+ .dst_fmt_i(fp_dst_fmt),
+ .int_fmt_i(fpnew_pkg_INT32),
+ .vectorial_op_i(1'b0),
+ .tag_i(),
+ .in_valid_i(in_valid_c2fpu),
+ .in_ready_o(out_ready_fpu2c),
+ .flush_i(fp_flush),
+ .result_o(fp_result),
+ .status_o(fp_status),
+ .tag_o(),
+ .out_valid_o(out_valid_fpu2c),
+ .out_ready_i(in_ready_c2fpu),
+ .busy_o(fp_busy)
+ );
+ assign fpu_busy_idu = fp_busy & ~out_valid_fpu2c;
+ assign data_wb = (is_fp_instr ? fp_result : result_ex);
+ localparam [1:0] brq_pkg_PMP_ACC_EXEC = 2'b00;
+ localparam [1:0] brq_pkg_PMP_ACC_READ = 2'b10;
+ localparam [1:0] brq_pkg_PMP_ACC_WRITE = 2'b01;
+ generate
+ if (PMPEnable) begin : g_pmp
+ wire [67:0] pmp_req_addr;
+ wire [3:0] pmp_req_type;
+ wire [3:0] pmp_priv_lvl;
+ assign pmp_req_addr[34+:34] = {2'b00, instr_addr_o[31:0]};
+ assign pmp_req_type[2+:2] = brq_pkg_PMP_ACC_EXEC;
+ assign pmp_priv_lvl[2+:2] = priv_mode_if;
+ assign pmp_req_addr[0+:34] = {2'b00, data_addr_o[31:0]};
+ assign pmp_req_type[0+:2] = (data_we_o ? brq_pkg_PMP_ACC_WRITE : brq_pkg_PMP_ACC_READ);
+ assign pmp_priv_lvl[0+:2] = priv_mode_lsu;
+ brq_pmp #(
+ .PMPGranularity(PMPGranularity),
+ .PMPNumChan(PMP_NUM_CHAN),
+ .PMPNumRegions(PMPNumRegions)
+ ) pmp_i(
+ .clk_i(clk),
+ .rst_ni(rst_ni),
+ .csr_pmp_cfg_i(csr_pmp_cfg),
+ .csr_pmp_addr_i(csr_pmp_addr),
+ .priv_mode_i(pmp_priv_lvl),
+ .pmp_req_addr_i(pmp_req_addr),
+ .pmp_req_type_i(pmp_req_type),
+ .pmp_req_err_o(pmp_req_err)
+ );
+ end
+ else begin : g_no_pmp
+ wire [1:0] unused_priv_lvl_if;
+ wire [1:0] unused_priv_lvl_ls;
+ wire [(0 >= (PMPNumRegions - 1) ? ((2 - PMPNumRegions) * 34) + (((PMPNumRegions - 1) * 34) - 1) : (PMPNumRegions * 34) - 1):(0 >= (PMPNumRegions - 1) ? (PMPNumRegions - 1) * 34 : 0)] unused_csr_pmp_addr;
+ wire [(0 >= (PMPNumRegions - 1) ? ((2 - PMPNumRegions) * 6) + (((PMPNumRegions - 1) * 6) - 1) : (PMPNumRegions * 6) - 1):(0 >= (PMPNumRegions - 1) ? (PMPNumRegions - 1) * 6 : 0)] unused_csr_pmp_cfg;
+ assign unused_priv_lvl_if = priv_mode_if;
+ assign unused_priv_lvl_ls = priv_mode_lsu;
+ assign unused_csr_pmp_addr = csr_pmp_addr;
+ assign unused_csr_pmp_cfg = csr_pmp_cfg;
+ assign pmp_req_err[brq_pkg_PMP_I] = 1'b0;
+ assign pmp_req_err[brq_pkg_PMP_D] = 1'b0;
+ end
+ endgenerate
+ wire unused_instr_new_id;
+ wire unused_instr_done_wb;
+ assign unused_instr_new_id = instr_new_id;
+ assign unused_instr_done_wb = instr_done_wb;
+endmodule
+module brq_core_top (
+ clk_i,
+ rst_ni,
+ tl_i_i,
+ tl_i_o,
+ tl_d_i,
+ tl_d_o,
+ hart_id_i,
+ boot_addr_i,
+ irq_software_i,
+ irq_timer_i,
+ irq_external_i,
+ irq_fast_i,
+ irq_nm_i,
+ debug_req_i,
+ fetch_enable_i,
+ alert_minor_o,
+ alert_major_o,
+ core_sleep_o
+);
+ parameter [0:0] PMPEnable = 1'b0;
+ parameter [31:0] PMPGranularity = 0;
+ parameter [31:0] PMPNumRegions = 0;
+ parameter [31:0] MHPMCounterNum = 0;
+ parameter [31:0] MHPMCounterWidth = 40;
+ parameter [0:0] RV32E = 1'b0;
+ localparam integer brq_pkg_RV32MFast = 2;
+ parameter integer RV32M = brq_pkg_RV32MFast;
+ localparam integer brq_pkg_RV32BNone = 0;
+ parameter integer RV32B = brq_pkg_RV32BNone;
+ localparam integer brq_pkg_RegFileFF = 0;
+ parameter integer RegFile = brq_pkg_RegFileFF;
+ parameter [0:0] BranchTargetALU = 1'b0;
+ parameter [0:0] WritebackStage = 1'b1;
+ parameter [0:0] ICache = 1'b0;
+ parameter [0:0] ICacheECC = 1'b0;
+ parameter [0:0] BranchPredictor = 1'b0;
+ parameter [0:0] DbgTriggerEn = 1'b0;
+ parameter [31:0] DbgHwBreakNum = 1;
+ parameter [0:0] Securebrq = 1'b0;
+ parameter [31:0] DmHaltAddr = 0;
+ parameter [31:0] DmExceptionAddr = 0;
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [51:0] tl_i_i;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ output wire [85:0] tl_i_o;
+ input wire [51:0] tl_d_i;
+ output wire [85:0] tl_d_o;
+ input wire [31:0] hart_id_i;
+ input wire [31:0] boot_addr_i;
+ input wire irq_software_i;
+ input wire irq_timer_i;
+ input wire irq_external_i;
+ input wire [14:0] irq_fast_i;
+ input wire irq_nm_i;
+ input wire debug_req_i;
+ input wire fetch_enable_i;
+ output wire alert_minor_o;
+ output wire alert_major_o;
+ output wire core_sleep_o;
+ wire instr_req;
+ wire instr_gnt;
+ wire instr_rvalid;
+ wire [31:0] instr_addr;
+ wire [31:0] instr_rdata;
+ wire instr_err;
+ wire data_req;
+ wire data_gnt;
+ wire data_rvalid;
+ wire data_we;
+ wire [3:0] data_be;
+ wire [31:0] data_addr;
+ wire [31:0] data_wdata;
+ wire [31:0] data_rdata;
+ wire data_err;
+ brq_core #(
+ .PMPEnable(PMPEnable),
+ .PMPGranularity(PMPGranularity),
+ .PMPNumRegions(PMPNumRegions),
+ .MHPMCounterNum(MHPMCounterNum),
+ .MHPMCounterWidth(MHPMCounterWidth),
+ .RV32E(RV32E),
+ .RV32M(RV32M),
+ .RV32B(RV32B),
+ .RegFile(RegFile),
+ .BranchTargetALU(BranchTargetALU),
+ .WritebackStage(WritebackStage),
+ .ICache(ICache),
+ .ICacheECC(ICacheECC),
+ .BranchPredictor(BranchPredictor),
+ .DbgTriggerEn(DbgTriggerEn),
+ .DbgHwBreakNum(DbgHwBreakNum),
+ .Securebrq(Securebrq),
+ .DmHaltAddr(DmHaltAddr),
+ .DmExceptionAddr(DmExceptionAddr)
+ ) u_core(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .hart_id_i(hart_id_i),
+ .boot_addr_i(boot_addr_i),
+ .instr_req_o(instr_req),
+ .instr_gnt_i(instr_gnt),
+ .instr_rvalid_i(instr_rvalid),
+ .instr_addr_o(instr_addr),
+ .instr_rdata_i(instr_rdata),
+ .instr_err_i(instr_err),
+ .data_req_o(data_req),
+ .data_gnt_i(data_gnt),
+ .data_rvalid_i(data_rvalid),
+ .data_we_o(data_we),
+ .data_be_o(data_be),
+ .data_addr_o(data_addr),
+ .data_wdata_o(data_wdata),
+ .data_rdata_i(data_rdata),
+ .data_err_i(data_err),
+ .irq_software_i(irq_software_i),
+ .irq_timer_i(irq_timer_i),
+ .irq_external_i(irq_external_i),
+ .irq_fast_i(irq_fast_i),
+ .irq_nm_i(irq_nm_i),
+ .debug_req_i(debug_req_i),
+ .fetch_enable_i(fetch_enable_i),
+ .alert_minor_o(alert_minor_o),
+ .alert_major_o(alert_major_o),
+ .core_sleep_o(core_sleep_o)
+ );
+ tlul_host_adapter #(.MAX_REQS(2)) intr_interface(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .req_i(instr_req),
+ .gnt_o(instr_gnt),
+ .addr_i(instr_addr),
+ .we_i(1'b0),
+ .wdata_i(32'b00000000000000000000000000000000),
+ .be_i(4'hf),
+ .valid_o(instr_rvalid),
+ .rdata_o(instr_rdata),
+ .err_o(instr_err),
+ .tl_h_c_a(tl_i_o),
+ .tl_h_c_d(tl_i_i)
+ );
+ tlul_host_adapter #(.MAX_REQS(2)) data_interface(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .req_i(data_req),
+ .gnt_o(data_gnt),
+ .addr_i(data_addr),
+ .we_i(data_we),
+ .wdata_i(data_wdata),
+ .be_i(data_be),
+ .valid_o(data_rvalid),
+ .rdata_o(data_rdata),
+ .err_o(data_err),
+ .tl_h_c_a(tl_d_o),
+ .tl_h_c_d(tl_d_i)
+ );
+endmodule
+module brq_counter (
+ clk_i,
+ rst_ni,
+ counter_inc_i,
+ counterh_we_i,
+ counter_we_i,
+ counter_val_i,
+ counter_val_o
+);
+ parameter signed [31:0] CounterWidth = 32;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire counter_inc_i;
+ input wire counterh_we_i;
+ input wire counter_we_i;
+ input wire [31:0] counter_val_i;
+ output wire [63:0] counter_val_o;
+ wire [63:0] counter;
+ reg [CounterWidth - 1:0] counter_upd;
+ reg [63:0] counter_load;
+ reg we;
+ reg [CounterWidth - 1:0] counter_d;
+ reg [CounterWidth - 1:0] counter_q;
+ always @(*) begin
+ we = counter_we_i | counterh_we_i;
+ counter_load[63:32] = counter[63:32];
+ counter_load[31:0] = counter_val_i;
+ if (counterh_we_i) begin
+ counter_load[63:32] = counter_val_i;
+ counter_load[31:0] = counter[31:0];
+ end
+ counter_upd = counter[CounterWidth - 1:0] + {{CounterWidth - 1 {1'b0}}, 1'b1};
+ if (we)
+ counter_d = counter_load[CounterWidth - 1:0];
+ else if (counter_inc_i)
+ counter_d = counter_upd[CounterWidth - 1:0];
+ else
+ counter_d = counter[CounterWidth - 1:0];
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ counter_q <= 0;
+ else
+ counter_q <= counter_d;
+ generate
+ if (CounterWidth < 64) begin : g_counter_narrow
+ wire [63:CounterWidth] unused_counter_load;
+ assign counter[CounterWidth - 1:0] = counter_q;
+ assign counter[63:CounterWidth] = {(63 >= CounterWidth ? 64 - CounterWidth : CounterWidth - 62) {1'sb0}};
+ assign unused_counter_load = counter_load[63:CounterWidth];
+ end
+ else begin : g_counter_full
+ assign counter = counter_q;
+ end
+ endgenerate
+ assign counter_val_o = counter;
+endmodule
+module brq_cs_registers (
+ clk_i,
+ rst_ni,
+ hart_id_i,
+ priv_mode_id_o,
+ priv_mode_if_o,
+ priv_mode_lsu_o,
+ csr_mstatus_tw_o,
+ csr_mtvec_o,
+ csr_mtvec_init_i,
+ boot_addr_i,
+ csr_access_i,
+ csr_addr_i,
+ csr_wdata_i,
+ csr_op_i,
+ csr_op_en_i,
+ csr_rdata_o,
+ irq_software_i,
+ irq_timer_i,
+ irq_external_i,
+ irq_fast_i,
+ nmi_mode_i,
+ irq_pending_o,
+ irqs_o,
+ csr_mstatus_mie_o,
+ csr_mepc_o,
+ csr_pmp_cfg_o,
+ csr_pmp_addr_o,
+ debug_mode_i,
+ debug_cause_i,
+ debug_csr_save_i,
+ csr_depc_o,
+ debug_single_step_o,
+ debug_ebreakm_o,
+ debug_ebreaku_o,
+ trigger_match_o,
+ pc_if_i,
+ pc_id_i,
+ pc_wb_i,
+ data_ind_timing_o,
+ csr_shadow_err_o,
+ csr_save_if_i,
+ csr_save_id_i,
+ csr_save_wb_i,
+ csr_restore_mret_i,
+ csr_restore_dret_i,
+ csr_save_cause_i,
+ csr_mcause_i,
+ csr_mtval_i,
+ illegal_csr_insn_o,
+ instr_ret_i,
+ instr_ret_compressed_i,
+ iside_wait_i,
+ jump_i,
+ branch_i,
+ branch_taken_i,
+ mem_load_i,
+ mem_store_i,
+ dside_wait_i,
+ mul_wait_i,
+ div_wait_i,
+ fp_rm_dynamic_i,
+ fp_frm_o,
+ fp_status_i,
+ is_fp_instr_i
+);
+ parameter [0:0] DbgTriggerEn = 0;
+ parameter [31:0] DbgHwBreakNum = 1;
+ parameter [0:0] DataIndTiming = 1'b0;
+ parameter [0:0] DummyInstructions = 1'b0;
+ parameter [0:0] ShadowCSR = 1'b0;
+ parameter [0:0] ICache = 1'b0;
+ parameter [31:0] MHPMCounterNum = 10;
+ parameter [31:0] MHPMCounterWidth = 40;
+ parameter [0:0] PMPEnable = 0;
+ parameter [31:0] PMPGranularity = 0;
+ parameter [31:0] PMPNumRegions = 4;
+ parameter [0:0] RV32E = 0;
+ localparam integer brq_pkg_RV32MFast = 2;
+ parameter integer RV32M = brq_pkg_RV32MFast;
+ localparam integer brq_pkg_RV64FDouble = 2;
+ parameter integer RVF = brq_pkg_RV64FDouble;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [31:0] hart_id_i;
+ output wire [1:0] priv_mode_id_o;
+ output wire [1:0] priv_mode_if_o;
+ output wire [1:0] priv_mode_lsu_o;
+ output wire csr_mstatus_tw_o;
+ output wire [31:0] csr_mtvec_o;
+ input wire csr_mtvec_init_i;
+ input wire [31:0] boot_addr_i;
+ input wire csr_access_i;
+ input wire [11:0] csr_addr_i;
+ input wire [31:0] csr_wdata_i;
+ input wire [1:0] csr_op_i;
+ input wire csr_op_en_i;
+ output wire [31:0] csr_rdata_o;
+ input wire irq_software_i;
+ input wire irq_timer_i;
+ input wire irq_external_i;
+ input wire [14:0] irq_fast_i;
+ input wire nmi_mode_i;
+ output wire irq_pending_o;
+ output wire [17:0] irqs_o;
+ output wire csr_mstatus_mie_o;
+ output wire [31:0] csr_mepc_o;
+ output wire [(0 >= (PMPNumRegions - 1) ? ((2 - PMPNumRegions) * 6) + (((PMPNumRegions - 1) * 6) - 1) : (PMPNumRegions * 6) - 1):(0 >= (PMPNumRegions - 1) ? (PMPNumRegions - 1) * 6 : 0)] csr_pmp_cfg_o;
+ output wire [(0 >= (PMPNumRegions - 1) ? ((2 - PMPNumRegions) * 34) + (((PMPNumRegions - 1) * 34) - 1) : (PMPNumRegions * 34) - 1):(0 >= (PMPNumRegions - 1) ? (PMPNumRegions - 1) * 34 : 0)] csr_pmp_addr_o;
+ input wire debug_mode_i;
+ input wire [2:0] debug_cause_i;
+ input wire debug_csr_save_i;
+ output wire [31:0] csr_depc_o;
+ output wire debug_single_step_o;
+ output wire debug_ebreakm_o;
+ output wire debug_ebreaku_o;
+ output wire trigger_match_o;
+ input wire [31:0] pc_if_i;
+ input wire [31:0] pc_id_i;
+ input wire [31:0] pc_wb_i;
+ output wire data_ind_timing_o;
+ output wire csr_shadow_err_o;
+ input wire csr_save_if_i;
+ input wire csr_save_id_i;
+ input wire csr_save_wb_i;
+ input wire csr_restore_mret_i;
+ input wire csr_restore_dret_i;
+ input wire csr_save_cause_i;
+ input wire [5:0] csr_mcause_i;
+ input wire [31:0] csr_mtval_i;
+ output wire illegal_csr_insn_o;
+ input wire instr_ret_i;
+ input wire instr_ret_compressed_i;
+ input wire iside_wait_i;
+ input wire jump_i;
+ input wire branch_i;
+ input wire branch_taken_i;
+ input wire mem_load_i;
+ input wire mem_store_i;
+ input wire dside_wait_i;
+ input wire mul_wait_i;
+ input wire div_wait_i;
+ input wire fp_rm_dynamic_i;
+ output reg [2:0] fp_frm_o;
+ input wire [4:0] fp_status_i;
+ input wire is_fp_instr_i;
+ wire dummy_instr_en_o;
+ wire [2:0] dummy_instr_mask_o;
+ wire dummy_instr_seed_en_o;
+ wire [31:0] dummy_instr_seed_o;
+ wire icache_enable_o;
+ localparam integer brq_pkg_RV32MNone = 0;
+ localparam [31:0] RV32MEnabled = (RV32M == brq_pkg_RV32MNone ? 0 : 1);
+ localparam [31:0] PMPAddrWidth = (PMPGranularity > 0 ? 33 - PMPGranularity : 32);
+ localparam integer brq_pkg_RV32FSingle = 1;
+ localparam [31:0] SinglePrecision = (RVF == brq_pkg_RV32FSingle ? 1 : 0);
+ localparam [31:0] DoublePrecision = (RVF == brq_pkg_RV64FDouble ? 1 : 0);
+ localparam [1:0] brq_pkg_CSR_MISA_MXL = 2'd1;
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ localparam [31:0] MISA_VALUE = ((((((((((0 | 4) | (DoublePrecision << 3)) | (sv2v_cast_32(RV32E) << 4)) | (SinglePrecision << 5)) | (sv2v_cast_32(!RV32E) << 8)) | (RV32MEnabled << 12)) | 0) | 0) | 1048576) | 0) | (sv2v_cast_32(brq_pkg_CSR_MISA_MXL) << 30);
+ reg [31:0] exception_pc;
+ wire [4:0] fflags_q;
+ reg [4:0] fflags_d;
+ wire [4:0] fflag_wdata;
+ reg fflags_en;
+ reg frm_en;
+ wire [2:0] frm_q;
+ reg [2:0] frm_d;
+ reg [1:0] priv_lvl_q;
+ reg [1:0] priv_lvl_d;
+ wire [5:0] mstatus_q;
+ reg [5:0] mstatus_d;
+ wire mstatus_err;
+ reg mstatus_en;
+ wire [17:0] mie_q;
+ wire [17:0] mie_d;
+ reg mie_en;
+ wire [31:0] mscratch_q;
+ reg mscratch_en;
+ wire [31:0] mepc_q;
+ reg [31:0] mepc_d;
+ reg mepc_en;
+ wire [5:0] mcause_q;
+ reg [5:0] mcause_d;
+ reg mcause_en;
+ wire [31:0] mtval_q;
+ reg [31:0] mtval_d;
+ reg mtval_en;
+ wire [31:0] mtvec_q;
+ reg [31:0] mtvec_d;
+ wire mtvec_err;
+ reg mtvec_en;
+ wire [17:0] mip;
+ wire [31:0] dcsr_q;
+ reg [31:0] dcsr_d;
+ reg dcsr_en;
+ wire [31:0] depc_q;
+ reg [31:0] depc_d;
+ reg depc_en;
+ wire [31:0] dscratch0_q;
+ wire [31:0] dscratch1_q;
+ reg dscratch0_en;
+ reg dscratch1_en;
+ wire [2:0] mstack_q;
+ reg [2:0] mstack_d;
+ reg mstack_en;
+ wire [31:0] mstack_epc_q;
+ reg [31:0] mstack_epc_d;
+ wire [5:0] mstack_cause_q;
+ reg [5:0] mstack_cause_d;
+ localparam [31:0] brq_pkg_PMP_MAX_REGIONS = 16;
+ reg [31:0] pmp_addr_rdata [0:15];
+ localparam [31:0] brq_pkg_PMP_CFG_W = 8;
+ wire [7:0] pmp_cfg_rdata [0:15];
+ wire pmp_csr_err;
+ wire [31:0] mcountinhibit;
+ reg [MHPMCounterNum + 2:0] mcountinhibit_d;
+ reg [MHPMCounterNum + 2:0] mcountinhibit_q;
+ reg mcountinhibit_we;
+ wire [63:0] mhpmcounter [0:31];
+ reg [31:0] mhpmcounter_we;
+ reg [31:0] mhpmcounterh_we;
+ reg [31:0] mhpmcounter_incr;
+ reg [31:0] mhpmevent [0:31];
+ wire [4:0] mhpmcounter_idx;
+ wire unused_mhpmcounter_we_1;
+ wire unused_mhpmcounterh_we_1;
+ wire unused_mhpmcounter_incr_1;
+ wire [31:0] tselect_rdata;
+ wire [31:0] tmatch_control_rdata;
+ wire [31:0] tmatch_value_rdata;
+ wire [5:0] cpuctrl_q;
+ wire [5:0] cpuctrl_d;
+ wire [5:0] cpuctrl_wdata;
+ reg cpuctrl_we;
+ wire cpuctrl_err;
+ reg [31:0] csr_wdata_int;
+ reg [31:0] csr_rdata_int;
+ wire csr_we_int;
+ wire csr_wreq;
+ reg illegal_csr;
+ wire illegal_csr_priv;
+ wire illegal_csr_write;
+ wire [7:0] unused_boot_addr;
+ wire [2:0] unused_csr_addr;
+ assign unused_boot_addr = boot_addr_i[7:0];
+ reg illegal_dyn_mod;
+ wire illegal_csr_dyn_mod;
+ wire [11:0] csr_addr;
+ assign csr_addr = {csr_addr_i};
+ assign unused_csr_addr = csr_addr[7:5];
+ assign mhpmcounter_idx = csr_addr[4:0];
+ assign illegal_csr_dyn_mod = illegal_dyn_mod & fp_rm_dynamic_i;
+ assign illegal_csr_priv = csr_addr[9:8] > {priv_lvl_q};
+ assign illegal_csr_write = (csr_addr[11:10] == 2'b11) && csr_wreq;
+ assign illegal_csr_insn_o = (csr_access_i & ((illegal_csr | illegal_csr_write) | illegal_csr_priv)) | illegal_csr_dyn_mod;
+ assign mip[17] = irq_software_i;
+ assign mip[16] = irq_timer_i;
+ assign mip[15] = irq_external_i;
+ assign mip[14-:15] = irq_fast_i;
+ always @(*) begin
+ case (frm_q)
+ 3'b000, 3'b001, 3'b010, 3'b011, 3'b100: illegal_dyn_mod = 1'b0;
+ 3'b101, 3'b110, 3'b111: illegal_dyn_mod = 1'b1;
+ endcase
+ fp_frm_o = frm_q;
+ end
+ localparam [31:0] brq_pkg_CSR_MEIX_BIT = 11;
+ localparam [31:0] brq_pkg_CSR_MFIX_BIT_HIGH = 30;
+ localparam [31:0] brq_pkg_CSR_MFIX_BIT_LOW = 16;
+ localparam [31:0] brq_pkg_CSR_MSIX_BIT = 3;
+ localparam [31:0] brq_pkg_CSR_MSTATUS_MIE_BIT = 3;
+ localparam [31:0] brq_pkg_CSR_MSTATUS_MPIE_BIT = 7;
+ localparam [31:0] brq_pkg_CSR_MSTATUS_MPP_BIT_HIGH = 12;
+ localparam [31:0] brq_pkg_CSR_MSTATUS_MPP_BIT_LOW = 11;
+ localparam [31:0] brq_pkg_CSR_MSTATUS_MPRV_BIT = 17;
+ localparam [31:0] brq_pkg_CSR_MSTATUS_TW_BIT = 21;
+ localparam [31:0] brq_pkg_CSR_MTIX_BIT = 7;
+ localparam [11:0] brq_pkg_CSR_CPUCTRL = 12'h7c0;
+ localparam [11:0] brq_pkg_CSR_DCSR = 12'h7b0;
+ localparam [11:0] brq_pkg_CSR_DPC = 12'h7b1;
+ localparam [11:0] brq_pkg_CSR_DSCRATCH0 = 12'h7b2;
+ localparam [11:0] brq_pkg_CSR_DSCRATCH1 = 12'h7b3;
+ localparam [11:0] brq_pkg_CSR_FCSR = 12'h003;
+ localparam [11:0] brq_pkg_CSR_FFLAG = 12'h001;
+ localparam [11:0] brq_pkg_CSR_FRM = 12'h002;
+ localparam [11:0] brq_pkg_CSR_MCAUSE = 12'h342;
+ localparam [11:0] brq_pkg_CSR_MCONTEXT = 12'h7a8;
+ localparam [11:0] brq_pkg_CSR_MCOUNTINHIBIT = 12'h320;
+ localparam [11:0] brq_pkg_CSR_MCYCLE = 12'hb00;
+ localparam [11:0] brq_pkg_CSR_MCYCLEH = 12'hb80;
+ localparam [11:0] brq_pkg_CSR_MEPC = 12'h341;
+ localparam [11:0] brq_pkg_CSR_MHARTID = 12'hf14;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER10 = 12'hb0a;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER10H = 12'hb8a;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER11 = 12'hb0b;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER11H = 12'hb8b;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER12 = 12'hb0c;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER12H = 12'hb8c;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER13 = 12'hb0d;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER13H = 12'hb8d;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER14 = 12'hb0e;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER14H = 12'hb8e;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER15 = 12'hb0f;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER15H = 12'hb8f;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER16 = 12'hb10;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER16H = 12'hb90;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER17 = 12'hb11;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER17H = 12'hb91;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER18 = 12'hb12;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER18H = 12'hb92;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER19 = 12'hb13;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER19H = 12'hb93;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER20 = 12'hb14;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER20H = 12'hb94;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER21 = 12'hb15;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER21H = 12'hb95;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER22 = 12'hb16;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER22H = 12'hb96;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER23 = 12'hb17;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER23H = 12'hb97;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER24 = 12'hb18;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER24H = 12'hb98;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER25 = 12'hb19;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER25H = 12'hb99;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER26 = 12'hb1a;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER26H = 12'hb9a;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER27 = 12'hb1b;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER27H = 12'hb9b;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER28 = 12'hb1c;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER28H = 12'hb9c;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER29 = 12'hb1d;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER29H = 12'hb9d;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER3 = 12'hb03;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER30 = 12'hb1e;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER30H = 12'hb9e;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER31 = 12'hb1f;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER31H = 12'hb9f;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER3H = 12'hb83;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER4 = 12'hb04;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER4H = 12'hb84;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER5 = 12'hb05;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER5H = 12'hb85;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER6 = 12'hb06;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER6H = 12'hb86;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER7 = 12'hb07;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER7H = 12'hb87;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER8 = 12'hb08;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER8H = 12'hb88;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER9 = 12'hb09;
+ localparam [11:0] brq_pkg_CSR_MHPMCOUNTER9H = 12'hb89;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT10 = 12'h32a;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT11 = 12'h32b;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT12 = 12'h32c;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT13 = 12'h32d;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT14 = 12'h32e;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT15 = 12'h32f;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT16 = 12'h330;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT17 = 12'h331;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT18 = 12'h332;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT19 = 12'h333;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT20 = 12'h334;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT21 = 12'h335;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT22 = 12'h336;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT23 = 12'h337;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT24 = 12'h338;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT25 = 12'h339;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT26 = 12'h33a;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT27 = 12'h33b;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT28 = 12'h33c;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT29 = 12'h33d;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT3 = 12'h323;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT30 = 12'h33e;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT31 = 12'h33f;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT4 = 12'h324;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT5 = 12'h325;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT6 = 12'h326;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT7 = 12'h327;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT8 = 12'h328;
+ localparam [11:0] brq_pkg_CSR_MHPMEVENT9 = 12'h329;
+ localparam [11:0] brq_pkg_CSR_MIE = 12'h304;
+ localparam [11:0] brq_pkg_CSR_MINSTRET = 12'hb02;
+ localparam [11:0] brq_pkg_CSR_MINSTRETH = 12'hb82;
+ localparam [11:0] brq_pkg_CSR_MIP = 12'h344;
+ localparam [11:0] brq_pkg_CSR_MISA = 12'h301;
+ localparam [11:0] brq_pkg_CSR_MSCRATCH = 12'h340;
+ localparam [11:0] brq_pkg_CSR_MSTATUS = 12'h300;
+ localparam [11:0] brq_pkg_CSR_MTVAL = 12'h343;
+ localparam [11:0] brq_pkg_CSR_MTVEC = 12'h305;
+ localparam [11:0] brq_pkg_CSR_PMPADDR0 = 12'h3b0;
+ localparam [11:0] brq_pkg_CSR_PMPADDR1 = 12'h3b1;
+ localparam [11:0] brq_pkg_CSR_PMPADDR10 = 12'h3ba;
+ localparam [11:0] brq_pkg_CSR_PMPADDR11 = 12'h3bb;
+ localparam [11:0] brq_pkg_CSR_PMPADDR12 = 12'h3bc;
+ localparam [11:0] brq_pkg_CSR_PMPADDR13 = 12'h3bd;
+ localparam [11:0] brq_pkg_CSR_PMPADDR14 = 12'h3be;
+ localparam [11:0] brq_pkg_CSR_PMPADDR15 = 12'h3bf;
+ localparam [11:0] brq_pkg_CSR_PMPADDR2 = 12'h3b2;
+ localparam [11:0] brq_pkg_CSR_PMPADDR3 = 12'h3b3;
+ localparam [11:0] brq_pkg_CSR_PMPADDR4 = 12'h3b4;
+ localparam [11:0] brq_pkg_CSR_PMPADDR5 = 12'h3b5;
+ localparam [11:0] brq_pkg_CSR_PMPADDR6 = 12'h3b6;
+ localparam [11:0] brq_pkg_CSR_PMPADDR7 = 12'h3b7;
+ localparam [11:0] brq_pkg_CSR_PMPADDR8 = 12'h3b8;
+ localparam [11:0] brq_pkg_CSR_PMPADDR9 = 12'h3b9;
+ localparam [11:0] brq_pkg_CSR_PMPCFG0 = 12'h3a0;
+ localparam [11:0] brq_pkg_CSR_PMPCFG1 = 12'h3a1;
+ localparam [11:0] brq_pkg_CSR_PMPCFG2 = 12'h3a2;
+ localparam [11:0] brq_pkg_CSR_PMPCFG3 = 12'h3a3;
+ localparam [11:0] brq_pkg_CSR_SCONTEXT = 12'h7aa;
+ localparam [11:0] brq_pkg_CSR_SECURESEED = 12'h7c1;
+ localparam [11:0] brq_pkg_CSR_TDATA1 = 12'h7a1;
+ localparam [11:0] brq_pkg_CSR_TDATA2 = 12'h7a2;
+ localparam [11:0] brq_pkg_CSR_TDATA3 = 12'h7a3;
+ localparam [11:0] brq_pkg_CSR_TSELECT = 12'h7a0;
+ always @(*) begin
+ csr_rdata_int = {32 {1'sb0}};
+ illegal_csr = 1'b0;
+ case (csr_addr_i)
+ brq_pkg_CSR_FCSR: csr_rdata_int = {24'b000000000000000000000000, frm_q, fflags_q};
+ brq_pkg_CSR_FFLAG: csr_rdata_int = {27'b000000000000000000000000000, fflags_q};
+ brq_pkg_CSR_FRM: csr_rdata_int = {29'b00000000000000000000000000000, frm_q};
+ brq_pkg_CSR_MHARTID: csr_rdata_int = hart_id_i;
+ brq_pkg_CSR_MSTATUS: begin
+ csr_rdata_int = {32 {1'sb0}};
+ csr_rdata_int[brq_pkg_CSR_MSTATUS_MIE_BIT] = mstatus_q[5];
+ csr_rdata_int[brq_pkg_CSR_MSTATUS_MPIE_BIT] = mstatus_q[4];
+ csr_rdata_int[brq_pkg_CSR_MSTATUS_MPP_BIT_HIGH:brq_pkg_CSR_MSTATUS_MPP_BIT_LOW] = mstatus_q[3-:2];
+ csr_rdata_int[brq_pkg_CSR_MSTATUS_MPRV_BIT] = mstatus_q[1];
+ csr_rdata_int[brq_pkg_CSR_MSTATUS_TW_BIT] = mstatus_q[0];
+ end
+ brq_pkg_CSR_MISA: csr_rdata_int = MISA_VALUE;
+ brq_pkg_CSR_MIE: begin
+ csr_rdata_int = {32 {1'sb0}};
+ csr_rdata_int[brq_pkg_CSR_MSIX_BIT] = mie_q[17];
+ csr_rdata_int[brq_pkg_CSR_MTIX_BIT] = mie_q[16];
+ csr_rdata_int[brq_pkg_CSR_MEIX_BIT] = mie_q[15];
+ csr_rdata_int[brq_pkg_CSR_MFIX_BIT_HIGH:brq_pkg_CSR_MFIX_BIT_LOW] = mie_q[14-:15];
+ end
+ brq_pkg_CSR_MSCRATCH: csr_rdata_int = mscratch_q;
+ brq_pkg_CSR_MTVEC: csr_rdata_int = mtvec_q;
+ brq_pkg_CSR_MEPC: csr_rdata_int = mepc_q;
+ brq_pkg_CSR_MCAUSE: csr_rdata_int = {mcause_q[5], 26'b00000000000000000000000000, mcause_q[4:0]};
+ brq_pkg_CSR_MTVAL: csr_rdata_int = mtval_q;
+ brq_pkg_CSR_MIP: begin
+ csr_rdata_int = {32 {1'sb0}};
+ csr_rdata_int[brq_pkg_CSR_MSIX_BIT] = mip[17];
+ csr_rdata_int[brq_pkg_CSR_MTIX_BIT] = mip[16];
+ csr_rdata_int[brq_pkg_CSR_MEIX_BIT] = mip[15];
+ csr_rdata_int[brq_pkg_CSR_MFIX_BIT_HIGH:brq_pkg_CSR_MFIX_BIT_LOW] = mip[14-:15];
+ end
+ brq_pkg_CSR_PMPCFG0: csr_rdata_int = {pmp_cfg_rdata[3], pmp_cfg_rdata[2], pmp_cfg_rdata[1], pmp_cfg_rdata[0]};
+ brq_pkg_CSR_PMPCFG1: csr_rdata_int = {pmp_cfg_rdata[7], pmp_cfg_rdata[6], pmp_cfg_rdata[5], pmp_cfg_rdata[4]};
+ brq_pkg_CSR_PMPCFG2: csr_rdata_int = {pmp_cfg_rdata[11], pmp_cfg_rdata[10], pmp_cfg_rdata[9], pmp_cfg_rdata[8]};
+ brq_pkg_CSR_PMPCFG3: csr_rdata_int = {pmp_cfg_rdata[15], pmp_cfg_rdata[14], pmp_cfg_rdata[13], pmp_cfg_rdata[12]};
+ brq_pkg_CSR_PMPADDR0: csr_rdata_int = pmp_addr_rdata[0];
+ brq_pkg_CSR_PMPADDR1: csr_rdata_int = pmp_addr_rdata[1];
+ brq_pkg_CSR_PMPADDR2: csr_rdata_int = pmp_addr_rdata[2];
+ brq_pkg_CSR_PMPADDR3: csr_rdata_int = pmp_addr_rdata[3];
+ brq_pkg_CSR_PMPADDR4: csr_rdata_int = pmp_addr_rdata[4];
+ brq_pkg_CSR_PMPADDR5: csr_rdata_int = pmp_addr_rdata[5];
+ brq_pkg_CSR_PMPADDR6: csr_rdata_int = pmp_addr_rdata[6];
+ brq_pkg_CSR_PMPADDR7: csr_rdata_int = pmp_addr_rdata[7];
+ brq_pkg_CSR_PMPADDR8: csr_rdata_int = pmp_addr_rdata[8];
+ brq_pkg_CSR_PMPADDR9: csr_rdata_int = pmp_addr_rdata[9];
+ brq_pkg_CSR_PMPADDR10: csr_rdata_int = pmp_addr_rdata[10];
+ brq_pkg_CSR_PMPADDR11: csr_rdata_int = pmp_addr_rdata[11];
+ brq_pkg_CSR_PMPADDR12: csr_rdata_int = pmp_addr_rdata[12];
+ brq_pkg_CSR_PMPADDR13: csr_rdata_int = pmp_addr_rdata[13];
+ brq_pkg_CSR_PMPADDR14: csr_rdata_int = pmp_addr_rdata[14];
+ brq_pkg_CSR_PMPADDR15: csr_rdata_int = pmp_addr_rdata[15];
+ brq_pkg_CSR_DCSR: begin
+ csr_rdata_int = dcsr_q;
+ illegal_csr = ~debug_mode_i;
+ end
+ brq_pkg_CSR_DPC: begin
+ csr_rdata_int = depc_q;
+ illegal_csr = ~debug_mode_i;
+ end
+ brq_pkg_CSR_DSCRATCH0: begin
+ csr_rdata_int = dscratch0_q;
+ illegal_csr = ~debug_mode_i;
+ end
+ brq_pkg_CSR_DSCRATCH1: begin
+ csr_rdata_int = dscratch1_q;
+ illegal_csr = ~debug_mode_i;
+ end
+ brq_pkg_CSR_MCOUNTINHIBIT: csr_rdata_int = mcountinhibit;
+ brq_pkg_CSR_MHPMEVENT3, brq_pkg_CSR_MHPMEVENT4, brq_pkg_CSR_MHPMEVENT5, brq_pkg_CSR_MHPMEVENT6, brq_pkg_CSR_MHPMEVENT7, brq_pkg_CSR_MHPMEVENT8, brq_pkg_CSR_MHPMEVENT9, brq_pkg_CSR_MHPMEVENT10, brq_pkg_CSR_MHPMEVENT11, brq_pkg_CSR_MHPMEVENT12, brq_pkg_CSR_MHPMEVENT13, brq_pkg_CSR_MHPMEVENT14, brq_pkg_CSR_MHPMEVENT15, brq_pkg_CSR_MHPMEVENT16, brq_pkg_CSR_MHPMEVENT17, brq_pkg_CSR_MHPMEVENT18, brq_pkg_CSR_MHPMEVENT19, brq_pkg_CSR_MHPMEVENT20, brq_pkg_CSR_MHPMEVENT21, brq_pkg_CSR_MHPMEVENT22, brq_pkg_CSR_MHPMEVENT23, brq_pkg_CSR_MHPMEVENT24, brq_pkg_CSR_MHPMEVENT25, brq_pkg_CSR_MHPMEVENT26, brq_pkg_CSR_MHPMEVENT27, brq_pkg_CSR_MHPMEVENT28, brq_pkg_CSR_MHPMEVENT29, brq_pkg_CSR_MHPMEVENT30, brq_pkg_CSR_MHPMEVENT31: csr_rdata_int = mhpmevent[mhpmcounter_idx];
+ brq_pkg_CSR_MCYCLE, brq_pkg_CSR_MINSTRET, brq_pkg_CSR_MHPMCOUNTER3, brq_pkg_CSR_MHPMCOUNTER4, brq_pkg_CSR_MHPMCOUNTER5, brq_pkg_CSR_MHPMCOUNTER6, brq_pkg_CSR_MHPMCOUNTER7, brq_pkg_CSR_MHPMCOUNTER8, brq_pkg_CSR_MHPMCOUNTER9, brq_pkg_CSR_MHPMCOUNTER10, brq_pkg_CSR_MHPMCOUNTER11, brq_pkg_CSR_MHPMCOUNTER12, brq_pkg_CSR_MHPMCOUNTER13, brq_pkg_CSR_MHPMCOUNTER14, brq_pkg_CSR_MHPMCOUNTER15, brq_pkg_CSR_MHPMCOUNTER16, brq_pkg_CSR_MHPMCOUNTER17, brq_pkg_CSR_MHPMCOUNTER18, brq_pkg_CSR_MHPMCOUNTER19, brq_pkg_CSR_MHPMCOUNTER20, brq_pkg_CSR_MHPMCOUNTER21, brq_pkg_CSR_MHPMCOUNTER22, brq_pkg_CSR_MHPMCOUNTER23, brq_pkg_CSR_MHPMCOUNTER24, brq_pkg_CSR_MHPMCOUNTER25, brq_pkg_CSR_MHPMCOUNTER26, brq_pkg_CSR_MHPMCOUNTER27, brq_pkg_CSR_MHPMCOUNTER28, brq_pkg_CSR_MHPMCOUNTER29, brq_pkg_CSR_MHPMCOUNTER30, brq_pkg_CSR_MHPMCOUNTER31: csr_rdata_int = mhpmcounter[mhpmcounter_idx][31:0];
+ brq_pkg_CSR_MCYCLEH, brq_pkg_CSR_MINSTRETH, brq_pkg_CSR_MHPMCOUNTER3H, brq_pkg_CSR_MHPMCOUNTER4H, brq_pkg_CSR_MHPMCOUNTER5H, brq_pkg_CSR_MHPMCOUNTER6H, brq_pkg_CSR_MHPMCOUNTER7H, brq_pkg_CSR_MHPMCOUNTER8H, brq_pkg_CSR_MHPMCOUNTER9H, brq_pkg_CSR_MHPMCOUNTER10H, brq_pkg_CSR_MHPMCOUNTER11H, brq_pkg_CSR_MHPMCOUNTER12H, brq_pkg_CSR_MHPMCOUNTER13H, brq_pkg_CSR_MHPMCOUNTER14H, brq_pkg_CSR_MHPMCOUNTER15H, brq_pkg_CSR_MHPMCOUNTER16H, brq_pkg_CSR_MHPMCOUNTER17H, brq_pkg_CSR_MHPMCOUNTER18H, brq_pkg_CSR_MHPMCOUNTER19H, brq_pkg_CSR_MHPMCOUNTER20H, brq_pkg_CSR_MHPMCOUNTER21H, brq_pkg_CSR_MHPMCOUNTER22H, brq_pkg_CSR_MHPMCOUNTER23H, brq_pkg_CSR_MHPMCOUNTER24H, brq_pkg_CSR_MHPMCOUNTER25H, brq_pkg_CSR_MHPMCOUNTER26H, brq_pkg_CSR_MHPMCOUNTER27H, brq_pkg_CSR_MHPMCOUNTER28H, brq_pkg_CSR_MHPMCOUNTER29H, brq_pkg_CSR_MHPMCOUNTER30H, brq_pkg_CSR_MHPMCOUNTER31H: csr_rdata_int = mhpmcounter[mhpmcounter_idx][63:32];
+ brq_pkg_CSR_TSELECT: begin
+ csr_rdata_int = tselect_rdata;
+ illegal_csr = ~DbgTriggerEn;
+ end
+ brq_pkg_CSR_TDATA1: begin
+ csr_rdata_int = tmatch_control_rdata;
+ illegal_csr = ~DbgTriggerEn;
+ end
+ brq_pkg_CSR_TDATA2: begin
+ csr_rdata_int = tmatch_value_rdata;
+ illegal_csr = ~DbgTriggerEn;
+ end
+ brq_pkg_CSR_TDATA3: begin
+ csr_rdata_int = {32 {1'sb0}};
+ illegal_csr = ~DbgTriggerEn;
+ end
+ brq_pkg_CSR_MCONTEXT: begin
+ csr_rdata_int = {32 {1'sb0}};
+ illegal_csr = ~DbgTriggerEn;
+ end
+ brq_pkg_CSR_SCONTEXT: begin
+ csr_rdata_int = {32 {1'sb0}};
+ illegal_csr = ~DbgTriggerEn;
+ end
+ brq_pkg_CSR_CPUCTRL: csr_rdata_int = {{26 {1'b0}}, cpuctrl_q};
+ brq_pkg_CSR_SECURESEED: csr_rdata_int = {32 {1'sb0}};
+ default: illegal_csr = 1'b1;
+ endcase
+ end
+ localparam [1:0] brq_pkg_PRIV_LVL_M = 2'b11;
+ localparam [1:0] brq_pkg_PRIV_LVL_U = 2'b00;
+ localparam [3:0] brq_pkg_XDEBUGVER_STD = 4'd4;
+ function automatic [1:0] sv2v_cast_2;
+ input reg [1:0] inp;
+ sv2v_cast_2 = inp;
+ endfunction
+ always @(*) begin
+ exception_pc = pc_id_i;
+ fflags_d = fflags_q;
+ fflags_en = 1'b0;
+ frm_d = frm_q;
+ frm_en = 1'b0;
+ priv_lvl_d = priv_lvl_q;
+ mstatus_en = 1'b0;
+ mstatus_d = mstatus_q;
+ mie_en = 1'b0;
+ mscratch_en = 1'b0;
+ mepc_en = 1'b0;
+ mepc_d = {csr_wdata_int[31:1], 1'b0};
+ mcause_en = 1'b0;
+ mcause_d = {csr_wdata_int[31], csr_wdata_int[4:0]};
+ mtval_en = 1'b0;
+ mtval_d = csr_wdata_int;
+ mtvec_en = csr_mtvec_init_i;
+ mtvec_d = (csr_mtvec_init_i ? {boot_addr_i[31:2], 2'b00} : {csr_wdata_int[31:2], 2'b00});
+ dcsr_en = 1'b0;
+ dcsr_d = dcsr_q;
+ depc_d = {csr_wdata_int[31:1], 1'b0};
+ depc_en = 1'b0;
+ dscratch0_en = 1'b0;
+ dscratch1_en = 1'b0;
+ mstack_en = 1'b0;
+ mstack_d[2] = mstatus_q[4];
+ mstack_d[1-:2] = mstatus_q[3-:2];
+ mstack_epc_d = mepc_q;
+ mstack_cause_d = mcause_q;
+ mcountinhibit_we = 1'b0;
+ mhpmcounter_we = {32 {1'sb0}};
+ mhpmcounterh_we = {32 {1'sb0}};
+ cpuctrl_we = 1'b0;
+ if (csr_we_int)
+ case (csr_addr_i)
+ brq_pkg_CSR_FCSR: begin
+ fflags_en = 1'b1;
+ frm_en = 1'b1;
+ fflags_d = csr_wdata_int[4:0];
+ frm_d = csr_wdata_int[7:5];
+ end
+ brq_pkg_CSR_FFLAG: begin
+ fflags_en = 1'b1;
+ fflags_d = csr_wdata_int[4:0];
+ end
+ brq_pkg_CSR_FRM: begin
+ frm_en = 1'b1;
+ frm_d = csr_wdata_int[2:0];
+ end
+ brq_pkg_CSR_MSTATUS: begin
+ mstatus_en = 1'b1;
+ mstatus_d = {csr_wdata_int[brq_pkg_CSR_MSTATUS_MIE_BIT], csr_wdata_int[brq_pkg_CSR_MSTATUS_MPIE_BIT], sv2v_cast_2(csr_wdata_int[brq_pkg_CSR_MSTATUS_MPP_BIT_HIGH:brq_pkg_CSR_MSTATUS_MPP_BIT_LOW]), csr_wdata_int[brq_pkg_CSR_MSTATUS_MPRV_BIT], csr_wdata_int[brq_pkg_CSR_MSTATUS_TW_BIT]};
+ if ((mstatus_d[3-:2] != brq_pkg_PRIV_LVL_M) && (mstatus_d[3-:2] != brq_pkg_PRIV_LVL_U))
+ mstatus_d[3-:2] = brq_pkg_PRIV_LVL_M;
+ end
+ brq_pkg_CSR_MIE: mie_en = 1'b1;
+ brq_pkg_CSR_MSCRATCH: mscratch_en = 1'b1;
+ brq_pkg_CSR_MEPC: mepc_en = 1'b1;
+ brq_pkg_CSR_MCAUSE: mcause_en = 1'b1;
+ brq_pkg_CSR_MTVAL: mtval_en = 1'b1;
+ brq_pkg_CSR_MTVEC: mtvec_en = 1'b1;
+ brq_pkg_CSR_DCSR: begin
+ dcsr_d = csr_wdata_int;
+ dcsr_d[31-:4] = brq_pkg_XDEBUGVER_STD;
+ if ((dcsr_d[1-:2] != brq_pkg_PRIV_LVL_M) && (dcsr_d[1-:2] != brq_pkg_PRIV_LVL_U))
+ dcsr_d[1-:2] = brq_pkg_PRIV_LVL_M;
+ dcsr_d[8-:3] = dcsr_q[8-:3];
+ dcsr_d[3] = 1'b0;
+ dcsr_d[4] = 1'b0;
+ dcsr_d[10] = 1'b0;
+ dcsr_d[9] = 1'b0;
+ dcsr_d[5] = 1'b0;
+ dcsr_d[14] = 1'b0;
+ dcsr_d[27-:12] = 12'h000;
+ dcsr_en = 1'b1;
+ end
+ brq_pkg_CSR_DPC: depc_en = 1'b1;
+ brq_pkg_CSR_DSCRATCH0: dscratch0_en = 1'b1;
+ brq_pkg_CSR_DSCRATCH1: dscratch1_en = 1'b1;
+ brq_pkg_CSR_MCOUNTINHIBIT: mcountinhibit_we = 1'b1;
+ brq_pkg_CSR_MCYCLE, brq_pkg_CSR_MINSTRET, brq_pkg_CSR_MHPMCOUNTER3, brq_pkg_CSR_MHPMCOUNTER4, brq_pkg_CSR_MHPMCOUNTER5, brq_pkg_CSR_MHPMCOUNTER6, brq_pkg_CSR_MHPMCOUNTER7, brq_pkg_CSR_MHPMCOUNTER8, brq_pkg_CSR_MHPMCOUNTER9, brq_pkg_CSR_MHPMCOUNTER10, brq_pkg_CSR_MHPMCOUNTER11, brq_pkg_CSR_MHPMCOUNTER12, brq_pkg_CSR_MHPMCOUNTER13, brq_pkg_CSR_MHPMCOUNTER14, brq_pkg_CSR_MHPMCOUNTER15, brq_pkg_CSR_MHPMCOUNTER16, brq_pkg_CSR_MHPMCOUNTER17, brq_pkg_CSR_MHPMCOUNTER18, brq_pkg_CSR_MHPMCOUNTER19, brq_pkg_CSR_MHPMCOUNTER20, brq_pkg_CSR_MHPMCOUNTER21, brq_pkg_CSR_MHPMCOUNTER22, brq_pkg_CSR_MHPMCOUNTER23, brq_pkg_CSR_MHPMCOUNTER24, brq_pkg_CSR_MHPMCOUNTER25, brq_pkg_CSR_MHPMCOUNTER26, brq_pkg_CSR_MHPMCOUNTER27, brq_pkg_CSR_MHPMCOUNTER28, brq_pkg_CSR_MHPMCOUNTER29, brq_pkg_CSR_MHPMCOUNTER30, brq_pkg_CSR_MHPMCOUNTER31: mhpmcounter_we[mhpmcounter_idx] = 1'b1;
+ brq_pkg_CSR_MCYCLEH, brq_pkg_CSR_MINSTRETH, brq_pkg_CSR_MHPMCOUNTER3H, brq_pkg_CSR_MHPMCOUNTER4H, brq_pkg_CSR_MHPMCOUNTER5H, brq_pkg_CSR_MHPMCOUNTER6H, brq_pkg_CSR_MHPMCOUNTER7H, brq_pkg_CSR_MHPMCOUNTER8H, brq_pkg_CSR_MHPMCOUNTER9H, brq_pkg_CSR_MHPMCOUNTER10H, brq_pkg_CSR_MHPMCOUNTER11H, brq_pkg_CSR_MHPMCOUNTER12H, brq_pkg_CSR_MHPMCOUNTER13H, brq_pkg_CSR_MHPMCOUNTER14H, brq_pkg_CSR_MHPMCOUNTER15H, brq_pkg_CSR_MHPMCOUNTER16H, brq_pkg_CSR_MHPMCOUNTER17H, brq_pkg_CSR_MHPMCOUNTER18H, brq_pkg_CSR_MHPMCOUNTER19H, brq_pkg_CSR_MHPMCOUNTER20H, brq_pkg_CSR_MHPMCOUNTER21H, brq_pkg_CSR_MHPMCOUNTER22H, brq_pkg_CSR_MHPMCOUNTER23H, brq_pkg_CSR_MHPMCOUNTER24H, brq_pkg_CSR_MHPMCOUNTER25H, brq_pkg_CSR_MHPMCOUNTER26H, brq_pkg_CSR_MHPMCOUNTER27H, brq_pkg_CSR_MHPMCOUNTER28H, brq_pkg_CSR_MHPMCOUNTER29H, brq_pkg_CSR_MHPMCOUNTER30H, brq_pkg_CSR_MHPMCOUNTER31H: mhpmcounterh_we[mhpmcounter_idx] = 1'b1;
+ brq_pkg_CSR_CPUCTRL: cpuctrl_we = 1'b1;
+ default:
+ ;
+ endcase
+ case (1'b1)
+ csr_save_cause_i: begin
+ case (1'b1)
+ csr_save_if_i: exception_pc = pc_if_i;
+ csr_save_id_i: exception_pc = pc_id_i;
+ csr_save_wb_i: exception_pc = pc_wb_i;
+ default:
+ ;
+ endcase
+ priv_lvl_d = brq_pkg_PRIV_LVL_M;
+ if (debug_csr_save_i) begin
+ dcsr_d[1-:2] = priv_lvl_q;
+ dcsr_d[8-:3] = debug_cause_i;
+ dcsr_en = 1'b1;
+ depc_d = exception_pc;
+ depc_en = 1'b1;
+ end
+ else if (!debug_mode_i) begin
+ mtval_en = 1'b1;
+ mtval_d = csr_mtval_i;
+ mstatus_en = 1'b1;
+ mstatus_d[5] = 1'b0;
+ mstatus_d[4] = mstatus_q[5];
+ mstatus_d[3-:2] = priv_lvl_q;
+ mepc_en = 1'b1;
+ mepc_d = exception_pc;
+ mcause_en = 1'b1;
+ mcause_d = {csr_mcause_i};
+ mstack_en = 1'b1;
+ end
+ end
+ csr_restore_dret_i: priv_lvl_d = dcsr_q[1-:2];
+ csr_restore_mret_i: begin
+ priv_lvl_d = mstatus_q[3-:2];
+ mstatus_en = 1'b1;
+ mstatus_d[5] = mstatus_q[4];
+ if (nmi_mode_i) begin
+ mstatus_d[4] = mstack_q[2];
+ mstatus_d[3-:2] = mstack_q[1-:2];
+ mepc_en = 1'b1;
+ mepc_d = mstack_epc_q;
+ mcause_en = 1'b1;
+ mcause_d = mstack_cause_q;
+ end
+ else begin
+ mstatus_d[4] = 1'b1;
+ mstatus_d[3-:2] = brq_pkg_PRIV_LVL_U;
+ end
+ end
+ default:
+ ;
+ endcase
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ priv_lvl_q <= brq_pkg_PRIV_LVL_M;
+ else
+ priv_lvl_q <= priv_lvl_d;
+ assign priv_mode_id_o = priv_lvl_q;
+ assign priv_mode_if_o = priv_lvl_d;
+ assign priv_mode_lsu_o = (mstatus_q[1] ? mstatus_q[3-:2] : priv_lvl_q);
+ localparam [1:0] brq_pkg_CSR_OP_CLEAR = 3;
+ localparam [1:0] brq_pkg_CSR_OP_READ = 0;
+ localparam [1:0] brq_pkg_CSR_OP_SET = 2;
+ localparam [1:0] brq_pkg_CSR_OP_WRITE = 1;
+ always @(*)
+ case (csr_op_i)
+ brq_pkg_CSR_OP_WRITE: csr_wdata_int = csr_wdata_i;
+ brq_pkg_CSR_OP_SET: csr_wdata_int = csr_wdata_i | csr_rdata_o;
+ brq_pkg_CSR_OP_CLEAR: csr_wdata_int = ~csr_wdata_i & csr_rdata_o;
+ brq_pkg_CSR_OP_READ: csr_wdata_int = csr_wdata_i;
+ endcase
+ assign csr_wreq = csr_op_en_i & |{csr_op_i == brq_pkg_CSR_OP_WRITE, csr_op_i == brq_pkg_CSR_OP_SET, csr_op_i == brq_pkg_CSR_OP_CLEAR};
+ assign csr_we_int = csr_wreq & ~illegal_csr_insn_o;
+ assign csr_rdata_o = csr_rdata_int;
+ assign csr_mepc_o = mepc_q;
+ assign csr_depc_o = depc_q;
+ assign csr_mtvec_o = mtvec_q;
+ assign csr_mstatus_mie_o = mstatus_q[5];
+ assign csr_mstatus_tw_o = mstatus_q[0];
+ assign debug_single_step_o = dcsr_q[2];
+ assign debug_ebreakm_o = dcsr_q[15];
+ assign debug_ebreaku_o = dcsr_q[12];
+ assign irqs_o = mip & mie_q;
+ assign irq_pending_o = |irqs_o;
+ wire unused_error1;
+ wire unused_error2;
+ wire unused_error3;
+ wire unused_error4;
+ wire unused_error5;
+ wire unused_error6;
+ wire unused_error7;
+ wire unused_error8;
+ wire unused_error9;
+ wire unused_error10;
+ wire unused_error11;
+ wire unused_error12;
+ wire unused_error13;
+ wire unused_error14;
+ wire unused_error15;
+ wire unused_error16;
+ wire unused_error17;
+ localparam [5:0] MSTATUS_RST_VAL = {2'b01, brq_pkg_PRIV_LVL_U, 1'b0, 1'b0};
+ brq_csr #(
+ .Width(6),
+ .ShadowCopy(ShadowCSR),
+ .ResetValue({MSTATUS_RST_VAL})
+ ) u_mstatus_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i({mstatus_d}),
+ .wr_en_i(mstatus_en),
+ .rd_data_o(mstatus_q),
+ .rd_error_o(mstatus_err)
+ );
+ assign fflag_wdata = (is_fp_instr_i ? fp_status_i : fflags_d);
+ brq_csr #(
+ .Width(5),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) fflags_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(fflag_wdata),
+ .wr_en_i(fflags_en | is_fp_instr_i),
+ .rd_data_o(fflags_q),
+ .rd_error_o(unused_error1)
+ );
+ wire [2:0] frmd;
+ wire [2:0] frmq;
+ assign frm_q = frmq;
+ assign frmd = frm_d;
+ brq_csr #(
+ .Width(3),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) frm_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(frmd),
+ .wr_en_i(frm_en),
+ .rd_data_o(frmq),
+ .rd_error_o(unused_error2)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_mepc_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(mepc_d),
+ .wr_en_i(mepc_en),
+ .rd_data_o(mepc_q),
+ .rd_error_o(unused_error3)
+ );
+ assign mie_d[17] = csr_wdata_int[brq_pkg_CSR_MSIX_BIT];
+ assign mie_d[16] = csr_wdata_int[brq_pkg_CSR_MTIX_BIT];
+ assign mie_d[15] = csr_wdata_int[brq_pkg_CSR_MEIX_BIT];
+ assign mie_d[14-:15] = csr_wdata_int[brq_pkg_CSR_MFIX_BIT_HIGH:brq_pkg_CSR_MFIX_BIT_LOW];
+ brq_csr #(
+ .Width(18),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_mie_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i({mie_d}),
+ .wr_en_i(mie_en),
+ .rd_data_o(mie_q),
+ .rd_error_o(unused_error4)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_mscratch_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(csr_wdata_int),
+ .wr_en_i(mscratch_en),
+ .rd_data_o(mscratch_q),
+ .rd_error_o(unused_error5)
+ );
+ brq_csr #(
+ .Width(6),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_mcause_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(mcause_d),
+ .wr_en_i(mcause_en),
+ .rd_data_o(mcause_q),
+ .rd_error_o(unused_error6)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_mtval_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(mtval_d),
+ .wr_en_i(mtval_en),
+ .rd_data_o(mtval_q),
+ .rd_error_o(unused_error7)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(ShadowCSR),
+ .ResetValue(32'd1)
+ ) u_mtvec_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(mtvec_d),
+ .wr_en_i(mtvec_en),
+ .rd_data_o(mtvec_q),
+ .rd_error_o(mtvec_err)
+ );
+ localparam [2:0] brq_pkg_DBG_CAUSE_NONE = 3'h0;
+ localparam [31:0] DCSR_RESET_VAL = {brq_pkg_XDEBUGVER_STD, 12'b000000000000, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, brq_pkg_DBG_CAUSE_NONE, 1'b0, 1'b0, 1'b0, 1'b0, brq_pkg_PRIV_LVL_M};
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue({DCSR_RESET_VAL})
+ ) u_dcsr_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i({dcsr_d}),
+ .wr_en_i(dcsr_en),
+ .rd_data_o(dcsr_q),
+ .rd_error_o(unused_error8)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_depc_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(depc_d),
+ .wr_en_i(depc_en),
+ .rd_data_o(depc_q),
+ .rd_error_o(unused_error9)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_dscratch0_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(csr_wdata_int),
+ .wr_en_i(dscratch0_en),
+ .rd_data_o(dscratch0_q),
+ .rd_error_o(unused_error10)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_dscratch1_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(csr_wdata_int),
+ .wr_en_i(dscratch1_en),
+ .rd_data_o(dscratch1_q),
+ .rd_error_o(unused_error11)
+ );
+ localparam [2:0] MSTACK_RESET_VAL = {1'b1, brq_pkg_PRIV_LVL_U};
+ brq_csr #(
+ .Width(3),
+ .ShadowCopy(1'b0),
+ .ResetValue({MSTACK_RESET_VAL})
+ ) u_mstack_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i({mstack_d}),
+ .wr_en_i(mstack_en),
+ .rd_data_o(mstack_q),
+ .rd_error_o(unused_error12)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_mstack_epc_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(mstack_epc_d),
+ .wr_en_i(mstack_en),
+ .rd_data_o(mstack_epc_q),
+ .rd_error_o(unused_error13)
+ );
+ brq_csr #(
+ .Width(6),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_mstack_cause_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(mstack_cause_d),
+ .wr_en_i(mstack_en),
+ .rd_data_o(mstack_cause_q),
+ .rd_error_o(unused_error14)
+ );
+ localparam [11:0] brq_pkg_CSR_OFF_PMP_ADDR = 12'h3b0;
+ localparam [11:0] brq_pkg_CSR_OFF_PMP_CFG = 12'h3a0;
+ localparam [1:0] brq_pkg_PMP_MODE_NA4 = 2'b10;
+ localparam [1:0] brq_pkg_PMP_MODE_NAPOT = 2'b11;
+ localparam [1:0] brq_pkg_PMP_MODE_OFF = 2'b00;
+ localparam [1:0] brq_pkg_PMP_MODE_TOR = 2'b01;
+ generate
+ if (PMPEnable) begin : g_pmp_registers
+ wire [5:0] pmp_cfg [0:PMPNumRegions - 1];
+ reg [5:0] pmp_cfg_wdata [0:PMPNumRegions - 1];
+ wire [PMPAddrWidth - 1:0] pmp_addr [0:PMPNumRegions - 1];
+ wire [PMPNumRegions - 1:0] pmp_cfg_we;
+ wire [PMPNumRegions - 1:0] pmp_cfg_err;
+ wire [PMPNumRegions - 1:0] pmp_addr_we;
+ wire [PMPNumRegions - 1:0] pmp_addr_err;
+ genvar i;
+ for (i = 0; i < brq_pkg_PMP_MAX_REGIONS; i = i + 1) begin : g_exp_rd_data
+ if (i < PMPNumRegions) begin : g_implemented_regions
+ assign pmp_cfg_rdata[i] = {pmp_cfg[i][5], 2'b00, pmp_cfg[i][4-:2], pmp_cfg[i][2], pmp_cfg[i][1], pmp_cfg[i][0]};
+ if (PMPGranularity == 0) begin : g_pmp_g0
+ wire [32:1] sv2v_tmp_D3A6A;
+ assign sv2v_tmp_D3A6A = pmp_addr[i];
+ always @(*) pmp_addr_rdata[i] = sv2v_tmp_D3A6A;
+ end
+ else if (PMPGranularity == 1) begin : g_pmp_g1
+ always @(*) begin
+ pmp_addr_rdata[i] = pmp_addr[i];
+ if ((pmp_cfg[i][4-:2] == brq_pkg_PMP_MODE_OFF) || (pmp_cfg[i][4-:2] == brq_pkg_PMP_MODE_TOR))
+ pmp_addr_rdata[i][PMPGranularity - 1:0] = {PMPGranularity {1'sb0}};
+ end
+ end
+ else begin : g_pmp_g2
+ always @(*) begin
+ pmp_addr_rdata[i] = {pmp_addr[i], {PMPGranularity - 1 {1'b1}}};
+ if ((pmp_cfg[i][4-:2] == brq_pkg_PMP_MODE_OFF) || (pmp_cfg[i][4-:2] == brq_pkg_PMP_MODE_TOR))
+ pmp_addr_rdata[i][PMPGranularity - 1:0] = {PMPGranularity {1'sb0}};
+ end
+ end
+ end
+ else begin : g_other_regions
+ assign pmp_cfg_rdata[i] = {8 {1'sb0}};
+ wire [32:1] sv2v_tmp_313D8;
+ assign sv2v_tmp_313D8 = {32 {1'sb0}};
+ always @(*) pmp_addr_rdata[i] = sv2v_tmp_313D8;
+ end
+ end
+ for (i = 0; i < PMPNumRegions; i = i + 1) begin : g_pmp_csrs
+ assign pmp_cfg_we[i] = (csr_we_int & ~pmp_cfg[i][5]) & (csr_addr == (brq_pkg_CSR_OFF_PMP_CFG + (i[11:0] >> 2)));
+ wire [1:1] sv2v_tmp_5B5A1;
+ assign sv2v_tmp_5B5A1 = csr_wdata_int[((i % 4) * brq_pkg_PMP_CFG_W) + 7];
+ always @(*) pmp_cfg_wdata[i][5] = sv2v_tmp_5B5A1;
+ always @(*)
+ case (csr_wdata_int[((i % 4) * brq_pkg_PMP_CFG_W) + 3+:2])
+ 2'b00: pmp_cfg_wdata[i][4-:2] = brq_pkg_PMP_MODE_OFF;
+ 2'b01: pmp_cfg_wdata[i][4-:2] = brq_pkg_PMP_MODE_TOR;
+ 2'b10: pmp_cfg_wdata[i][4-:2] = (PMPGranularity == 0 ? brq_pkg_PMP_MODE_NA4 : brq_pkg_PMP_MODE_OFF);
+ 2'b11: pmp_cfg_wdata[i][4-:2] = brq_pkg_PMP_MODE_NAPOT;
+ default: pmp_cfg_wdata[i][4-:2] = brq_pkg_PMP_MODE_OFF;
+ endcase
+ wire [1:1] sv2v_tmp_7A6DE;
+ assign sv2v_tmp_7A6DE = csr_wdata_int[((i % 4) * brq_pkg_PMP_CFG_W) + 2];
+ always @(*) pmp_cfg_wdata[i][2] = sv2v_tmp_7A6DE;
+ wire [1:1] sv2v_tmp_65F7E;
+ assign sv2v_tmp_65F7E = &csr_wdata_int[(i % 4) * brq_pkg_PMP_CFG_W+:2];
+ always @(*) pmp_cfg_wdata[i][1] = sv2v_tmp_65F7E;
+ wire [1:1] sv2v_tmp_54FD8;
+ assign sv2v_tmp_54FD8 = csr_wdata_int[(i % 4) * brq_pkg_PMP_CFG_W];
+ always @(*) pmp_cfg_wdata[i][0] = sv2v_tmp_54FD8;
+ brq_csr #(
+ .Width(6),
+ .ShadowCopy(ShadowCSR),
+ .ResetValue(1'sb0)
+ ) u_pmp_cfg_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i({pmp_cfg_wdata[i]}),
+ .wr_en_i(pmp_cfg_we[i]),
+ .rd_data_o(pmp_cfg[i]),
+ .rd_error_o(pmp_cfg_err[i])
+ );
+ if (i < (PMPNumRegions - 1)) begin : g_lower
+ assign pmp_addr_we[i] = ((csr_we_int & ~pmp_cfg[i][5]) & (~pmp_cfg[i + 1][5] | (pmp_cfg[i + 1][4-:2] != brq_pkg_PMP_MODE_TOR))) & (csr_addr == (brq_pkg_CSR_OFF_PMP_ADDR + i[11:0]));
+ end
+ else begin : g_upper
+ assign pmp_addr_we[i] = (csr_we_int & ~pmp_cfg[i][5]) & (csr_addr == (brq_pkg_CSR_OFF_PMP_ADDR + i[11:0]));
+ end
+ brq_csr #(
+ .Width(PMPAddrWidth),
+ .ShadowCopy(ShadowCSR),
+ .ResetValue(1'sb0)
+ ) u_pmp_addr_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(csr_wdata_int[31-:PMPAddrWidth]),
+ .wr_en_i(pmp_addr_we[i]),
+ .rd_data_o(pmp_addr[i]),
+ .rd_error_o(pmp_addr_err[i])
+ );
+ assign csr_pmp_cfg_o[(0 >= (PMPNumRegions - 1) ? i : (PMPNumRegions - 1) - i) * 6+:6] = pmp_cfg[i];
+ assign csr_pmp_addr_o[(0 >= (PMPNumRegions - 1) ? i : (PMPNumRegions - 1) - i) * 34+:34] = {pmp_addr_rdata[i], 2'b00};
+ end
+ assign pmp_csr_err = |pmp_cfg_err | |pmp_addr_err;
+ end
+ else begin : g_no_pmp_tieoffs
+ genvar i;
+ for (i = 0; i < brq_pkg_PMP_MAX_REGIONS; i = i + 1) begin : g_rdata
+ wire [32:1] sv2v_tmp_313D8;
+ assign sv2v_tmp_313D8 = {32 {1'sb0}};
+ always @(*) pmp_addr_rdata[i] = sv2v_tmp_313D8;
+ assign pmp_cfg_rdata[i] = {8 {1'sb0}};
+ end
+ for (i = 0; i < PMPNumRegions; i = i + 1) begin : g_outputs
+ function automatic [5:0] sv2v_cast_6;
+ input reg [5:0] inp;
+ sv2v_cast_6 = inp;
+ endfunction
+ assign csr_pmp_cfg_o[(0 >= (PMPNumRegions - 1) ? i : (PMPNumRegions - 1) - i) * 6+:6] = sv2v_cast_6(1'b0);
+ assign csr_pmp_addr_o[(0 >= (PMPNumRegions - 1) ? i : (PMPNumRegions - 1) - i) * 34+:34] = {34 {1'sb0}};
+ end
+ assign pmp_csr_err = 1'b0;
+ end
+ endgenerate
+ always @(*) begin : mcountinhibit_update
+ if (mcountinhibit_we == 1'b1)
+ mcountinhibit_d = {csr_wdata_int[MHPMCounterNum + 2:2], 1'b0, csr_wdata_int[0]};
+ else
+ mcountinhibit_d = mcountinhibit_q;
+ end
+ always @(*) begin : gen_mhpmcounter_incr
+ begin : sv2v_autoblock_81
+ reg [31:0] i;
+ for (i = 0; i < 32; i = i + 1)
+ begin : gen_mhpmcounter_incr_inactive
+ mhpmcounter_incr[i] = 1'b0;
+ end
+ end
+ mhpmcounter_incr[0] = 1'b1;
+ mhpmcounter_incr[1] = 1'b0;
+ mhpmcounter_incr[2] = instr_ret_i;
+ mhpmcounter_incr[3] = dside_wait_i;
+ mhpmcounter_incr[4] = iside_wait_i;
+ mhpmcounter_incr[5] = mem_load_i;
+ mhpmcounter_incr[6] = mem_store_i;
+ mhpmcounter_incr[7] = jump_i;
+ mhpmcounter_incr[8] = branch_i;
+ mhpmcounter_incr[9] = branch_taken_i;
+ mhpmcounter_incr[10] = instr_ret_compressed_i;
+ mhpmcounter_incr[11] = mul_wait_i;
+ mhpmcounter_incr[12] = div_wait_i;
+ end
+ always @(*) begin : gen_mhpmevent
+ begin : sv2v_autoblock_82
+ reg signed [31:0] i;
+ for (i = 0; i < 32; i = i + 1)
+ begin : gen_mhpmevent_active
+ mhpmevent[i] = {32 {1'sb0}};
+ mhpmevent[i][i] = 1'b1;
+ end
+ end
+ mhpmevent[1] = {32 {1'sb0}};
+ begin : sv2v_autoblock_83
+ reg [31:0] i;
+ for (i = 3 + MHPMCounterNum; i < 32; i = i + 1)
+ begin : gen_mhpmevent_inactive
+ mhpmevent[i] = {32 {1'sb0}};
+ end
+ end
+ end
+ brq_counter #(.CounterWidth(64)) mcycle_counter_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .counter_inc_i(mhpmcounter_incr[0] & ~mcountinhibit[0]),
+ .counterh_we_i(mhpmcounterh_we[0]),
+ .counter_we_i(mhpmcounter_we[0]),
+ .counter_val_i(csr_wdata_int),
+ .counter_val_o(mhpmcounter[0])
+ );
+ brq_counter #(.CounterWidth(64)) minstret_counter_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .counter_inc_i(mhpmcounter_incr[2] & ~mcountinhibit[2]),
+ .counterh_we_i(mhpmcounterh_we[2]),
+ .counter_we_i(mhpmcounter_we[2]),
+ .counter_val_i(csr_wdata_int),
+ .counter_val_o(mhpmcounter[2])
+ );
+ assign mhpmcounter[1] = {64 {1'sb0}};
+ assign unused_mhpmcounter_we_1 = mhpmcounter_we[1];
+ assign unused_mhpmcounterh_we_1 = mhpmcounterh_we[1];
+ assign unused_mhpmcounter_incr_1 = mhpmcounter_incr[1];
+ generate
+ genvar cnt;
+ for (cnt = 0; cnt < 29; cnt = cnt + 1) begin : gen_cntrs
+ if (cnt < MHPMCounterNum) begin : gen_imp
+ brq_counter #(.CounterWidth(MHPMCounterWidth)) mcounters_variable_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .counter_inc_i(mhpmcounter_incr[cnt + 3] & ~mcountinhibit[cnt + 3]),
+ .counterh_we_i(mhpmcounterh_we[cnt + 3]),
+ .counter_we_i(mhpmcounter_we[cnt + 3]),
+ .counter_val_i(csr_wdata_int),
+ .counter_val_o(mhpmcounter[cnt + 3])
+ );
+ end
+ else begin : gen_unimp
+ assign mhpmcounter[cnt + 3] = {64 {1'sb0}};
+ end
+ end
+ endgenerate
+ generate
+ if (MHPMCounterNum < 29) begin : g_mcountinhibit_reduced
+ wire [(29 - MHPMCounterNum) - 1:0] unused_mhphcounter_we;
+ wire [(29 - MHPMCounterNum) - 1:0] unused_mhphcounterh_we;
+ wire [(29 - MHPMCounterNum) - 1:0] unused_mhphcounter_incr;
+ assign mcountinhibit = {{29 - MHPMCounterNum {1'b1}}, mcountinhibit_q};
+ assign unused_mhphcounter_we = mhpmcounter_we[31:MHPMCounterNum + 3];
+ assign unused_mhphcounterh_we = mhpmcounterh_we[31:MHPMCounterNum + 3];
+ assign unused_mhphcounter_incr = mhpmcounter_incr[31:MHPMCounterNum + 3];
+ end
+ else begin : g_mcountinhibit_full
+ assign mcountinhibit = mcountinhibit_q;
+ end
+ endgenerate
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ mcountinhibit_q <= {((MHPMCounterNum + 2) >= 0 ? MHPMCounterNum + 3 : 1 - (MHPMCounterNum + 2)) {1'sb0}};
+ else
+ mcountinhibit_q <= mcountinhibit_d;
+ generate
+ if (DbgTriggerEn) begin : gen_trigger_regs
+ localparam [31:0] DbgHwNumLen = (DbgHwBreakNum > 1 ? $clog2(DbgHwBreakNum) : 1);
+ wire [DbgHwNumLen - 1:0] tselect_d;
+ wire [DbgHwNumLen - 1:0] tselect_q;
+ wire tmatch_control_d;
+ wire [DbgHwBreakNum - 1:0] tmatch_control_q;
+ wire [31:0] tmatch_value_d;
+ wire [31:0] tmatch_value_q [0:DbgHwBreakNum - 1];
+ wire tselect_we;
+ wire [DbgHwBreakNum - 1:0] tmatch_control_we;
+ wire [DbgHwBreakNum - 1:0] tmatch_value_we;
+ wire [DbgHwBreakNum - 1:0] trigger_match;
+ assign tselect_we = (csr_we_int & debug_mode_i) & (csr_addr_i == brq_pkg_CSR_TSELECT);
+ genvar i;
+ for (i = 0; i < DbgHwBreakNum; i = i + 1) begin : g_dbg_tmatch_we
+ assign tmatch_control_we[i] = (((i[DbgHwNumLen - 1:0] == tselect_q) & csr_we_int) & debug_mode_i) & (csr_addr_i == brq_pkg_CSR_TDATA1);
+ assign tmatch_value_we[i] = (((i[DbgHwNumLen - 1:0] == tselect_q) & csr_we_int) & debug_mode_i) & (csr_addr_i == brq_pkg_CSR_TDATA2);
+ end
+ assign tselect_d = (csr_wdata_int < DbgHwBreakNum ? csr_wdata_int[DbgHwNumLen - 1:0] : DbgHwBreakNum - 1);
+ assign tmatch_control_d = csr_wdata_int[2];
+ assign tmatch_value_d = csr_wdata_int[31:0];
+ brq_csr #(
+ .Width(DbgHwNumLen),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_tselect_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(tselect_d),
+ .wr_en_i(tselect_we),
+ .rd_data_o(tselect_q),
+ .rd_error_o(unused_error15)
+ );
+ for (i = 0; i < DbgHwBreakNum; i = i + 1) begin : g_dbg_tmatch_reg
+ brq_csr #(
+ .Width(1),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_tmatch_control_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(tmatch_control_d),
+ .wr_en_i(tmatch_control_we[i]),
+ .rd_data_o(tmatch_control_q[i]),
+ .rd_error_o(unused_error16)
+ );
+ brq_csr #(
+ .Width(32),
+ .ShadowCopy(1'b0),
+ .ResetValue(1'sb0)
+ ) u_tmatch_value_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i(tmatch_value_d),
+ .wr_en_i(tmatch_value_we[i]),
+ .rd_data_o(tmatch_value_q[i]),
+ .rd_error_o(unused_error17)
+ );
+ end
+ localparam [31:0] TSelectRdataPadlen = (DbgHwNumLen >= 32 ? 0 : 32 - DbgHwNumLen);
+ assign tselect_rdata = {{TSelectRdataPadlen {1'b0}}, tselect_q};
+ assign tmatch_control_rdata = {29'b00101000000000000001000001001, tmatch_control_q[tselect_q], 1'b0, 1'b0};
+ assign tmatch_value_rdata = tmatch_value_q[tselect_q];
+ for (i = 0; i < DbgHwBreakNum; i = i + 1) begin : g_dbg_trigger_match
+ assign trigger_match[i] = tmatch_control_q[i] & (pc_if_i[31:0] == tmatch_value_q[i]);
+ end
+ assign trigger_match_o = |trigger_match;
+ end
+ else begin : gen_no_trigger_regs
+ assign tselect_rdata = 'b0;
+ assign tmatch_control_rdata = 'b0;
+ assign tmatch_value_rdata = 'b0;
+ assign trigger_match_o = 'b0;
+ end
+ endgenerate
+ assign cpuctrl_wdata = csr_wdata_int[5:0];
+ generate
+ if (DataIndTiming) begin : gen_dit
+ assign cpuctrl_d[1] = cpuctrl_wdata[1];
+ end
+ else begin : gen_no_dit
+ wire unused_dit;
+ assign unused_dit = cpuctrl_wdata[1];
+ assign cpuctrl_d[1] = 1'b0;
+ end
+ endgenerate
+ assign data_ind_timing_o = cpuctrl_q[1];
+ generate
+ if (DummyInstructions) begin : gen_dummy
+ assign cpuctrl_d[2] = cpuctrl_wdata[2];
+ assign cpuctrl_d[5-:3] = cpuctrl_wdata[5-:3];
+ assign dummy_instr_seed_en_o = csr_we_int && (csr_addr == brq_pkg_CSR_SECURESEED);
+ assign dummy_instr_seed_o = csr_wdata_int;
+ end
+ else begin : gen_no_dummy
+ wire unused_dummy_en;
+ wire [2:0] unused_dummy_mask;
+ assign unused_dummy_en = cpuctrl_wdata[2];
+ assign unused_dummy_mask = cpuctrl_wdata[5-:3];
+ assign cpuctrl_d[2] = 1'b0;
+ assign cpuctrl_d[5-:3] = 3'b000;
+ assign dummy_instr_seed_en_o = 1'b0;
+ assign dummy_instr_seed_o = {32 {1'sb0}};
+ end
+ endgenerate
+ assign dummy_instr_en_o = cpuctrl_q[2];
+ assign dummy_instr_mask_o = cpuctrl_q[5-:3];
+ generate
+ if (ICache) begin : gen_icache_enable
+ assign cpuctrl_d[0] = cpuctrl_wdata[0];
+ end
+ else begin : gen_no_icache
+ wire unused_icen;
+ assign unused_icen = cpuctrl_wdata[0];
+ assign cpuctrl_d[0] = 1'b0;
+ end
+ endgenerate
+ assign icache_enable_o = cpuctrl_q[0];
+ brq_csr #(
+ .Width(6),
+ .ShadowCopy(ShadowCSR),
+ .ResetValue(1'sb0)
+ ) u_cpuctrl_csr(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .wr_data_i({cpuctrl_d}),
+ .wr_en_i(cpuctrl_we),
+ .rd_data_o(cpuctrl_q),
+ .rd_error_o(cpuctrl_err)
+ );
+ assign csr_shadow_err_o = ((mstatus_err | mtvec_err) | pmp_csr_err) | cpuctrl_err;
+endmodule
+module brq_csr (
+ clk_i,
+ rst_ni,
+ wr_data_i,
+ wr_en_i,
+ rd_data_o,
+ rd_error_o
+);
+ parameter [31:0] Width = 32;
+ parameter [0:0] ShadowCopy = 1'b0;
+ parameter [Width - 1:0] ResetValue = 1'sb0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [Width - 1:0] wr_data_i;
+ input wire wr_en_i;
+ output wire [Width - 1:0] rd_data_o;
+ output wire rd_error_o;
+ reg [Width - 1:0] rdata_q;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ rdata_q <= ResetValue;
+ else if (wr_en_i)
+ rdata_q <= wr_data_i;
+ assign rd_data_o = rdata_q;
+ generate
+ if (ShadowCopy) begin : gen_shadow
+ reg [Width - 1:0] shadow_q;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ shadow_q <= ~ResetValue;
+ else if (wr_en_i)
+ shadow_q <= ~wr_data_i;
+ assign rd_error_o = rdata_q != ~shadow_q;
+ end
+ else begin : gen_no_shadow
+ assign rd_error_o = 1'b0;
+ end
+ endgenerate
+endmodule
+module brq_exu_alu (
+ operator_i,
+ operand_a_i,
+ operand_b_i,
+ instr_first_cycle_i,
+ multdiv_operand_a_i,
+ multdiv_operand_b_i,
+ multdiv_sel_i,
+ imd_val_q_i,
+ imd_val_d_o,
+ imd_val_we_o,
+ adder_result_o,
+ adder_result_ext_o,
+ result_o,
+ comparison_result_o,
+ is_equal_result_o
+);
+ localparam integer brq_pkg_RV32BNone = 0;
+ parameter integer RV32B = brq_pkg_RV32BNone;
+ input wire [5:0] operator_i;
+ input wire [31:0] operand_a_i;
+ input wire [31:0] operand_b_i;
+ input wire instr_first_cycle_i;
+ input wire [32:0] multdiv_operand_a_i;
+ input wire [32:0] multdiv_operand_b_i;
+ input wire multdiv_sel_i;
+ input wire [63:0] imd_val_q_i;
+ output reg [63:0] imd_val_d_o;
+ output reg [1:0] imd_val_we_o;
+ output wire [31:0] adder_result_o;
+ output wire [33:0] adder_result_ext_o;
+ output reg [31:0] result_o;
+ output wire comparison_result_o;
+ output wire is_equal_result_o;
+ wire [31:0] operand_a_rev;
+ wire [32:0] operand_b_neg;
+ generate
+ genvar k;
+ for (k = 0; k < 32; k = k + 1) begin : gen_rev_operand_a
+ assign operand_a_rev[k] = operand_a_i[31 - k];
+ end
+ endgenerate
+ reg adder_op_b_negate;
+ wire [32:0] adder_in_a;
+ reg [32:0] adder_in_b;
+ wire [31:0] adder_result;
+ localparam [5:0] brq_pkg_ALU_EQ = 23;
+ localparam [5:0] brq_pkg_ALU_GE = 21;
+ localparam [5:0] brq_pkg_ALU_GEU = 22;
+ localparam [5:0] brq_pkg_ALU_LT = 19;
+ localparam [5:0] brq_pkg_ALU_LTU = 20;
+ localparam [5:0] brq_pkg_ALU_MAX = 27;
+ localparam [5:0] brq_pkg_ALU_MAXU = 28;
+ localparam [5:0] brq_pkg_ALU_MIN = 25;
+ localparam [5:0] brq_pkg_ALU_MINU = 26;
+ localparam [5:0] brq_pkg_ALU_NE = 24;
+ localparam [5:0] brq_pkg_ALU_SLT = 37;
+ localparam [5:0] brq_pkg_ALU_SLTU = 38;
+ localparam [5:0] brq_pkg_ALU_SUB = 1;
+ always @(*) begin
+ adder_op_b_negate = 1'b0;
+ case (operator_i)
+ brq_pkg_ALU_SUB, brq_pkg_ALU_EQ, brq_pkg_ALU_NE, brq_pkg_ALU_GE, brq_pkg_ALU_GEU, brq_pkg_ALU_LT, brq_pkg_ALU_LTU, brq_pkg_ALU_SLT, brq_pkg_ALU_SLTU, brq_pkg_ALU_MIN, brq_pkg_ALU_MINU, brq_pkg_ALU_MAX, brq_pkg_ALU_MAXU: adder_op_b_negate = 1'b1;
+ default:
+ ;
+ endcase
+ end
+ assign adder_in_a = (multdiv_sel_i ? multdiv_operand_a_i : {operand_a_i, 1'b1});
+ assign operand_b_neg = {operand_b_i, 1'b0} ^ {33 {1'b1}};
+ always @(*)
+ case (1'b1)
+ multdiv_sel_i: adder_in_b = multdiv_operand_b_i;
+ adder_op_b_negate: adder_in_b = operand_b_neg;
+ default: adder_in_b = {operand_b_i, 1'b0};
+ endcase
+ assign adder_result_ext_o = $unsigned(adder_in_a) + $unsigned(adder_in_b);
+ assign adder_result = adder_result_ext_o[32:1];
+ assign adder_result_o = adder_result;
+ wire is_equal;
+ reg is_greater_equal;
+ reg cmp_signed;
+ always @(*)
+ case (operator_i)
+ brq_pkg_ALU_GE, brq_pkg_ALU_LT, brq_pkg_ALU_SLT, brq_pkg_ALU_MIN, brq_pkg_ALU_MAX: cmp_signed = 1'b1;
+ default: cmp_signed = 1'b0;
+ endcase
+ assign is_equal = adder_result == 32'b00000000000000000000000000000000;
+ assign is_equal_result_o = is_equal;
+ always @(*)
+ if ((operand_a_i[31] ^ operand_b_i[31]) == 1'b0)
+ is_greater_equal = adder_result[31] == 1'b0;
+ else
+ is_greater_equal = operand_a_i[31] ^ cmp_signed;
+ reg cmp_result;
+ always @(*)
+ case (operator_i)
+ brq_pkg_ALU_EQ: cmp_result = is_equal;
+ brq_pkg_ALU_NE: cmp_result = ~is_equal;
+ brq_pkg_ALU_GE, brq_pkg_ALU_GEU, brq_pkg_ALU_MAX, brq_pkg_ALU_MAXU: cmp_result = is_greater_equal;
+ brq_pkg_ALU_LT, brq_pkg_ALU_LTU, brq_pkg_ALU_MIN, brq_pkg_ALU_MINU, brq_pkg_ALU_SLT, brq_pkg_ALU_SLTU: cmp_result = ~is_greater_equal;
+ default: cmp_result = is_equal;
+ endcase
+ assign comparison_result_o = cmp_result;
+ reg shift_left;
+ wire shift_ones;
+ wire shift_arith;
+ wire shift_funnel;
+ wire shift_sbmode;
+ reg [5:0] shift_amt;
+ wire [5:0] shift_amt_compl;
+ reg [31:0] shift_operand;
+ reg [32:0] shift_result_ext;
+ reg unused_shift_result_ext;
+ reg [31:0] shift_result;
+ reg [31:0] shift_result_rev;
+ wire bfp_op;
+ wire [4:0] bfp_len;
+ wire [4:0] bfp_off;
+ wire [31:0] bfp_mask;
+ wire [31:0] bfp_mask_rev;
+ wire [31:0] bfp_result;
+ localparam [5:0] brq_pkg_ALU_BFP = 49;
+ assign bfp_op = (RV32B != brq_pkg_RV32BNone ? operator_i == brq_pkg_ALU_BFP : 1'b0);
+ assign bfp_len = {~(|operand_b_i[27:24]), operand_b_i[27:24]};
+ assign bfp_off = operand_b_i[20:16];
+ assign bfp_mask = (RV32B != brq_pkg_RV32BNone ? ~(32'hffffffff << bfp_len) : {32 {1'sb0}});
+ generate
+ genvar i;
+ for (i = 0; i < 32; i = i + 1) begin : gen_rev_bfp_mask
+ assign bfp_mask_rev[i] = bfp_mask[31 - i];
+ end
+ endgenerate
+ assign bfp_result = (RV32B != brq_pkg_RV32BNone ? (~shift_result & operand_a_i) | ((operand_b_i & bfp_mask) << bfp_off) : {32 {1'sb0}});
+ wire [1:1] sv2v_tmp_86907;
+ assign sv2v_tmp_86907 = operand_b_i[5] & shift_funnel;
+ always @(*) shift_amt[5] = sv2v_tmp_86907;
+ assign shift_amt_compl = 32 - operand_b_i[4:0];
+ always @(*)
+ if (bfp_op)
+ shift_amt[4:0] = bfp_off;
+ else
+ shift_amt[4:0] = (instr_first_cycle_i ? (operand_b_i[5] && shift_funnel ? shift_amt_compl[4:0] : operand_b_i[4:0]) : (operand_b_i[5] && shift_funnel ? operand_b_i[4:0] : shift_amt_compl[4:0]));
+ localparam [5:0] brq_pkg_ALU_SBCLR = 44;
+ localparam [5:0] brq_pkg_ALU_SBINV = 45;
+ localparam [5:0] brq_pkg_ALU_SBSET = 43;
+ assign shift_sbmode = (RV32B != brq_pkg_RV32BNone ? ((operator_i == brq_pkg_ALU_SBSET) | (operator_i == brq_pkg_ALU_SBCLR)) | (operator_i == brq_pkg_ALU_SBINV) : 1'b0);
+ localparam [5:0] brq_pkg_ALU_FSL = 41;
+ localparam [5:0] brq_pkg_ALU_FSR = 42;
+ localparam [5:0] brq_pkg_ALU_ROL = 14;
+ localparam [5:0] brq_pkg_ALU_ROR = 13;
+ localparam [5:0] brq_pkg_ALU_SLL = 10;
+ localparam [5:0] brq_pkg_ALU_SLO = 12;
+ always @(*) begin
+ case (operator_i)
+ brq_pkg_ALU_SLL: shift_left = 1'b1;
+ brq_pkg_ALU_SLO, brq_pkg_ALU_BFP: shift_left = (RV32B != brq_pkg_RV32BNone ? 1'b1 : 1'b0);
+ brq_pkg_ALU_ROL: shift_left = (RV32B != brq_pkg_RV32BNone ? instr_first_cycle_i : 0);
+ brq_pkg_ALU_ROR: shift_left = (RV32B != brq_pkg_RV32BNone ? ~instr_first_cycle_i : 0);
+ brq_pkg_ALU_FSL: shift_left = (RV32B != brq_pkg_RV32BNone ? (shift_amt[5] ? ~instr_first_cycle_i : instr_first_cycle_i) : 1'b0);
+ brq_pkg_ALU_FSR: shift_left = (RV32B != brq_pkg_RV32BNone ? (shift_amt[5] ? instr_first_cycle_i : ~instr_first_cycle_i) : 1'b0);
+ default: shift_left = 1'b0;
+ endcase
+ if (shift_sbmode)
+ shift_left = 1'b1;
+ end
+ localparam [5:0] brq_pkg_ALU_SRA = 8;
+ assign shift_arith = operator_i == brq_pkg_ALU_SRA;
+ localparam [5:0] brq_pkg_ALU_SRO = 11;
+ assign shift_ones = (RV32B != brq_pkg_RV32BNone ? (operator_i == brq_pkg_ALU_SLO) | (operator_i == brq_pkg_ALU_SRO) : 1'b0);
+ assign shift_funnel = (RV32B != brq_pkg_RV32BNone ? (operator_i == brq_pkg_ALU_FSL) | (operator_i == brq_pkg_ALU_FSR) : 1'b0);
+ always @(*) begin
+ if (RV32B == brq_pkg_RV32BNone)
+ shift_operand = (shift_left ? operand_a_rev : operand_a_i);
+ else
+ case (1'b1)
+ bfp_op: shift_operand = bfp_mask_rev;
+ shift_sbmode: shift_operand = 32'h80000000;
+ default: shift_operand = (shift_left ? operand_a_rev : operand_a_i);
+ endcase
+ shift_result_ext = $unsigned($signed({shift_ones | (shift_arith & shift_operand[31]), shift_operand}) >>> shift_amt[4:0]);
+ shift_result = shift_result_ext[31:0];
+ unused_shift_result_ext = shift_result_ext[32];
+ begin : sv2v_autoblock_84
+ reg [31:0] i;
+ for (i = 0; i < 32; i = i + 1)
+ shift_result_rev[i] = shift_result[31 - i];
+ end
+ shift_result = (shift_left ? shift_result_rev : shift_result);
+ end
+ wire bwlogic_or;
+ wire bwlogic_and;
+ wire [31:0] bwlogic_operand_b;
+ wire [31:0] bwlogic_or_result;
+ wire [31:0] bwlogic_and_result;
+ wire [31:0] bwlogic_xor_result;
+ reg [31:0] bwlogic_result;
+ reg bwlogic_op_b_negate;
+ localparam [5:0] brq_pkg_ALU_ANDN = 7;
+ localparam [5:0] brq_pkg_ALU_CMIX = 40;
+ localparam [5:0] brq_pkg_ALU_ORN = 6;
+ localparam [5:0] brq_pkg_ALU_XNOR = 5;
+ always @(*)
+ case (operator_i)
+ brq_pkg_ALU_XNOR, brq_pkg_ALU_ORN, brq_pkg_ALU_ANDN: bwlogic_op_b_negate = (RV32B != brq_pkg_RV32BNone ? 1'b1 : 1'b0);
+ brq_pkg_ALU_CMIX: bwlogic_op_b_negate = (RV32B != brq_pkg_RV32BNone ? ~instr_first_cycle_i : 1'b0);
+ default: bwlogic_op_b_negate = 1'b0;
+ endcase
+ assign bwlogic_operand_b = (bwlogic_op_b_negate ? operand_b_neg[32:1] : operand_b_i);
+ assign bwlogic_or_result = operand_a_i | bwlogic_operand_b;
+ assign bwlogic_and_result = operand_a_i & bwlogic_operand_b;
+ assign bwlogic_xor_result = operand_a_i ^ bwlogic_operand_b;
+ localparam [5:0] brq_pkg_ALU_OR = 3;
+ assign bwlogic_or = (operator_i == brq_pkg_ALU_OR) | (operator_i == brq_pkg_ALU_ORN);
+ localparam [5:0] brq_pkg_ALU_AND = 4;
+ assign bwlogic_and = (operator_i == brq_pkg_ALU_AND) | (operator_i == brq_pkg_ALU_ANDN);
+ always @(*)
+ case (1'b1)
+ bwlogic_or: bwlogic_result = bwlogic_or_result;
+ bwlogic_and: bwlogic_result = bwlogic_and_result;
+ default: bwlogic_result = bwlogic_xor_result;
+ endcase
+ wire [5:0] bitcnt_result;
+ wire [31:0] minmax_result;
+ reg [31:0] pack_result;
+ wire [31:0] sext_result;
+ reg [31:0] singlebit_result;
+ reg [31:0] rev_result;
+ reg [31:0] shuffle_result;
+ reg [31:0] butterfly_result;
+ reg [31:0] invbutterfly_result;
+ reg [31:0] clmul_result;
+ reg [31:0] multicycle_result;
+ localparam [5:0] brq_pkg_ALU_BDEP = 48;
+ localparam [5:0] brq_pkg_ALU_BEXT = 47;
+ localparam [5:0] brq_pkg_ALU_CLMULH = 52;
+ localparam [5:0] brq_pkg_ALU_CLMULR = 51;
+ localparam [5:0] brq_pkg_ALU_CLZ = 34;
+ localparam [5:0] brq_pkg_ALU_CMOV = 39;
+ localparam [5:0] brq_pkg_ALU_CRC32C_B = 54;
+ localparam [5:0] brq_pkg_ALU_CRC32C_H = 56;
+ localparam [5:0] brq_pkg_ALU_CRC32C_W = 58;
+ localparam [5:0] brq_pkg_ALU_CRC32_B = 53;
+ localparam [5:0] brq_pkg_ALU_CRC32_H = 55;
+ localparam [5:0] brq_pkg_ALU_CRC32_W = 57;
+ localparam [5:0] brq_pkg_ALU_CTZ = 35;
+ localparam [5:0] brq_pkg_ALU_GORC = 16;
+ localparam [5:0] brq_pkg_ALU_PACKH = 31;
+ localparam [5:0] brq_pkg_ALU_PACKU = 30;
+ localparam [5:0] brq_pkg_ALU_SEXTB = 32;
+ localparam [5:0] brq_pkg_ALU_UNSHFL = 18;
+ localparam integer brq_pkg_RV32BFull = 2;
+ generate
+ if (RV32B != brq_pkg_RV32BNone) begin : g_alu_rvb
+ wire zbe_op;
+ wire bitcnt_ctz;
+ wire bitcnt_clz;
+ wire bitcnt_cz;
+ reg [31:0] bitcnt_bits;
+ wire [31:0] bitcnt_mask_op;
+ reg [31:0] bitcnt_bit_mask;
+ reg [191:0] bitcnt_partial;
+ wire [31:0] bitcnt_partial_lsb_d;
+ wire [31:0] bitcnt_partial_msb_d;
+ assign bitcnt_ctz = operator_i == brq_pkg_ALU_CTZ;
+ assign bitcnt_clz = operator_i == brq_pkg_ALU_CLZ;
+ assign bitcnt_cz = bitcnt_ctz | bitcnt_clz;
+ assign bitcnt_result = bitcnt_partial[0+:6];
+ assign bitcnt_mask_op = (bitcnt_clz ? operand_a_rev : operand_a_i);
+ always @(*) begin
+ bitcnt_bit_mask = bitcnt_mask_op;
+ bitcnt_bit_mask = bitcnt_bit_mask | (bitcnt_bit_mask << 1);
+ bitcnt_bit_mask = bitcnt_bit_mask | (bitcnt_bit_mask << 2);
+ bitcnt_bit_mask = bitcnt_bit_mask | (bitcnt_bit_mask << 4);
+ bitcnt_bit_mask = bitcnt_bit_mask | (bitcnt_bit_mask << 8);
+ bitcnt_bit_mask = bitcnt_bit_mask | (bitcnt_bit_mask << 16);
+ bitcnt_bit_mask = ~bitcnt_bit_mask;
+ end
+ assign zbe_op = (operator_i == brq_pkg_ALU_BEXT) | (operator_i == brq_pkg_ALU_BDEP);
+ always @(*)
+ case (1'b1)
+ zbe_op: bitcnt_bits = operand_b_i;
+ bitcnt_cz: bitcnt_bits = bitcnt_bit_mask & ~bitcnt_mask_op;
+ default: bitcnt_bits = operand_a_i;
+ endcase
+ always @(*) begin
+ bitcnt_partial = {32 {6'b000000}};
+ begin : sv2v_autoblock_85
+ reg [31:0] i;
+ for (i = 1; i < 32; i = i + 2)
+ bitcnt_partial[(31 - i) * 6+:6] = {5'h00, bitcnt_bits[i]} + {5'h00, bitcnt_bits[i - 1]};
+ end
+ begin : sv2v_autoblock_86
+ reg [31:0] i;
+ for (i = 3; i < 32; i = i + 4)
+ bitcnt_partial[(31 - i) * 6+:6] = bitcnt_partial[(33 - i) * 6+:6] + bitcnt_partial[(31 - i) * 6+:6];
+ end
+ begin : sv2v_autoblock_87
+ reg [31:0] i;
+ for (i = 7; i < 32; i = i + 8)
+ bitcnt_partial[(31 - i) * 6+:6] = bitcnt_partial[(35 - i) * 6+:6] + bitcnt_partial[(31 - i) * 6+:6];
+ end
+ begin : sv2v_autoblock_88
+ reg [31:0] i;
+ for (i = 15; i < 32; i = i + 16)
+ bitcnt_partial[(31 - i) * 6+:6] = bitcnt_partial[(39 - i) * 6+:6] + bitcnt_partial[(31 - i) * 6+:6];
+ end
+ bitcnt_partial[0+:6] = bitcnt_partial[96+:6] + bitcnt_partial[0+:6];
+ bitcnt_partial[48+:6] = bitcnt_partial[96+:6] + bitcnt_partial[48+:6];
+ begin : sv2v_autoblock_89
+ reg [31:0] i;
+ for (i = 11; i < 32; i = i + 8)
+ bitcnt_partial[(31 - i) * 6+:6] = bitcnt_partial[(35 - i) * 6+:6] + bitcnt_partial[(31 - i) * 6+:6];
+ end
+ begin : sv2v_autoblock_90
+ reg [31:0] i;
+ for (i = 5; i < 32; i = i + 4)
+ bitcnt_partial[(31 - i) * 6+:6] = bitcnt_partial[(33 - i) * 6+:6] + bitcnt_partial[(31 - i) * 6+:6];
+ end
+ bitcnt_partial[186+:6] = {5'h00, bitcnt_bits[0]};
+ begin : sv2v_autoblock_91
+ reg [31:0] i;
+ for (i = 2; i < 32; i = i + 2)
+ bitcnt_partial[(31 - i) * 6+:6] = bitcnt_partial[(32 - i) * 6+:6] + {5'h00, bitcnt_bits[i]};
+ end
+ end
+ assign minmax_result = (cmp_result ? operand_a_i : operand_b_i);
+ wire packu;
+ wire packh;
+ assign packu = operator_i == brq_pkg_ALU_PACKU;
+ assign packh = operator_i == brq_pkg_ALU_PACKH;
+ always @(*)
+ case (1'b1)
+ packu: pack_result = {operand_b_i[31:16], operand_a_i[31:16]};
+ packh: pack_result = {16'h0000, operand_b_i[7:0], operand_a_i[7:0]};
+ default: pack_result = {operand_b_i[15:0], operand_a_i[15:0]};
+ endcase
+ assign sext_result = (operator_i == brq_pkg_ALU_SEXTB ? {{24 {operand_a_i[7]}}, operand_a_i[7:0]} : {{16 {operand_a_i[15]}}, operand_a_i[15:0]});
+ always @(*)
+ case (operator_i)
+ brq_pkg_ALU_SBSET: singlebit_result = operand_a_i | shift_result;
+ brq_pkg_ALU_SBCLR: singlebit_result = operand_a_i & ~shift_result;
+ brq_pkg_ALU_SBINV: singlebit_result = operand_a_i ^ shift_result;
+ default: singlebit_result = {31'h00000000, shift_result[0]};
+ endcase
+ wire [4:0] zbp_shift_amt;
+ wire gorc_op;
+ assign gorc_op = operator_i == brq_pkg_ALU_GORC;
+ assign zbp_shift_amt[2:0] = (RV32B == brq_pkg_RV32BFull ? shift_amt[2:0] : {3 {&shift_amt[2:0]}});
+ assign zbp_shift_amt[4:3] = (RV32B == brq_pkg_RV32BFull ? shift_amt[4:3] : {2 {&shift_amt[4:3]}});
+ always @(*) begin
+ rev_result = operand_a_i;
+ if (zbp_shift_amt[0])
+ rev_result = ((gorc_op ? rev_result : 32'h00000000) | ((rev_result & 32'h55555555) << 1)) | ((rev_result & 32'haaaaaaaa) >> 1);
+ if (zbp_shift_amt[1])
+ rev_result = ((gorc_op ? rev_result : 32'h00000000) | ((rev_result & 32'h33333333) << 2)) | ((rev_result & 32'hcccccccc) >> 2);
+ if (zbp_shift_amt[2])
+ rev_result = ((gorc_op ? rev_result : 32'h00000000) | ((rev_result & 32'h0f0f0f0f) << 4)) | ((rev_result & 32'hf0f0f0f0) >> 4);
+ if (zbp_shift_amt[3])
+ rev_result = ((gorc_op & (RV32B == brq_pkg_RV32BFull) ? rev_result : 32'h00000000) | ((rev_result & 32'h00ff00ff) << 8)) | ((rev_result & 32'hff00ff00) >> 8);
+ if (zbp_shift_amt[4])
+ rev_result = ((gorc_op & (RV32B == brq_pkg_RV32BFull) ? rev_result : 32'h00000000) | ((rev_result & 32'h0000ffff) << 16)) | ((rev_result & 32'hffff0000) >> 16);
+ end
+ wire crc_hmode;
+ wire crc_bmode;
+ wire [31:0] clmul_result_rev;
+ if (RV32B == brq_pkg_RV32BFull) begin : gen_alu_rvb_full
+ localparam [127:0] SHUFFLE_MASK_L = 128'h00ff00000f000f003030303044444444;
+ localparam [127:0] SHUFFLE_MASK_R = 128'h0000ff0000f000f00c0c0c0c22222222;
+ localparam [127:0] FLIP_MASK_L = 128'h22001100004400004411000011000000;
+ localparam [127:0] FLIP_MASK_R = 128'h00880044000022000000882200000088;
+ wire [31:0] SHUFFLE_MASK_NOT [0:3];
+ for (i = 0; i < 4; i = i + 1) begin : gen_shuffle_mask_not
+ assign SHUFFLE_MASK_NOT[i] = ~(SHUFFLE_MASK_L[(3 - i) * 32+:32] | SHUFFLE_MASK_R[(3 - i) * 32+:32]);
+ end
+ wire shuffle_flip;
+ assign shuffle_flip = operator_i == brq_pkg_ALU_UNSHFL;
+ reg [3:0] shuffle_mode;
+ always @(*) begin
+ shuffle_result = operand_a_i;
+ if (shuffle_flip) begin
+ shuffle_mode[3] = shift_amt[0];
+ shuffle_mode[2] = shift_amt[1];
+ shuffle_mode[1] = shift_amt[2];
+ shuffle_mode[0] = shift_amt[3];
+ end
+ else
+ shuffle_mode = shift_amt[3:0];
+ if (shuffle_flip)
+ shuffle_result = ((((((((shuffle_result & 32'h88224411) | ((shuffle_result << 6) & FLIP_MASK_L[96+:32])) | ((shuffle_result >> 6) & FLIP_MASK_R[96+:32])) | ((shuffle_result << 9) & FLIP_MASK_L[64+:32])) | ((shuffle_result >> 9) & FLIP_MASK_R[64+:32])) | ((shuffle_result << 15) & FLIP_MASK_L[32+:32])) | ((shuffle_result >> 15) & FLIP_MASK_R[32+:32])) | ((shuffle_result << 21) & FLIP_MASK_L[0+:32])) | ((shuffle_result >> 21) & FLIP_MASK_R[0+:32]);
+ if (shuffle_mode[3])
+ shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[0]) | (((shuffle_result << 8) & SHUFFLE_MASK_L[96+:32]) | ((shuffle_result >> 8) & SHUFFLE_MASK_R[96+:32]));
+ if (shuffle_mode[2])
+ shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[1]) | (((shuffle_result << 4) & SHUFFLE_MASK_L[64+:32]) | ((shuffle_result >> 4) & SHUFFLE_MASK_R[64+:32]));
+ if (shuffle_mode[1])
+ shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[2]) | (((shuffle_result << 2) & SHUFFLE_MASK_L[32+:32]) | ((shuffle_result >> 2) & SHUFFLE_MASK_R[32+:32]));
+ if (shuffle_mode[0])
+ shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[3]) | (((shuffle_result << 1) & SHUFFLE_MASK_L[0+:32]) | ((shuffle_result >> 1) & SHUFFLE_MASK_R[0+:32]));
+ if (shuffle_flip)
+ shuffle_result = ((((((((shuffle_result & 32'h88224411) | ((shuffle_result << 6) & FLIP_MASK_L[96+:32])) | ((shuffle_result >> 6) & FLIP_MASK_R[96+:32])) | ((shuffle_result << 9) & FLIP_MASK_L[64+:32])) | ((shuffle_result >> 9) & FLIP_MASK_R[64+:32])) | ((shuffle_result << 15) & FLIP_MASK_L[32+:32])) | ((shuffle_result >> 15) & FLIP_MASK_R[32+:32])) | ((shuffle_result << 21) & FLIP_MASK_L[0+:32])) | ((shuffle_result >> 21) & FLIP_MASK_R[0+:32]);
+ end
+ reg [191:0] bitcnt_partial_q;
+ for (i = 0; i < 32; i = i + 1) begin : gen_bitcnt_reg_in_lsb
+ assign bitcnt_partial_lsb_d[i] = bitcnt_partial[(31 - i) * 6];
+ end
+ for (i = 0; i < 16; i = i + 1) begin : gen_bitcnt_reg_in_b1
+ assign bitcnt_partial_msb_d[i] = bitcnt_partial[((31 - ((2 * i) + 1)) * 6) + 1];
+ end
+ for (i = 0; i < 8; i = i + 1) begin : gen_bitcnt_reg_in_b2
+ assign bitcnt_partial_msb_d[16 + i] = bitcnt_partial[((31 - ((4 * i) + 3)) * 6) + 2];
+ end
+ for (i = 0; i < 4; i = i + 1) begin : gen_bitcnt_reg_in_b3
+ assign bitcnt_partial_msb_d[24 + i] = bitcnt_partial[((31 - ((8 * i) + 7)) * 6) + 3];
+ end
+ for (i = 0; i < 2; i = i + 1) begin : gen_bitcnt_reg_in_b4
+ assign bitcnt_partial_msb_d[28 + i] = bitcnt_partial[((31 - ((16 * i) + 15)) * 6) + 4];
+ end
+ assign bitcnt_partial_msb_d[30] = bitcnt_partial[5];
+ assign bitcnt_partial_msb_d[31] = 1'b0;
+ always @(*) begin
+ bitcnt_partial_q = {32 {6'b000000}};
+ begin : sv2v_autoblock_92
+ reg [31:0] i;
+ for (i = 0; i < 32; i = i + 1)
+ begin : gen_bitcnt_reg_out_lsb
+ bitcnt_partial_q[(31 - i) * 6] = imd_val_q_i[32 + i];
+ end
+ end
+ begin : sv2v_autoblock_93
+ reg [31:0] i;
+ for (i = 0; i < 16; i = i + 1)
+ begin : gen_bitcnt_reg_out_b1
+ bitcnt_partial_q[((31 - ((2 * i) + 1)) * 6) + 1] = imd_val_q_i[i];
+ end
+ end
+ begin : sv2v_autoblock_94
+ reg [31:0] i;
+ for (i = 0; i < 8; i = i + 1)
+ begin : gen_bitcnt_reg_out_b2
+ bitcnt_partial_q[((31 - ((4 * i) + 3)) * 6) + 2] = imd_val_q_i[16 + i];
+ end
+ end
+ begin : sv2v_autoblock_95
+ reg [31:0] i;
+ for (i = 0; i < 4; i = i + 1)
+ begin : gen_bitcnt_reg_out_b3
+ bitcnt_partial_q[((31 - ((8 * i) + 7)) * 6) + 3] = imd_val_q_i[24 + i];
+ end
+ end
+ begin : sv2v_autoblock_96
+ reg [31:0] i;
+ for (i = 0; i < 2; i = i + 1)
+ begin : gen_bitcnt_reg_out_b4
+ bitcnt_partial_q[((31 - ((16 * i) + 15)) * 6) + 4] = imd_val_q_i[28 + i];
+ end
+ end
+ bitcnt_partial_q[5] = imd_val_q_i[30];
+ end
+ wire [31:0] butterfly_mask_l [0:4];
+ wire [31:0] butterfly_mask_r [0:4];
+ wire [31:0] butterfly_mask_not [0:4];
+ wire [31:0] lrotc_stage [0:4];
+ genvar stg;
+ for (stg = 0; stg < 5; stg = stg + 1) begin : gen_butterfly_ctrl_stage
+ genvar seg;
+ for (seg = 0; seg < (2 ** stg); seg = seg + 1) begin : gen_butterfly_ctrl
+ assign lrotc_stage[stg][((2 * (16 >> stg)) * (seg + 1)) - 1:(2 * (16 >> stg)) * seg] = {{16 >> stg {1'b0}}, {16 >> stg {1'b1}}} << bitcnt_partial_q[((32 - ((16 >> stg) * ((2 * seg) + 1))) * 6) + ($clog2(16 >> stg) >= 0 ? $clog2(16 >> stg) : ($clog2(16 >> stg) + ($clog2(16 >> stg) >= 0 ? $clog2(16 >> stg) + 1 : 1 - $clog2(16 >> stg))) - 1)-:($clog2(16 >> stg) >= 0 ? $clog2(16 >> stg) + 1 : 1 - $clog2(16 >> stg))];
+ assign butterfly_mask_l[stg][((16 >> stg) * ((2 * seg) + 2)) - 1:(16 >> stg) * ((2 * seg) + 1)] = ~lrotc_stage[stg][((16 >> stg) * ((2 * seg) + 2)) - 1:(16 >> stg) * ((2 * seg) + 1)];
+ assign butterfly_mask_r[stg][((16 >> stg) * ((2 * seg) + 1)) - 1:(16 >> stg) * (2 * seg)] = ~lrotc_stage[stg][((16 >> stg) * ((2 * seg) + 2)) - 1:(16 >> stg) * ((2 * seg) + 1)];
+ assign butterfly_mask_l[stg][((16 >> stg) * ((2 * seg) + 1)) - 1:(16 >> stg) * (2 * seg)] = {((((16 >> stg) * ((2 * seg) + 1)) - 1) >= ((16 >> stg) * (2 * seg)) ? ((((16 >> stg) * ((2 * seg) + 1)) - 1) - ((16 >> stg) * (2 * seg))) + 1 : (((16 >> stg) * (2 * seg)) - (((16 >> stg) * ((2 * seg) + 1)) - 1)) + 1) {1'sb0}};
+ assign butterfly_mask_r[stg][((16 >> stg) * ((2 * seg) + 2)) - 1:(16 >> stg) * ((2 * seg) + 1)] = {((((16 >> stg) * ((2 * seg) + 2)) - 1) >= ((16 >> stg) * ((2 * seg) + 1)) ? ((((16 >> stg) * ((2 * seg) + 2)) - 1) - ((16 >> stg) * ((2 * seg) + 1))) + 1 : (((16 >> stg) * ((2 * seg) + 1)) - (((16 >> stg) * ((2 * seg) + 2)) - 1)) + 1) {1'sb0}};
+ end
+ end
+ for (stg = 0; stg < 5; stg = stg + 1) begin : gen_butterfly_not
+ assign butterfly_mask_not[stg] = ~(butterfly_mask_l[stg] | butterfly_mask_r[stg]);
+ end
+ always @(*) begin
+ butterfly_result = operand_a_i;
+ butterfly_result = ((butterfly_result & butterfly_mask_not[0]) | ((butterfly_result & butterfly_mask_l[0]) >> 16)) | ((butterfly_result & butterfly_mask_r[0]) << 16);
+ butterfly_result = ((butterfly_result & butterfly_mask_not[1]) | ((butterfly_result & butterfly_mask_l[1]) >> 8)) | ((butterfly_result & butterfly_mask_r[1]) << 8);
+ butterfly_result = ((butterfly_result & butterfly_mask_not[2]) | ((butterfly_result & butterfly_mask_l[2]) >> 4)) | ((butterfly_result & butterfly_mask_r[2]) << 4);
+ butterfly_result = ((butterfly_result & butterfly_mask_not[3]) | ((butterfly_result & butterfly_mask_l[3]) >> 2)) | ((butterfly_result & butterfly_mask_r[3]) << 2);
+ butterfly_result = ((butterfly_result & butterfly_mask_not[4]) | ((butterfly_result & butterfly_mask_l[4]) >> 1)) | ((butterfly_result & butterfly_mask_r[4]) << 1);
+ butterfly_result = butterfly_result & operand_b_i;
+ end
+ always @(*) begin
+ invbutterfly_result = operand_a_i & operand_b_i;
+ invbutterfly_result = ((invbutterfly_result & butterfly_mask_not[4]) | ((invbutterfly_result & butterfly_mask_l[4]) >> 1)) | ((invbutterfly_result & butterfly_mask_r[4]) << 1);
+ invbutterfly_result = ((invbutterfly_result & butterfly_mask_not[3]) | ((invbutterfly_result & butterfly_mask_l[3]) >> 2)) | ((invbutterfly_result & butterfly_mask_r[3]) << 2);
+ invbutterfly_result = ((invbutterfly_result & butterfly_mask_not[2]) | ((invbutterfly_result & butterfly_mask_l[2]) >> 4)) | ((invbutterfly_result & butterfly_mask_r[2]) << 4);
+ invbutterfly_result = ((invbutterfly_result & butterfly_mask_not[1]) | ((invbutterfly_result & butterfly_mask_l[1]) >> 8)) | ((invbutterfly_result & butterfly_mask_r[1]) << 8);
+ invbutterfly_result = ((invbutterfly_result & butterfly_mask_not[0]) | ((invbutterfly_result & butterfly_mask_l[0]) >> 16)) | ((invbutterfly_result & butterfly_mask_r[0]) << 16);
+ end
+ wire clmul_rmode;
+ wire clmul_hmode;
+ reg [31:0] clmul_op_a;
+ reg [31:0] clmul_op_b;
+ wire [31:0] operand_b_rev;
+ wire [31:0] clmul_and_stage [0:31];
+ wire [31:0] clmul_xor_stage1 [0:15];
+ wire [31:0] clmul_xor_stage2 [0:7];
+ wire [31:0] clmul_xor_stage3 [0:3];
+ wire [31:0] clmul_xor_stage4 [0:1];
+ wire [31:0] clmul_result_raw;
+ for (i = 0; i < 32; i = i + 1) begin : gen_rev_operand_b
+ assign operand_b_rev[i] = operand_b_i[31 - i];
+ end
+ assign clmul_rmode = operator_i == brq_pkg_ALU_CLMULR;
+ assign clmul_hmode = operator_i == brq_pkg_ALU_CLMULH;
+ localparam [31:0] CRC32_POLYNOMIAL = 32'h04c11db7;
+ localparam [31:0] CRC32_MU_REV = 32'hf7011641;
+ localparam [31:0] CRC32C_POLYNOMIAL = 32'h1edc6f41;
+ localparam [31:0] CRC32C_MU_REV = 32'hdea713f1;
+ wire crc_op;
+ wire crc_cpoly;
+ reg [31:0] crc_operand;
+ wire [31:0] crc_poly;
+ wire [31:0] crc_mu_rev;
+ assign crc_op = (((((operator_i == brq_pkg_ALU_CRC32C_W) | (operator_i == brq_pkg_ALU_CRC32_W)) | (operator_i == brq_pkg_ALU_CRC32C_H)) | (operator_i == brq_pkg_ALU_CRC32_H)) | (operator_i == brq_pkg_ALU_CRC32C_B)) | (operator_i == brq_pkg_ALU_CRC32_B);
+ assign crc_cpoly = ((operator_i == brq_pkg_ALU_CRC32C_W) | (operator_i == brq_pkg_ALU_CRC32C_H)) | (operator_i == brq_pkg_ALU_CRC32C_B);
+ assign crc_hmode = (operator_i == brq_pkg_ALU_CRC32_H) | (operator_i == brq_pkg_ALU_CRC32C_H);
+ assign crc_bmode = (operator_i == brq_pkg_ALU_CRC32_B) | (operator_i == brq_pkg_ALU_CRC32C_B);
+ assign crc_poly = (crc_cpoly ? CRC32C_POLYNOMIAL : CRC32_POLYNOMIAL);
+ assign crc_mu_rev = (crc_cpoly ? CRC32C_MU_REV : CRC32_MU_REV);
+ always @(*)
+ case (1'b1)
+ crc_bmode: crc_operand = {operand_a_i[7:0], 24'h000000};
+ crc_hmode: crc_operand = {operand_a_i[15:0], 16'h0000};
+ default: crc_operand = operand_a_i;
+ endcase
+ always @(*)
+ if (crc_op) begin
+ clmul_op_a = (instr_first_cycle_i ? crc_operand : imd_val_q_i[32+:32]);
+ clmul_op_b = (instr_first_cycle_i ? crc_mu_rev : crc_poly);
+ end
+ else begin
+ clmul_op_a = (clmul_rmode | clmul_hmode ? operand_a_rev : operand_a_i);
+ clmul_op_b = (clmul_rmode | clmul_hmode ? operand_b_rev : operand_b_i);
+ end
+ for (i = 0; i < 32; i = i + 1) begin : gen_clmul_and_op
+ assign clmul_and_stage[i] = (clmul_op_b[i] ? clmul_op_a << i : {32 {1'sb0}});
+ end
+ for (i = 0; i < 16; i = i + 1) begin : gen_clmul_xor_op_l1
+ assign clmul_xor_stage1[i] = clmul_and_stage[2 * i] ^ clmul_and_stage[(2 * i) + 1];
+ end
+ for (i = 0; i < 8; i = i + 1) begin : gen_clmul_xor_op_l2
+ assign clmul_xor_stage2[i] = clmul_xor_stage1[2 * i] ^ clmul_xor_stage1[(2 * i) + 1];
+ end
+ for (i = 0; i < 4; i = i + 1) begin : gen_clmul_xor_op_l3
+ assign clmul_xor_stage3[i] = clmul_xor_stage2[2 * i] ^ clmul_xor_stage2[(2 * i) + 1];
+ end
+ for (i = 0; i < 2; i = i + 1) begin : gen_clmul_xor_op_l4
+ assign clmul_xor_stage4[i] = clmul_xor_stage3[2 * i] ^ clmul_xor_stage3[(2 * i) + 1];
+ end
+ assign clmul_result_raw = clmul_xor_stage4[0] ^ clmul_xor_stage4[1];
+ for (i = 0; i < 32; i = i + 1) begin : gen_rev_clmul_result
+ assign clmul_result_rev[i] = clmul_result_raw[31 - i];
+ end
+ always @(*)
+ case (1'b1)
+ clmul_rmode: clmul_result = clmul_result_rev;
+ clmul_hmode: clmul_result = {1'b0, clmul_result_rev[31:1]};
+ default: clmul_result = clmul_result_raw;
+ endcase
+ end
+ else begin : gen_alu_rvb_notfull
+ wire [31:0] unused_imd_val_q_1;
+ assign unused_imd_val_q_1 = imd_val_q_i[0+:32];
+ wire [32:1] sv2v_tmp_8C42B;
+ assign sv2v_tmp_8C42B = {32 {1'sb0}};
+ always @(*) shuffle_result = sv2v_tmp_8C42B;
+ wire [32:1] sv2v_tmp_B0AD4;
+ assign sv2v_tmp_B0AD4 = {32 {1'sb0}};
+ always @(*) butterfly_result = sv2v_tmp_B0AD4;
+ wire [32:1] sv2v_tmp_AFC2C;
+ assign sv2v_tmp_AFC2C = {32 {1'sb0}};
+ always @(*) invbutterfly_result = sv2v_tmp_AFC2C;
+ wire [32:1] sv2v_tmp_3A741;
+ assign sv2v_tmp_3A741 = {32 {1'sb0}};
+ always @(*) clmul_result = sv2v_tmp_3A741;
+ assign bitcnt_partial_lsb_d = {32 {1'sb0}};
+ assign bitcnt_partial_msb_d = {32 {1'sb0}};
+ assign clmul_result_rev = {32 {1'sb0}};
+ assign crc_bmode = 1'b0;
+ assign crc_hmode = 1'b0;
+ end
+ always @(*)
+ case (operator_i)
+ brq_pkg_ALU_CMOV: begin
+ multicycle_result = (operand_b_i == 32'h00000000 ? operand_a_i : imd_val_q_i[32+:32]);
+ imd_val_d_o = {operand_a_i, 32'h00000000};
+ if (instr_first_cycle_i)
+ imd_val_we_o = 2'b01;
+ else
+ imd_val_we_o = 2'b00;
+ end
+ brq_pkg_ALU_CMIX: begin
+ multicycle_result = imd_val_q_i[32+:32] | bwlogic_and_result;
+ imd_val_d_o = {bwlogic_and_result, 32'h00000000};
+ if (instr_first_cycle_i)
+ imd_val_we_o = 2'b01;
+ else
+ imd_val_we_o = 2'b00;
+ end
+ brq_pkg_ALU_FSR, brq_pkg_ALU_FSL, brq_pkg_ALU_ROL, brq_pkg_ALU_ROR: begin
+ if (shift_amt[4:0] == 5'h00)
+ multicycle_result = (shift_amt[5] ? operand_a_i : imd_val_q_i[32+:32]);
+ else
+ multicycle_result = imd_val_q_i[32+:32] | shift_result;
+ imd_val_d_o = {shift_result, 32'h00000000};
+ if (instr_first_cycle_i)
+ imd_val_we_o = 2'b01;
+ else
+ imd_val_we_o = 2'b00;
+ end
+ brq_pkg_ALU_CRC32_W, brq_pkg_ALU_CRC32C_W, brq_pkg_ALU_CRC32_H, brq_pkg_ALU_CRC32C_H, brq_pkg_ALU_CRC32_B, brq_pkg_ALU_CRC32C_B:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ case (1'b1)
+ crc_bmode: multicycle_result = clmul_result_rev ^ (operand_a_i >> 8);
+ crc_hmode: multicycle_result = clmul_result_rev ^ (operand_a_i >> 16);
+ default: multicycle_result = clmul_result_rev;
+ endcase
+ imd_val_d_o = {clmul_result_rev, 32'h00000000};
+ if (instr_first_cycle_i)
+ imd_val_we_o = 2'b01;
+ else
+ imd_val_we_o = 2'b00;
+ end
+ else begin
+ imd_val_d_o = {operand_a_i, 32'h00000000};
+ imd_val_we_o = 2'b00;
+ multicycle_result = {32 {1'sb0}};
+ end
+ brq_pkg_ALU_BEXT, brq_pkg_ALU_BDEP:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ multicycle_result = (operator_i == brq_pkg_ALU_BDEP ? butterfly_result : invbutterfly_result);
+ imd_val_d_o = {bitcnt_partial_lsb_d, bitcnt_partial_msb_d};
+ if (instr_first_cycle_i)
+ imd_val_we_o = 2'b11;
+ else
+ imd_val_we_o = 2'b00;
+ end
+ else begin
+ imd_val_d_o = {operand_a_i, 32'h00000000};
+ imd_val_we_o = 2'b00;
+ multicycle_result = {32 {1'sb0}};
+ end
+ default: begin
+ imd_val_d_o = {operand_a_i, 32'h00000000};
+ imd_val_we_o = 2'b00;
+ multicycle_result = {32 {1'sb0}};
+ end
+ endcase
+ end
+ else begin : g_no_alu_rvb
+ wire [63:0] unused_imd_val_q;
+ assign unused_imd_val_q = imd_val_q_i;
+ wire [31:0] unused_butterfly_result;
+ assign unused_butterfly_result = butterfly_result;
+ wire [31:0] unused_invbutterfly_result;
+ assign unused_invbutterfly_result = invbutterfly_result;
+ assign bitcnt_result = {6 {1'sb0}};
+ assign minmax_result = {32 {1'sb0}};
+ wire [32:1] sv2v_tmp_68181;
+ assign sv2v_tmp_68181 = {32 {1'sb0}};
+ always @(*) pack_result = sv2v_tmp_68181;
+ assign sext_result = {32 {1'sb0}};
+ wire [32:1] sv2v_tmp_D756E;
+ assign sv2v_tmp_D756E = {32 {1'sb0}};
+ always @(*) singlebit_result = sv2v_tmp_D756E;
+ wire [32:1] sv2v_tmp_BAAB3;
+ assign sv2v_tmp_BAAB3 = {32 {1'sb0}};
+ always @(*) rev_result = sv2v_tmp_BAAB3;
+ wire [32:1] sv2v_tmp_8C42B;
+ assign sv2v_tmp_8C42B = {32 {1'sb0}};
+ always @(*) shuffle_result = sv2v_tmp_8C42B;
+ wire [32:1] sv2v_tmp_B0AD4;
+ assign sv2v_tmp_B0AD4 = {32 {1'sb0}};
+ always @(*) butterfly_result = sv2v_tmp_B0AD4;
+ wire [32:1] sv2v_tmp_AFC2C;
+ assign sv2v_tmp_AFC2C = {32 {1'sb0}};
+ always @(*) invbutterfly_result = sv2v_tmp_AFC2C;
+ wire [32:1] sv2v_tmp_3A741;
+ assign sv2v_tmp_3A741 = {32 {1'sb0}};
+ always @(*) clmul_result = sv2v_tmp_3A741;
+ wire [32:1] sv2v_tmp_172E8;
+ assign sv2v_tmp_172E8 = {32 {1'sb0}};
+ always @(*) multicycle_result = sv2v_tmp_172E8;
+ wire [64:1] sv2v_tmp_CAB3F;
+ assign sv2v_tmp_CAB3F = {2 {32'b00000000000000000000000000000000}};
+ always @(*) imd_val_d_o = sv2v_tmp_CAB3F;
+ wire [2:1] sv2v_tmp_B65CC;
+ assign sv2v_tmp_B65CC = {2 {1'b0}};
+ always @(*) imd_val_we_o = sv2v_tmp_B65CC;
+ end
+ endgenerate
+ localparam [5:0] brq_pkg_ALU_ADD = 0;
+ localparam [5:0] brq_pkg_ALU_CLMUL = 50;
+ localparam [5:0] brq_pkg_ALU_GREV = 15;
+ localparam [5:0] brq_pkg_ALU_PACK = 29;
+ localparam [5:0] brq_pkg_ALU_PCNT = 36;
+ localparam [5:0] brq_pkg_ALU_SBEXT = 46;
+ localparam [5:0] brq_pkg_ALU_SEXTH = 33;
+ localparam [5:0] brq_pkg_ALU_SHFL = 17;
+ localparam [5:0] brq_pkg_ALU_SRL = 9;
+ localparam [5:0] brq_pkg_ALU_XOR = 2;
+ always @(*) begin
+ result_o = {32 {1'sb0}};
+ case (operator_i)
+ brq_pkg_ALU_XOR, brq_pkg_ALU_XNOR, brq_pkg_ALU_OR, brq_pkg_ALU_ORN, brq_pkg_ALU_AND, brq_pkg_ALU_ANDN: result_o = bwlogic_result;
+ brq_pkg_ALU_ADD, brq_pkg_ALU_SUB: result_o = adder_result;
+ brq_pkg_ALU_SLL, brq_pkg_ALU_SRL, brq_pkg_ALU_SRA, brq_pkg_ALU_SLO, brq_pkg_ALU_SRO: result_o = shift_result;
+ brq_pkg_ALU_SHFL, brq_pkg_ALU_UNSHFL: result_o = shuffle_result;
+ brq_pkg_ALU_EQ, brq_pkg_ALU_NE, brq_pkg_ALU_GE, brq_pkg_ALU_GEU, brq_pkg_ALU_LT, brq_pkg_ALU_LTU, brq_pkg_ALU_SLT, brq_pkg_ALU_SLTU: result_o = {31'h00000000, cmp_result};
+ brq_pkg_ALU_MIN, brq_pkg_ALU_MAX, brq_pkg_ALU_MINU, brq_pkg_ALU_MAXU: result_o = minmax_result;
+ brq_pkg_ALU_CLZ, brq_pkg_ALU_CTZ, brq_pkg_ALU_PCNT: result_o = {26'h0000000, bitcnt_result};
+ brq_pkg_ALU_PACK, brq_pkg_ALU_PACKH, brq_pkg_ALU_PACKU: result_o = pack_result;
+ brq_pkg_ALU_SEXTB, brq_pkg_ALU_SEXTH: result_o = sext_result;
+ brq_pkg_ALU_CMIX, brq_pkg_ALU_CMOV, brq_pkg_ALU_FSL, brq_pkg_ALU_FSR, brq_pkg_ALU_ROL, brq_pkg_ALU_ROR, brq_pkg_ALU_CRC32_W, brq_pkg_ALU_CRC32C_W, brq_pkg_ALU_CRC32_H, brq_pkg_ALU_CRC32C_H, brq_pkg_ALU_CRC32_B, brq_pkg_ALU_CRC32C_B, brq_pkg_ALU_BEXT, brq_pkg_ALU_BDEP: result_o = multicycle_result;
+ brq_pkg_ALU_SBSET, brq_pkg_ALU_SBCLR, brq_pkg_ALU_SBINV, brq_pkg_ALU_SBEXT: result_o = singlebit_result;
+ brq_pkg_ALU_GREV, brq_pkg_ALU_GORC: result_o = rev_result;
+ brq_pkg_ALU_BFP: result_o = bfp_result;
+ brq_pkg_ALU_CLMUL, brq_pkg_ALU_CLMULR, brq_pkg_ALU_CLMULH: result_o = clmul_result;
+ default:
+ ;
+ endcase
+ end
+ wire unused_shift_amt_compl;
+ assign unused_shift_amt_compl = shift_amt_compl[5];
+endmodule
+module brq_exu_multdiv_fast (
+ clk_i,
+ rst_ni,
+ mult_en_i,
+ div_en_i,
+ mult_sel_i,
+ div_sel_i,
+ operator_i,
+ signed_mode_i,
+ op_a_i,
+ op_b_i,
+ alu_adder_ext_i,
+ alu_adder_i,
+ equal_to_zero_i,
+ data_ind_timing_i,
+ alu_operand_a_o,
+ alu_operand_b_o,
+ imd_val_q_i,
+ imd_val_d_o,
+ imd_val_we_o,
+ multdiv_ready_id_i,
+ multdiv_result_o,
+ valid_o
+);
+ localparam integer brq_pkg_RV32MFast = 2;
+ parameter integer RV32M = brq_pkg_RV32MFast;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire mult_en_i;
+ input wire div_en_i;
+ input wire mult_sel_i;
+ input wire div_sel_i;
+ input wire [1:0] operator_i;
+ input wire [1:0] signed_mode_i;
+ input wire [31:0] op_a_i;
+ input wire [31:0] op_b_i;
+ input wire [33:0] alu_adder_ext_i;
+ input wire [31:0] alu_adder_i;
+ input wire equal_to_zero_i;
+ input wire data_ind_timing_i;
+ output reg [32:0] alu_operand_a_o;
+ output reg [32:0] alu_operand_b_o;
+ input wire [67:0] imd_val_q_i;
+ output wire [67:0] imd_val_d_o;
+ output wire [1:0] imd_val_we_o;
+ input wire multdiv_ready_id_i;
+ output wire [31:0] multdiv_result_o;
+ output wire valid_o;
+ wire signed [34:0] mac_res_signed;
+ wire [34:0] mac_res_ext;
+ reg [33:0] accum;
+ reg sign_a;
+ reg sign_b;
+ reg mult_valid;
+ wire signed_mult;
+ reg [33:0] mac_res_d;
+ reg [33:0] op_remainder_d;
+ wire [33:0] mac_res;
+ wire div_sign_a;
+ wire div_sign_b;
+ reg is_greater_equal;
+ wire div_change_sign;
+ wire rem_change_sign;
+ wire [31:0] one_shift;
+ wire [31:0] op_denominator_q;
+ reg [31:0] op_numerator_q;
+ reg [31:0] op_quotient_q;
+ reg [31:0] op_denominator_d;
+ reg [31:0] op_numerator_d;
+ reg [31:0] op_quotient_d;
+ wire [31:0] next_remainder;
+ wire [32:0] next_quotient;
+ wire [31:0] res_adder_h;
+ reg div_valid;
+ reg [4:0] div_counter_q;
+ reg [4:0] div_counter_d;
+ wire multdiv_en;
+ reg mult_hold;
+ reg div_hold;
+ reg div_by_zero_d;
+ reg div_by_zero_q;
+ wire mult_en_internal;
+ wire div_en_internal;
+ reg [2:0] md_state_q;
+ reg [2:0] md_state_d;
+ wire unused_mult_sel_i;
+ assign unused_mult_sel_i = mult_sel_i;
+ assign mult_en_internal = mult_en_i & ~mult_hold;
+ assign div_en_internal = div_en_i & ~div_hold;
+ localparam [2:0] MD_IDLE = 0;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ div_counter_q <= {5 {1'sb0}};
+ md_state_q <= MD_IDLE;
+ op_numerator_q <= {32 {1'sb0}};
+ op_quotient_q <= {32 {1'sb0}};
+ div_by_zero_q <= 1'b0;
+ end
+ else if (div_en_internal) begin
+ div_counter_q <= div_counter_d;
+ op_numerator_q <= op_numerator_d;
+ op_quotient_q <= op_quotient_d;
+ md_state_q <= md_state_d;
+ div_by_zero_q <= div_by_zero_d;
+ end
+ assign multdiv_en = mult_en_internal | div_en_internal;
+ assign imd_val_d_o[34+:34] = (div_sel_i ? op_remainder_d : mac_res_d);
+ assign imd_val_we_o[0] = multdiv_en;
+ assign imd_val_d_o[0+:34] = {2'b00, op_denominator_d};
+ assign imd_val_we_o[1] = div_en_internal;
+ assign op_denominator_q = imd_val_q_i[31-:32];
+ wire [1:0] unused_imd_val;
+ assign unused_imd_val = imd_val_q_i[33-:2];
+ wire unused_mac_res_ext;
+ assign unused_mac_res_ext = mac_res_ext[34];
+ assign signed_mult = signed_mode_i != 2'b00;
+ assign multdiv_result_o = (div_sel_i ? imd_val_q_i[65-:32] : mac_res_d[31:0]);
+ localparam [1:0] AHBH = 3;
+ localparam [1:0] AHBL = 2;
+ localparam [1:0] ALBH = 1;
+ localparam [1:0] ALBL = 0;
+ localparam [0:0] MULH = 1;
+ localparam [0:0] MULL = 0;
+ localparam [1:0] brq_pkg_MD_OP_MULL = 0;
+ localparam integer brq_pkg_RV32MSingleCycle = 3;
+ generate
+ if (RV32M == brq_pkg_RV32MSingleCycle) begin : gen_mult_single_cycle
+ reg mult_state_q;
+ reg mult_state_d;
+ wire signed [33:0] mult1_res;
+ wire signed [33:0] mult2_res;
+ wire signed [33:0] mult3_res;
+ wire [33:0] mult1_res_uns;
+ wire [33:32] unused_mult1_res_uns;
+ wire [15:0] mult1_op_a;
+ wire [15:0] mult1_op_b;
+ wire [15:0] mult2_op_a;
+ wire [15:0] mult2_op_b;
+ reg [15:0] mult3_op_a;
+ reg [15:0] mult3_op_b;
+ wire mult1_sign_a;
+ wire mult1_sign_b;
+ wire mult2_sign_a;
+ wire mult2_sign_b;
+ reg mult3_sign_a;
+ reg mult3_sign_b;
+ reg [33:0] summand1;
+ reg [33:0] summand2;
+ reg [33:0] summand3;
+ assign mult1_res = $signed({mult1_sign_a, mult1_op_a}) * $signed({mult1_sign_b, mult1_op_b});
+ assign mult2_res = $signed({mult2_sign_a, mult2_op_a}) * $signed({mult2_sign_b, mult2_op_b});
+ assign mult3_res = $signed({mult3_sign_a, mult3_op_a}) * $signed({mult3_sign_b, mult3_op_b});
+ assign mac_res_signed = ($signed(summand1) + $signed(summand2)) + $signed(summand3);
+ assign mult1_res_uns = $unsigned(mult1_res);
+ assign mac_res_ext = $unsigned(mac_res_signed);
+ assign mac_res = mac_res_ext[33:0];
+ wire [1:1] sv2v_tmp_1E8D3;
+ assign sv2v_tmp_1E8D3 = signed_mode_i[0] & op_a_i[31];
+ always @(*) sign_a = sv2v_tmp_1E8D3;
+ wire [1:1] sv2v_tmp_3B65C;
+ assign sv2v_tmp_3B65C = signed_mode_i[1] & op_b_i[31];
+ always @(*) sign_b = sv2v_tmp_3B65C;
+ assign mult1_sign_a = 1'b0;
+ assign mult1_sign_b = 1'b0;
+ assign mult1_op_a = op_a_i[15:0];
+ assign mult1_op_b = op_b_i[15:0];
+ assign mult2_sign_a = 1'b0;
+ assign mult2_sign_b = sign_b;
+ assign mult2_op_a = op_a_i[15:0];
+ assign mult2_op_b = op_b_i[31:16];
+ wire [18:1] sv2v_tmp_4D45D;
+ assign sv2v_tmp_4D45D = imd_val_q_i[67-:18];
+ always @(*) accum[17:0] = sv2v_tmp_4D45D;
+ wire [16:1] sv2v_tmp_D5F47;
+ assign sv2v_tmp_D5F47 = {16 {signed_mult & imd_val_q_i[67]}};
+ always @(*) accum[33:18] = sv2v_tmp_D5F47;
+ always @(*) begin
+ mult3_sign_a = sign_a;
+ mult3_sign_b = 1'b0;
+ mult3_op_a = op_a_i[31:16];
+ mult3_op_b = op_b_i[15:0];
+ summand1 = {18'h00000, mult1_res_uns[31:16]};
+ summand2 = $unsigned(mult2_res);
+ summand3 = $unsigned(mult3_res);
+ mac_res_d = {2'b00, mac_res[15:0], mult1_res_uns[15:0]};
+ mult_valid = mult_en_i;
+ mult_state_d = MULL;
+ mult_hold = 1'b0;
+ case (mult_state_q)
+ MULL:
+ if (operator_i != brq_pkg_MD_OP_MULL) begin
+ mac_res_d = mac_res;
+ mult_valid = 1'b0;
+ mult_state_d = MULH;
+ end
+ else
+ mult_hold = ~multdiv_ready_id_i;
+ MULH: begin
+ mult3_sign_a = sign_a;
+ mult3_sign_b = sign_b;
+ mult3_op_a = op_a_i[31:16];
+ mult3_op_b = op_b_i[31:16];
+ mac_res_d = mac_res;
+ summand1 = {34 {1'sb0}};
+ summand2 = accum;
+ summand3 = mult3_res;
+ mult_state_d = MULL;
+ mult_valid = 1'b1;
+ mult_hold = ~multdiv_ready_id_i;
+ end
+ default: mult_state_d = MULL;
+ endcase
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ mult_state_q <= MULL;
+ else if (mult_en_internal)
+ mult_state_q <= mult_state_d;
+ assign unused_mult1_res_uns = mult1_res_uns[33:32];
+ end
+ else begin : gen_mult_fast
+ reg [15:0] mult_op_a;
+ reg [15:0] mult_op_b;
+ reg [1:0] mult_state_q;
+ reg [1:0] mult_state_d;
+ assign mac_res_signed = ($signed({sign_a, mult_op_a}) * $signed({sign_b, mult_op_b})) + $signed(accum);
+ assign mac_res_ext = $unsigned(mac_res_signed);
+ assign mac_res = mac_res_ext[33:0];
+ always @(*) begin
+ mult_op_a = op_a_i[15:0];
+ mult_op_b = op_b_i[15:0];
+ sign_a = 1'b0;
+ sign_b = 1'b0;
+ accum = imd_val_q_i[34+:34];
+ mac_res_d = mac_res;
+ mult_state_d = mult_state_q;
+ mult_valid = 1'b0;
+ mult_hold = 1'b0;
+ case (mult_state_q)
+ ALBL: begin
+ mult_op_a = op_a_i[15:0];
+ mult_op_b = op_b_i[15:0];
+ sign_a = 1'b0;
+ sign_b = 1'b0;
+ accum = {34 {1'sb0}};
+ mac_res_d = mac_res;
+ mult_state_d = ALBH;
+ end
+ ALBH: begin
+ mult_op_a = op_a_i[15:0];
+ mult_op_b = op_b_i[31:16];
+ sign_a = 1'b0;
+ sign_b = signed_mode_i[1] & op_b_i[31];
+ accum = {18'b000000000000000000, imd_val_q_i[65-:16]};
+ if (operator_i == brq_pkg_MD_OP_MULL)
+ mac_res_d = {2'b00, mac_res[15:0], imd_val_q_i[49-:16]};
+ else
+ mac_res_d = mac_res;
+ mult_state_d = AHBL;
+ end
+ AHBL: begin
+ mult_op_a = op_a_i[31:16];
+ mult_op_b = op_b_i[15:0];
+ sign_a = signed_mode_i[0] & op_a_i[31];
+ sign_b = 1'b0;
+ if (operator_i == brq_pkg_MD_OP_MULL) begin
+ accum = {18'b000000000000000000, imd_val_q_i[65-:16]};
+ mac_res_d = {2'b00, mac_res[15:0], imd_val_q_i[49-:16]};
+ mult_valid = 1'b1;
+ mult_state_d = ALBL;
+ mult_hold = ~multdiv_ready_id_i;
+ end
+ else begin
+ accum = imd_val_q_i[34+:34];
+ mac_res_d = mac_res;
+ mult_state_d = AHBH;
+ end
+ end
+ AHBH: begin
+ mult_op_a = op_a_i[31:16];
+ mult_op_b = op_b_i[31:16];
+ sign_a = signed_mode_i[0] & op_a_i[31];
+ sign_b = signed_mode_i[1] & op_b_i[31];
+ accum[17:0] = imd_val_q_i[67-:18];
+ accum[33:18] = {16 {signed_mult & imd_val_q_i[67]}};
+ mac_res_d = mac_res;
+ mult_valid = 1'b1;
+ mult_state_d = ALBL;
+ mult_hold = ~multdiv_ready_id_i;
+ end
+ default: mult_state_d = ALBL;
+ endcase
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ mult_state_q <= ALBL;
+ else if (mult_en_internal)
+ mult_state_q <= mult_state_d;
+ end
+ endgenerate
+ assign res_adder_h = alu_adder_ext_i[32:1];
+ wire [1:0] unused_alu_adder_ext;
+ assign unused_alu_adder_ext = {alu_adder_ext_i[33], alu_adder_ext_i[0]};
+ assign next_remainder = (is_greater_equal ? res_adder_h[31:0] : imd_val_q_i[65-:32]);
+ assign next_quotient = (is_greater_equal ? {1'b0, op_quotient_q} | {1'b0, one_shift} : {1'b0, op_quotient_q});
+ assign one_shift = 32'b00000000000000000000000000000001 << div_counter_q;
+ always @(*)
+ if ((imd_val_q_i[65] ^ op_denominator_q[31]) == 1'b0)
+ is_greater_equal = res_adder_h[31] == 1'b0;
+ else
+ is_greater_equal = imd_val_q_i[65];
+ assign div_sign_a = op_a_i[31] & signed_mode_i[0];
+ assign div_sign_b = op_b_i[31] & signed_mode_i[1];
+ assign div_change_sign = (div_sign_a ^ div_sign_b) & ~div_by_zero_q;
+ assign rem_change_sign = div_sign_a;
+ localparam [2:0] MD_ABS_A = 1;
+ localparam [2:0] MD_ABS_B = 2;
+ localparam [2:0] MD_CHANGE_SIGN = 5;
+ localparam [2:0] MD_COMP = 3;
+ localparam [2:0] MD_FINISH = 6;
+ localparam [2:0] MD_LAST = 4;
+ localparam [1:0] brq_pkg_MD_OP_DIV = 2;
+ always @(*) begin
+ div_counter_d = div_counter_q - 5'h01;
+ op_remainder_d = imd_val_q_i[34+:34];
+ op_quotient_d = op_quotient_q;
+ md_state_d = md_state_q;
+ op_numerator_d = op_numerator_q;
+ op_denominator_d = op_denominator_q;
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~op_b_i, 1'b1};
+ div_valid = 1'b0;
+ div_hold = 1'b0;
+ div_by_zero_d = div_by_zero_q;
+ case (md_state_q)
+ MD_IDLE: begin
+ if (operator_i == brq_pkg_MD_OP_DIV) begin
+ op_remainder_d = {34 {1'sb1}};
+ md_state_d = (!data_ind_timing_i && equal_to_zero_i ? MD_FINISH : MD_ABS_A);
+ div_by_zero_d = equal_to_zero_i;
+ end
+ else begin
+ op_remainder_d = {2'b00, op_a_i};
+ md_state_d = (!data_ind_timing_i && equal_to_zero_i ? MD_FINISH : MD_ABS_A);
+ end
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~op_b_i, 1'b1};
+ div_counter_d = 5'd31;
+ end
+ MD_ABS_A: begin
+ op_quotient_d = {32 {1'sb0}};
+ op_numerator_d = (div_sign_a ? alu_adder_i : op_a_i);
+ md_state_d = MD_ABS_B;
+ div_counter_d = 5'd31;
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~op_a_i, 1'b1};
+ end
+ MD_ABS_B: begin
+ op_remainder_d = {33'h000000000, op_numerator_q[31]};
+ op_denominator_d = (div_sign_b ? alu_adder_i : op_b_i);
+ md_state_d = MD_COMP;
+ div_counter_d = 5'd31;
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~op_b_i, 1'b1};
+ end
+ MD_COMP: begin
+ op_remainder_d = {1'b0, next_remainder[31:0], op_numerator_q[div_counter_d]};
+ op_quotient_d = next_quotient[31:0];
+ md_state_d = (div_counter_q == 5'd1 ? MD_LAST : MD_COMP);
+ alu_operand_a_o = {imd_val_q_i[65-:32], 1'b1};
+ alu_operand_b_o = {~op_denominator_q[31:0], 1'b1};
+ end
+ MD_LAST: begin
+ if (operator_i == brq_pkg_MD_OP_DIV)
+ op_remainder_d = {1'b0, next_quotient};
+ else
+ op_remainder_d = {2'b00, next_remainder[31:0]};
+ alu_operand_a_o = {imd_val_q_i[65-:32], 1'b1};
+ alu_operand_b_o = {~op_denominator_q[31:0], 1'b1};
+ md_state_d = MD_CHANGE_SIGN;
+ end
+ MD_CHANGE_SIGN: begin
+ md_state_d = MD_FINISH;
+ if (operator_i == brq_pkg_MD_OP_DIV)
+ op_remainder_d = (div_change_sign ? {2'h0, alu_adder_i} : imd_val_q_i[34+:34]);
+ else
+ op_remainder_d = (rem_change_sign ? {2'h0, alu_adder_i} : imd_val_q_i[34+:34]);
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~imd_val_q_i[65-:32], 1'b1};
+ end
+ MD_FINISH: begin
+ md_state_d = MD_IDLE;
+ div_hold = ~multdiv_ready_id_i;
+ div_valid = 1'b1;
+ end
+ default: md_state_d = MD_IDLE;
+ endcase
+ end
+ assign valid_o = mult_valid | div_valid;
+endmodule
+module brq_exu_multdiv_slow (
+ clk_i,
+ rst_ni,
+ mult_en_i,
+ div_en_i,
+ mult_sel_i,
+ div_sel_i,
+ operator_i,
+ signed_mode_i,
+ op_a_i,
+ op_b_i,
+ alu_adder_ext_i,
+ alu_adder_i,
+ equal_to_zero_i,
+ data_ind_timing_i,
+ alu_operand_a_o,
+ alu_operand_b_o,
+ imd_val_q_i,
+ imd_val_d_o,
+ imd_val_we_o,
+ multdiv_ready_id_i,
+ multdiv_result_o,
+ valid_o
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire mult_en_i;
+ input wire div_en_i;
+ input wire mult_sel_i;
+ input wire div_sel_i;
+ input wire [1:0] operator_i;
+ input wire [1:0] signed_mode_i;
+ input wire [31:0] op_a_i;
+ input wire [31:0] op_b_i;
+ input wire [33:0] alu_adder_ext_i;
+ input wire [31:0] alu_adder_i;
+ input wire equal_to_zero_i;
+ input wire data_ind_timing_i;
+ output reg [32:0] alu_operand_a_o;
+ output reg [32:0] alu_operand_b_o;
+ input wire [67:0] imd_val_q_i;
+ output wire [67:0] imd_val_d_o;
+ output wire [1:0] imd_val_we_o;
+ input wire multdiv_ready_id_i;
+ output wire [31:0] multdiv_result_o;
+ output wire valid_o;
+ reg [2:0] md_state_q;
+ reg [2:0] md_state_d;
+ wire [32:0] accum_window_q;
+ reg [32:0] accum_window_d;
+ wire unused_imd_val0;
+ wire [1:0] unused_imd_val1;
+ wire [32:0] res_adder_l;
+ wire [32:0] res_adder_h;
+ reg [4:0] multdiv_count_q;
+ reg [4:0] multdiv_count_d;
+ reg [32:0] op_b_shift_q;
+ reg [32:0] op_b_shift_d;
+ reg [32:0] op_a_shift_q;
+ reg [32:0] op_a_shift_d;
+ wire [32:0] op_a_ext;
+ wire [32:0] op_b_ext;
+ wire [32:0] one_shift;
+ wire [32:0] op_a_bw_pp;
+ wire [32:0] op_a_bw_last_pp;
+ wire [31:0] b_0;
+ wire sign_a;
+ wire sign_b;
+ wire [32:0] next_quotient;
+ wire [31:0] next_remainder;
+ wire [31:0] op_numerator_q;
+ reg [31:0] op_numerator_d;
+ wire is_greater_equal;
+ wire div_change_sign;
+ wire rem_change_sign;
+ reg div_by_zero_d;
+ reg div_by_zero_q;
+ reg multdiv_hold;
+ wire multdiv_en;
+ assign res_adder_l = alu_adder_ext_i[32:0];
+ assign res_adder_h = alu_adder_ext_i[33:1];
+ assign imd_val_d_o[34+:34] = {1'b0, accum_window_d};
+ assign imd_val_we_o[0] = ~multdiv_hold;
+ assign accum_window_q = imd_val_q_i[66-:33];
+ assign unused_imd_val0 = imd_val_q_i[67];
+ assign imd_val_d_o[0+:34] = {2'b00, op_numerator_d};
+ assign imd_val_we_o[1] = multdiv_en;
+ assign op_numerator_q = imd_val_q_i[31-:32];
+ assign unused_imd_val1 = imd_val_q_i[33-:2];
+ localparam [2:0] MD_ABS_A = 1;
+ localparam [2:0] MD_ABS_B = 2;
+ localparam [2:0] MD_CHANGE_SIGN = 5;
+ localparam [2:0] MD_IDLE = 0;
+ localparam [2:0] MD_LAST = 4;
+ localparam [1:0] brq_pkg_MD_OP_DIV = 2;
+ localparam [1:0] brq_pkg_MD_OP_MULH = 1;
+ localparam [1:0] brq_pkg_MD_OP_MULL = 0;
+ localparam [1:0] brq_pkg_MD_OP_REM = 3;
+ always @(*) begin
+ alu_operand_a_o = accum_window_q;
+ case (operator_i)
+ brq_pkg_MD_OP_MULL: alu_operand_b_o = op_a_bw_pp;
+ brq_pkg_MD_OP_MULH: alu_operand_b_o = (md_state_q == MD_LAST ? op_a_bw_last_pp : op_a_bw_pp);
+ brq_pkg_MD_OP_DIV, brq_pkg_MD_OP_REM:
+ case (md_state_q)
+ MD_IDLE: begin
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~op_b_i, 1'b1};
+ end
+ MD_ABS_A: begin
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~op_a_i, 1'b1};
+ end
+ MD_ABS_B: begin
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~op_b_i, 1'b1};
+ end
+ MD_CHANGE_SIGN: begin
+ alu_operand_a_o = 33'b000000000000000000000000000000001;
+ alu_operand_b_o = {~accum_window_q[31:0], 1'b1};
+ end
+ default: begin
+ alu_operand_a_o = {accum_window_q[31:0], 1'b1};
+ alu_operand_b_o = {~op_b_shift_q[31:0], 1'b1};
+ end
+ endcase
+ endcase
+ end
+ assign b_0 = {32 {op_b_shift_q[0]}};
+ assign op_a_bw_pp = {~(op_a_shift_q[32] & op_b_shift_q[0]), op_a_shift_q[31:0] & b_0};
+ assign op_a_bw_last_pp = {op_a_shift_q[32] & op_b_shift_q[0], ~(op_a_shift_q[31:0] & b_0)};
+ assign sign_a = op_a_i[31] & signed_mode_i[0];
+ assign sign_b = op_b_i[31] & signed_mode_i[1];
+ assign op_a_ext = {sign_a, op_a_i};
+ assign op_b_ext = {sign_b, op_b_i};
+ assign is_greater_equal = (accum_window_q[31] == op_b_shift_q[31] ? ~res_adder_h[31] : accum_window_q[31]);
+ assign one_shift = 33'b000000000000000000000000000000001 << multdiv_count_q;
+ assign next_remainder = (is_greater_equal ? res_adder_h[31:0] : accum_window_q[31:0]);
+ assign next_quotient = (is_greater_equal ? op_a_shift_q | one_shift : op_a_shift_q);
+ assign div_change_sign = (sign_a ^ sign_b) & ~div_by_zero_q;
+ assign rem_change_sign = sign_a;
+ localparam [2:0] MD_COMP = 3;
+ localparam [2:0] MD_FINISH = 6;
+ always @(*) begin
+ multdiv_count_d = multdiv_count_q;
+ accum_window_d = accum_window_q;
+ op_b_shift_d = op_b_shift_q;
+ op_a_shift_d = op_a_shift_q;
+ op_numerator_d = op_numerator_q;
+ md_state_d = md_state_q;
+ multdiv_hold = 1'b0;
+ div_by_zero_d = div_by_zero_q;
+ if (mult_sel_i || div_sel_i)
+ case (md_state_q)
+ MD_IDLE: begin
+ case (operator_i)
+ brq_pkg_MD_OP_MULL: begin
+ op_a_shift_d = op_a_ext << 1;
+ accum_window_d = {~(op_a_ext[32] & op_b_i[0]), op_a_ext[31:0] & {32 {op_b_i[0]}}};
+ op_b_shift_d = op_b_ext >> 1;
+ md_state_d = (!data_ind_timing_i && ((op_b_ext >> 1) == 0) ? MD_LAST : MD_COMP);
+ end
+ brq_pkg_MD_OP_MULH: begin
+ op_a_shift_d = op_a_ext;
+ accum_window_d = {1'b1, ~(op_a_ext[32] & op_b_i[0]), op_a_ext[31:1] & {31 {op_b_i[0]}}};
+ op_b_shift_d = op_b_ext >> 1;
+ md_state_d = MD_COMP;
+ end
+ brq_pkg_MD_OP_DIV: begin
+ accum_window_d = {33 {1'b1}};
+ md_state_d = (!data_ind_timing_i && equal_to_zero_i ? MD_FINISH : MD_ABS_A);
+ div_by_zero_d = equal_to_zero_i;
+ end
+ brq_pkg_MD_OP_REM: begin
+ accum_window_d = op_a_ext;
+ md_state_d = (!data_ind_timing_i && equal_to_zero_i ? MD_FINISH : MD_ABS_A);
+ end
+ endcase
+ multdiv_count_d = 5'd31;
+ end
+ MD_ABS_A: begin
+ op_a_shift_d = {33 {1'sb0}};
+ op_numerator_d = (sign_a ? alu_adder_i : op_a_i);
+ md_state_d = MD_ABS_B;
+ end
+ MD_ABS_B: begin
+ accum_window_d = {32'h00000000, op_numerator_q[31]};
+ op_b_shift_d = (sign_b ? {1'b0, alu_adder_i} : {1'b0, op_b_i});
+ md_state_d = MD_COMP;
+ end
+ MD_COMP: begin
+ multdiv_count_d = multdiv_count_q - 5'h01;
+ case (operator_i)
+ brq_pkg_MD_OP_MULL: begin
+ accum_window_d = res_adder_l;
+ op_a_shift_d = op_a_shift_q << 1;
+ op_b_shift_d = op_b_shift_q >> 1;
+ md_state_d = ((!data_ind_timing_i && (op_b_shift_d == 0)) || (multdiv_count_q == 5'd1) ? MD_LAST : MD_COMP);
+ end
+ brq_pkg_MD_OP_MULH: begin
+ accum_window_d = res_adder_h;
+ op_a_shift_d = op_a_shift_q;
+ op_b_shift_d = op_b_shift_q >> 1;
+ md_state_d = (multdiv_count_q == 5'd1 ? MD_LAST : MD_COMP);
+ end
+ brq_pkg_MD_OP_DIV, brq_pkg_MD_OP_REM: begin
+ accum_window_d = {next_remainder[31:0], op_numerator_q[multdiv_count_d]};
+ op_a_shift_d = next_quotient;
+ md_state_d = (multdiv_count_q == 5'd1 ? MD_LAST : MD_COMP);
+ end
+ endcase
+ end
+ MD_LAST:
+ case (operator_i)
+ brq_pkg_MD_OP_MULL: begin
+ accum_window_d = res_adder_l;
+ md_state_d = MD_IDLE;
+ multdiv_hold = ~multdiv_ready_id_i;
+ end
+ brq_pkg_MD_OP_MULH: begin
+ accum_window_d = res_adder_l;
+ md_state_d = MD_IDLE;
+ md_state_d = MD_IDLE;
+ multdiv_hold = ~multdiv_ready_id_i;
+ end
+ brq_pkg_MD_OP_DIV: begin
+ accum_window_d = next_quotient;
+ md_state_d = MD_CHANGE_SIGN;
+ end
+ brq_pkg_MD_OP_REM: begin
+ accum_window_d = {1'b0, next_remainder[31:0]};
+ md_state_d = MD_CHANGE_SIGN;
+ end
+ endcase
+ MD_CHANGE_SIGN: begin
+ md_state_d = MD_FINISH;
+ case (operator_i)
+ brq_pkg_MD_OP_DIV: accum_window_d = (div_change_sign ? {1'b0, alu_adder_i} : accum_window_q);
+ brq_pkg_MD_OP_REM: accum_window_d = (rem_change_sign ? {1'b0, alu_adder_i} : accum_window_q);
+ default:
+ ;
+ endcase
+ end
+ MD_FINISH: begin
+ md_state_d = MD_IDLE;
+ multdiv_hold = ~multdiv_ready_id_i;
+ end
+ default: md_state_d = MD_IDLE;
+ endcase
+ end
+ assign multdiv_en = (mult_en_i | div_en_i) & ~multdiv_hold;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ multdiv_count_q <= 5'h00;
+ op_b_shift_q <= 33'h000000000;
+ op_a_shift_q <= 33'h000000000;
+ md_state_q <= MD_IDLE;
+ div_by_zero_q <= 1'b0;
+ end
+ else if (multdiv_en) begin
+ multdiv_count_q <= multdiv_count_d;
+ op_b_shift_q <= op_b_shift_d;
+ op_a_shift_q <= op_a_shift_d;
+ md_state_q <= md_state_d;
+ div_by_zero_q <= div_by_zero_d;
+ end
+ assign valid_o = (md_state_q == MD_FINISH) | ((md_state_q == MD_LAST) & ((operator_i == brq_pkg_MD_OP_MULL) | (operator_i == brq_pkg_MD_OP_MULH)));
+ assign multdiv_result_o = (div_en_i ? accum_window_q[31:0] : res_adder_l[31:0]);
+endmodule
+module brq_exu (
+ clk_i,
+ rst_ni,
+ alu_operator_i,
+ alu_operand_a_i,
+ alu_operand_b_i,
+ alu_instr_first_cycle_i,
+ bt_a_operand_i,
+ bt_b_operand_i,
+ multdiv_operator_i,
+ mult_en_i,
+ div_en_i,
+ mult_sel_i,
+ div_sel_i,
+ multdiv_signed_mode_i,
+ multdiv_operand_a_i,
+ multdiv_operand_b_i,
+ multdiv_ready_id_i,
+ data_ind_timing_i,
+ imd_val_we_o,
+ imd_val_d_o,
+ imd_val_q_i,
+ alu_adder_result_ex_o,
+ result_ex_o,
+ branch_target_o,
+ branch_decision_o,
+ ex_valid_o
+);
+ localparam integer brq_pkg_RV32MFast = 2;
+ parameter integer RV32M = brq_pkg_RV32MFast;
+ localparam integer brq_pkg_RV32BNone = 0;
+ parameter integer RV32B = brq_pkg_RV32BNone;
+ parameter [0:0] BranchTargetALU = 0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [5:0] alu_operator_i;
+ input wire [31:0] alu_operand_a_i;
+ input wire [31:0] alu_operand_b_i;
+ input wire alu_instr_first_cycle_i;
+ input wire [31:0] bt_a_operand_i;
+ input wire [31:0] bt_b_operand_i;
+ input wire [1:0] multdiv_operator_i;
+ input wire mult_en_i;
+ input wire div_en_i;
+ input wire mult_sel_i;
+ input wire div_sel_i;
+ input wire [1:0] multdiv_signed_mode_i;
+ input wire [31:0] multdiv_operand_a_i;
+ input wire [31:0] multdiv_operand_b_i;
+ input wire multdiv_ready_id_i;
+ input wire data_ind_timing_i;
+ output wire [1:0] imd_val_we_o;
+ output wire [67:0] imd_val_d_o;
+ input wire [67:0] imd_val_q_i;
+ output wire [31:0] alu_adder_result_ex_o;
+ output wire [31:0] result_ex_o;
+ output wire [31:0] branch_target_o;
+ output wire branch_decision_o;
+ output wire ex_valid_o;
+ wire [31:0] alu_result;
+ wire [31:0] multdiv_result;
+ wire [32:0] multdiv_alu_operand_b;
+ wire [32:0] multdiv_alu_operand_a;
+ wire [33:0] alu_adder_result_ext;
+ wire alu_cmp_result;
+ wire alu_is_equal_result;
+ wire multdiv_valid;
+ wire multdiv_sel;
+ wire [63:0] alu_imd_val_q;
+ wire [63:0] alu_imd_val_d;
+ wire [1:0] alu_imd_val_we;
+ wire [67:0] multdiv_imd_val_d;
+ wire [1:0] multdiv_imd_val_we;
+ localparam integer brq_pkg_RV32MNone = 0;
+ generate
+ if (RV32M != brq_pkg_RV32MNone) begin : gen_multdiv_m
+ assign multdiv_sel = mult_sel_i | div_sel_i;
+ end
+ else begin : gen_multdiv_no_m
+ assign multdiv_sel = 1'b0;
+ end
+ endgenerate
+ assign imd_val_d_o[34+:34] = (multdiv_sel ? multdiv_imd_val_d[34+:34] : {2'b00, alu_imd_val_d[32+:32]});
+ assign imd_val_d_o[0+:34] = (multdiv_sel ? multdiv_imd_val_d[0+:34] : {2'b00, alu_imd_val_d[0+:32]});
+ assign imd_val_we_o = (multdiv_sel ? multdiv_imd_val_we : alu_imd_val_we);
+ assign alu_imd_val_q = {imd_val_q_i[65-:32], imd_val_q_i[31-:32]};
+ assign result_ex_o = (multdiv_sel ? multdiv_result : alu_result);
+ assign branch_decision_o = alu_cmp_result;
+ generate
+ if (BranchTargetALU) begin : g_branch_target_alu
+ wire [32:0] bt_alu_result;
+ wire unused_bt_carry;
+ assign bt_alu_result = bt_a_operand_i + bt_b_operand_i;
+ assign unused_bt_carry = bt_alu_result[32];
+ assign branch_target_o = bt_alu_result[31:0];
+ end
+ else begin : g_no_branch_target_alu
+ wire [31:0] unused_bt_a_operand;
+ wire [31:0] unused_bt_b_operand;
+ assign unused_bt_a_operand = bt_a_operand_i;
+ assign unused_bt_b_operand = bt_b_operand_i;
+ assign branch_target_o = alu_adder_result_ex_o;
+ end
+ endgenerate
+ brq_exu_alu #(.RV32B(RV32B)) alu_i(
+ .operator_i(alu_operator_i),
+ .operand_a_i(alu_operand_a_i),
+ .operand_b_i(alu_operand_b_i),
+ .instr_first_cycle_i(alu_instr_first_cycle_i),
+ .imd_val_q_i(alu_imd_val_q),
+ .imd_val_we_o(alu_imd_val_we),
+ .imd_val_d_o(alu_imd_val_d),
+ .multdiv_operand_a_i(multdiv_alu_operand_a),
+ .multdiv_operand_b_i(multdiv_alu_operand_b),
+ .multdiv_sel_i(multdiv_sel),
+ .adder_result_o(alu_adder_result_ex_o),
+ .adder_result_ext_o(alu_adder_result_ext),
+ .result_o(alu_result),
+ .comparison_result_o(alu_cmp_result),
+ .is_equal_result_o(alu_is_equal_result)
+ );
+ localparam integer brq_pkg_RV32MSingleCycle = 3;
+ localparam integer brq_pkg_RV32MSlow = 1;
+ generate
+ if (RV32M == brq_pkg_RV32MSlow) begin : gen_multdiv_slow
+ brq_exu_multdiv_slow multdiv_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .mult_en_i(mult_en_i),
+ .div_en_i(div_en_i),
+ .mult_sel_i(mult_sel_i),
+ .div_sel_i(div_sel_i),
+ .operator_i(multdiv_operator_i),
+ .signed_mode_i(multdiv_signed_mode_i),
+ .op_a_i(multdiv_operand_a_i),
+ .op_b_i(multdiv_operand_b_i),
+ .alu_adder_ext_i(alu_adder_result_ext),
+ .alu_adder_i(alu_adder_result_ex_o),
+ .equal_to_zero_i(alu_is_equal_result),
+ .data_ind_timing_i(data_ind_timing_i),
+ .valid_o(multdiv_valid),
+ .alu_operand_a_o(multdiv_alu_operand_a),
+ .alu_operand_b_o(multdiv_alu_operand_b),
+ .imd_val_q_i(imd_val_q_i),
+ .imd_val_d_o(multdiv_imd_val_d),
+ .imd_val_we_o(multdiv_imd_val_we),
+ .multdiv_ready_id_i(multdiv_ready_id_i),
+ .multdiv_result_o(multdiv_result)
+ );
+ end
+ else if ((RV32M == brq_pkg_RV32MFast) || (RV32M == brq_pkg_RV32MSingleCycle)) begin : gen_multdiv_fast
+ brq_exu_multdiv_fast #(.RV32M(RV32M)) multdiv_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .mult_en_i(mult_en_i),
+ .div_en_i(div_en_i),
+ .mult_sel_i(mult_sel_i),
+ .div_sel_i(div_sel_i),
+ .operator_i(multdiv_operator_i),
+ .signed_mode_i(multdiv_signed_mode_i),
+ .op_a_i(multdiv_operand_a_i),
+ .op_b_i(multdiv_operand_b_i),
+ .alu_operand_a_o(multdiv_alu_operand_a),
+ .alu_operand_b_o(multdiv_alu_operand_b),
+ .alu_adder_ext_i(alu_adder_result_ext),
+ .alu_adder_i(alu_adder_result_ex_o),
+ .equal_to_zero_i(alu_is_equal_result),
+ .data_ind_timing_i(data_ind_timing_i),
+ .imd_val_q_i(imd_val_q_i),
+ .imd_val_d_o(multdiv_imd_val_d),
+ .imd_val_we_o(multdiv_imd_val_we),
+ .multdiv_ready_id_i(multdiv_ready_id_i),
+ .valid_o(multdiv_valid),
+ .multdiv_result_o(multdiv_result)
+ );
+ end
+ endgenerate
+ assign ex_valid_o = (multdiv_sel ? multdiv_valid : ~(|alu_imd_val_we));
+endmodule
+module brq_fp_register_file_ff (
+ clk_i,
+ rst_ni,
+ raddr_a_i,
+ rdata_a_o,
+ raddr_b_i,
+ rdata_b_o,
+ raddr_c_i,
+ rdata_c_o,
+ waddr_a_i,
+ wdata_a_i,
+ we_a_i
+);
+ localparam integer brq_pkg_RV32FSingle = 1;
+ parameter integer RVF = brq_pkg_RV32FSingle;
+ parameter [31:0] DataWidth = 32;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [4:0] raddr_a_i;
+ output wire [DataWidth - 1:0] rdata_a_o;
+ input wire [4:0] raddr_b_i;
+ output wire [DataWidth - 1:0] rdata_b_o;
+ input wire [4:0] raddr_c_i;
+ output wire [DataWidth - 1:0] rdata_c_o;
+ input wire [4:0] waddr_a_i;
+ input wire [DataWidth - 1:0] wdata_a_i;
+ input wire we_a_i;
+ localparam integer brq_pkg_RV64FDouble = 2;
+ localparam [31:0] ADDR_WIDTH = (RVF == brq_pkg_RV64FDouble ? 6 : 5);
+ localparam [31:0] NUM_WORDS = (RVF == brq_pkg_RV64FDouble ? 64 : 32);
+ wire [(NUM_WORDS * DataWidth) - 1:0] rf_reg;
+ reg [(NUM_WORDS * DataWidth) - 1:0] rf_reg_q;
+ reg [NUM_WORDS - 1:0] we_a_dec;
+ function automatic [4:0] sv2v_cast_5;
+ input reg [4:0] inp;
+ sv2v_cast_5 = inp;
+ endfunction
+ always @(*) begin : we_a_decoder
+ begin : sv2v_autoblock_97
+ reg [31:0] i;
+ for (i = 0; i < NUM_WORDS; i = i + 1)
+ we_a_dec[i] = (waddr_a_i == sv2v_cast_5(i) ? we_a_i : 1'b0);
+ end
+ end
+ generate
+ genvar i;
+ for (i = 0; i < NUM_WORDS; i = i + 1) begin : g_rf_flops
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ rf_reg_q[i * DataWidth+:DataWidth] <= {DataWidth {1'sb0}};
+ else if (we_a_dec[i])
+ rf_reg_q[i * DataWidth+:DataWidth] <= wdata_a_i;
+ end
+ endgenerate
+ assign rf_reg[DataWidth * ((NUM_WORDS - 1) - (NUM_WORDS - 1))+:DataWidth * NUM_WORDS] = rf_reg_q[DataWidth * ((NUM_WORDS - 1) - (NUM_WORDS - 1))+:DataWidth * NUM_WORDS];
+ assign rdata_a_o = rf_reg[raddr_a_i * DataWidth+:DataWidth];
+ assign rdata_b_o = rf_reg[raddr_b_i * DataWidth+:DataWidth];
+ assign rdata_c_o = rf_reg[raddr_c_i * DataWidth+:DataWidth];
+endmodule
+module brq_idu_controller (
+ clk_i,
+ rst_ni,
+ ctrl_busy_o,
+ illegal_insn_i,
+ ecall_insn_i,
+ mret_insn_i,
+ dret_insn_i,
+ wfi_insn_i,
+ ebrk_insn_i,
+ csr_pipe_flush_i,
+ instr_valid_i,
+ instr_i,
+ instr_compressed_i,
+ instr_is_compressed_i,
+ instr_fetch_err_i,
+ instr_fetch_err_plus2_i,
+ pc_id_i,
+ instr_valid_clear_o,
+ id_in_ready_o,
+ controller_run_o,
+ instr_req_o,
+ pc_set_o,
+ pc_set_spec_o,
+ pc_mux_o,
+ exc_pc_mux_o,
+ exc_cause_o,
+ lsu_addr_last_i,
+ load_err_i,
+ store_err_i,
+ wb_exception_o,
+ branch_set_i,
+ branch_set_spec_i,
+ jump_set_i,
+ csr_mstatus_mie_i,
+ irq_pending_i,
+ irqs_i,
+ irq_nm_i,
+ nmi_mode_o,
+ debug_req_i,
+ debug_cause_o,
+ debug_csr_save_o,
+ debug_mode_o,
+ debug_single_step_i,
+ debug_ebreakm_i,
+ debug_ebreaku_i,
+ trigger_match_i,
+ csr_save_if_o,
+ csr_save_id_o,
+ csr_save_wb_o,
+ csr_restore_mret_id_o,
+ csr_restore_dret_id_o,
+ csr_save_cause_o,
+ csr_mtval_o,
+ priv_mode_i,
+ csr_mstatus_tw_i,
+ stall_id_i,
+ stall_wb_i,
+ flush_id_o,
+ ready_wb_i,
+ perf_jump_o,
+ perf_tbranch_o
+);
+ parameter [0:0] WritebackStage = 0;
+ parameter [0:0] BranchPredictor = 0;
+ input wire clk_i;
+ input wire rst_ni;
+ output reg ctrl_busy_o;
+ input wire illegal_insn_i;
+ input wire ecall_insn_i;
+ input wire mret_insn_i;
+ input wire dret_insn_i;
+ input wire wfi_insn_i;
+ input wire ebrk_insn_i;
+ input wire csr_pipe_flush_i;
+ input wire instr_valid_i;
+ input wire [31:0] instr_i;
+ input wire [15:0] instr_compressed_i;
+ input wire instr_is_compressed_i;
+ input wire instr_fetch_err_i;
+ input wire instr_fetch_err_plus2_i;
+ input wire [31:0] pc_id_i;
+ output wire instr_valid_clear_o;
+ output wire id_in_ready_o;
+ output reg controller_run_o;
+ output reg instr_req_o;
+ output reg pc_set_o;
+ output reg pc_set_spec_o;
+ output reg [2:0] pc_mux_o;
+ output reg [1:0] exc_pc_mux_o;
+ output reg [5:0] exc_cause_o;
+ input wire [31:0] lsu_addr_last_i;
+ input wire load_err_i;
+ input wire store_err_i;
+ output wire wb_exception_o;
+ input wire branch_set_i;
+ input wire branch_set_spec_i;
+ input wire jump_set_i;
+ input wire csr_mstatus_mie_i;
+ input wire irq_pending_i;
+ input wire [17:0] irqs_i;
+ input wire irq_nm_i;
+ output wire nmi_mode_o;
+ input wire debug_req_i;
+ output reg [2:0] debug_cause_o;
+ output reg debug_csr_save_o;
+ output wire debug_mode_o;
+ input wire debug_single_step_i;
+ input wire debug_ebreakm_i;
+ input wire debug_ebreaku_i;
+ input wire trigger_match_i;
+ output reg csr_save_if_o;
+ output reg csr_save_id_o;
+ output reg csr_save_wb_o;
+ output reg csr_restore_mret_id_o;
+ output reg csr_restore_dret_id_o;
+ output reg csr_save_cause_o;
+ output reg [31:0] csr_mtval_o;
+ input wire [1:0] priv_mode_i;
+ input wire csr_mstatus_tw_i;
+ input wire stall_id_i;
+ input wire stall_wb_i;
+ output wire flush_id_o;
+ input wire ready_wb_i;
+ output reg perf_jump_o;
+ output reg perf_tbranch_o;
+ wire instr_bp_taken_i;
+ assign instr_bp_taken_i = 1'b0;
+ reg [3:0] ctrl_fsm_cs;
+ reg [3:0] ctrl_fsm_ns;
+ reg nmi_mode_q;
+ reg nmi_mode_d;
+ reg debug_mode_q;
+ reg debug_mode_d;
+ reg load_err_q;
+ wire load_err_d;
+ reg store_err_q;
+ wire store_err_d;
+ reg exc_req_q;
+ wire exc_req_d;
+ reg illegal_insn_q;
+ wire illegal_insn_d;
+ reg instr_fetch_err_prio;
+ reg illegal_insn_prio;
+ reg ecall_insn_prio;
+ reg ebrk_insn_prio;
+ reg store_err_prio;
+ reg load_err_prio;
+ wire stall;
+ reg halt_if;
+ reg retain_id;
+ reg flush_id;
+ wire illegal_dret;
+ wire illegal_umode;
+ wire exc_req_lsu;
+ wire special_req_all;
+ wire special_req_branch;
+ wire enter_debug_mode;
+ wire ebreak_into_debug;
+ wire handle_irq;
+ reg [3:0] mfip_id;
+ wire unused_irq_timer;
+ wire ecall_insn;
+ wire mret_insn;
+ wire dret_insn;
+ wire wfi_insn;
+ wire ebrk_insn;
+ wire csr_pipe_flush;
+ wire instr_fetch_err;
+ assign load_err_d = load_err_i;
+ assign store_err_d = store_err_i;
+ assign ecall_insn = ecall_insn_i & instr_valid_i;
+ assign mret_insn = mret_insn_i & instr_valid_i;
+ assign dret_insn = dret_insn_i & instr_valid_i;
+ assign wfi_insn = wfi_insn_i & instr_valid_i;
+ assign ebrk_insn = ebrk_insn_i & instr_valid_i;
+ assign csr_pipe_flush = csr_pipe_flush_i & instr_valid_i;
+ assign instr_fetch_err = instr_fetch_err_i & instr_valid_i;
+ assign illegal_dret = dret_insn & ~debug_mode_q;
+ localparam [1:0] brq_pkg_PRIV_LVL_M = 2'b11;
+ assign illegal_umode = (priv_mode_i != brq_pkg_PRIV_LVL_M) & (mret_insn | (csr_mstatus_tw_i & wfi_insn));
+ localparam [3:0] FLUSH = 6;
+ assign illegal_insn_d = ((illegal_insn_i | illegal_dret) | illegal_umode) & (ctrl_fsm_cs != FLUSH);
+ assign exc_req_d = (((ecall_insn | ebrk_insn) | illegal_insn_d) | instr_fetch_err) & (ctrl_fsm_cs != FLUSH);
+ assign exc_req_lsu = store_err_i | load_err_i;
+ assign special_req_all = ((((mret_insn | dret_insn) | wfi_insn) | csr_pipe_flush) | exc_req_d) | exc_req_lsu;
+ assign special_req_branch = instr_fetch_err & (ctrl_fsm_cs != FLUSH);
+ generate
+ if (WritebackStage) begin : g_wb_exceptions
+ always @(*) begin
+ instr_fetch_err_prio = 0;
+ illegal_insn_prio = 0;
+ ecall_insn_prio = 0;
+ ebrk_insn_prio = 0;
+ store_err_prio = 0;
+ load_err_prio = 0;
+ if (store_err_q)
+ store_err_prio = 1'b1;
+ else if (load_err_q)
+ load_err_prio = 1'b1;
+ else if (instr_fetch_err)
+ instr_fetch_err_prio = 1'b1;
+ else if (illegal_insn_q)
+ illegal_insn_prio = 1'b1;
+ else if (ecall_insn)
+ ecall_insn_prio = 1'b1;
+ else if (ebrk_insn)
+ ebrk_insn_prio = 1'b1;
+ end
+ assign wb_exception_o = ((load_err_q | store_err_q) | load_err_i) | store_err_i;
+ end
+ else begin : g_no_wb_exceptions
+ always @(*) begin
+ instr_fetch_err_prio = 0;
+ illegal_insn_prio = 0;
+ ecall_insn_prio = 0;
+ ebrk_insn_prio = 0;
+ store_err_prio = 0;
+ load_err_prio = 0;
+ if (instr_fetch_err)
+ instr_fetch_err_prio = 1'b1;
+ else if (illegal_insn_q)
+ illegal_insn_prio = 1'b1;
+ else if (ecall_insn)
+ ecall_insn_prio = 1'b1;
+ else if (ebrk_insn)
+ ebrk_insn_prio = 1'b1;
+ else if (store_err_q)
+ store_err_prio = 1'b1;
+ else if (load_err_q)
+ load_err_prio = 1'b1;
+ end
+ assign wb_exception_o = 1'b0;
+ end
+ endgenerate
+ assign enter_debug_mode = ((debug_req_i | (debug_single_step_i & instr_valid_i)) | trigger_match_i) & ~debug_mode_q;
+ localparam [1:0] brq_pkg_PRIV_LVL_U = 2'b00;
+ assign ebreak_into_debug = (priv_mode_i == brq_pkg_PRIV_LVL_M ? debug_ebreakm_i : (priv_mode_i == brq_pkg_PRIV_LVL_U ? debug_ebreaku_i : 1'b0));
+ assign handle_irq = (~debug_mode_q & ~nmi_mode_q) & (irq_nm_i | (irq_pending_i & csr_mstatus_mie_i));
+ always @(*) begin : gen_mfip_id
+ if (irqs_i[14])
+ mfip_id = 4'd14;
+ else if (irqs_i[13])
+ mfip_id = 4'd13;
+ else if (irqs_i[12])
+ mfip_id = 4'd12;
+ else if (irqs_i[11])
+ mfip_id = 4'd11;
+ else if (irqs_i[10])
+ mfip_id = 4'd10;
+ else if (irqs_i[9])
+ mfip_id = 4'd9;
+ else if (irqs_i[8])
+ mfip_id = 4'd8;
+ else if (irqs_i[7])
+ mfip_id = 4'd7;
+ else if (irqs_i[6])
+ mfip_id = 4'd6;
+ else if (irqs_i[5])
+ mfip_id = 4'd5;
+ else if (irqs_i[4])
+ mfip_id = 4'd4;
+ else if (irqs_i[3])
+ mfip_id = 4'd3;
+ else if (irqs_i[2])
+ mfip_id = 4'd2;
+ else if (irqs_i[1])
+ mfip_id = 4'd1;
+ else
+ mfip_id = 4'd0;
+ end
+ assign unused_irq_timer = irqs_i[16];
+ localparam [3:0] BOOT_SET = 1;
+ localparam [3:0] DBG_TAKEN_ID = 9;
+ localparam [3:0] DBG_TAKEN_IF = 8;
+ localparam [3:0] DECODE = 5;
+ localparam [3:0] FIRST_FETCH = 4;
+ localparam [3:0] IRQ_TAKEN = 7;
+ localparam [3:0] RESET = 0;
+ localparam [3:0] SLEEP = 3;
+ localparam [3:0] WAIT_SLEEP = 2;
+ localparam [2:0] brq_pkg_DBG_CAUSE_EBREAK = 3'h1;
+ localparam [2:0] brq_pkg_DBG_CAUSE_HALTREQ = 3'h3;
+ localparam [2:0] brq_pkg_DBG_CAUSE_STEP = 3'h4;
+ localparam [2:0] brq_pkg_DBG_CAUSE_TRIGGER = 3'h2;
+ localparam [5:0] brq_pkg_EXC_CAUSE_BREAKPOINT = 6'b000011;
+ localparam [5:0] brq_pkg_EXC_CAUSE_ECALL_MMODE = 6'b001011;
+ localparam [5:0] brq_pkg_EXC_CAUSE_ECALL_UMODE = 6'b001000;
+ localparam [5:0] brq_pkg_EXC_CAUSE_ILLEGAL_INSN = 6'b000010;
+ localparam [5:0] brq_pkg_EXC_CAUSE_INSN_ADDR_MISA = 6'b000000;
+ localparam [5:0] brq_pkg_EXC_CAUSE_INSTR_ACCESS_FAULT = 6'b000001;
+ localparam [5:0] brq_pkg_EXC_CAUSE_IRQ_EXTERNAL_M = 6'b101011;
+ localparam [5:0] brq_pkg_EXC_CAUSE_IRQ_NM = 6'b111111;
+ localparam [5:0] brq_pkg_EXC_CAUSE_IRQ_SOFTWARE_M = 6'b100011;
+ localparam [5:0] brq_pkg_EXC_CAUSE_IRQ_TIMER_M = 6'b100111;
+ localparam [5:0] brq_pkg_EXC_CAUSE_LOAD_ACCESS_FAULT = 6'b000101;
+ localparam [5:0] brq_pkg_EXC_CAUSE_STORE_ACCESS_FAULT = 6'b000111;
+ localparam [1:0] brq_pkg_EXC_PC_DBD = 2;
+ localparam [1:0] brq_pkg_EXC_PC_DBG_EXC = 3;
+ localparam [1:0] brq_pkg_EXC_PC_EXC = 0;
+ localparam [1:0] brq_pkg_EXC_PC_IRQ = 1;
+ localparam [2:0] brq_pkg_PC_BOOT = 0;
+ localparam [2:0] brq_pkg_PC_DRET = 4;
+ localparam [2:0] brq_pkg_PC_ERET = 3;
+ localparam [2:0] brq_pkg_PC_EXC = 2;
+ localparam [2:0] brq_pkg_PC_JUMP = 1;
+ function automatic [5:0] sv2v_cast_6;
+ input reg [5:0] inp;
+ sv2v_cast_6 = inp;
+ endfunction
+ always @(*) begin
+ instr_req_o = 1'b1;
+ csr_save_if_o = 1'b0;
+ csr_save_id_o = 1'b0;
+ csr_save_wb_o = 1'b0;
+ csr_restore_mret_id_o = 1'b0;
+ csr_restore_dret_id_o = 1'b0;
+ csr_save_cause_o = 1'b0;
+ csr_mtval_o = {32 {1'sb0}};
+ pc_mux_o = brq_pkg_PC_BOOT;
+ pc_set_o = 1'b0;
+ pc_set_spec_o = 1'b0;
+ exc_pc_mux_o = brq_pkg_EXC_PC_IRQ;
+ exc_cause_o = brq_pkg_EXC_CAUSE_INSN_ADDR_MISA;
+ ctrl_fsm_ns = ctrl_fsm_cs;
+ ctrl_busy_o = 1'b1;
+ halt_if = 1'b0;
+ retain_id = 1'b0;
+ flush_id = 1'b0;
+ debug_csr_save_o = 1'b0;
+ debug_cause_o = brq_pkg_DBG_CAUSE_EBREAK;
+ debug_mode_d = debug_mode_q;
+ nmi_mode_d = nmi_mode_q;
+ perf_tbranch_o = 1'b0;
+ perf_jump_o = 1'b0;
+ controller_run_o = 1'b0;
+ case (ctrl_fsm_cs)
+ RESET: begin
+ instr_req_o = 1'b0;
+ pc_mux_o = brq_pkg_PC_BOOT;
+ pc_set_o = 1'b1;
+ pc_set_spec_o = 1'b1;
+ ctrl_fsm_ns = BOOT_SET;
+ end
+ BOOT_SET: begin
+ instr_req_o = 1'b1;
+ pc_mux_o = brq_pkg_PC_BOOT;
+ pc_set_o = 1'b1;
+ pc_set_spec_o = 1'b1;
+ ctrl_fsm_ns = FIRST_FETCH;
+ end
+ WAIT_SLEEP: begin
+ ctrl_busy_o = 1'b0;
+ instr_req_o = 1'b0;
+ halt_if = 1'b1;
+ flush_id = 1'b1;
+ ctrl_fsm_ns = SLEEP;
+ end
+ SLEEP: begin
+ instr_req_o = 1'b0;
+ halt_if = 1'b1;
+ flush_id = 1'b1;
+ if ((((irq_nm_i || irq_pending_i) || debug_req_i) || debug_mode_q) || debug_single_step_i)
+ ctrl_fsm_ns = FIRST_FETCH;
+ else
+ ctrl_busy_o = 1'b0;
+ end
+ FIRST_FETCH: begin
+ if (id_in_ready_o)
+ ctrl_fsm_ns = DECODE;
+ if (handle_irq) begin
+ ctrl_fsm_ns = IRQ_TAKEN;
+ halt_if = 1'b1;
+ end
+ if (enter_debug_mode) begin
+ ctrl_fsm_ns = DBG_TAKEN_IF;
+ halt_if = 1'b1;
+ end
+ end
+ DECODE: begin
+ controller_run_o = 1'b1;
+ pc_mux_o = brq_pkg_PC_JUMP;
+ if (special_req_all) begin
+ retain_id = 1'b1;
+ if (ready_wb_i | wb_exception_o)
+ ctrl_fsm_ns = FLUSH;
+ end
+ if (!special_req_branch)
+ if (branch_set_i || jump_set_i) begin
+ pc_set_o = (BranchPredictor ? ~instr_bp_taken_i : 1'b1);
+ perf_tbranch_o = branch_set_i;
+ perf_jump_o = jump_set_i;
+ end
+ if ((branch_set_spec_i || jump_set_i) && !special_req_branch)
+ pc_set_spec_o = 1'b1;
+ if ((enter_debug_mode || handle_irq) && stall)
+ halt_if = 1'b1;
+ if (!stall && !special_req_all)
+ if (enter_debug_mode) begin
+ ctrl_fsm_ns = DBG_TAKEN_IF;
+ halt_if = 1'b1;
+ end
+ else if (handle_irq) begin
+ ctrl_fsm_ns = IRQ_TAKEN;
+ halt_if = 1'b1;
+ end
+ end
+ IRQ_TAKEN: begin
+ pc_mux_o = brq_pkg_PC_EXC;
+ exc_pc_mux_o = brq_pkg_EXC_PC_IRQ;
+ if (handle_irq) begin
+ pc_set_o = 1'b1;
+ pc_set_spec_o = 1'b1;
+ csr_save_if_o = 1'b1;
+ csr_save_cause_o = 1'b1;
+ if (irq_nm_i && !nmi_mode_q) begin
+ exc_cause_o = brq_pkg_EXC_CAUSE_IRQ_NM;
+ nmi_mode_d = 1'b1;
+ end
+ else if (irqs_i[14-:15] != 15'b000000000000000)
+ exc_cause_o = sv2v_cast_6({2'b11, mfip_id});
+ else if (irqs_i[15])
+ exc_cause_o = brq_pkg_EXC_CAUSE_IRQ_EXTERNAL_M;
+ else if (irqs_i[17])
+ exc_cause_o = brq_pkg_EXC_CAUSE_IRQ_SOFTWARE_M;
+ else if (irqs_i[16])
+ exc_cause_o = brq_pkg_EXC_CAUSE_IRQ_TIMER_M;
+ end
+ ctrl_fsm_ns = DECODE;
+ end
+ DBG_TAKEN_IF: begin
+ pc_mux_o = brq_pkg_PC_EXC;
+ exc_pc_mux_o = brq_pkg_EXC_PC_DBD;
+ if ((debug_single_step_i || debug_req_i) || trigger_match_i) begin
+ flush_id = 1'b1;
+ pc_set_o = 1'b1;
+ pc_set_spec_o = 1'b1;
+ csr_save_if_o = 1'b1;
+ debug_csr_save_o = 1'b1;
+ csr_save_cause_o = 1'b1;
+ if (trigger_match_i)
+ debug_cause_o = brq_pkg_DBG_CAUSE_TRIGGER;
+ else if (debug_single_step_i)
+ debug_cause_o = brq_pkg_DBG_CAUSE_STEP;
+ else
+ debug_cause_o = brq_pkg_DBG_CAUSE_HALTREQ;
+ debug_mode_d = 1'b1;
+ end
+ ctrl_fsm_ns = DECODE;
+ end
+ DBG_TAKEN_ID: begin
+ flush_id = 1'b1;
+ pc_mux_o = brq_pkg_PC_EXC;
+ pc_set_o = 1'b1;
+ pc_set_spec_o = 1'b1;
+ exc_pc_mux_o = brq_pkg_EXC_PC_DBD;
+ if (ebreak_into_debug && !debug_mode_q) begin
+ csr_save_cause_o = 1'b1;
+ csr_save_id_o = 1'b1;
+ debug_csr_save_o = 1'b1;
+ debug_cause_o = brq_pkg_DBG_CAUSE_EBREAK;
+ end
+ debug_mode_d = 1'b1;
+ ctrl_fsm_ns = DECODE;
+ end
+ FLUSH: begin
+ halt_if = 1'b1;
+ flush_id = 1'b1;
+ ctrl_fsm_ns = DECODE;
+ if ((exc_req_q || store_err_q) || load_err_q) begin
+ pc_set_o = 1'b1;
+ pc_set_spec_o = 1'b1;
+ pc_mux_o = brq_pkg_PC_EXC;
+ exc_pc_mux_o = (debug_mode_q ? brq_pkg_EXC_PC_DBG_EXC : brq_pkg_EXC_PC_EXC);
+ if (WritebackStage) begin : g_writeback_mepc_save
+ csr_save_id_o = ~(store_err_q | load_err_q);
+ csr_save_wb_o = store_err_q | load_err_q;
+ end
+ else begin : g_no_writeback_mepc_save
+ csr_save_id_o = 1'b0;
+ end
+ csr_save_cause_o = 1'b1;
+ case (1'b1)
+ instr_fetch_err_prio: begin
+ exc_cause_o = brq_pkg_EXC_CAUSE_INSTR_ACCESS_FAULT;
+ csr_mtval_o = (instr_fetch_err_plus2_i ? pc_id_i + 32'd2 : pc_id_i);
+ end
+ illegal_insn_prio: begin
+ exc_cause_o = brq_pkg_EXC_CAUSE_ILLEGAL_INSN;
+ csr_mtval_o = (instr_is_compressed_i ? {16'b0000000000000000, instr_compressed_i} : instr_i);
+ end
+ ecall_insn_prio: exc_cause_o = (priv_mode_i == brq_pkg_PRIV_LVL_M ? brq_pkg_EXC_CAUSE_ECALL_MMODE : brq_pkg_EXC_CAUSE_ECALL_UMODE);
+ ebrk_insn_prio:
+ if (debug_mode_q | ebreak_into_debug) begin
+ pc_set_o = 1'b0;
+ pc_set_spec_o = 1'b0;
+ csr_save_id_o = 1'b0;
+ csr_save_cause_o = 1'b0;
+ ctrl_fsm_ns = DBG_TAKEN_ID;
+ flush_id = 1'b0;
+ end
+ else
+ exc_cause_o = brq_pkg_EXC_CAUSE_BREAKPOINT;
+ store_err_prio: begin
+ exc_cause_o = brq_pkg_EXC_CAUSE_STORE_ACCESS_FAULT;
+ csr_mtval_o = lsu_addr_last_i;
+ end
+ load_err_prio: begin
+ exc_cause_o = brq_pkg_EXC_CAUSE_LOAD_ACCESS_FAULT;
+ csr_mtval_o = lsu_addr_last_i;
+ end
+ default:
+ ;
+ endcase
+ end
+ else if (mret_insn) begin
+ pc_mux_o = brq_pkg_PC_ERET;
+ pc_set_o = 1'b1;
+ pc_set_spec_o = 1'b1;
+ csr_restore_mret_id_o = 1'b1;
+ if (nmi_mode_q)
+ nmi_mode_d = 1'b0;
+ end
+ else if (dret_insn) begin
+ pc_mux_o = brq_pkg_PC_DRET;
+ pc_set_o = 1'b1;
+ pc_set_spec_o = 1'b1;
+ debug_mode_d = 1'b0;
+ csr_restore_dret_id_o = 1'b1;
+ end
+ else if (wfi_insn)
+ ctrl_fsm_ns = WAIT_SLEEP;
+ else if (csr_pipe_flush && handle_irq)
+ ctrl_fsm_ns = IRQ_TAKEN;
+ if (enter_debug_mode && !(ebrk_insn_prio && ebreak_into_debug))
+ ctrl_fsm_ns = DBG_TAKEN_IF;
+ end
+ default: begin
+ instr_req_o = 1'b0;
+ ctrl_fsm_ns = RESET;
+ end
+ endcase
+ end
+ assign flush_id_o = flush_id;
+ assign debug_mode_o = debug_mode_q;
+ assign nmi_mode_o = nmi_mode_q;
+ assign stall = stall_id_i | stall_wb_i;
+ assign id_in_ready_o = (~stall & ~halt_if) & ~retain_id;
+ assign instr_valid_clear_o = ~(stall | retain_id) | flush_id;
+ always @(posedge clk_i or negedge rst_ni) begin : update_regs
+ if (!rst_ni) begin
+ ctrl_fsm_cs <= RESET;
+ nmi_mode_q <= 1'b0;
+ debug_mode_q <= 1'b0;
+ load_err_q <= 1'b0;
+ store_err_q <= 1'b0;
+ exc_req_q <= 1'b0;
+ illegal_insn_q <= 1'b0;
+ end
+ else begin
+ ctrl_fsm_cs <= ctrl_fsm_ns;
+ nmi_mode_q <= nmi_mode_d;
+ debug_mode_q <= debug_mode_d;
+ load_err_q <= load_err_d;
+ store_err_q <= store_err_d;
+ exc_req_q <= exc_req_d;
+ illegal_insn_q <= illegal_insn_d;
+ end
+ end
+endmodule
+module brq_idu_decoder (
+ clk_i,
+ rst_ni,
+ illegal_insn_o,
+ ebrk_insn_o,
+ mret_insn_o,
+ dret_insn_o,
+ ecall_insn_o,
+ wfi_insn_o,
+ jump_set_o,
+ branch_taken_i,
+ icache_inval_o,
+ instr_first_cycle_i,
+ instr_rdata_i,
+ instr_rdata_alu_i,
+ illegal_c_insn_i,
+ imm_a_mux_sel_o,
+ imm_b_mux_sel_o,
+ bt_a_mux_sel_o,
+ bt_b_mux_sel_o,
+ imm_i_type_o,
+ imm_s_type_o,
+ imm_b_type_o,
+ imm_u_type_o,
+ imm_j_type_o,
+ zimm_rs1_type_o,
+ rf_wdata_sel_o,
+ rf_we_o,
+ rf_raddr_a_o,
+ rf_raddr_b_o,
+ rf_waddr_o,
+ rf_ren_a_o,
+ rf_ren_b_o,
+ alu_operator_o,
+ alu_op_a_mux_sel_o,
+ alu_op_b_mux_sel_o,
+ alu_multicycle_o,
+ mult_en_o,
+ div_en_o,
+ mult_sel_o,
+ div_sel_o,
+ multdiv_operator_o,
+ multdiv_signed_mode_o,
+ csr_access_o,
+ csr_op_o,
+ data_req_o,
+ data_we_o,
+ data_type_o,
+ data_sign_extension_o,
+ jump_in_dec_o,
+ branch_in_dec_o,
+ fp_rounding_mode_o,
+ fp_rf_raddr_a_o,
+ fp_rf_raddr_b_o,
+ fp_rf_raddr_c_o,
+ fp_rf_waddr_o,
+ fp_rf_we_o,
+ fp_alu_operator_o,
+ fp_alu_op_mod_o,
+ fp_rm_dynamic_o,
+ fp_src_fmt_o,
+ fp_dst_fmt_o,
+ is_fp_instr_o,
+ use_fp_rs1_o,
+ use_fp_rs2_o,
+ use_fp_rs3_o,
+ use_fp_rd_o,
+ fp_swap_oprnds_o,
+ fp_load_o,
+ mv_instr_o
+);
+ parameter [0:0] RV32E = 0;
+ localparam integer brq_pkg_RV32MFast = 2;
+ parameter integer RV32M = brq_pkg_RV32MFast;
+ localparam integer brq_pkg_RV32BNone = 0;
+ parameter integer RV32B = brq_pkg_RV32BNone;
+ localparam integer brq_pkg_RV64FDouble = 2;
+ parameter integer RVF = brq_pkg_RV64FDouble;
+ parameter [0:0] BranchTargetALU = 0;
+ input wire clk_i;
+ input wire rst_ni;
+ output wire illegal_insn_o;
+ output reg ebrk_insn_o;
+ output reg mret_insn_o;
+ output reg dret_insn_o;
+ output reg ecall_insn_o;
+ output reg wfi_insn_o;
+ output reg jump_set_o;
+ input wire branch_taken_i;
+ output reg icache_inval_o;
+ input wire instr_first_cycle_i;
+ input wire [31:0] instr_rdata_i;
+ input wire [31:0] instr_rdata_alu_i;
+ input wire illegal_c_insn_i;
+ output reg imm_a_mux_sel_o;
+ output reg [2:0] imm_b_mux_sel_o;
+ output reg [1:0] bt_a_mux_sel_o;
+ output reg [2:0] bt_b_mux_sel_o;
+ output wire [31:0] imm_i_type_o;
+ output wire [31:0] imm_s_type_o;
+ output wire [31:0] imm_b_type_o;
+ output wire [31:0] imm_u_type_o;
+ output wire [31:0] imm_j_type_o;
+ output wire [31:0] zimm_rs1_type_o;
+ output reg rf_wdata_sel_o;
+ output wire rf_we_o;
+ output wire [4:0] rf_raddr_a_o;
+ output wire [4:0] rf_raddr_b_o;
+ output wire [4:0] rf_waddr_o;
+ output reg rf_ren_a_o;
+ output reg rf_ren_b_o;
+ output reg [5:0] alu_operator_o;
+ output reg [1:0] alu_op_a_mux_sel_o;
+ output reg alu_op_b_mux_sel_o;
+ output reg alu_multicycle_o;
+ output wire mult_en_o;
+ output wire div_en_o;
+ output reg mult_sel_o;
+ output reg div_sel_o;
+ output reg [1:0] multdiv_operator_o;
+ output reg [1:0] multdiv_signed_mode_o;
+ output reg csr_access_o;
+ output reg [1:0] csr_op_o;
+ output reg data_req_o;
+ output reg data_we_o;
+ output reg [1:0] data_type_o;
+ output reg data_sign_extension_o;
+ output reg jump_in_dec_o;
+ output reg branch_in_dec_o;
+ output wire [2:0] fp_rounding_mode_o;
+ output wire [4:0] fp_rf_raddr_a_o;
+ output wire [4:0] fp_rf_raddr_b_o;
+ output wire [4:0] fp_rf_raddr_c_o;
+ output wire [4:0] fp_rf_waddr_o;
+ output reg fp_rf_we_o;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ output reg [3:0] fp_alu_operator_o;
+ output reg fp_alu_op_mod_o;
+ output wire fp_rm_dynamic_o;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ output reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fp_src_fmt_o;
+ output reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fp_dst_fmt_o;
+ output reg is_fp_instr_o;
+ output reg use_fp_rs1_o;
+ output reg use_fp_rs2_o;
+ output reg use_fp_rs3_o;
+ output reg use_fp_rd_o;
+ output reg fp_swap_oprnds_o;
+ output reg fp_load_o;
+ output reg mv_instr_o;
+ wire fp_invalid_rm;
+ reg illegal_insn;
+ wire illegal_reg_rv32e;
+ reg csr_illegal;
+ reg rf_we;
+ wire [31:0] instr;
+ wire [31:0] instr_alu;
+ wire [4:0] instr_rs1;
+ wire [4:0] instr_rs2;
+ wire [4:0] instr_rs3;
+ wire [4:0] instr_rd;
+ reg use_rs3_d;
+ reg use_rs3_q;
+ reg [1:0] csr_op;
+ reg [6:0] opcode;
+ reg [6:0] opcode_alu;
+ assign instr = instr_rdata_i;
+ assign instr_alu = instr_rdata_alu_i;
+ assign imm_i_type_o = {{20 {instr[31]}}, instr[31:20]};
+ assign imm_s_type_o = {{20 {instr[31]}}, instr[31:25], instr[11:7]};
+ assign imm_b_type_o = {{19 {instr[31]}}, instr[31], instr[7], instr[30:25], instr[11:8], 1'b0};
+ assign imm_u_type_o = {instr[31:12], 12'b000000000000};
+ assign imm_j_type_o = {{12 {instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0};
+ assign zimm_rs1_type_o = {27'b000000000000000000000000000, instr_rs1};
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ use_rs3_q <= 1'b0;
+ else
+ use_rs3_q <= use_rs3_d;
+ assign instr_rs1 = instr[19:15];
+ assign instr_rs2 = instr[24:20];
+ assign instr_rs3 = instr[31:27];
+ assign rf_raddr_a_o = (use_rs3_q & ~instr_first_cycle_i ? instr_rs3 : instr_rs1);
+ assign rf_raddr_b_o = instr_rs2;
+ assign instr_rd = instr[11:7];
+ assign rf_waddr_o = instr_rd;
+ assign fp_rf_raddr_a_o = instr_rs1;
+ assign fp_rf_raddr_b_o = instr_rs2;
+ assign fp_rf_raddr_c_o = instr_rs3;
+ assign fp_rf_waddr_o = instr_rd;
+ assign fp_rounding_mode_o = instr[14:12];
+ assign fp_invalid_rm = (instr[14:12] == 3'b101 ? 1'b1 : (instr[14:12] == 3'b110 ? 1'b1 : 1'b0));
+ assign fp_rm_dynamic_o = (instr[14:12] == 3'b111 ? 1'b1 : 1'b0);
+ localparam [fpnew_pkg_FP_FORMAT_BITS - 1:0] fpnew_pkg_FP32 = 'd0;
+ wire [0:1] sv2v_tmp_24DB7;
+ assign sv2v_tmp_24DB7 = fpnew_pkg_FP32;
+ always @(*) fp_dst_fmt_o = sv2v_tmp_24DB7;
+ localparam [1:0] brq_pkg_OP_A_REG_A = 0;
+ localparam [0:0] brq_pkg_OP_B_REG_B = 0;
+ generate
+ if (RV32E) begin : gen_rv32e_reg_check_active
+ assign illegal_reg_rv32e = ((rf_raddr_a_o[4] & (alu_op_a_mux_sel_o == brq_pkg_OP_A_REG_A)) | (rf_raddr_b_o[4] & (alu_op_b_mux_sel_o == brq_pkg_OP_B_REG_B))) | (rf_waddr_o[4] & rf_we);
+ end
+ else begin : gen_rv32e_reg_check_inactive
+ assign illegal_reg_rv32e = 1'b0;
+ end
+ endgenerate
+ localparam [1:0] brq_pkg_CSR_OP_CLEAR = 3;
+ localparam [1:0] brq_pkg_CSR_OP_READ = 0;
+ localparam [1:0] brq_pkg_CSR_OP_SET = 2;
+ always @(*) begin : csr_operand_check
+ csr_op_o = csr_op;
+ if (((csr_op == brq_pkg_CSR_OP_SET) || (csr_op == brq_pkg_CSR_OP_CLEAR)) && (instr_rs1 == {5 {1'sb0}}))
+ csr_op_o = brq_pkg_CSR_OP_READ;
+ end
+ localparam [1:0] brq_pkg_CSR_OP_WRITE = 1;
+ localparam [1:0] brq_pkg_MD_OP_DIV = 2;
+ localparam [1:0] brq_pkg_MD_OP_MULH = 1;
+ localparam [1:0] brq_pkg_MD_OP_MULL = 0;
+ localparam [1:0] brq_pkg_MD_OP_REM = 3;
+ localparam [6:0] brq_pkg_OPCODE_AUIPC = 7'h17;
+ localparam [6:0] brq_pkg_OPCODE_BRANCH = 7'h63;
+ localparam [6:0] brq_pkg_OPCODE_JAL = 7'h6f;
+ localparam [6:0] brq_pkg_OPCODE_JALR = 7'h67;
+ localparam [6:0] brq_pkg_OPCODE_LOAD = 7'h03;
+ localparam [6:0] brq_pkg_OPCODE_LOAD_FP = 7'h07;
+ localparam [6:0] brq_pkg_OPCODE_LUI = 7'h37;
+ localparam [6:0] brq_pkg_OPCODE_MADD_FP = 7'h43;
+ localparam [6:0] brq_pkg_OPCODE_MISC_MEM = 7'h0f;
+ localparam [6:0] brq_pkg_OPCODE_MSUB_FP = 7'h47;
+ localparam [6:0] brq_pkg_OPCODE_NMADD_FP = 7'h4f;
+ localparam [6:0] brq_pkg_OPCODE_NMSUB_FP = 7'h4b;
+ localparam [6:0] brq_pkg_OPCODE_OP = 7'h33;
+ localparam [6:0] brq_pkg_OPCODE_OP_FP = 7'h53;
+ localparam [6:0] brq_pkg_OPCODE_OP_IMM = 7'h13;
+ localparam [6:0] brq_pkg_OPCODE_STORE = 7'h23;
+ localparam [6:0] brq_pkg_OPCODE_STORE_FP = 7'h27;
+ localparam [6:0] brq_pkg_OPCODE_SYSTEM = 7'h73;
+ localparam [0:0] brq_pkg_RF_WD_CSR = 1;
+ localparam [0:0] brq_pkg_RF_WD_EX = 0;
+ localparam integer brq_pkg_RV32BBalanced = 1;
+ localparam integer brq_pkg_RV32BFull = 2;
+ localparam integer brq_pkg_RV32FNone = 0;
+ localparam integer brq_pkg_RV32MNone = 0;
+ always @(*) begin
+ jump_in_dec_o = 1'b0;
+ jump_set_o = 1'b0;
+ branch_in_dec_o = 1'b0;
+ icache_inval_o = 1'b0;
+ multdiv_operator_o = brq_pkg_MD_OP_MULL;
+ multdiv_signed_mode_o = 2'b00;
+ rf_wdata_sel_o = brq_pkg_RF_WD_EX;
+ rf_we = 1'b0;
+ rf_ren_a_o = 1'b0;
+ rf_ren_b_o = 1'b0;
+ csr_access_o = 1'b0;
+ csr_illegal = 1'b0;
+ csr_op = brq_pkg_CSR_OP_READ;
+ data_we_o = 1'b0;
+ data_type_o = 2'b00;
+ data_sign_extension_o = 1'b0;
+ data_req_o = 1'b0;
+ illegal_insn = 1'b0;
+ ebrk_insn_o = 1'b0;
+ mret_insn_o = 1'b0;
+ dret_insn_o = 1'b0;
+ ecall_insn_o = 1'b0;
+ wfi_insn_o = 1'b0;
+ fp_rf_we_o = 1'b0;
+ is_fp_instr_o = 1'b0;
+ use_fp_rs1_o = 1'b0;
+ use_fp_rs2_o = 1'b0;
+ use_fp_rs3_o = 1'b0;
+ use_fp_rd_o = 1'b0;
+ fp_load_o = 1'b0;
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ fp_dst_fmt_o = fpnew_pkg_FP32;
+ fp_swap_oprnds_o = 1'b0;
+ mv_instr_o = 1'b0;
+ opcode = instr[6:0];
+ case (opcode)
+ brq_pkg_OPCODE_JAL: begin
+ jump_in_dec_o = 1'b1;
+ if (instr_first_cycle_i) begin
+ rf_we = BranchTargetALU;
+ jump_set_o = 1'b1;
+ end
+ else
+ rf_we = 1'b1;
+ end
+ brq_pkg_OPCODE_JALR: begin
+ jump_in_dec_o = 1'b1;
+ if (instr_first_cycle_i) begin
+ rf_we = BranchTargetALU;
+ jump_set_o = 1'b1;
+ end
+ else
+ rf_we = 1'b1;
+ if (instr[14:12] != 3'b000)
+ illegal_insn = 1'b1;
+ rf_ren_a_o = 1'b1;
+ end
+ brq_pkg_OPCODE_BRANCH: begin
+ branch_in_dec_o = 1'b1;
+ case (instr[14:12])
+ 3'b000, 3'b001, 3'b100, 3'b101, 3'b110, 3'b111: illegal_insn = 1'b0;
+ default: illegal_insn = 1'b1;
+ endcase
+ rf_ren_a_o = 1'b1;
+ rf_ren_b_o = 1'b1;
+ end
+ brq_pkg_OPCODE_STORE: begin
+ rf_ren_a_o = 1'b1;
+ rf_ren_b_o = 1'b1;
+ data_req_o = 1'b1;
+ data_we_o = 1'b1;
+ if (instr[14])
+ illegal_insn = 1'b1;
+ case (instr[13:12])
+ 2'b00: data_type_o = 2'b10;
+ 2'b01: data_type_o = 2'b01;
+ 2'b10: data_type_o = 2'b00;
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ brq_pkg_OPCODE_LOAD: begin
+ rf_ren_a_o = 1'b1;
+ data_req_o = 1'b1;
+ data_type_o = 2'b00;
+ data_sign_extension_o = ~instr[14];
+ case (instr[13:12])
+ 2'b00: data_type_o = 2'b10;
+ 2'b01: data_type_o = 2'b01;
+ 2'b10: begin
+ data_type_o = 2'b00;
+ if (instr[14])
+ illegal_insn = 1'b1;
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ brq_pkg_OPCODE_LUI: rf_we = 1'b1;
+ brq_pkg_OPCODE_AUIPC: rf_we = 1'b1;
+ brq_pkg_OPCODE_OP_IMM: begin
+ rf_ren_a_o = 1'b1;
+ rf_we = 1'b1;
+ case (instr[14:12])
+ 3'b000, 3'b010, 3'b011, 3'b100, 3'b110, 3'b111: illegal_insn = 1'b0;
+ 3'b001:
+ case (instr[31:27])
+ 5'b00000: illegal_insn = (instr[26:25] == 2'b00 ? 1'b0 : 1'b1);
+ 5'b00100, 5'b01001, 5'b00101, 5'b01101: illegal_insn = (RV32B != brq_pkg_RV32BNone ? 1'b0 : 1'b1);
+ 5'b00001:
+ if (instr[26] == 1'b0)
+ illegal_insn = (RV32B == brq_pkg_RV32BFull ? 1'b0 : 1'b1);
+ else
+ illegal_insn = 1'b1;
+ 5'b01100:
+ case (instr[26:20])
+ 7'b0000000, 7'b0000001, 7'b0000010, 7'b0000100, 7'b0000101: illegal_insn = (RV32B != brq_pkg_RV32BNone ? 1'b0 : 1'b1);
+ 7'b0010000, 7'b0010001, 7'b0010010, 7'b0011000, 7'b0011001, 7'b0011010: illegal_insn = (RV32B == brq_pkg_RV32BFull ? 1'b0 : 1'b1);
+ default: illegal_insn = 1'b1;
+ endcase
+ default: illegal_insn = 1'b1;
+ endcase
+ 3'b101:
+ if (instr[26])
+ illegal_insn = (RV32B != brq_pkg_RV32BNone ? 1'b0 : 1'b1);
+ else
+ case (instr[31:27])
+ 5'b00000, 5'b01000: illegal_insn = (instr[26:25] == 2'b00 ? 1'b0 : 1'b1);
+ 5'b00100, 5'b01100, 5'b01001: illegal_insn = (RV32B != brq_pkg_RV32BNone ? 1'b0 : 1'b1);
+ 5'b01101:
+ if (RV32B == brq_pkg_RV32BFull)
+ illegal_insn = 1'b0;
+ else
+ case (instr[24:20])
+ 5'b11111, 5'b11000: illegal_insn = (RV32B == brq_pkg_RV32BBalanced ? 1'b0 : 1'b1);
+ default: illegal_insn = 1'b1;
+ endcase
+ 5'b00101:
+ if (RV32B == brq_pkg_RV32BFull)
+ illegal_insn = 1'b0;
+ else if (instr[24:20] == 5'b00111)
+ illegal_insn = (RV32B == brq_pkg_RV32BBalanced ? 1'b0 : 1'b1);
+ 5'b00001:
+ if (instr[26] == 1'b0)
+ illegal_insn = (RV32B == brq_pkg_RV32BFull ? 1'b0 : 1'b1);
+ else
+ illegal_insn = 1'b1;
+ default: illegal_insn = 1'b1;
+ endcase
+ endcase
+ end
+ brq_pkg_OPCODE_OP: begin
+ rf_ren_a_o = 1'b1;
+ rf_ren_b_o = 1'b1;
+ rf_we = 1'b1;
+ if ({instr[26], instr[13:12]} == 3'b101)
+ illegal_insn = (RV32B != brq_pkg_RV32BNone ? 1'b0 : 1'b1);
+ else
+ case ({instr[31:25], instr[14:12]})
+ 10'b0000000000, 10'b0100000000, 10'b0000000010, 10'b0000000011, 10'b0000000100, 10'b0000000110, 10'b0000000111, 10'b0000000001, 10'b0000000101, 10'b0100000101: illegal_insn = 1'b0;
+ 10'b0100000111, 10'b0100000110, 10'b0100000100, 10'b0010000001, 10'b0010000101, 10'b0110000001, 10'b0110000101, 10'b0000101100, 10'b0000101101, 10'b0000101110, 10'b0000101111, 10'b0000100100, 10'b0100100100, 10'b0000100111, 10'b0100100001, 10'b0010100001, 10'b0110100001, 10'b0100100101, 10'b0100100111: illegal_insn = (RV32B != brq_pkg_RV32BNone ? 1'b0 : 1'b1);
+ 10'b0100100110, 10'b0000100110, 10'b0110100101, 10'b0010100101, 10'b0000100001, 10'b0000100101, 10'b0000101001, 10'b0000101010, 10'b0000101011: illegal_insn = (RV32B == brq_pkg_RV32BFull ? 1'b0 : 1'b1);
+ 10'b0000001000: begin
+ multdiv_operator_o = brq_pkg_MD_OP_MULL;
+ multdiv_signed_mode_o = 2'b00;
+ illegal_insn = (RV32M == brq_pkg_RV32MNone ? 1'b1 : 1'b0);
+ end
+ 10'b0000001001: begin
+ multdiv_operator_o = brq_pkg_MD_OP_MULH;
+ multdiv_signed_mode_o = 2'b11;
+ illegal_insn = (RV32M == brq_pkg_RV32MNone ? 1'b1 : 1'b0);
+ end
+ 10'b0000001010: begin
+ multdiv_operator_o = brq_pkg_MD_OP_MULH;
+ multdiv_signed_mode_o = 2'b01;
+ illegal_insn = (RV32M == brq_pkg_RV32MNone ? 1'b1 : 1'b0);
+ end
+ 10'b0000001011: begin
+ multdiv_operator_o = brq_pkg_MD_OP_MULH;
+ multdiv_signed_mode_o = 2'b00;
+ illegal_insn = (RV32M == brq_pkg_RV32MNone ? 1'b1 : 1'b0);
+ end
+ 10'b0000001100: begin
+ multdiv_operator_o = brq_pkg_MD_OP_DIV;
+ multdiv_signed_mode_o = 2'b11;
+ illegal_insn = (RV32M == brq_pkg_RV32MNone ? 1'b1 : 1'b0);
+ end
+ 10'b0000001101: begin
+ multdiv_operator_o = brq_pkg_MD_OP_DIV;
+ multdiv_signed_mode_o = 2'b00;
+ illegal_insn = (RV32M == brq_pkg_RV32MNone ? 1'b1 : 1'b0);
+ end
+ 10'b0000001110: begin
+ multdiv_operator_o = brq_pkg_MD_OP_REM;
+ multdiv_signed_mode_o = 2'b11;
+ illegal_insn = (RV32M == brq_pkg_RV32MNone ? 1'b1 : 1'b0);
+ end
+ 10'b0000001111: begin
+ multdiv_operator_o = brq_pkg_MD_OP_REM;
+ multdiv_signed_mode_o = 2'b00;
+ illegal_insn = (RV32M == brq_pkg_RV32MNone ? 1'b1 : 1'b0);
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ brq_pkg_OPCODE_MISC_MEM:
+ case (instr[14:12])
+ 3'b000: rf_we = 1'b0;
+ 3'b001: begin
+ jump_in_dec_o = 1'b1;
+ rf_we = 1'b0;
+ if (instr_first_cycle_i) begin
+ jump_set_o = 1'b1;
+ icache_inval_o = 1'b1;
+ end
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ brq_pkg_OPCODE_SYSTEM:
+ if (instr[14:12] == 3'b000) begin
+ case (instr[31:20])
+ 12'h000: ecall_insn_o = 1'b1;
+ 12'h001: ebrk_insn_o = 1'b1;
+ 12'h302: mret_insn_o = 1'b1;
+ 12'h7b2: dret_insn_o = 1'b1;
+ 12'h105: wfi_insn_o = 1'b1;
+ default: illegal_insn = 1'b1;
+ endcase
+ if ((instr_rs1 != 5'b00000) || (instr_rd != 5'b00000))
+ illegal_insn = 1'b1;
+ end
+ else begin
+ csr_access_o = 1'b1;
+ rf_wdata_sel_o = brq_pkg_RF_WD_CSR;
+ rf_we = 1'b1;
+ if (~instr[14])
+ rf_ren_a_o = 1'b1;
+ case (instr[13:12])
+ 2'b01: csr_op = brq_pkg_CSR_OP_WRITE;
+ 2'b10: csr_op = brq_pkg_CSR_OP_SET;
+ 2'b11: csr_op = brq_pkg_CSR_OP_CLEAR;
+ default: csr_illegal = 1'b1;
+ endcase
+ illegal_insn = csr_illegal;
+ end
+ brq_pkg_OPCODE_STORE_FP: begin
+ data_req_o = 1'b1;
+ data_we_o = 1'b1;
+ data_type_o = 2'b00;
+ use_fp_rs2_o = 1'b1;
+ case (instr[14:12])
+ 3'b011: illegal_insn = (RVF == brq_pkg_RV64FDouble ? 1'b0 : 1'b1);
+ 3'b010: begin
+ illegal_insn = (RVF == brq_pkg_RV32FNone ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ brq_pkg_OPCODE_LOAD_FP: begin
+ data_req_o = 1'b1;
+ data_type_o = 2'b00;
+ fp_load_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ case (instr[14:12])
+ 3'b011: illegal_insn = (RVF == brq_pkg_RV64FDouble ? 1'b0 : 1'b1);
+ 3'b010: begin
+ illegal_insn = (RVF == brq_pkg_RV32FNone ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ brq_pkg_OPCODE_MADD_FP, brq_pkg_OPCODE_MSUB_FP, brq_pkg_OPCODE_NMSUB_FP, brq_pkg_OPCODE_NMADD_FP: begin
+ fp_rf_we_o = 1'b1;
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ is_fp_instr_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rs3_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ case (instr[26:25])
+ 1: illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ 0: begin
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ brq_pkg_OPCODE_OP_FP: begin
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ is_fp_instr_o = 1'b1;
+ case (instr[31:25])
+ 7'b0000001, 7'b0000101: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ fp_swap_oprnds_o = 1'b1;
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b0001001, 7'b0001101: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b0000000, 7'b0000100: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ fp_swap_oprnds_o = 1'b1;
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ 7'b0001000, 7'b0001100: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ 7'b0101101: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~|instr[24:20])
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b0101100: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~|instr[24:20]) begin
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ end
+ 7'b0010001: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~(instr[14] | &instr[13:12])) begin
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ fp_src_fmt_o = FP64;
+ end
+ end
+ 7'b0010000: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~(instr[14] | &instr[13:12])) begin
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ end
+ 7'b0010101: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~|instr[14:13])
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b0010100: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~|instr[14:13]) begin
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ end
+ 7'b0100000: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~(|instr[24:21] | ~instr[20]))
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b1100000: begin
+ rf_we = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ if (~|instr[24:21]) begin
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ end
+ 7'b0100001: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~|instr[24:20])
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b1110000: begin
+ rf_we = 1'b1;
+ case ({instr[24:20], instr[14:12]})
+ 8'b00000000: begin
+ use_fp_rs1_o = 1'b1;
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ mv_instr_o = 1'b1;
+ end
+ 8'b00000001: begin
+ use_fp_rs1_o = 1'b1;
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ 7'b1010001: begin
+ rf_we = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ if (~instr[14] | &instr[13:12])
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b1010000: begin
+ rf_we = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ use_fp_rs2_o = 1'b1;
+ if (~instr[14] | &instr[13:12]) begin
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ end
+ 7'b1110001: begin
+ rf_we = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ case ({instr[24:20], instr[14:12]})
+ 8'b00000001: illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ 7'b1100001: begin
+ rf_we = 1'b1;
+ use_fp_rs1_o = 1'b1;
+ if (~|instr[24:21])
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b1101000: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~|instr[24:21]) begin
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ end
+ 7'b1111001: begin
+ rf_we = 1'b1;
+ use_fp_rd_o = 1'b1;
+ if (~|instr[24:21])
+ illegal_insn = ((RVF == brq_pkg_RV64FDouble) & fp_invalid_rm ? 1'b0 : 1'b1);
+ end
+ 7'b1111000: begin
+ fp_rf_we_o = 1'b1;
+ use_fp_rd_o = 1'b1;
+ mv_instr_o = 1'b1;
+ if (~(|instr[24:20]) | |instr[14:12]) begin
+ illegal_insn = ((RVF == brq_pkg_RV32FNone) & ~fp_invalid_rm ? 1'b1 : 1'b0);
+ fp_src_fmt_o = fpnew_pkg_FP32;
+ end
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ end
+ default: illegal_insn = 1'b1;
+ endcase
+ if (illegal_c_insn_i)
+ illegal_insn = 1'b1;
+ if (illegal_insn) begin
+ rf_we = 1'b0;
+ data_req_o = 1'b0;
+ data_we_o = 1'b0;
+ jump_in_dec_o = 1'b0;
+ jump_set_o = 1'b0;
+ branch_in_dec_o = 1'b0;
+ csr_access_o = 1'b0;
+ fp_rf_we_o = 1'b0;
+ end
+ end
+ localparam [5:0] brq_pkg_ALU_ADD = 0;
+ localparam [5:0] brq_pkg_ALU_AND = 4;
+ localparam [5:0] brq_pkg_ALU_ANDN = 7;
+ localparam [5:0] brq_pkg_ALU_BDEP = 48;
+ localparam [5:0] brq_pkg_ALU_BEXT = 47;
+ localparam [5:0] brq_pkg_ALU_BFP = 49;
+ localparam [5:0] brq_pkg_ALU_CLMUL = 50;
+ localparam [5:0] brq_pkg_ALU_CLMULH = 52;
+ localparam [5:0] brq_pkg_ALU_CLMULR = 51;
+ localparam [5:0] brq_pkg_ALU_CLZ = 34;
+ localparam [5:0] brq_pkg_ALU_CMIX = 40;
+ localparam [5:0] brq_pkg_ALU_CMOV = 39;
+ localparam [5:0] brq_pkg_ALU_CRC32C_B = 54;
+ localparam [5:0] brq_pkg_ALU_CRC32C_H = 56;
+ localparam [5:0] brq_pkg_ALU_CRC32C_W = 58;
+ localparam [5:0] brq_pkg_ALU_CRC32_B = 53;
+ localparam [5:0] brq_pkg_ALU_CRC32_H = 55;
+ localparam [5:0] brq_pkg_ALU_CRC32_W = 57;
+ localparam [5:0] brq_pkg_ALU_CTZ = 35;
+ localparam [5:0] brq_pkg_ALU_EQ = 23;
+ localparam [5:0] brq_pkg_ALU_FSL = 41;
+ localparam [5:0] brq_pkg_ALU_FSR = 42;
+ localparam [5:0] brq_pkg_ALU_GE = 21;
+ localparam [5:0] brq_pkg_ALU_GEU = 22;
+ localparam [5:0] brq_pkg_ALU_GORC = 16;
+ localparam [5:0] brq_pkg_ALU_GREV = 15;
+ localparam [5:0] brq_pkg_ALU_LT = 19;
+ localparam [5:0] brq_pkg_ALU_LTU = 20;
+ localparam [5:0] brq_pkg_ALU_MAX = 27;
+ localparam [5:0] brq_pkg_ALU_MAXU = 28;
+ localparam [5:0] brq_pkg_ALU_MIN = 25;
+ localparam [5:0] brq_pkg_ALU_MINU = 26;
+ localparam [5:0] brq_pkg_ALU_NE = 24;
+ localparam [5:0] brq_pkg_ALU_OR = 3;
+ localparam [5:0] brq_pkg_ALU_ORN = 6;
+ localparam [5:0] brq_pkg_ALU_PACK = 29;
+ localparam [5:0] brq_pkg_ALU_PACKH = 31;
+ localparam [5:0] brq_pkg_ALU_PACKU = 30;
+ localparam [5:0] brq_pkg_ALU_PCNT = 36;
+ localparam [5:0] brq_pkg_ALU_ROL = 14;
+ localparam [5:0] brq_pkg_ALU_ROR = 13;
+ localparam [5:0] brq_pkg_ALU_SBCLR = 44;
+ localparam [5:0] brq_pkg_ALU_SBEXT = 46;
+ localparam [5:0] brq_pkg_ALU_SBINV = 45;
+ localparam [5:0] brq_pkg_ALU_SBSET = 43;
+ localparam [5:0] brq_pkg_ALU_SEXTB = 32;
+ localparam [5:0] brq_pkg_ALU_SEXTH = 33;
+ localparam [5:0] brq_pkg_ALU_SHFL = 17;
+ localparam [5:0] brq_pkg_ALU_SLL = 10;
+ localparam [5:0] brq_pkg_ALU_SLO = 12;
+ localparam [5:0] brq_pkg_ALU_SLT = 37;
+ localparam [5:0] brq_pkg_ALU_SLTU = 38;
+ localparam [5:0] brq_pkg_ALU_SRA = 8;
+ localparam [5:0] brq_pkg_ALU_SRL = 9;
+ localparam [5:0] brq_pkg_ALU_SRO = 11;
+ localparam [5:0] brq_pkg_ALU_SUB = 1;
+ localparam [5:0] brq_pkg_ALU_UNSHFL = 18;
+ localparam [5:0] brq_pkg_ALU_XNOR = 5;
+ localparam [5:0] brq_pkg_ALU_XOR = 2;
+ localparam [0:0] brq_pkg_IMM_A_Z = 0;
+ localparam [0:0] brq_pkg_IMM_A_ZERO = 1;
+ localparam [2:0] brq_pkg_IMM_B_B = 2;
+ localparam [2:0] brq_pkg_IMM_B_I = 0;
+ localparam [2:0] brq_pkg_IMM_B_INCR_PC = 5;
+ localparam [2:0] brq_pkg_IMM_B_J = 4;
+ localparam [2:0] brq_pkg_IMM_B_S = 1;
+ localparam [2:0] brq_pkg_IMM_B_U = 3;
+ localparam [1:0] brq_pkg_OP_A_CURRPC = 2;
+ localparam [1:0] brq_pkg_OP_A_IMM = 3;
+ localparam [0:0] brq_pkg_OP_B_IMM = 1;
+ localparam [3:0] fpnew_pkg_ADD = 2;
+ localparam [3:0] fpnew_pkg_CLASSIFY = 9;
+ localparam [3:0] fpnew_pkg_CMP = 8;
+ localparam [3:0] fpnew_pkg_DIV = 4;
+ localparam [3:0] fpnew_pkg_F2F = 10;
+ localparam [3:0] fpnew_pkg_F2I = 11;
+ localparam [3:0] fpnew_pkg_FMADD = 0;
+ localparam [3:0] fpnew_pkg_FNMSUB = 1;
+ localparam [3:0] fpnew_pkg_I2F = 12;
+ localparam [3:0] fpnew_pkg_MINMAX = 7;
+ localparam [3:0] fpnew_pkg_MUL = 3;
+ localparam [3:0] fpnew_pkg_SGNJ = 6;
+ localparam [3:0] fpnew_pkg_SQRT = 5;
+ always @(*) begin
+ alu_operator_o = brq_pkg_ALU_SLTU;
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_IMM;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_a_mux_sel_o = brq_pkg_IMM_A_ZERO;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_I;
+ bt_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ bt_b_mux_sel_o = brq_pkg_IMM_B_I;
+ opcode_alu = instr_alu[6:0];
+ use_rs3_d = 1'b0;
+ alu_multicycle_o = 1'b0;
+ mult_sel_o = 1'b0;
+ div_sel_o = 1'b0;
+ fp_alu_op_mod_o = 1'b0;
+ fp_alu_operator_o = fpnew_pkg_FMADD;
+ case (opcode_alu)
+ brq_pkg_OPCODE_JAL: begin
+ if (BranchTargetALU) begin
+ bt_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ bt_b_mux_sel_o = brq_pkg_IMM_B_J;
+ end
+ if (instr_first_cycle_i && !BranchTargetALU) begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_J;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ end
+ else begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_INCR_PC;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ end
+ end
+ brq_pkg_OPCODE_JALR: begin
+ if (BranchTargetALU) begin
+ bt_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ bt_b_mux_sel_o = brq_pkg_IMM_B_I;
+ end
+ if (instr_first_cycle_i && !BranchTargetALU) begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_I;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ end
+ else begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_INCR_PC;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ end
+ end
+ brq_pkg_OPCODE_BRANCH: begin
+ case (instr_alu[14:12])
+ 3'b000: alu_operator_o = brq_pkg_ALU_EQ;
+ 3'b001: alu_operator_o = brq_pkg_ALU_NE;
+ 3'b100: alu_operator_o = brq_pkg_ALU_LT;
+ 3'b101: alu_operator_o = brq_pkg_ALU_GE;
+ 3'b110: alu_operator_o = brq_pkg_ALU_LTU;
+ 3'b111: alu_operator_o = brq_pkg_ALU_GEU;
+ default:
+ ;
+ endcase
+ if (BranchTargetALU) begin
+ bt_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ bt_b_mux_sel_o = (branch_taken_i ? brq_pkg_IMM_B_B : brq_pkg_IMM_B_INCR_PC);
+ end
+ if (instr_first_cycle_i) begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_REG_B;
+ end
+ else begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = (branch_taken_i ? brq_pkg_IMM_B_B : brq_pkg_IMM_B_INCR_PC);
+ alu_operator_o = brq_pkg_ALU_ADD;
+ end
+ end
+ brq_pkg_OPCODE_STORE: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_REG_B;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ if (!instr_alu[14]) begin
+ imm_b_mux_sel_o = brq_pkg_IMM_B_S;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ end
+ end
+ brq_pkg_OPCODE_LOAD: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_I;
+ end
+ brq_pkg_OPCODE_LUI: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_IMM;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_a_mux_sel_o = brq_pkg_IMM_A_ZERO;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_U;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ end
+ brq_pkg_OPCODE_AUIPC: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_U;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ end
+ brq_pkg_OPCODE_OP_IMM: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_I;
+ case (instr_alu[14:12])
+ 3'b000: alu_operator_o = brq_pkg_ALU_ADD;
+ 3'b010: alu_operator_o = brq_pkg_ALU_SLT;
+ 3'b011: alu_operator_o = brq_pkg_ALU_SLTU;
+ 3'b100: alu_operator_o = brq_pkg_ALU_XOR;
+ 3'b110: alu_operator_o = brq_pkg_ALU_OR;
+ 3'b111: alu_operator_o = brq_pkg_ALU_AND;
+ 3'b001:
+ if (RV32B != brq_pkg_RV32BNone)
+ case (instr_alu[31:27])
+ 5'b00000: alu_operator_o = brq_pkg_ALU_SLL;
+ 5'b00100: alu_operator_o = brq_pkg_ALU_SLO;
+ 5'b01001: alu_operator_o = brq_pkg_ALU_SBCLR;
+ 5'b00101: alu_operator_o = brq_pkg_ALU_SBSET;
+ 5'b01101: alu_operator_o = brq_pkg_ALU_SBINV;
+ 5'b00001:
+ if (instr_alu[26] == 0)
+ alu_operator_o = brq_pkg_ALU_SHFL;
+ 5'b01100:
+ case (instr_alu[26:20])
+ 7'b0000000: alu_operator_o = brq_pkg_ALU_CLZ;
+ 7'b0000001: alu_operator_o = brq_pkg_ALU_CTZ;
+ 7'b0000010: alu_operator_o = brq_pkg_ALU_PCNT;
+ 7'b0000100: alu_operator_o = brq_pkg_ALU_SEXTB;
+ 7'b0000101: alu_operator_o = brq_pkg_ALU_SEXTH;
+ 7'b0010000:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ alu_operator_o = brq_pkg_ALU_CRC32_B;
+ alu_multicycle_o = 1'b1;
+ end
+ 7'b0010001:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ alu_operator_o = brq_pkg_ALU_CRC32_H;
+ alu_multicycle_o = 1'b1;
+ end
+ 7'b0010010:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ alu_operator_o = brq_pkg_ALU_CRC32_W;
+ alu_multicycle_o = 1'b1;
+ end
+ 7'b0011000:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ alu_operator_o = brq_pkg_ALU_CRC32C_B;
+ alu_multicycle_o = 1'b1;
+ end
+ 7'b0011001:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ alu_operator_o = brq_pkg_ALU_CRC32C_H;
+ alu_multicycle_o = 1'b1;
+ end
+ 7'b0011010:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ alu_operator_o = brq_pkg_ALU_CRC32C_W;
+ alu_multicycle_o = 1'b1;
+ end
+ default:
+ ;
+ endcase
+ default:
+ ;
+ endcase
+ else
+ alu_operator_o = brq_pkg_ALU_SLL;
+ 3'b101:
+ if (RV32B != brq_pkg_RV32BNone) begin
+ if (instr_alu[26] == 1'b1) begin
+ alu_operator_o = brq_pkg_ALU_FSR;
+ alu_multicycle_o = 1'b1;
+ if (instr_first_cycle_i)
+ use_rs3_d = 1'b1;
+ else
+ use_rs3_d = 1'b0;
+ end
+ else
+ case (instr_alu[31:27])
+ 5'b00000: alu_operator_o = brq_pkg_ALU_SRL;
+ 5'b01000: alu_operator_o = brq_pkg_ALU_SRA;
+ 5'b00100: alu_operator_o = brq_pkg_ALU_SRO;
+ 5'b01001: alu_operator_o = brq_pkg_ALU_SBEXT;
+ 5'b01100: begin
+ alu_operator_o = brq_pkg_ALU_ROR;
+ alu_multicycle_o = 1'b1;
+ end
+ 5'b01101: alu_operator_o = brq_pkg_ALU_GREV;
+ 5'b00101: alu_operator_o = brq_pkg_ALU_GORC;
+ 5'b00001:
+ if (RV32B == brq_pkg_RV32BFull)
+ if (instr_alu[26] == 1'b0)
+ alu_operator_o = brq_pkg_ALU_UNSHFL;
+ default:
+ ;
+ endcase
+ end
+ else if (instr_alu[31:27] == 5'b00000)
+ alu_operator_o = brq_pkg_ALU_SRL;
+ else if (instr_alu[31:27] == 5'b01000)
+ alu_operator_o = brq_pkg_ALU_SRA;
+ endcase
+ end
+ brq_pkg_OPCODE_OP: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_REG_B;
+ if (instr_alu[26]) begin
+ if (RV32B != brq_pkg_RV32BNone)
+ case ({instr_alu[26:25], instr_alu[14:12]})
+ 5'b11001: begin
+ alu_operator_o = brq_pkg_ALU_CMIX;
+ alu_multicycle_o = 1'b1;
+ if (instr_first_cycle_i)
+ use_rs3_d = 1'b1;
+ else
+ use_rs3_d = 1'b0;
+ end
+ 5'b11101: begin
+ alu_operator_o = brq_pkg_ALU_CMOV;
+ alu_multicycle_o = 1'b1;
+ if (instr_first_cycle_i)
+ use_rs3_d = 1'b1;
+ else
+ use_rs3_d = 1'b0;
+ end
+ 5'b10001: begin
+ alu_operator_o = brq_pkg_ALU_FSL;
+ alu_multicycle_o = 1'b1;
+ if (instr_first_cycle_i)
+ use_rs3_d = 1'b1;
+ else
+ use_rs3_d = 1'b0;
+ end
+ 5'b10101: begin
+ alu_operator_o = brq_pkg_ALU_FSR;
+ alu_multicycle_o = 1'b1;
+ if (instr_first_cycle_i)
+ use_rs3_d = 1'b1;
+ else
+ use_rs3_d = 1'b0;
+ end
+ default:
+ ;
+ endcase
+ end
+ else
+ case ({instr_alu[31:25], instr_alu[14:12]})
+ 10'b0000000000: alu_operator_o = brq_pkg_ALU_ADD;
+ 10'b0100000000: alu_operator_o = brq_pkg_ALU_SUB;
+ 10'b0000000010: alu_operator_o = brq_pkg_ALU_SLT;
+ 10'b0000000011: alu_operator_o = brq_pkg_ALU_SLTU;
+ 10'b0000000100: alu_operator_o = brq_pkg_ALU_XOR;
+ 10'b0000000110: alu_operator_o = brq_pkg_ALU_OR;
+ 10'b0000000111: alu_operator_o = brq_pkg_ALU_AND;
+ 10'b0000000001: alu_operator_o = brq_pkg_ALU_SLL;
+ 10'b0000000101: alu_operator_o = brq_pkg_ALU_SRL;
+ 10'b0100000101: alu_operator_o = brq_pkg_ALU_SRA;
+ 10'b0010000001:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_SLO;
+ 10'b0010000101:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_SRO;
+ 10'b0110000001:
+ if (RV32B != brq_pkg_RV32BNone) begin
+ alu_operator_o = brq_pkg_ALU_ROL;
+ alu_multicycle_o = 1'b1;
+ end
+ 10'b0110000101:
+ if (RV32B != brq_pkg_RV32BNone) begin
+ alu_operator_o = brq_pkg_ALU_ROR;
+ alu_multicycle_o = 1'b1;
+ end
+ 10'b0000101100:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_MIN;
+ 10'b0000101101:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_MAX;
+ 10'b0000101110:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_MINU;
+ 10'b0000101111:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_MAXU;
+ 10'b0000100100:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_PACK;
+ 10'b0100100100:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_PACKU;
+ 10'b0000100111:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_PACKH;
+ 10'b0100000100:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_XNOR;
+ 10'b0100000110:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_ORN;
+ 10'b0100000111:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_ANDN;
+ 10'b0100100001:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_SBCLR;
+ 10'b0010100001:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_SBSET;
+ 10'b0110100001:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_SBINV;
+ 10'b0100100101:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_SBEXT;
+ 10'b0100100111:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_BFP;
+ 10'b0110100101:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_GREV;
+ 10'b0010100101:
+ if (RV32B != brq_pkg_RV32BNone)
+ alu_operator_o = brq_pkg_ALU_GORC;
+ 10'b0000100001:
+ if (RV32B == brq_pkg_RV32BFull)
+ alu_operator_o = brq_pkg_ALU_SHFL;
+ 10'b0000100101:
+ if (RV32B == brq_pkg_RV32BFull)
+ alu_operator_o = brq_pkg_ALU_UNSHFL;
+ 10'b0000101001:
+ if (RV32B == brq_pkg_RV32BFull)
+ alu_operator_o = brq_pkg_ALU_CLMUL;
+ 10'b0000101010:
+ if (RV32B == brq_pkg_RV32BFull)
+ alu_operator_o = brq_pkg_ALU_CLMULR;
+ 10'b0000101011:
+ if (RV32B == brq_pkg_RV32BFull)
+ alu_operator_o = brq_pkg_ALU_CLMULH;
+ 10'b0100100110:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ alu_operator_o = brq_pkg_ALU_BDEP;
+ alu_multicycle_o = 1'b1;
+ end
+ 10'b0000100110:
+ if (RV32B == brq_pkg_RV32BFull) begin
+ alu_operator_o = brq_pkg_ALU_BEXT;
+ alu_multicycle_o = 1'b1;
+ end
+ 10'b0000001000: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ mult_sel_o = (RV32M == brq_pkg_RV32MNone ? 1'b0 : 1'b1);
+ end
+ 10'b0000001001: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ mult_sel_o = (RV32M == brq_pkg_RV32MNone ? 1'b0 : 1'b1);
+ end
+ 10'b0000001010: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ mult_sel_o = (RV32M == brq_pkg_RV32MNone ? 1'b0 : 1'b1);
+ end
+ 10'b0000001011: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ mult_sel_o = (RV32M == brq_pkg_RV32MNone ? 1'b0 : 1'b1);
+ end
+ 10'b0000001100: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ div_sel_o = (RV32M == brq_pkg_RV32MNone ? 1'b0 : 1'b1);
+ end
+ 10'b0000001101: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ div_sel_o = (RV32M == brq_pkg_RV32MNone ? 1'b0 : 1'b1);
+ end
+ 10'b0000001110: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ div_sel_o = (RV32M == brq_pkg_RV32MNone ? 1'b0 : 1'b1);
+ end
+ 10'b0000001111: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ div_sel_o = (RV32M == brq_pkg_RV32MNone ? 1'b0 : 1'b1);
+ end
+ default:
+ ;
+ endcase
+ end
+ brq_pkg_OPCODE_MISC_MEM:
+ case (instr_alu[14:12])
+ 3'b000: begin
+ alu_operator_o = brq_pkg_ALU_ADD;
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ end
+ 3'b001:
+ if (BranchTargetALU) begin
+ bt_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ bt_b_mux_sel_o = brq_pkg_IMM_B_INCR_PC;
+ end
+ else begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_CURRPC;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_INCR_PC;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ end
+ default:
+ ;
+ endcase
+ brq_pkg_OPCODE_SYSTEM:
+ if (instr_alu[14:12] == 3'b000) begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ end
+ else begin
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_a_mux_sel_o = brq_pkg_IMM_A_Z;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_I;
+ if (instr_alu[14])
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_IMM;
+ else
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ end
+ brq_pkg_OPCODE_STORE_FP: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_REG_B;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ case (instr[14:12])
+ 3'b011: begin
+ imm_b_mux_sel_o = brq_pkg_IMM_B_S;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ end
+ 3'b010: begin
+ imm_b_mux_sel_o = brq_pkg_IMM_B_S;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ end
+ default:
+ ;
+ endcase
+ end
+ brq_pkg_OPCODE_LOAD_FP:
+ case (instr[14:12])
+ 3'b011: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_I;
+ end
+ 3'b010: begin
+ alu_op_a_mux_sel_o = brq_pkg_OP_A_REG_A;
+ alu_operator_o = brq_pkg_ALU_ADD;
+ alu_op_b_mux_sel_o = brq_pkg_OP_B_IMM;
+ imm_b_mux_sel_o = brq_pkg_IMM_B_I;
+ end
+ default:
+ ;
+ endcase
+ brq_pkg_OPCODE_MADD_FP:
+ case (instr[26:25])
+ 1: begin
+ fp_alu_operator_o = fpnew_pkg_FMADD;
+ fp_alu_op_mod_o = 1'b0;
+ end
+ 0: begin
+ fp_alu_operator_o = fpnew_pkg_FMADD;
+ fp_alu_op_mod_o = 1'b0;
+ end
+ default:
+ ;
+ endcase
+ brq_pkg_OPCODE_MSUB_FP:
+ case (instr[26:25])
+ 1: begin
+ fp_alu_operator_o = fpnew_pkg_FMADD;
+ fp_alu_op_mod_o = 1'b1;
+ end
+ 0: begin
+ fp_alu_operator_o = fpnew_pkg_FMADD;
+ fp_alu_op_mod_o = 1'b1;
+ end
+ default:
+ ;
+ endcase
+ brq_pkg_OPCODE_NMSUB_FP:
+ case (instr[26:25])
+ 1: fp_alu_operator_o = fpnew_pkg_FNMSUB;
+ 0: fp_alu_operator_o = fpnew_pkg_FNMSUB;
+ default:
+ ;
+ endcase
+ brq_pkg_OPCODE_NMADD_FP:
+ case (instr[26:25])
+ 1: begin
+ fp_alu_operator_o = fpnew_pkg_FNMSUB;
+ fp_alu_op_mod_o = 1'b1;
+ end
+ 0: begin
+ fp_alu_operator_o = fpnew_pkg_FNMSUB;
+ fp_alu_op_mod_o = 1'b1;
+ end
+ default:
+ ;
+ endcase
+ brq_pkg_OPCODE_OP_FP:
+ case (instr[31:25])
+ 7'b0000001: fp_alu_operator_o = fpnew_pkg_ADD;
+ 7'b0000101: begin
+ fp_alu_operator_o = fpnew_pkg_ADD;
+ fp_alu_op_mod_o = 1'b1;
+ end
+ 7'b0001001: fp_alu_operator_o = fpnew_pkg_MUL;
+ 7'b0001101: fp_alu_operator_o = fpnew_pkg_DIV;
+ 7'b0000000: fp_alu_operator_o = fpnew_pkg_ADD;
+ 7'b0000100: begin
+ fp_alu_operator_o = fpnew_pkg_ADD;
+ fp_alu_op_mod_o = 1'b1;
+ end
+ 7'b0001000: fp_alu_operator_o = fpnew_pkg_MUL;
+ 7'b0001100: fp_alu_operator_o = fpnew_pkg_DIV;
+ 7'b0101101:
+ if (~|instr[24:20])
+ fp_alu_operator_o = fpnew_pkg_SQRT;
+ 7'b0101100:
+ if (~|instr[24:20])
+ fp_alu_operator_o = fpnew_pkg_SQRT;
+ 7'b0010001:
+ if (~(instr[14] | &instr[13:12]))
+ fp_alu_operator_o = fpnew_pkg_SGNJ;
+ 7'b0010000:
+ if (~(instr[14] | &instr[13:12]))
+ fp_alu_operator_o = fpnew_pkg_SGNJ;
+ 7'b0010101:
+ if (~|instr[14:13])
+ fp_alu_operator_o = fpnew_pkg_MINMAX;
+ 7'b0010100:
+ if (~|instr[14:13])
+ fp_alu_operator_o = fpnew_pkg_MINMAX;
+ 7'b0100000:
+ if (~(|instr[24:21] | ~instr[20]))
+ fp_alu_operator_o = fpnew_pkg_F2F;
+ 7'b1100000:
+ if (~|instr[24:21]) begin
+ fp_alu_operator_o = fpnew_pkg_F2I;
+ if (instr[20])
+ fp_alu_op_mod_o = 1'b1;
+ end
+ 7'b0100001:
+ if (~|instr[24:20])
+ fp_alu_operator_o = fpnew_pkg_F2F;
+ 7'b1110000:
+ case ({instr[24:20], instr[14:12]})
+ 6'b000001: fp_alu_operator_o = fpnew_pkg_CLASSIFY;
+ default:
+ ;
+ endcase
+ 7'b1010001:
+ if (~instr[14] | &instr[13:12])
+ fp_alu_operator_o = fpnew_pkg_CMP;
+ 7'b1010000:
+ if (~instr[14] | &instr[13:12])
+ fp_alu_operator_o = fpnew_pkg_CMP;
+ 7'b1110001:
+ case ({instr[24:20], instr[14:12]})
+ 6'b000001: fp_alu_operator_o = fpnew_pkg_CLASSIFY;
+ default:
+ ;
+ endcase
+ 7'b1100001:
+ if (~|instr[24:21]) begin
+ fp_alu_operator_o = fpnew_pkg_F2I;
+ if (instr[20])
+ fp_alu_op_mod_o = 1'b1;
+ end
+ 7'b1101000:
+ if (~(|instr[24:21])) begin
+ fp_alu_operator_o = fpnew_pkg_I2F;
+ if (instr[20])
+ fp_alu_op_mod_o = 1'b1;
+ end
+ 7'b1111001:
+ if (~|instr[24:21]) begin
+ fp_alu_operator_o = fpnew_pkg_I2F;
+ if (instr[20])
+ fp_alu_op_mod_o = 1'b1;
+ end
+ default:
+ ;
+ endcase
+ default:
+ ;
+ endcase
+ end
+ assign mult_en_o = (illegal_insn ? 1'b0 : mult_sel_o);
+ assign div_en_o = (illegal_insn ? 1'b0 : div_sel_o);
+ assign illegal_insn_o = illegal_insn | illegal_reg_rv32e;
+ assign rf_we_o = rf_we & ~illegal_reg_rv32e;
+endmodule
+module brq_idu (
+ clk_i,
+ rst_ni,
+ ctrl_busy_o,
+ illegal_insn_o,
+ instr_valid_i,
+ instr_rdata_i,
+ instr_rdata_alu_i,
+ instr_rdata_c_i,
+ instr_is_compressed_i,
+ instr_req_o,
+ instr_first_cycle_id_o,
+ instr_valid_clear_o,
+ id_in_ready_o,
+ icache_inval_o,
+ branch_decision_i,
+ pc_set_o,
+ pc_set_spec_o,
+ pc_mux_o,
+ exc_pc_mux_o,
+ exc_cause_o,
+ illegal_c_insn_i,
+ instr_fetch_err_i,
+ instr_fetch_err_plus2_i,
+ pc_id_i,
+ ex_valid_i,
+ lsu_resp_valid_i,
+ alu_operator_ex_o,
+ alu_operand_a_ex_o,
+ alu_operand_b_ex_o,
+ imd_val_we_ex_i,
+ imd_val_d_ex_i,
+ imd_val_q_ex_o,
+ bt_a_operand_o,
+ bt_b_operand_o,
+ mult_en_ex_o,
+ div_en_ex_o,
+ mult_sel_ex_o,
+ div_sel_ex_o,
+ multdiv_operator_ex_o,
+ multdiv_signed_mode_ex_o,
+ multdiv_operand_a_ex_o,
+ multdiv_operand_b_ex_o,
+ multdiv_ready_id_o,
+ csr_access_o,
+ csr_op_o,
+ csr_op_en_o,
+ csr_save_if_o,
+ csr_save_id_o,
+ csr_save_wb_o,
+ csr_restore_mret_id_o,
+ csr_restore_dret_id_o,
+ csr_save_cause_o,
+ csr_mtval_o,
+ priv_mode_i,
+ csr_mstatus_tw_i,
+ illegal_csr_insn_i,
+ data_ind_timing_i,
+ lsu_req_o,
+ lsu_we_o,
+ lsu_type_o,
+ lsu_sign_ext_o,
+ lsu_wdata_o,
+ lsu_req_done_i,
+ lsu_addr_incr_req_i,
+ lsu_addr_last_i,
+ csr_mstatus_mie_i,
+ irq_pending_i,
+ irqs_i,
+ irq_nm_i,
+ nmi_mode_o,
+ lsu_load_err_i,
+ lsu_store_err_i,
+ debug_mode_o,
+ debug_cause_o,
+ debug_csr_save_o,
+ debug_req_i,
+ debug_single_step_i,
+ debug_ebreakm_i,
+ debug_ebreaku_i,
+ trigger_match_i,
+ result_ex_i,
+ csr_rdata_i,
+ rf_raddr_a_o,
+ rf_rdata_a_i,
+ rf_raddr_b_o,
+ rf_rdata_b_i,
+ rf_ren_a_o,
+ rf_ren_b_o,
+ rf_waddr_id_o,
+ rf_wdata_id_o,
+ rf_we_id_o,
+ rf_rd_a_wb_match_o,
+ rf_rd_b_wb_match_o,
+ rf_waddr_wb_i,
+ rf_wdata_fwd_wb_i,
+ rf_write_wb_i,
+ en_wb_o,
+ instr_type_wb_o,
+ instr_perf_count_id_o,
+ ready_wb_i,
+ outstanding_load_wb_i,
+ outstanding_store_wb_i,
+ perf_jump_o,
+ perf_branch_o,
+ perf_tbranch_o,
+ perf_dside_wait_o,
+ perf_mul_wait_o,
+ perf_div_wait_o,
+ instr_id_done_o,
+ fp_rounding_mode_o,
+ fp_rf_rdata_a_i,
+ fp_rf_rdata_b_i,
+ fp_rf_rdata_c_i,
+ fp_rf_raddr_a_o,
+ fp_rf_raddr_b_o,
+ fp_rf_raddr_c_o,
+ fp_rf_waddr_o,
+ fp_rf_we_o,
+ fp_alu_operator_o,
+ fp_alu_op_mod_o,
+ fp_src_fmt_o,
+ fp_dst_fmt_o,
+ fp_rm_dynamic_o,
+ fp_flush_o,
+ is_fp_instr_o,
+ use_fp_rs1_o,
+ use_fp_rs2_o,
+ use_fp_rs3_o,
+ use_fp_rd_o,
+ fpu_busy_i,
+ fp_rf_write_wb_i,
+ fp_rf_wdata_fwd_wb_i,
+ fp_operands_o,
+ fp_load_o
+);
+ parameter [0:0] RV32E = 0;
+ localparam integer brq_pkg_RV32MFast = 2;
+ parameter integer RV32M = brq_pkg_RV32MFast;
+ localparam integer brq_pkg_RV32BNone = 0;
+ parameter integer RV32B = brq_pkg_RV32BNone;
+ localparam integer brq_pkg_RV64FDouble = 2;
+ parameter integer RVF = brq_pkg_RV64FDouble;
+ parameter [0:0] DataIndTiming = 1'b0;
+ parameter [0:0] BranchTargetALU = 0;
+ parameter [0:0] SpecBranch = 0;
+ parameter [0:0] WritebackStage = 0;
+ parameter [0:0] BranchPredictor = 0;
+ parameter FloatingPoint = 1;
+ input wire clk_i;
+ input wire rst_ni;
+ output wire ctrl_busy_o;
+ output wire illegal_insn_o;
+ input wire instr_valid_i;
+ input wire [31:0] instr_rdata_i;
+ input wire [31:0] instr_rdata_alu_i;
+ input wire [15:0] instr_rdata_c_i;
+ input wire instr_is_compressed_i;
+ output wire instr_req_o;
+ output wire instr_first_cycle_id_o;
+ output wire instr_valid_clear_o;
+ output wire id_in_ready_o;
+ output wire icache_inval_o;
+ input wire branch_decision_i;
+ output wire pc_set_o;
+ output wire pc_set_spec_o;
+ output wire [2:0] pc_mux_o;
+ output wire [1:0] exc_pc_mux_o;
+ output wire [5:0] exc_cause_o;
+ input wire illegal_c_insn_i;
+ input wire instr_fetch_err_i;
+ input wire instr_fetch_err_plus2_i;
+ input wire [31:0] pc_id_i;
+ input wire ex_valid_i;
+ input wire lsu_resp_valid_i;
+ output wire [5:0] alu_operator_ex_o;
+ output wire [31:0] alu_operand_a_ex_o;
+ output wire [31:0] alu_operand_b_ex_o;
+ input wire [1:0] imd_val_we_ex_i;
+ input wire [67:0] imd_val_d_ex_i;
+ output wire [67:0] imd_val_q_ex_o;
+ output reg [31:0] bt_a_operand_o;
+ output reg [31:0] bt_b_operand_o;
+ output wire mult_en_ex_o;
+ output wire div_en_ex_o;
+ output wire mult_sel_ex_o;
+ output wire div_sel_ex_o;
+ output wire [1:0] multdiv_operator_ex_o;
+ output wire [1:0] multdiv_signed_mode_ex_o;
+ output wire [31:0] multdiv_operand_a_ex_o;
+ output wire [31:0] multdiv_operand_b_ex_o;
+ output wire multdiv_ready_id_o;
+ output wire csr_access_o;
+ output wire [1:0] csr_op_o;
+ output wire csr_op_en_o;
+ output wire csr_save_if_o;
+ output wire csr_save_id_o;
+ output wire csr_save_wb_o;
+ output wire csr_restore_mret_id_o;
+ output wire csr_restore_dret_id_o;
+ output wire csr_save_cause_o;
+ output wire [31:0] csr_mtval_o;
+ input wire [1:0] priv_mode_i;
+ input wire csr_mstatus_tw_i;
+ input wire illegal_csr_insn_i;
+ input wire data_ind_timing_i;
+ output wire lsu_req_o;
+ output wire lsu_we_o;
+ output wire [1:0] lsu_type_o;
+ output wire lsu_sign_ext_o;
+ output wire [31:0] lsu_wdata_o;
+ input wire lsu_req_done_i;
+ input wire lsu_addr_incr_req_i;
+ input wire [31:0] lsu_addr_last_i;
+ input wire csr_mstatus_mie_i;
+ input wire irq_pending_i;
+ input wire [17:0] irqs_i;
+ input wire irq_nm_i;
+ output wire nmi_mode_o;
+ input wire lsu_load_err_i;
+ input wire lsu_store_err_i;
+ output wire debug_mode_o;
+ output wire [2:0] debug_cause_o;
+ output wire debug_csr_save_o;
+ input wire debug_req_i;
+ input wire debug_single_step_i;
+ input wire debug_ebreakm_i;
+ input wire debug_ebreaku_i;
+ input wire trigger_match_i;
+ input wire [31:0] result_ex_i;
+ input wire [31:0] csr_rdata_i;
+ output wire [4:0] rf_raddr_a_o;
+ input wire [31:0] rf_rdata_a_i;
+ output wire [4:0] rf_raddr_b_o;
+ input wire [31:0] rf_rdata_b_i;
+ output wire rf_ren_a_o;
+ output wire rf_ren_b_o;
+ output wire [4:0] rf_waddr_id_o;
+ output reg [31:0] rf_wdata_id_o;
+ output wire rf_we_id_o;
+ output wire rf_rd_a_wb_match_o;
+ output wire rf_rd_b_wb_match_o;
+ input wire [4:0] rf_waddr_wb_i;
+ input wire [31:0] rf_wdata_fwd_wb_i;
+ input wire rf_write_wb_i;
+ output wire en_wb_o;
+ output wire [1:0] instr_type_wb_o;
+ output wire instr_perf_count_id_o;
+ input wire ready_wb_i;
+ input wire outstanding_load_wb_i;
+ input wire outstanding_store_wb_i;
+ output wire perf_jump_o;
+ output reg perf_branch_o;
+ output wire perf_tbranch_o;
+ output wire perf_dside_wait_o;
+ output wire perf_mul_wait_o;
+ output wire perf_div_wait_o;
+ output wire instr_id_done_o;
+ output wire [2:0] fp_rounding_mode_o;
+ input wire [31:0] fp_rf_rdata_a_i;
+ input wire [31:0] fp_rf_rdata_b_i;
+ input wire [31:0] fp_rf_rdata_c_i;
+ output wire [4:0] fp_rf_raddr_a_o;
+ output wire [4:0] fp_rf_raddr_b_o;
+ output wire [4:0] fp_rf_raddr_c_o;
+ output wire [4:0] fp_rf_waddr_o;
+ output wire fp_rf_we_o;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ output wire [3:0] fp_alu_operator_o;
+ output wire fp_alu_op_mod_o;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ output wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] fp_src_fmt_o;
+ output wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] fp_dst_fmt_o;
+ output wire fp_rm_dynamic_o;
+ output wire fp_flush_o;
+ output wire is_fp_instr_o;
+ output wire use_fp_rs1_o;
+ output wire use_fp_rs2_o;
+ output wire use_fp_rs3_o;
+ output wire use_fp_rd_o;
+ input wire fpu_busy_i;
+ input wire fp_rf_write_wb_i;
+ input wire [31:0] fp_rf_wdata_fwd_wb_i;
+ output reg [95:0] fp_operands_o;
+ output wire fp_load_o;
+ wire illegal_insn_dec;
+ wire ebrk_insn;
+ wire mret_insn_dec;
+ wire dret_insn_dec;
+ wire ecall_insn_dec;
+ wire wfi_insn_dec;
+ wire wb_exception;
+ wire branch_in_dec;
+ reg branch_spec;
+ wire branch_set_spec;
+ wire branch_set;
+ reg branch_set_d;
+ reg branch_not_set;
+ wire branch_taken;
+ wire jump_in_dec;
+ wire jump_set_dec;
+ reg jump_set;
+ wire instr_first_cycle;
+ wire instr_executing;
+ wire instr_done;
+ wire controller_run;
+ wire stall_ld_hz;
+ wire stall_mem;
+ reg stall_multdiv;
+ reg stall_branch;
+ reg stall_jump;
+ wire stall_id;
+ wire stall_wb;
+ reg stall_fpu;
+ wire flush_id;
+ wire multicycle_done;
+ wire [31:0] imm_i_type;
+ wire [31:0] imm_s_type;
+ wire [31:0] imm_b_type;
+ wire [31:0] imm_u_type;
+ wire [31:0] imm_j_type;
+ wire [31:0] zimm_rs1_type;
+ wire [31:0] imm_a;
+ reg [31:0] imm_b;
+ wire rf_wdata_sel;
+ wire rf_we_dec;
+ reg rf_we_raw;
+ wire rf_ren_a;
+ wire rf_ren_b;
+ assign rf_ren_a_o = rf_ren_a;
+ assign rf_ren_b_o = rf_ren_b;
+ wire [31:0] rf_rdata_a_fwd;
+ wire [31:0] rf_rdata_b_fwd;
+ wire [5:0] alu_operator;
+ wire [1:0] alu_op_a_mux_sel;
+ wire [1:0] alu_op_a_mux_sel_dec;
+ wire alu_op_b_mux_sel;
+ wire alu_op_b_mux_sel_dec;
+ wire alu_multicycle_dec;
+ reg stall_alu;
+ reg [67:0] imd_val_q;
+ wire [1:0] bt_a_mux_sel;
+ wire [2:0] bt_b_mux_sel;
+ wire imm_a_mux_sel;
+ wire [2:0] imm_b_mux_sel;
+ wire [2:0] imm_b_mux_sel_dec;
+ wire mult_en_id;
+ wire mult_en_dec;
+ wire div_en_id;
+ wire div_en_dec;
+ wire multdiv_en_dec;
+ wire [1:0] multdiv_operator;
+ wire [1:0] multdiv_signed_mode;
+ wire lsu_we;
+ wire [1:0] lsu_type;
+ wire lsu_sign_ext;
+ wire lsu_req;
+ wire lsu_req_dec;
+ wire data_req_allowed;
+ reg csr_pipe_flush;
+ reg [31:0] alu_operand_a;
+ wire [31:0] alu_operand_b;
+ wire fp_swap_oprnds;
+ wire [31:0] fp_rf_rdata_a_fwd;
+ wire [31:0] fp_rf_rdata_b_fwd;
+ wire [31:0] fp_rf_rdata_c_fwd;
+ wire [31:0] temp;
+ reg [31:0] fpu_op_a;
+ reg [31:0] fpu_op_b;
+ reg [31:0] fpu_op_c;
+ wire mv_instr;
+ wire [31:0] result_wb;
+ localparam [1:0] brq_pkg_OP_A_FWD = 1;
+ assign alu_op_a_mux_sel = (lsu_addr_incr_req_i ? brq_pkg_OP_A_FWD : alu_op_a_mux_sel_dec);
+ localparam [0:0] brq_pkg_OP_B_IMM = 1;
+ assign alu_op_b_mux_sel = (lsu_addr_incr_req_i ? brq_pkg_OP_B_IMM : alu_op_b_mux_sel_dec);
+ localparam [2:0] brq_pkg_IMM_B_INCR_ADDR = 6;
+ assign imm_b_mux_sel = (lsu_addr_incr_req_i ? brq_pkg_IMM_B_INCR_ADDR : imm_b_mux_sel_dec);
+ localparam [0:0] brq_pkg_IMM_A_Z = 0;
+ assign imm_a = (imm_a_mux_sel == brq_pkg_IMM_A_Z ? zimm_rs1_type : {32 {1'sb0}});
+ localparam [1:0] brq_pkg_OP_A_CURRPC = 2;
+ localparam [1:0] brq_pkg_OP_A_IMM = 3;
+ localparam [1:0] brq_pkg_OP_A_REG_A = 0;
+ always @(*) begin : alu_operand_a_mux
+ case (alu_op_a_mux_sel)
+ brq_pkg_OP_A_REG_A: alu_operand_a = rf_rdata_a_fwd;
+ brq_pkg_OP_A_FWD: alu_operand_a = lsu_addr_last_i;
+ brq_pkg_OP_A_CURRPC: alu_operand_a = pc_id_i;
+ brq_pkg_OP_A_IMM: alu_operand_a = imm_a;
+ endcase
+ end
+ localparam [2:0] brq_pkg_IMM_B_B = 2;
+ localparam [2:0] brq_pkg_IMM_B_I = 0;
+ localparam [2:0] brq_pkg_IMM_B_INCR_PC = 5;
+ localparam [2:0] brq_pkg_IMM_B_J = 4;
+ localparam [2:0] brq_pkg_IMM_B_S = 1;
+ localparam [2:0] brq_pkg_IMM_B_U = 3;
+ generate
+ if (BranchTargetALU) begin : g_btalu_muxes
+ always @(*) begin : bt_operand_a_mux
+ case (bt_a_mux_sel)
+ brq_pkg_OP_A_REG_A: bt_a_operand_o = rf_rdata_a_fwd;
+ brq_pkg_OP_A_CURRPC: bt_a_operand_o = pc_id_i;
+ default: bt_a_operand_o = pc_id_i;
+ endcase
+ end
+ always @(*) begin : bt_immediate_b_mux
+ case (bt_b_mux_sel)
+ brq_pkg_IMM_B_I: bt_b_operand_o = imm_i_type;
+ brq_pkg_IMM_B_B: bt_b_operand_o = imm_b_type;
+ brq_pkg_IMM_B_J: bt_b_operand_o = imm_j_type;
+ brq_pkg_IMM_B_INCR_PC: bt_b_operand_o = (instr_is_compressed_i ? 32'h00000002 : 32'h00000004);
+ default: bt_b_operand_o = (instr_is_compressed_i ? 32'h00000002 : 32'h00000004);
+ endcase
+ end
+ always @(*) begin : immediate_b_mux
+ case (imm_b_mux_sel)
+ brq_pkg_IMM_B_I: imm_b = imm_i_type;
+ brq_pkg_IMM_B_S: imm_b = imm_s_type;
+ brq_pkg_IMM_B_U: imm_b = imm_u_type;
+ brq_pkg_IMM_B_INCR_PC: imm_b = (instr_is_compressed_i ? 32'h00000002 : 32'h00000004);
+ brq_pkg_IMM_B_INCR_ADDR: imm_b = 32'h00000004;
+ default: imm_b = 32'h00000004;
+ endcase
+ end
+ end
+ else begin : g_nobtalu
+ wire [1:0] unused_a_mux_sel;
+ wire [2:0] unused_b_mux_sel;
+ assign unused_a_mux_sel = bt_a_mux_sel;
+ assign unused_b_mux_sel = bt_b_mux_sel;
+ wire [32:1] sv2v_tmp_456A8;
+ assign sv2v_tmp_456A8 = {32 {1'sb0}};
+ always @(*) bt_a_operand_o = sv2v_tmp_456A8;
+ wire [32:1] sv2v_tmp_EDBFD;
+ assign sv2v_tmp_EDBFD = {32 {1'sb0}};
+ always @(*) bt_b_operand_o = sv2v_tmp_EDBFD;
+ always @(*) begin : immediate_b_mux
+ case (imm_b_mux_sel)
+ brq_pkg_IMM_B_I: imm_b = imm_i_type;
+ brq_pkg_IMM_B_S: imm_b = imm_s_type;
+ brq_pkg_IMM_B_B: imm_b = imm_b_type;
+ brq_pkg_IMM_B_U: imm_b = imm_u_type;
+ brq_pkg_IMM_B_J: imm_b = imm_j_type;
+ brq_pkg_IMM_B_INCR_PC: imm_b = (instr_is_compressed_i ? 32'h00000002 : 32'h00000004);
+ brq_pkg_IMM_B_INCR_ADDR: imm_b = 32'h00000004;
+ default: imm_b = 32'h00000004;
+ endcase
+ end
+ end
+ endgenerate
+ assign alu_operand_b = (alu_op_b_mux_sel == brq_pkg_OP_B_IMM ? imm_b : rf_rdata_b_fwd);
+ generate
+ genvar i;
+ for (i = 0; i < 2; i = i + 1) begin : gen_intermediate_val_reg
+ always @(posedge clk_i or negedge rst_ni) begin : intermediate_val_reg
+ if (!rst_ni)
+ imd_val_q[(1 - i) * 34+:34] <= {34 {1'sb0}};
+ else if (imd_val_we_ex_i[i])
+ imd_val_q[(1 - i) * 34+:34] <= imd_val_d_ex_i[(1 - i) * 34+:34];
+ end
+ end
+ endgenerate
+ assign imd_val_q_ex_o = imd_val_q;
+ brq_idu_decoder #(
+ .RV32E(RV32E),
+ .RV32M(RV32M),
+ .RV32B(RV32B),
+ .BranchTargetALU(BranchTargetALU)
+ ) decoder_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .illegal_insn_o(illegal_insn_dec),
+ .ebrk_insn_o(ebrk_insn),
+ .mret_insn_o(mret_insn_dec),
+ .dret_insn_o(dret_insn_dec),
+ .ecall_insn_o(ecall_insn_dec),
+ .wfi_insn_o(wfi_insn_dec),
+ .jump_set_o(jump_set_dec),
+ .branch_taken_i(branch_taken),
+ .icache_inval_o(icache_inval_o),
+ .instr_first_cycle_i(instr_first_cycle),
+ .instr_rdata_i(instr_rdata_i),
+ .instr_rdata_alu_i(instr_rdata_alu_i),
+ .illegal_c_insn_i(illegal_c_insn_i),
+ .imm_a_mux_sel_o(imm_a_mux_sel),
+ .imm_b_mux_sel_o(imm_b_mux_sel_dec),
+ .bt_a_mux_sel_o(bt_a_mux_sel),
+ .bt_b_mux_sel_o(bt_b_mux_sel),
+ .imm_i_type_o(imm_i_type),
+ .imm_s_type_o(imm_s_type),
+ .imm_b_type_o(imm_b_type),
+ .imm_u_type_o(imm_u_type),
+ .imm_j_type_o(imm_j_type),
+ .zimm_rs1_type_o(zimm_rs1_type),
+ .rf_wdata_sel_o(rf_wdata_sel),
+ .rf_we_o(rf_we_dec),
+ .rf_raddr_a_o(rf_raddr_a_o),
+ .rf_raddr_b_o(rf_raddr_b_o),
+ .rf_waddr_o(rf_waddr_id_o),
+ .rf_ren_a_o(rf_ren_a),
+ .rf_ren_b_o(rf_ren_b),
+ .alu_operator_o(alu_operator),
+ .alu_op_a_mux_sel_o(alu_op_a_mux_sel_dec),
+ .alu_op_b_mux_sel_o(alu_op_b_mux_sel_dec),
+ .alu_multicycle_o(alu_multicycle_dec),
+ .mult_en_o(mult_en_dec),
+ .div_en_o(div_en_dec),
+ .mult_sel_o(mult_sel_ex_o),
+ .div_sel_o(div_sel_ex_o),
+ .multdiv_operator_o(multdiv_operator),
+ .multdiv_signed_mode_o(multdiv_signed_mode),
+ .csr_access_o(csr_access_o),
+ .csr_op_o(csr_op_o),
+ .data_req_o(lsu_req_dec),
+ .data_we_o(lsu_we),
+ .data_type_o(lsu_type),
+ .data_sign_extension_o(lsu_sign_ext),
+ .jump_in_dec_o(jump_in_dec),
+ .branch_in_dec_o(branch_in_dec),
+ .fp_rounding_mode_o(fp_rounding_mode_o),
+ .fp_rf_raddr_a_o(fp_rf_raddr_a_o),
+ .fp_rf_raddr_b_o(fp_rf_raddr_b_o),
+ .fp_rf_raddr_c_o(fp_rf_raddr_c_o),
+ .fp_rf_waddr_o(fp_rf_waddr_o),
+ .fp_rf_we_o(fp_rf_we_o),
+ .fp_alu_operator_o(fp_alu_operator_o),
+ .fp_alu_op_mod_o(fp_alu_op_mod_o),
+ .fp_src_fmt_o(fp_src_fmt_o),
+ .fp_dst_fmt_o(fp_dst_fmt_o),
+ .fp_rm_dynamic_o(fp_rm_dynamic_o),
+ .is_fp_instr_o(is_fp_instr_o),
+ .use_fp_rs1_o(use_fp_rs1_o),
+ .use_fp_rs2_o(use_fp_rs2_o),
+ .use_fp_rs3_o(use_fp_rs3_o),
+ .use_fp_rd_o(use_fp_rd_o),
+ .fp_swap_oprnds_o(fp_swap_oprnds),
+ .fp_load_o(fp_load_o),
+ .mv_instr_o(mv_instr)
+ );
+ assign rf_we_id_o = (rf_we_raw & instr_executing) & ~illegal_csr_insn_i;
+ localparam [0:0] brq_pkg_RF_WD_CSR = 1;
+ localparam [0:0] brq_pkg_RF_WD_EX = 0;
+ always @(*) begin : rf_wdata_id_mux
+ case (rf_wdata_sel)
+ brq_pkg_RF_WD_EX: rf_wdata_id_o = result_wb;
+ brq_pkg_RF_WD_CSR: rf_wdata_id_o = csr_rdata_i;
+ endcase
+ end
+ localparam [11:0] brq_pkg_CSR_DCSR = 12'h7b0;
+ localparam [11:0] brq_pkg_CSR_DPC = 12'h7b1;
+ localparam [11:0] brq_pkg_CSR_DSCRATCH0 = 12'h7b2;
+ localparam [11:0] brq_pkg_CSR_DSCRATCH1 = 12'h7b3;
+ localparam [11:0] brq_pkg_CSR_MIE = 12'h304;
+ localparam [11:0] brq_pkg_CSR_MSTATUS = 12'h300;
+ localparam [1:0] brq_pkg_CSR_OP_READ = 0;
+ localparam [1:0] brq_pkg_CSR_OP_SET = 2;
+ localparam [1:0] brq_pkg_CSR_OP_WRITE = 1;
+ always @(*) begin : csr_pipeline_flushes
+ csr_pipe_flush = 1'b0;
+ if ((csr_op_en_o == 1'b1) && ((csr_op_o == brq_pkg_CSR_OP_WRITE) || (csr_op_o == brq_pkg_CSR_OP_SET))) begin
+ if ((instr_rdata_i[31:20] == brq_pkg_CSR_MSTATUS) || (instr_rdata_i[31:20] == brq_pkg_CSR_MIE))
+ csr_pipe_flush = 1'b1;
+ end
+ else if ((csr_op_en_o == 1'b1) && (csr_op_o != brq_pkg_CSR_OP_READ))
+ if ((((instr_rdata_i[31:20] == brq_pkg_CSR_DCSR) || (instr_rdata_i[31:20] == brq_pkg_CSR_DPC)) || (instr_rdata_i[31:20] == brq_pkg_CSR_DSCRATCH0)) || (instr_rdata_i[31:20] == brq_pkg_CSR_DSCRATCH1))
+ csr_pipe_flush = 1'b1;
+ end
+ assign illegal_insn_o = instr_valid_i & (illegal_insn_dec | illegal_csr_insn_i);
+ brq_idu_controller #(
+ .WritebackStage(WritebackStage),
+ .BranchPredictor(BranchPredictor)
+ ) controller_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .ctrl_busy_o(ctrl_busy_o),
+ .illegal_insn_i(illegal_insn_o),
+ .ecall_insn_i(ecall_insn_dec),
+ .mret_insn_i(mret_insn_dec),
+ .dret_insn_i(dret_insn_dec),
+ .wfi_insn_i(wfi_insn_dec),
+ .ebrk_insn_i(ebrk_insn),
+ .csr_pipe_flush_i(csr_pipe_flush),
+ .instr_valid_i(instr_valid_i),
+ .instr_i(instr_rdata_i),
+ .instr_compressed_i(instr_rdata_c_i),
+ .instr_is_compressed_i(instr_is_compressed_i),
+ .instr_fetch_err_i(instr_fetch_err_i),
+ .instr_fetch_err_plus2_i(instr_fetch_err_plus2_i),
+ .pc_id_i(pc_id_i),
+ .instr_valid_clear_o(instr_valid_clear_o),
+ .id_in_ready_o(id_in_ready_o),
+ .controller_run_o(controller_run),
+ .instr_req_o(instr_req_o),
+ .pc_set_o(pc_set_o),
+ .pc_set_spec_o(pc_set_spec_o),
+ .pc_mux_o(pc_mux_o),
+ .exc_pc_mux_o(exc_pc_mux_o),
+ .exc_cause_o(exc_cause_o),
+ .lsu_addr_last_i(lsu_addr_last_i),
+ .load_err_i(lsu_load_err_i),
+ .store_err_i(lsu_store_err_i),
+ .wb_exception_o(wb_exception),
+ .branch_set_i(branch_set),
+ .branch_set_spec_i(branch_set_spec),
+ .jump_set_i(jump_set),
+ .csr_mstatus_mie_i(csr_mstatus_mie_i),
+ .irq_pending_i(irq_pending_i),
+ .irqs_i(irqs_i),
+ .irq_nm_i(irq_nm_i),
+ .nmi_mode_o(nmi_mode_o),
+ .csr_save_if_o(csr_save_if_o),
+ .csr_save_id_o(csr_save_id_o),
+ .csr_save_wb_o(csr_save_wb_o),
+ .csr_restore_mret_id_o(csr_restore_mret_id_o),
+ .csr_restore_dret_id_o(csr_restore_dret_id_o),
+ .csr_save_cause_o(csr_save_cause_o),
+ .csr_mtval_o(csr_mtval_o),
+ .priv_mode_i(priv_mode_i),
+ .csr_mstatus_tw_i(csr_mstatus_tw_i),
+ .debug_mode_o(debug_mode_o),
+ .debug_cause_o(debug_cause_o),
+ .debug_csr_save_o(debug_csr_save_o),
+ .debug_req_i(debug_req_i),
+ .debug_single_step_i(debug_single_step_i),
+ .debug_ebreakm_i(debug_ebreakm_i),
+ .debug_ebreaku_i(debug_ebreaku_i),
+ .trigger_match_i(trigger_match_i),
+ .stall_id_i(stall_id),
+ .stall_wb_i(stall_wb),
+ .flush_id_o(flush_id),
+ .ready_wb_i(ready_wb_i),
+ .perf_jump_o(perf_jump_o),
+ .perf_tbranch_o(perf_tbranch_o)
+ );
+ assign fp_flush_o = flush_id;
+ assign multdiv_en_dec = mult_en_dec | div_en_dec;
+ assign lsu_req = (instr_executing ? data_req_allowed & lsu_req_dec : 1'b0);
+ assign mult_en_id = (instr_executing ? mult_en_dec : 1'b0);
+ assign div_en_id = (instr_executing ? div_en_dec : 1'b0);
+ assign lsu_req_o = lsu_req;
+ assign lsu_we_o = lsu_we;
+ assign lsu_type_o = lsu_type;
+ assign lsu_sign_ext_o = lsu_sign_ext;
+ assign lsu_wdata_o = fpu_op_b;
+ assign csr_op_en_o = (csr_access_o & instr_executing) & instr_id_done_o;
+ assign alu_operator_ex_o = alu_operator;
+ assign alu_operand_a_ex_o = alu_operand_a;
+ assign alu_operand_b_ex_o = alu_operand_b;
+ assign mult_en_ex_o = mult_en_id;
+ assign div_en_ex_o = div_en_id;
+ assign multdiv_operator_ex_o = multdiv_operator;
+ assign multdiv_signed_mode_ex_o = multdiv_signed_mode;
+ assign multdiv_operand_a_ex_o = rf_rdata_a_fwd;
+ assign multdiv_operand_b_ex_o = rf_rdata_b_fwd;
+ generate
+ if (BranchTargetALU && !DataIndTiming) begin : g_branch_set_direct
+ assign branch_set = branch_set_d;
+ assign branch_set_spec = branch_spec;
+ end
+ else begin : g_branch_set_flop
+ reg branch_set_q;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ branch_set_q <= 1'b0;
+ else
+ branch_set_q <= branch_set_d;
+ assign branch_set = (BranchTargetALU && !data_ind_timing_i ? branch_set_d : branch_set_q);
+ assign branch_set_spec = (BranchTargetALU && !data_ind_timing_i ? branch_spec : branch_set_q);
+ end
+ endgenerate
+ generate
+ if (DataIndTiming) begin : g_sec_branch_taken
+ reg branch_taken_q;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ branch_taken_q <= 1'b0;
+ else
+ branch_taken_q <= branch_decision_i;
+ assign branch_taken = ~data_ind_timing_i | branch_taken_q;
+ end
+ else begin : g_nosec_branch_taken
+ assign branch_taken = 1'b1;
+ end
+ endgenerate
+ reg id_fsm_q;
+ reg id_fsm_d;
+ localparam [0:0] FIRST_CYCLE = 0;
+ always @(posedge clk_i or negedge rst_ni) begin : id_pipeline_reg
+ if (!rst_ni)
+ id_fsm_q <= FIRST_CYCLE;
+ else
+ id_fsm_q <= id_fsm_d;
+ end
+ localparam [0:0] MULTI_CYCLE = 1;
+ always @(*) begin
+ id_fsm_d = id_fsm_q;
+ rf_we_raw = rf_we_dec;
+ stall_multdiv = 1'b0;
+ stall_jump = 1'b0;
+ stall_branch = 1'b0;
+ stall_alu = 1'b0;
+ stall_fpu = 1'b0;
+ branch_set_d = 1'b0;
+ branch_spec = 1'b0;
+ branch_not_set = 1'b0;
+ jump_set = 1'b0;
+ perf_branch_o = 1'b0;
+ if (instr_executing)
+ case (id_fsm_q)
+ FIRST_CYCLE:
+ case (1'b1)
+ lsu_req_dec:
+ if (!WritebackStage)
+ id_fsm_d = MULTI_CYCLE;
+ else if (~lsu_req_done_i)
+ id_fsm_d = MULTI_CYCLE;
+ FloatingPoint: stall_fpu = fpu_busy_i;
+ multdiv_en_dec:
+ if (~ex_valid_i) begin
+ id_fsm_d = MULTI_CYCLE;
+ rf_we_raw = 1'b0;
+ stall_multdiv = 1'b1;
+ end
+ branch_in_dec: begin
+ id_fsm_d = (data_ind_timing_i || (!BranchTargetALU && branch_decision_i) ? MULTI_CYCLE : FIRST_CYCLE);
+ stall_branch = (~BranchTargetALU & branch_decision_i) | data_ind_timing_i;
+ branch_set_d = branch_decision_i | data_ind_timing_i;
+ if (BranchPredictor)
+ branch_not_set = ~branch_decision_i;
+ branch_spec = (SpecBranch ? 1'b1 : branch_decision_i);
+ perf_branch_o = 1'b1;
+ end
+ jump_in_dec: begin
+ id_fsm_d = (BranchTargetALU ? FIRST_CYCLE : MULTI_CYCLE);
+ stall_jump = ~BranchTargetALU;
+ jump_set = jump_set_dec;
+ end
+ alu_multicycle_dec: begin
+ stall_alu = 1'b1;
+ id_fsm_d = MULTI_CYCLE;
+ rf_we_raw = 1'b0;
+ end
+ default: id_fsm_d = FIRST_CYCLE;
+ endcase
+ MULTI_CYCLE: begin
+ if (multdiv_en_dec)
+ rf_we_raw = rf_we_dec & ex_valid_i;
+ if (multicycle_done & ready_wb_i)
+ id_fsm_d = FIRST_CYCLE;
+ else begin
+ stall_multdiv = multdiv_en_dec;
+ stall_branch = branch_in_dec;
+ stall_jump = jump_in_dec;
+ stall_fpu = fpu_busy_i;
+ end
+ end
+ default: id_fsm_d = FIRST_CYCLE;
+ endcase
+ end
+ assign multdiv_ready_id_o = ready_wb_i;
+ assign stall_id = (((((stall_ld_hz | stall_mem) | stall_multdiv) | stall_jump) | stall_branch) | stall_alu) | stall_fpu;
+ assign instr_done = (~stall_id & ~flush_id) & instr_executing;
+ assign instr_first_cycle = instr_valid_i & (id_fsm_q == FIRST_CYCLE);
+ assign instr_first_cycle_id_o = instr_first_cycle;
+ localparam [1:0] brq_pkg_WB_INSTR_LOAD = 0;
+ localparam [1:0] brq_pkg_WB_INSTR_OTHER = 2;
+ localparam [1:0] brq_pkg_WB_INSTR_STORE = 1;
+ generate
+ if (WritebackStage) begin : gen_stall_mem
+ wire rf_rd_a_wb_match;
+ wire rf_rd_b_wb_match;
+ wire fp_rf_rd_a_wb_match;
+ wire fp_rf_rd_b_wb_match;
+ wire fp_rf_rd_c_wb_match;
+ wire rf_rd_a_hz;
+ wire rf_rd_b_hz;
+ wire rf_rd_c_hz;
+ wire outstanding_memory_access;
+ wire instr_kill;
+ assign multicycle_done = (lsu_req_dec ? ~stall_mem : ex_valid_i);
+ assign outstanding_memory_access = (outstanding_load_wb_i | outstanding_store_wb_i) & ~lsu_resp_valid_i;
+ assign data_req_allowed = ~outstanding_memory_access;
+ assign instr_kill = (instr_fetch_err_i | wb_exception) | ~controller_run;
+ assign instr_executing = ((instr_valid_i & ~instr_kill) & ~stall_ld_hz) & ~outstanding_memory_access;
+ assign stall_mem = instr_valid_i & (outstanding_memory_access | (lsu_req_dec & ~lsu_req_done_i));
+ assign rf_rd_a_wb_match = (rf_waddr_wb_i == rf_raddr_a_o) & |rf_raddr_a_o;
+ assign rf_rd_b_wb_match = (rf_waddr_wb_i == rf_raddr_b_o) & |rf_raddr_b_o;
+ assign fp_rf_rd_a_wb_match = rf_waddr_wb_i == rf_raddr_a_o;
+ assign fp_rf_rd_b_wb_match = rf_waddr_wb_i == rf_raddr_b_o;
+ assign fp_rf_rd_c_wb_match = rf_waddr_wb_i == fp_rf_raddr_c_o;
+ assign rf_rd_a_wb_match_o = rf_rd_a_wb_match;
+ assign rf_rd_b_wb_match_o = rf_rd_b_wb_match;
+ assign rf_rd_a_hz = rf_rd_a_wb_match & (rf_ren_a | use_fp_rs1_o);
+ assign rf_rd_b_hz = rf_rd_b_wb_match & (rf_ren_b | use_fp_rs2_o);
+ assign rf_rd_c_hz = rf_rd_b_wb_match & use_fp_rs3_o;
+ assign rf_rdata_a_fwd = (rf_rd_a_wb_match & rf_write_wb_i ? rf_wdata_fwd_wb_i : rf_rdata_a_i);
+ assign rf_rdata_b_fwd = (rf_rd_b_wb_match & rf_write_wb_i ? rf_wdata_fwd_wb_i : rf_rdata_b_i);
+ assign fp_rf_rdata_a_fwd = (fp_rf_rd_a_wb_match & fp_rf_write_wb_i ? fp_rf_wdata_fwd_wb_i : fp_rf_rdata_a_i);
+ assign fp_rf_rdata_b_fwd = (fp_rf_rd_b_wb_match & fp_rf_write_wb_i ? fp_rf_wdata_fwd_wb_i : fp_rf_rdata_b_i);
+ assign fp_rf_rdata_c_fwd = (fp_rf_rd_c_wb_match & fp_rf_write_wb_i ? fp_rf_wdata_fwd_wb_i : fp_rf_rdata_c_i);
+ assign stall_ld_hz = outstanding_load_wb_i & ((rf_rd_a_hz | rf_rd_b_hz) | rf_rd_c_hz);
+ assign instr_type_wb_o = (~lsu_req_dec ? brq_pkg_WB_INSTR_OTHER : (lsu_we ? brq_pkg_WB_INSTR_STORE : brq_pkg_WB_INSTR_LOAD));
+ assign instr_id_done_o = en_wb_o & ready_wb_i;
+ assign stall_wb = en_wb_o & ~ready_wb_i;
+ assign perf_dside_wait_o = (instr_valid_i & ~instr_kill) & (outstanding_memory_access | stall_ld_hz);
+ end
+ else begin : gen_no_stall_mem
+ assign multicycle_done = (lsu_req_dec ? lsu_resp_valid_i : ex_valid_i);
+ assign data_req_allowed = instr_first_cycle;
+ assign stall_mem = instr_valid_i & (lsu_req_dec & (~lsu_resp_valid_i | instr_first_cycle));
+ assign stall_ld_hz = 1'b0;
+ assign instr_executing = (instr_valid_i & ~instr_fetch_err_i) & controller_run;
+ assign rf_rdata_a_fwd = rf_rdata_a_i;
+ assign rf_rdata_b_fwd = rf_rdata_b_i;
+ assign fp_rf_rdata_a_fwd = fp_rf_rdata_a_i;
+ assign fp_rf_rdata_b_fwd = fp_rf_rdata_b_i;
+ assign fp_rf_rdata_c_fwd = fp_rf_rdata_c_i;
+ assign rf_rd_a_wb_match_o = 1'b0;
+ assign rf_rd_b_wb_match_o = 1'b0;
+ wire unused_data_req_done_ex;
+ wire [4:0] unused_rf_waddr_wb;
+ wire unused_rf_write_wb;
+ wire unused_outstanding_load_wb;
+ wire unused_outstanding_store_wb;
+ wire unused_wb_exception;
+ wire [31:0] unused_rf_wdata_fwd_wb;
+ assign unused_data_req_done_ex = lsu_req_done_i;
+ assign unused_rf_waddr_wb = rf_waddr_wb_i;
+ assign unused_rf_write_wb = rf_write_wb_i;
+ assign unused_outstanding_load_wb = outstanding_load_wb_i;
+ assign unused_outstanding_store_wb = outstanding_store_wb_i;
+ assign unused_wb_exception = wb_exception;
+ assign unused_rf_wdata_fwd_wb = rf_wdata_fwd_wb_i;
+ assign instr_type_wb_o = brq_pkg_WB_INSTR_OTHER;
+ assign stall_wb = 1'b0;
+ assign perf_dside_wait_o = (instr_executing & lsu_req_dec) & ~lsu_resp_valid_i;
+ assign instr_id_done_o = instr_done;
+ end
+ endgenerate
+ always @(*) begin : swapping
+ fpu_op_a = (use_fp_rs1_o ? fp_rf_rdata_a_fwd : rf_rdata_a_fwd);
+ fpu_op_b = (use_fp_rs2_o ? fp_rf_rdata_b_fwd : rf_rdata_b_fwd);
+ if (fp_swap_oprnds)
+ fpu_op_c = fpu_op_a;
+ else
+ fpu_op_c = fp_rf_rdata_c_fwd;
+ fp_operands_o = {fpu_op_c, fpu_op_b, fpu_op_a};
+ end
+ assign result_wb = (mv_instr ? fpu_op_a : result_ex_i);
+ assign instr_perf_count_id_o = (((~ebrk_insn & ~ecall_insn_dec) & ~illegal_insn_dec) & ~illegal_csr_insn_i) & ~instr_fetch_err_i;
+ assign en_wb_o = instr_done;
+ assign perf_mul_wait_o = stall_multdiv & mult_en_dec;
+ assign perf_div_wait_o = stall_multdiv & div_en_dec;
+endmodule
+module brq_ifu_compressed_decoder (
+ instr_i,
+ instr_o,
+ is_compressed_o,
+ illegal_instr_o
+);
+ input wire [31:0] instr_i;
+ output reg [31:0] instr_o;
+ output wire is_compressed_o;
+ output reg illegal_instr_o;
+ localparam [6:0] brq_pkg_OPCODE_BRANCH = 7'h63;
+ localparam [6:0] brq_pkg_OPCODE_JAL = 7'h6f;
+ localparam [6:0] brq_pkg_OPCODE_JALR = 7'h67;
+ localparam [6:0] brq_pkg_OPCODE_LOAD = 7'h03;
+ localparam [6:0] brq_pkg_OPCODE_LUI = 7'h37;
+ localparam [6:0] brq_pkg_OPCODE_OP = 7'h33;
+ localparam [6:0] brq_pkg_OPCODE_OP_IMM = 7'h13;
+ localparam [6:0] brq_pkg_OPCODE_STORE = 7'h23;
+ always @(*) begin
+ instr_o = instr_i;
+ illegal_instr_o = 1'b0;
+ case (instr_i[1:0])
+ 2'b00:
+ case (instr_i[15:13])
+ 3'b000: begin
+ instr_o = {2'b00, instr_i[10:7], instr_i[12:11], instr_i[5], instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], {brq_pkg_OPCODE_OP_IMM}};
+ if (instr_i[12:5] == 8'b00000000)
+ illegal_instr_o = 1'b1;
+ end
+ 3'b010: instr_o = {5'b00000, instr_i[5], instr_i[12:10], instr_i[6], 2'b00, 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[4:2], {brq_pkg_OPCODE_LOAD}};
+ 3'b110: instr_o = {5'b00000, instr_i[5], instr_i[12], 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b010, instr_i[11:10], instr_i[6], 2'b00, {brq_pkg_OPCODE_STORE}};
+ 3'b001, 3'b011, 3'b100, 3'b101, 3'b111: illegal_instr_o = 1'b1;
+ endcase
+ 2'b01:
+ case (instr_i[15:13])
+ 3'b000: instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], {brq_pkg_OPCODE_OP_IMM}};
+ 3'b001, 3'b101: instr_o = {instr_i[12], instr_i[8], instr_i[10:9], instr_i[6], instr_i[7], instr_i[2], instr_i[11], instr_i[5:3], {9 {instr_i[12]}}, 4'b0000, ~instr_i[15], {brq_pkg_OPCODE_JAL}};
+ 3'b010: instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b00000, 3'b000, instr_i[11:7], {brq_pkg_OPCODE_OP_IMM}};
+ 3'b011: begin
+ instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], {brq_pkg_OPCODE_LUI}};
+ if (instr_i[11:7] == 5'h02)
+ instr_o = {{3 {instr_i[12]}}, instr_i[4:3], instr_i[5], instr_i[2], instr_i[6], 4'b0000, 5'h02, 3'b000, 5'h02, {brq_pkg_OPCODE_OP_IMM}};
+ if ({instr_i[12], instr_i[6:2]} == 6'b000000)
+ illegal_instr_o = 1'b1;
+ end
+ 3'b100:
+ case (instr_i[11:10])
+ 2'b00, 2'b01: begin
+ instr_o = {1'b0, instr_i[10], 5'b00000, instr_i[6:2], 2'b01, instr_i[9:7], 3'b101, 2'b01, instr_i[9:7], {brq_pkg_OPCODE_OP_IMM}};
+ if (instr_i[12] == 1'b1)
+ illegal_instr_o = 1'b1;
+ end
+ 2'b10: instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], {brq_pkg_OPCODE_OP_IMM}};
+ 2'b11:
+ case ({instr_i[12], instr_i[6:5]})
+ 3'b000: instr_o = {9'b010000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[9:7], {brq_pkg_OPCODE_OP}};
+ 3'b001: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[9:7], {brq_pkg_OPCODE_OP}};
+ 3'b010: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[9:7], {brq_pkg_OPCODE_OP}};
+ 3'b011: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], {brq_pkg_OPCODE_OP}};
+ 3'b100, 3'b101, 3'b110, 3'b111: illegal_instr_o = 1'b1;
+ endcase
+ endcase
+ 3'b110, 3'b111: instr_o = {{4 {instr_i[12]}}, instr_i[6:5], instr_i[2], 5'b00000, 2'b01, instr_i[9:7], 2'b00, instr_i[13], instr_i[11:10], instr_i[4:3], instr_i[12], {brq_pkg_OPCODE_BRANCH}};
+ endcase
+ 2'b10:
+ case (instr_i[15:13])
+ 3'b000: begin
+ instr_o = {7'b0000000, instr_i[6:2], instr_i[11:7], 3'b001, instr_i[11:7], {brq_pkg_OPCODE_OP_IMM}};
+ if (instr_i[12] == 1'b1)
+ illegal_instr_o = 1'b1;
+ end
+ 3'b010: begin
+ instr_o = {4'b0000, instr_i[3:2], instr_i[12], instr_i[6:4], 2'b00, 5'h02, 3'b010, instr_i[11:7], brq_pkg_OPCODE_LOAD};
+ if (instr_i[11:7] == 5'b00000)
+ illegal_instr_o = 1'b1;
+ end
+ 3'b100:
+ if (instr_i[12] == 1'b0) begin
+ if (instr_i[6:2] != 5'b00000)
+ instr_o = {7'b0000000, instr_i[6:2], 5'b00000, 3'b000, instr_i[11:7], {brq_pkg_OPCODE_OP}};
+ else begin
+ instr_o = {12'b000000000000, instr_i[11:7], 3'b000, 5'b00000, {brq_pkg_OPCODE_JALR}};
+ if (instr_i[11:7] == 5'b00000)
+ illegal_instr_o = 1'b1;
+ end
+ end
+ else if (instr_i[6:2] != 5'b00000)
+ instr_o = {7'b0000000, instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], {brq_pkg_OPCODE_OP}};
+ else if (instr_i[11:7] == 5'b00000)
+ instr_o = 32'h00100073;
+ else
+ instr_o = {12'b000000000000, instr_i[11:7], 3'b000, 5'b00001, {brq_pkg_OPCODE_JALR}};
+ 3'b110: instr_o = {4'b0000, instr_i[8:7], instr_i[12], instr_i[6:2], 5'h02, 3'b010, instr_i[11:9], 2'b00, {brq_pkg_OPCODE_STORE}};
+ 3'b001, 3'b011, 3'b101, 3'b111: illegal_instr_o = 1'b1;
+ endcase
+ 2'b11:
+ ;
+ endcase
+ end
+ assign is_compressed_o = instr_i[1:0] != 2'b11;
+endmodule
+module brq_ifu_fifo (
+ clk_i,
+ rst_ni,
+ clear_i,
+ busy_o,
+ in_valid_i,
+ in_addr_i,
+ in_rdata_i,
+ in_err_i,
+ out_valid_o,
+ out_ready_i,
+ out_addr_o,
+ out_addr_next_o,
+ out_rdata_o,
+ out_err_o,
+ out_err_plus2_o
+);
+ parameter [31:0] NUM_REQS = 2;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire clear_i;
+ output wire [NUM_REQS - 1:0] busy_o;
+ input wire in_valid_i;
+ input wire [31:0] in_addr_i;
+ input wire [31:0] in_rdata_i;
+ input wire in_err_i;
+ output reg out_valid_o;
+ input wire out_ready_i;
+ output wire [31:0] out_addr_o;
+ output wire [31:0] out_addr_next_o;
+ output reg [31:0] out_rdata_o;
+ output reg out_err_o;
+ output reg out_err_plus2_o;
+ localparam [31:0] DEPTH = NUM_REQS + 1;
+ wire [(DEPTH * 32) - 1:0] rdata_d;
+ reg [(DEPTH * 32) - 1:0] rdata_q;
+ wire [DEPTH - 1:0] err_d;
+ reg [DEPTH - 1:0] err_q;
+ wire [DEPTH - 1:0] valid_d;
+ reg [DEPTH - 1:0] valid_q;
+ wire [DEPTH - 1:0] lowest_free_entry;
+ wire [DEPTH - 1:0] valid_pushed;
+ wire [DEPTH - 1:0] valid_popped;
+ wire [DEPTH - 1:0] entry_en;
+ wire pop_fifo;
+ wire [31:0] rdata;
+ wire [31:0] rdata_unaligned;
+ wire err;
+ wire err_unaligned;
+ wire err_plus2;
+ wire valid;
+ wire valid_unaligned;
+ wire aligned_is_compressed;
+ wire unaligned_is_compressed;
+ wire addr_incr_two;
+ wire [31:1] instr_addr_next;
+ wire [31:1] instr_addr_d;
+ reg [31:1] instr_addr_q;
+ wire instr_addr_en;
+ wire unused_addr_in;
+ assign rdata = (valid_q[0] ? rdata_q[0+:32] : in_rdata_i);
+ assign err = (valid_q[0] ? err_q[0] : in_err_i);
+ assign valid = valid_q[0] | in_valid_i;
+ assign rdata_unaligned = (valid_q[1] ? {rdata_q[47-:16], rdata[31:16]} : {in_rdata_i[15:0], rdata[31:16]});
+ assign err_unaligned = (valid_q[1] ? (err_q[1] & ~unaligned_is_compressed) | err_q[0] : (valid_q[0] & err_q[0]) | (in_err_i & (~valid_q[0] | ~unaligned_is_compressed)));
+ assign err_plus2 = (valid_q[1] ? err_q[1] & ~err_q[0] : (in_err_i & valid_q[0]) & ~err_q[0]);
+ assign valid_unaligned = (valid_q[1] ? 1'b1 : valid_q[0] & in_valid_i);
+ assign unaligned_is_compressed = (rdata[17:16] != 2'b11) & ~err;
+ assign aligned_is_compressed = (rdata[1:0] != 2'b11) & ~err;
+ always @(*)
+ if (out_addr_o[1]) begin
+ out_rdata_o = rdata_unaligned;
+ out_err_o = err_unaligned;
+ out_err_plus2_o = err_plus2;
+ if (unaligned_is_compressed)
+ out_valid_o = valid;
+ else
+ out_valid_o = valid_unaligned;
+ end
+ else begin
+ out_rdata_o = rdata;
+ out_err_o = err;
+ out_err_plus2_o = 1'b0;
+ out_valid_o = valid;
+ end
+ assign instr_addr_en = clear_i | (out_ready_i & out_valid_o);
+ assign addr_incr_two = (instr_addr_q[1] ? unaligned_is_compressed : aligned_is_compressed);
+ assign instr_addr_next = instr_addr_q[31:1] + {29'd0, ~addr_incr_two, addr_incr_two};
+ assign instr_addr_d = (clear_i ? in_addr_i[31:1] : instr_addr_next);
+ always @(posedge clk_i)
+ if (instr_addr_en)
+ instr_addr_q <= instr_addr_d;
+ assign out_addr_next_o = {instr_addr_next, 1'b0};
+ assign out_addr_o = {instr_addr_q, 1'b0};
+ assign unused_addr_in = in_addr_i[0];
+ assign busy_o = valid_q[DEPTH - 1:DEPTH - NUM_REQS];
+ assign pop_fifo = (out_ready_i & out_valid_o) & (~aligned_is_compressed | out_addr_o[1]);
+ generate
+ genvar i;
+ for (i = 0; i < (DEPTH - 1); i = i + 1) begin : g_fifo_next
+ if (i == 0) begin : g_ent0
+ assign lowest_free_entry[i] = ~valid_q[i];
+ end
+ else begin : g_ent_others
+ assign lowest_free_entry[i] = ~valid_q[i] & valid_q[i - 1];
+ end
+ assign valid_pushed[i] = (in_valid_i & lowest_free_entry[i]) | valid_q[i];
+ assign valid_popped[i] = (pop_fifo ? valid_pushed[i + 1] : valid_pushed[i]);
+ assign valid_d[i] = valid_popped[i] & ~clear_i;
+ assign entry_en[i] = (valid_pushed[i + 1] & pop_fifo) | ((in_valid_i & lowest_free_entry[i]) & ~pop_fifo);
+ assign rdata_d[i * 32+:32] = (valid_q[i + 1] ? rdata_q[(i + 1) * 32+:32] : in_rdata_i);
+ assign err_d[i] = (valid_q[i + 1] ? err_q[i + 1] : in_err_i);
+ end
+ endgenerate
+ assign lowest_free_entry[DEPTH - 1] = ~valid_q[DEPTH - 1] & valid_q[DEPTH - 2];
+ assign valid_pushed[DEPTH - 1] = valid_q[DEPTH - 1] | (in_valid_i & lowest_free_entry[DEPTH - 1]);
+ assign valid_popped[DEPTH - 1] = (pop_fifo ? 1'b0 : valid_pushed[DEPTH - 1]);
+ assign valid_d[DEPTH - 1] = valid_popped[DEPTH - 1] & ~clear_i;
+ assign entry_en[DEPTH - 1] = in_valid_i & lowest_free_entry[DEPTH - 1];
+ assign rdata_d[(DEPTH - 1) * 32+:32] = in_rdata_i;
+ assign err_d[DEPTH - 1] = in_err_i;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ valid_q <= {DEPTH {1'sb0}};
+ else
+ valid_q <= valid_d;
+ generate
+ for (i = 0; i < DEPTH; i = i + 1) begin : g_fifo_regs
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni) begin
+ rdata_q[i * 32+:32] <= {32 {1'sb0}};
+ err_q[i] <= 1'b0;
+ end
+ else if (entry_en[i]) begin
+ rdata_q[i * 32+:32] <= rdata_d[i * 32+:32];
+ err_q[i] <= err_d[i];
+ end
+ end
+ endgenerate
+endmodule
+module brq_ifu_prefetch_buffer (
+ clk_i,
+ rst_ni,
+ req_i,
+ branch_i,
+ branch_spec_i,
+ predicted_branch_i,
+ addr_i,
+ ready_i,
+ valid_o,
+ rdata_o,
+ addr_o,
+ err_o,
+ err_plus2_o,
+ instr_req_o,
+ instr_gnt_i,
+ instr_addr_o,
+ instr_rdata_i,
+ instr_err_i,
+ instr_pmp_err_i,
+ instr_rvalid_i,
+ busy_o
+);
+ parameter [0:0] BranchPredictor = 1'b0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire req_i;
+ input wire branch_i;
+ input wire branch_spec_i;
+ input wire predicted_branch_i;
+ input wire [31:0] addr_i;
+ input wire ready_i;
+ output wire valid_o;
+ output wire [31:0] rdata_o;
+ output wire [31:0] addr_o;
+ output wire err_o;
+ output wire err_plus2_o;
+ output wire instr_req_o;
+ input wire instr_gnt_i;
+ output wire [31:0] instr_addr_o;
+ input wire [31:0] instr_rdata_i;
+ input wire instr_err_i;
+ input wire instr_pmp_err_i;
+ input wire instr_rvalid_i;
+ output wire busy_o;
+ wire branch_mispredict_i;
+ assign branch_mispredict_i = 1'b0;
+ localparam [31:0] NUM_REQS = 2;
+ wire branch_suppress;
+ wire valid_new_req;
+ wire valid_req;
+ wire valid_req_d;
+ reg valid_req_q;
+ wire discard_req_d;
+ reg discard_req_q;
+ wire gnt_or_pmp_err;
+ wire rvalid_or_pmp_err;
+ wire [1:0] rdata_outstanding_n;
+ wire [1:0] rdata_outstanding_s;
+ reg [1:0] rdata_outstanding_q;
+ wire [1:0] branch_discard_n;
+ wire [1:0] branch_discard_s;
+ reg [1:0] branch_discard_q;
+ wire [1:0] rdata_pmp_err_n;
+ wire [1:0] rdata_pmp_err_s;
+ reg [1:0] rdata_pmp_err_q;
+ wire [1:0] rdata_outstanding_rev;
+ wire [31:0] stored_addr_d;
+ reg [31:0] stored_addr_q;
+ wire stored_addr_en;
+ wire [31:0] fetch_addr_d;
+ reg [31:0] fetch_addr_q;
+ wire fetch_addr_en;
+ wire [31:0] branch_mispredict_addr;
+ wire [31:0] instr_addr;
+ wire [31:0] instr_addr_w_aligned;
+ wire instr_or_pmp_err;
+ wire fifo_valid;
+ wire [31:0] fifo_addr;
+ wire fifo_ready;
+ wire fifo_clear;
+ wire [1:0] fifo_busy;
+ wire valid_raw;
+ wire [31:0] addr_next;
+ wire branch_or_mispredict;
+ assign busy_o = |rdata_outstanding_q | instr_req_o;
+ assign branch_or_mispredict = branch_i | branch_mispredict_i;
+ assign instr_or_pmp_err = instr_err_i | rdata_pmp_err_q[0];
+ assign fifo_clear = branch_or_mispredict;
+ generate
+ genvar i;
+ for (i = 0; i < NUM_REQS; i = i + 1) begin : gen_rd_rev
+ assign rdata_outstanding_rev[i] = rdata_outstanding_q[1 - i];
+ end
+ endgenerate
+ assign fifo_ready = ~&(fifo_busy | rdata_outstanding_rev);
+ brq_ifu_fifo #(.NUM_REQS(NUM_REQS)) fifo_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .clear_i(fifo_clear),
+ .busy_o(fifo_busy),
+ .in_valid_i(fifo_valid),
+ .in_addr_i(fifo_addr),
+ .in_rdata_i(instr_rdata_i),
+ .in_err_i(instr_or_pmp_err),
+ .out_valid_o(valid_raw),
+ .out_ready_i(ready_i),
+ .out_rdata_o(rdata_o),
+ .out_addr_o(addr_o),
+ .out_addr_next_o(addr_next),
+ .out_err_o(err_o),
+ .out_err_plus2_o(err_plus2_o)
+ );
+ assign branch_suppress = branch_spec_i & ~branch_i;
+ assign valid_new_req = ((~branch_suppress & req_i) & (fifo_ready | branch_or_mispredict)) & ~rdata_outstanding_q[1];
+ assign valid_req = valid_req_q | valid_new_req;
+ assign gnt_or_pmp_err = instr_gnt_i | instr_pmp_err_i;
+ assign rvalid_or_pmp_err = rdata_outstanding_q[0] & (instr_rvalid_i | rdata_pmp_err_q[0]);
+ assign valid_req_d = valid_req & ~gnt_or_pmp_err;
+ assign discard_req_d = valid_req_q & (branch_or_mispredict | discard_req_q);
+ assign stored_addr_en = (valid_new_req & ~valid_req_q) & ~gnt_or_pmp_err;
+ assign stored_addr_d = instr_addr;
+ always @(posedge clk_i)
+ if (stored_addr_en)
+ stored_addr_q <= stored_addr_d;
+ generate
+ if (BranchPredictor) begin : g_branch_predictor
+ reg [31:0] branch_mispredict_addr_q;
+ wire branch_mispredict_addr_en;
+ assign branch_mispredict_addr_en = branch_i & predicted_branch_i;
+ always @(posedge clk_i)
+ if (branch_mispredict_addr_en)
+ branch_mispredict_addr_q <= addr_next;
+ assign branch_mispredict_addr = branch_mispredict_addr_q;
+ end
+ else begin : g_no_branch_predictor
+ wire unused_predicted_branch;
+ wire [31:0] unused_addr_next;
+ assign unused_predicted_branch = predicted_branch_i;
+ assign unused_addr_next = addr_next;
+ assign branch_mispredict_addr = {32 {1'sb0}};
+ end
+ endgenerate
+ assign fetch_addr_en = branch_or_mispredict | (valid_new_req & ~valid_req_q);
+ assign fetch_addr_d = (branch_i ? addr_i : (branch_mispredict_i ? {branch_mispredict_addr[31:2], 2'b00} : {fetch_addr_q[31:2], 2'b00})) + {{29 {1'b0}}, valid_new_req & ~valid_req_q, 2'b00};
+ always @(posedge clk_i)
+ if (fetch_addr_en)
+ fetch_addr_q <= fetch_addr_d;
+ assign instr_addr = (valid_req_q ? stored_addr_q : (branch_spec_i ? addr_i : (branch_mispredict_i ? branch_mispredict_addr : fetch_addr_q)));
+ assign instr_addr_w_aligned = {instr_addr[31:2], 2'b00};
+ generate
+ for (i = 0; i < NUM_REQS; i = i + 1) begin : g_outstanding_reqs
+ if (i == 0) begin : g_req0
+ assign rdata_outstanding_n[i] = (valid_req & gnt_or_pmp_err) | rdata_outstanding_q[i];
+ assign branch_discard_n[i] = (((valid_req & gnt_or_pmp_err) & discard_req_d) | (branch_or_mispredict & rdata_outstanding_q[i])) | branch_discard_q[i];
+ assign rdata_pmp_err_n[i] = ((valid_req & ~rdata_outstanding_q[i]) & instr_pmp_err_i) | rdata_pmp_err_q[i];
+ end
+ else begin : g_reqtop
+ assign rdata_outstanding_n[i] = ((valid_req & gnt_or_pmp_err) & rdata_outstanding_q[i - 1]) | rdata_outstanding_q[i];
+ assign branch_discard_n[i] = ((((valid_req & gnt_or_pmp_err) & discard_req_d) & rdata_outstanding_q[i - 1]) | (branch_or_mispredict & rdata_outstanding_q[i])) | branch_discard_q[i];
+ assign rdata_pmp_err_n[i] = (((valid_req & ~rdata_outstanding_q[i]) & instr_pmp_err_i) & rdata_outstanding_q[i - 1]) | rdata_pmp_err_q[i];
+ end
+ end
+ endgenerate
+ assign rdata_outstanding_s = (rvalid_or_pmp_err ? {1'b0, rdata_outstanding_n[1:1]} : rdata_outstanding_n);
+ assign branch_discard_s = (rvalid_or_pmp_err ? {1'b0, branch_discard_n[1:1]} : branch_discard_n);
+ assign rdata_pmp_err_s = (rvalid_or_pmp_err ? {1'b0, rdata_pmp_err_n[1:1]} : rdata_pmp_err_n);
+ assign fifo_valid = rvalid_or_pmp_err & ~branch_discard_q[0];
+ assign fifo_addr = (branch_i ? addr_i : branch_mispredict_addr);
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ valid_req_q <= 1'b0;
+ discard_req_q <= 1'b0;
+ rdata_outstanding_q <= 'b0;
+ branch_discard_q <= 'b0;
+ rdata_pmp_err_q <= 'b0;
+ end
+ else begin
+ valid_req_q <= valid_req_d;
+ discard_req_q <= discard_req_d;
+ rdata_outstanding_q <= rdata_outstanding_s;
+ branch_discard_q <= branch_discard_s;
+ rdata_pmp_err_q <= rdata_pmp_err_s;
+ end
+ assign instr_req_o = valid_req;
+ assign instr_addr_o = instr_addr_w_aligned;
+ assign valid_o = valid_raw & ~branch_mispredict_i;
+endmodule
+module brq_ifu (
+ clk_i,
+ rst_ni,
+ boot_addr_i,
+ req_i,
+ instr_req_o,
+ instr_addr_o,
+ instr_gnt_i,
+ instr_rvalid_i,
+ instr_rdata_i,
+ instr_err_i,
+ instr_pmp_err_i,
+ instr_valid_id_o,
+ instr_new_id_o,
+ instr_rdata_id_o,
+ instr_rdata_alu_id_o,
+ instr_rdata_c_id_o,
+ instr_is_compressed_id_o,
+ instr_fetch_err_o,
+ instr_fetch_err_plus2_o,
+ illegal_c_insn_id_o,
+ pc_if_o,
+ pc_id_o,
+ instr_valid_clear_i,
+ pc_set_i,
+ pc_set_spec_i,
+ pc_mux_i,
+ exc_pc_mux_i,
+ branch_target_ex_i,
+ csr_mepc_i,
+ csr_depc_i,
+ csr_mtvec_i,
+ csr_mtvec_init_o,
+ id_in_ready_i,
+ pc_mismatch_alert_o,
+ if_busy_o
+);
+ parameter [31:0] DmHaltAddr = 32'h1a110800;
+ parameter [31:0] DmExceptionAddr = 32'h1a110808;
+ parameter [0:0] DummyInstructions = 1'b0;
+ parameter [0:0] ICache = 1'b0;
+ parameter [0:0] ICacheECC = 1'b0;
+ parameter [0:0] PCIncrCheck = 1'b0;
+ parameter [0:0] BranchPredictor = 1'b0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [31:0] boot_addr_i;
+ input wire req_i;
+ output wire instr_req_o;
+ output wire [31:0] instr_addr_o;
+ input wire instr_gnt_i;
+ input wire instr_rvalid_i;
+ input wire [31:0] instr_rdata_i;
+ input wire instr_err_i;
+ input wire instr_pmp_err_i;
+ output wire instr_valid_id_o;
+ output wire instr_new_id_o;
+ output reg [31:0] instr_rdata_id_o;
+ output reg [31:0] instr_rdata_alu_id_o;
+ output reg [15:0] instr_rdata_c_id_o;
+ output reg instr_is_compressed_id_o;
+ output reg instr_fetch_err_o;
+ output reg instr_fetch_err_plus2_o;
+ output reg illegal_c_insn_id_o;
+ output wire [31:0] pc_if_o;
+ output reg [31:0] pc_id_o;
+ input wire instr_valid_clear_i;
+ input wire pc_set_i;
+ input wire pc_set_spec_i;
+ input wire [2:0] pc_mux_i;
+ input wire [1:0] exc_pc_mux_i;
+ input wire [31:0] branch_target_ex_i;
+ input wire [31:0] csr_mepc_i;
+ input wire [31:0] csr_depc_i;
+ input wire [31:0] csr_mtvec_i;
+ output wire csr_mtvec_init_o;
+ input wire id_in_ready_i;
+ output wire pc_mismatch_alert_o;
+ output wire if_busy_o;
+ wire instr_valid_id_d;
+ reg instr_valid_id_q;
+ wire instr_new_id_d;
+ reg instr_new_id_q;
+ wire prefetch_busy;
+ wire branch_req;
+ wire branch_spec;
+ wire predicted_branch;
+ reg [31:0] fetch_addr_n;
+ wire fetch_valid;
+ wire fetch_ready;
+ wire [31:0] fetch_rdata;
+ wire [31:0] fetch_addr;
+ wire fetch_err;
+ wire fetch_err_plus2;
+ wire if_instr_valid;
+ wire [31:0] if_instr_rdata;
+ wire [31:0] if_instr_addr;
+ wire if_instr_err;
+ reg [31:0] exc_pc;
+ wire if_id_pipe_reg_we;
+ wire [31:0] instr_out;
+ wire instr_is_compressed_out;
+ wire illegal_c_instr_out;
+ wire instr_err_out;
+ wire predict_branch_taken;
+ wire [31:0] predict_branch_pc;
+ wire [2:0] pc_mux_internal;
+ localparam [1:0] brq_pkg_EXC_PC_DBD = 2;
+ localparam [1:0] brq_pkg_EXC_PC_DBG_EXC = 3;
+ localparam [1:0] brq_pkg_EXC_PC_EXC = 0;
+ localparam [1:0] brq_pkg_EXC_PC_IRQ = 1;
+ always @(*) begin : exc_pc_mux
+ case (exc_pc_mux_i)
+ brq_pkg_EXC_PC_EXC: exc_pc = {csr_mtvec_i[31:2], 2'b00};
+ brq_pkg_EXC_PC_IRQ: exc_pc = {csr_mtvec_i[31:2], 2'b00};
+ brq_pkg_EXC_PC_DBD: exc_pc = DmHaltAddr;
+ brq_pkg_EXC_PC_DBG_EXC: exc_pc = DmExceptionAddr;
+ endcase
+ end
+ localparam [2:0] brq_pkg_PC_BP = 5;
+ assign pc_mux_internal = ((BranchPredictor && predict_branch_taken) && !pc_set_i ? brq_pkg_PC_BP : pc_mux_i);
+ localparam [2:0] brq_pkg_PC_BOOT = 0;
+ localparam [2:0] brq_pkg_PC_DRET = 4;
+ localparam [2:0] brq_pkg_PC_ERET = 3;
+ localparam [2:0] brq_pkg_PC_EXC = 2;
+ localparam [2:0] brq_pkg_PC_JUMP = 1;
+ always @(*) begin : fetch_addr_mux
+ case (pc_mux_internal)
+ brq_pkg_PC_BOOT: fetch_addr_n = {boot_addr_i[31:2], 2'b00};
+ brq_pkg_PC_JUMP: fetch_addr_n = branch_target_ex_i;
+ brq_pkg_PC_EXC: fetch_addr_n = exc_pc;
+ brq_pkg_PC_ERET: fetch_addr_n = csr_mepc_i;
+ brq_pkg_PC_DRET: fetch_addr_n = csr_depc_i;
+ brq_pkg_PC_BP: fetch_addr_n = (BranchPredictor ? predict_branch_pc : {boot_addr_i[31:2], 2'b00});
+ default: fetch_addr_n = {boot_addr_i[31:2], 2'b00};
+ endcase
+ end
+ assign csr_mtvec_init_o = (pc_mux_i == brq_pkg_PC_BOOT) & pc_set_i;
+ brq_ifu_prefetch_buffer #(.BranchPredictor(BranchPredictor)) ifu_prefetch_buffer_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .req_i(req_i),
+ .branch_i(branch_req),
+ .branch_spec_i(branch_spec),
+ .predicted_branch_i(predicted_branch),
+ .addr_i({fetch_addr_n[31:1], 1'b0}),
+ .ready_i(fetch_ready),
+ .valid_o(fetch_valid),
+ .rdata_o(fetch_rdata),
+ .addr_o(fetch_addr),
+ .err_o(fetch_err),
+ .err_plus2_o(fetch_err_plus2),
+ .instr_req_o(instr_req_o),
+ .instr_addr_o(instr_addr_o),
+ .instr_gnt_i(instr_gnt_i),
+ .instr_rvalid_i(instr_rvalid_i),
+ .instr_rdata_i(instr_rdata_i),
+ .instr_err_i(instr_err_i),
+ .instr_pmp_err_i(instr_pmp_err_i),
+ .busy_o(prefetch_busy)
+ );
+ assign branch_req = pc_set_i | predict_branch_taken;
+ assign branch_spec = pc_set_spec_i | predict_branch_taken;
+ assign pc_if_o = if_instr_addr;
+ assign if_busy_o = prefetch_busy;
+ wire [31:0] instr_decompressed;
+ wire illegal_c_insn;
+ wire instr_is_compressed;
+ brq_ifu_compressed_decoder ifu_compressed_decoder_i(
+ .instr_i(if_instr_rdata),
+ .instr_o(instr_decompressed),
+ .is_compressed_o(instr_is_compressed),
+ .illegal_instr_o(illegal_c_insn)
+ );
+ assign instr_out = instr_decompressed;
+ assign instr_is_compressed_out = instr_is_compressed;
+ assign illegal_c_instr_out = illegal_c_insn;
+ assign instr_err_out = if_instr_err;
+ assign instr_valid_id_d = ((if_instr_valid & id_in_ready_i) & ~pc_set_i) | (instr_valid_id_q & ~instr_valid_clear_i);
+ assign instr_new_id_d = if_instr_valid & id_in_ready_i;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ instr_valid_id_q <= 1'b0;
+ instr_new_id_q <= 1'b0;
+ end
+ else begin
+ instr_valid_id_q <= instr_valid_id_d;
+ instr_new_id_q <= instr_new_id_d;
+ end
+ assign instr_valid_id_o = instr_valid_id_q;
+ assign instr_new_id_o = instr_new_id_q;
+ assign if_id_pipe_reg_we = instr_new_id_d;
+ always @(posedge clk_i)
+ if (if_id_pipe_reg_we) begin
+ instr_rdata_id_o <= instr_out;
+ instr_rdata_alu_id_o <= instr_out;
+ instr_fetch_err_o <= instr_err_out;
+ instr_fetch_err_plus2_o <= fetch_err_plus2;
+ instr_rdata_c_id_o <= if_instr_rdata[15:0];
+ instr_is_compressed_id_o <= instr_is_compressed_out;
+ illegal_c_insn_id_o <= illegal_c_instr_out;
+ pc_id_o <= pc_if_o;
+ end
+ assign pc_mismatch_alert_o = 1'b0;
+ assign predict_branch_taken = 1'b0;
+ assign predicted_branch = 1'b0;
+ assign predict_branch_pc = 32'b00000000000000000000000000000000;
+ assign if_instr_valid = fetch_valid;
+ assign if_instr_rdata = fetch_rdata;
+ assign if_instr_addr = fetch_addr;
+ assign if_instr_err = fetch_err;
+ assign fetch_ready = id_in_ready_i;
+endmodule
+module brq_lsu (
+ clk_i,
+ rst_ni,
+ data_req_o,
+ data_gnt_i,
+ data_rvalid_i,
+ data_err_i,
+ data_pmp_err_i,
+ data_addr_o,
+ data_we_o,
+ data_be_o,
+ data_wdata_o,
+ data_rdata_i,
+ lsu_we_i,
+ lsu_type_i,
+ lsu_wdata_i,
+ lsu_sign_ext_i,
+ lsu_rdata_o,
+ lsu_rdata_valid_o,
+ lsu_req_i,
+ adder_result_ex_i,
+ addr_incr_req_o,
+ addr_last_o,
+ lsu_req_done_o,
+ lsu_resp_valid_o,
+ load_err_o,
+ store_err_o,
+ busy_o,
+ perf_load_o,
+ perf_store_o
+);
+ input wire clk_i;
+ input wire rst_ni;
+ output reg data_req_o;
+ input wire data_gnt_i;
+ input wire data_rvalid_i;
+ input wire data_err_i;
+ input wire data_pmp_err_i;
+ output wire [31:0] data_addr_o;
+ output wire data_we_o;
+ output wire [3:0] data_be_o;
+ output wire [31:0] data_wdata_o;
+ input wire [31:0] data_rdata_i;
+ input wire lsu_we_i;
+ input wire [1:0] lsu_type_i;
+ input wire [31:0] lsu_wdata_i;
+ input wire lsu_sign_ext_i;
+ output wire [31:0] lsu_rdata_o;
+ output wire lsu_rdata_valid_o;
+ input wire lsu_req_i;
+ input wire [31:0] adder_result_ex_i;
+ output reg addr_incr_req_o;
+ output wire [31:0] addr_last_o;
+ output wire lsu_req_done_o;
+ output wire lsu_resp_valid_o;
+ output wire load_err_o;
+ output wire store_err_o;
+ output wire busy_o;
+ output reg perf_load_o;
+ output reg perf_store_o;
+ wire [31:0] data_addr;
+ wire [31:0] data_addr_w_aligned;
+ reg [31:0] addr_last_q;
+ reg addr_update;
+ reg ctrl_update;
+ reg rdata_update;
+ reg [31:8] rdata_q;
+ reg [1:0] rdata_offset_q;
+ reg [1:0] data_type_q;
+ reg data_sign_ext_q;
+ reg data_we_q;
+ wire [1:0] data_offset;
+ reg [3:0] data_be;
+ reg [31:0] data_wdata;
+ reg [31:0] data_rdata_ext;
+ reg [31:0] rdata_w_ext;
+ reg [31:0] rdata_h_ext;
+ reg [31:0] rdata_b_ext;
+ wire split_misaligned_access;
+ reg handle_misaligned_q;
+ reg handle_misaligned_d;
+ reg pmp_err_q;
+ reg pmp_err_d;
+ reg lsu_err_q;
+ reg lsu_err_d;
+ wire data_or_pmp_err;
+ reg [2:0] ls_fsm_cs;
+ reg [2:0] ls_fsm_ns;
+ assign data_addr = adder_result_ex_i;
+ assign data_offset = data_addr[1:0];
+ always @(*)
+ case (lsu_type_i)
+ 2'b00:
+ if (!handle_misaligned_q)
+ case (data_offset)
+ 2'b00: data_be = 4'b1111;
+ 2'b01: data_be = 4'b1110;
+ 2'b10: data_be = 4'b1100;
+ 2'b11: data_be = 4'b1000;
+ endcase
+ else
+ case (data_offset)
+ 2'b00: data_be = 4'b0000;
+ 2'b01: data_be = 4'b0001;
+ 2'b10: data_be = 4'b0011;
+ 2'b11: data_be = 4'b0111;
+ endcase
+ 2'b01:
+ if (!handle_misaligned_q)
+ case (data_offset)
+ 2'b00: data_be = 4'b0011;
+ 2'b01: data_be = 4'b0110;
+ 2'b10: data_be = 4'b1100;
+ 2'b11: data_be = 4'b1000;
+ endcase
+ else
+ data_be = 4'b0001;
+ 2'b10, 2'b11:
+ case (data_offset)
+ 2'b00: data_be = 4'b0001;
+ 2'b01: data_be = 4'b0010;
+ 2'b10: data_be = 4'b0100;
+ 2'b11: data_be = 4'b1000;
+ endcase
+ endcase
+ always @(*)
+ case (data_offset)
+ 2'b00: data_wdata = lsu_wdata_i[31:0];
+ 2'b01: data_wdata = {lsu_wdata_i[23:0], lsu_wdata_i[31:24]};
+ 2'b10: data_wdata = {lsu_wdata_i[15:0], lsu_wdata_i[31:16]};
+ 2'b11: data_wdata = {lsu_wdata_i[7:0], lsu_wdata_i[31:8]};
+ endcase
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ rdata_q <= {24 {1'sb0}};
+ else if (rdata_update)
+ rdata_q <= data_rdata_i[31:8];
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ rdata_offset_q <= 2'h0;
+ data_type_q <= 2'h0;
+ data_sign_ext_q <= 1'b0;
+ data_we_q <= 1'b0;
+ end
+ else if (ctrl_update) begin
+ rdata_offset_q <= data_offset;
+ data_type_q <= lsu_type_i;
+ data_sign_ext_q <= lsu_sign_ext_i;
+ data_we_q <= lsu_we_i;
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ addr_last_q <= {32 {1'sb0}};
+ else if (addr_update)
+ addr_last_q <= data_addr;
+ always @(*)
+ case (rdata_offset_q)
+ 2'b00: rdata_w_ext = data_rdata_i[31:0];
+ 2'b01: rdata_w_ext = {data_rdata_i[7:0], rdata_q[31:8]};
+ 2'b10: rdata_w_ext = {data_rdata_i[15:0], rdata_q[31:16]};
+ 2'b11: rdata_w_ext = {data_rdata_i[23:0], rdata_q[31:24]};
+ endcase
+ always @(*)
+ case (rdata_offset_q)
+ 2'b00:
+ if (!data_sign_ext_q)
+ rdata_h_ext = {16'h0000, data_rdata_i[15:0]};
+ else
+ rdata_h_ext = {{16 {data_rdata_i[15]}}, data_rdata_i[15:0]};
+ 2'b01:
+ if (!data_sign_ext_q)
+ rdata_h_ext = {16'h0000, data_rdata_i[23:8]};
+ else
+ rdata_h_ext = {{16 {data_rdata_i[23]}}, data_rdata_i[23:8]};
+ 2'b10:
+ if (!data_sign_ext_q)
+ rdata_h_ext = {16'h0000, data_rdata_i[31:16]};
+ else
+ rdata_h_ext = {{16 {data_rdata_i[31]}}, data_rdata_i[31:16]};
+ 2'b11:
+ if (!data_sign_ext_q)
+ rdata_h_ext = {16'h0000, data_rdata_i[7:0], rdata_q[31:24]};
+ else
+ rdata_h_ext = {{16 {data_rdata_i[7]}}, data_rdata_i[7:0], rdata_q[31:24]};
+ endcase
+ always @(*)
+ case (rdata_offset_q)
+ 2'b00:
+ if (!data_sign_ext_q)
+ rdata_b_ext = {24'h000000, data_rdata_i[7:0]};
+ else
+ rdata_b_ext = {{24 {data_rdata_i[7]}}, data_rdata_i[7:0]};
+ 2'b01:
+ if (!data_sign_ext_q)
+ rdata_b_ext = {24'h000000, data_rdata_i[15:8]};
+ else
+ rdata_b_ext = {{24 {data_rdata_i[15]}}, data_rdata_i[15:8]};
+ 2'b10:
+ if (!data_sign_ext_q)
+ rdata_b_ext = {24'h000000, data_rdata_i[23:16]};
+ else
+ rdata_b_ext = {{24 {data_rdata_i[23]}}, data_rdata_i[23:16]};
+ 2'b11:
+ if (!data_sign_ext_q)
+ rdata_b_ext = {24'h000000, data_rdata_i[31:24]};
+ else
+ rdata_b_ext = {{24 {data_rdata_i[31]}}, data_rdata_i[31:24]};
+ endcase
+ always @(*)
+ case (data_type_q)
+ 2'b00: data_rdata_ext = rdata_w_ext;
+ 2'b01: data_rdata_ext = rdata_h_ext;
+ 2'b10, 2'b11: data_rdata_ext = rdata_b_ext;
+ endcase
+ assign split_misaligned_access = ((lsu_type_i == 2'b00) && (data_offset != 2'b00)) || ((lsu_type_i == 2'b01) && (data_offset == 2'b11));
+ localparam [2:0] IDLE = 0;
+ localparam [2:0] WAIT_GNT = 3;
+ localparam [2:0] WAIT_GNT_MIS = 1;
+ localparam [2:0] WAIT_RVALID_MIS = 2;
+ localparam [2:0] WAIT_RVALID_MIS_GNTS_DONE = 4;
+ always @(*) begin
+ ls_fsm_ns = ls_fsm_cs;
+ data_req_o = 1'b0;
+ addr_incr_req_o = 1'b0;
+ handle_misaligned_d = handle_misaligned_q;
+ pmp_err_d = pmp_err_q;
+ lsu_err_d = lsu_err_q;
+ addr_update = 1'b0;
+ ctrl_update = 1'b0;
+ rdata_update = 1'b0;
+ perf_load_o = 1'b0;
+ perf_store_o = 1'b0;
+ case (ls_fsm_cs)
+ IDLE: begin
+ pmp_err_d = 1'b0;
+ if (lsu_req_i) begin
+ data_req_o = 1'b1;
+ pmp_err_d = data_pmp_err_i;
+ lsu_err_d = 1'b0;
+ perf_load_o = ~lsu_we_i;
+ perf_store_o = lsu_we_i;
+ if (data_gnt_i) begin
+ ctrl_update = 1'b1;
+ addr_update = 1'b1;
+ handle_misaligned_d = split_misaligned_access;
+ ls_fsm_ns = (split_misaligned_access ? WAIT_RVALID_MIS : IDLE);
+ end
+ else
+ ls_fsm_ns = (split_misaligned_access ? WAIT_GNT_MIS : WAIT_GNT);
+ end
+ end
+ WAIT_GNT_MIS: begin
+ data_req_o = 1'b1;
+ if (data_gnt_i || pmp_err_q) begin
+ addr_update = 1'b1;
+ ctrl_update = 1'b1;
+ handle_misaligned_d = 1'b1;
+ ls_fsm_ns = WAIT_RVALID_MIS;
+ end
+ end
+ WAIT_RVALID_MIS: begin
+ data_req_o = 1'b1;
+ addr_incr_req_o = 1'b1;
+ if (data_rvalid_i || pmp_err_q) begin
+ pmp_err_d = data_pmp_err_i;
+ lsu_err_d = data_err_i | pmp_err_q;
+ rdata_update = ~data_we_q;
+ ls_fsm_ns = (data_gnt_i ? IDLE : WAIT_GNT);
+ addr_update = data_gnt_i & ~(data_err_i | pmp_err_q);
+ handle_misaligned_d = ~data_gnt_i;
+ end
+ else if (data_gnt_i) begin
+ ls_fsm_ns = WAIT_RVALID_MIS_GNTS_DONE;
+ handle_misaligned_d = 1'b0;
+ end
+ end
+ WAIT_GNT: begin
+ addr_incr_req_o = handle_misaligned_q;
+ data_req_o = 1'b1;
+ if (data_gnt_i || pmp_err_q) begin
+ ctrl_update = 1'b1;
+ addr_update = ~lsu_err_q;
+ ls_fsm_ns = IDLE;
+ handle_misaligned_d = 1'b0;
+ end
+ end
+ WAIT_RVALID_MIS_GNTS_DONE: begin
+ addr_incr_req_o = 1'b1;
+ if (data_rvalid_i) begin
+ pmp_err_d = data_pmp_err_i;
+ lsu_err_d = data_err_i;
+ addr_update = ~data_err_i;
+ rdata_update = ~data_we_q;
+ ls_fsm_ns = IDLE;
+ end
+ end
+ default: ls_fsm_ns = IDLE;
+ endcase
+ end
+ assign lsu_req_done_o = (lsu_req_i | (ls_fsm_cs != IDLE)) & (ls_fsm_ns == IDLE);
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ ls_fsm_cs <= IDLE;
+ handle_misaligned_q <= 1'b0;
+ pmp_err_q <= 1'b0;
+ lsu_err_q <= 1'b0;
+ end
+ else begin
+ ls_fsm_cs <= ls_fsm_ns;
+ handle_misaligned_q <= handle_misaligned_d;
+ pmp_err_q <= pmp_err_d;
+ lsu_err_q <= lsu_err_d;
+ end
+ assign data_or_pmp_err = (lsu_err_q | data_err_i) | pmp_err_q;
+ assign lsu_resp_valid_o = (data_rvalid_i | pmp_err_q) & (ls_fsm_cs == IDLE);
+ assign lsu_rdata_valid_o = (((ls_fsm_cs == IDLE) & data_rvalid_i) & ~data_or_pmp_err) & ~data_we_q;
+ assign lsu_rdata_o = data_rdata_ext;
+ assign data_addr_w_aligned = {data_addr[31:2], 2'b00};
+ assign data_addr_o = data_addr_w_aligned;
+ assign data_wdata_o = data_wdata;
+ assign data_we_o = lsu_we_i;
+ assign data_be_o = data_be;
+ assign addr_last_o = addr_last_q;
+ assign load_err_o = (data_or_pmp_err & ~data_we_q) & lsu_resp_valid_o;
+ assign store_err_o = (data_or_pmp_err & data_we_q) & lsu_resp_valid_o;
+ assign busy_o = ls_fsm_cs != IDLE;
+endmodule
+module brq_pmp (
+ clk_i,
+ rst_ni,
+ csr_pmp_cfg_i,
+ csr_pmp_addr_i,
+ priv_mode_i,
+ pmp_req_addr_i,
+ pmp_req_type_i,
+ pmp_req_err_o
+);
+ parameter [31:0] PMPGranularity = 0;
+ parameter [31:0] PMPNumChan = 2;
+ parameter [31:0] PMPNumRegions = 4;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(0 >= (PMPNumRegions - 1) ? ((2 - PMPNumRegions) * 6) + (((PMPNumRegions - 1) * 6) - 1) : (PMPNumRegions * 6) - 1):(0 >= (PMPNumRegions - 1) ? (PMPNumRegions - 1) * 6 : 0)] csr_pmp_cfg_i;
+ input wire [(0 >= (PMPNumRegions - 1) ? ((2 - PMPNumRegions) * 34) + (((PMPNumRegions - 1) * 34) - 1) : (PMPNumRegions * 34) - 1):(0 >= (PMPNumRegions - 1) ? (PMPNumRegions - 1) * 34 : 0)] csr_pmp_addr_i;
+ input wire [(0 >= (PMPNumChan - 1) ? ((2 - PMPNumChan) * 2) + (((PMPNumChan - 1) * 2) - 1) : (PMPNumChan * 2) - 1):(0 >= (PMPNumChan - 1) ? (PMPNumChan - 1) * 2 : 0)] priv_mode_i;
+ input wire [(0 >= (PMPNumChan - 1) ? ((2 - PMPNumChan) * 34) + (((PMPNumChan - 1) * 34) - 1) : (PMPNumChan * 34) - 1):(0 >= (PMPNumChan - 1) ? (PMPNumChan - 1) * 34 : 0)] pmp_req_addr_i;
+ input wire [(0 >= (PMPNumChan - 1) ? ((2 - PMPNumChan) * 2) + (((PMPNumChan - 1) * 2) - 1) : (PMPNumChan * 2) - 1):(0 >= (PMPNumChan - 1) ? (PMPNumChan - 1) * 2 : 0)] pmp_req_type_i;
+ output wire [0:PMPNumChan - 1] pmp_req_err_o;
+ wire [33:0] region_start_addr [0:PMPNumRegions - 1];
+ wire [33:PMPGranularity + 2] region_addr_mask [0:PMPNumRegions - 1];
+ wire [(PMPNumChan * PMPNumRegions) - 1:0] region_match_gt;
+ wire [(PMPNumChan * PMPNumRegions) - 1:0] region_match_lt;
+ wire [(PMPNumChan * PMPNumRegions) - 1:0] region_match_eq;
+ reg [(PMPNumChan * PMPNumRegions) - 1:0] region_match_all;
+ wire [(PMPNumChan * PMPNumRegions) - 1:0] region_perm_check;
+ reg [PMPNumChan - 1:0] access_fault;
+ localparam [1:0] brq_pkg_PMP_MODE_NAPOT = 2'b11;
+ localparam [1:0] brq_pkg_PMP_MODE_TOR = 2'b01;
+ generate
+ genvar r;
+ for (r = 0; r < PMPNumRegions; r = r + 1) begin : g_addr_exp
+ if (r == 0) begin : g_entry0
+ assign region_start_addr[r] = (csr_pmp_cfg_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6) + 4-:2] == brq_pkg_PMP_MODE_TOR ? 34'h000000000 : csr_pmp_addr_i[(0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 34+:34]);
+ end
+ else begin : g_oth
+ assign region_start_addr[r] = (csr_pmp_cfg_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6) + 4-:2] == brq_pkg_PMP_MODE_TOR ? csr_pmp_addr_i[(0 >= (PMPNumRegions - 1) ? r - 1 : (PMPNumRegions - 1) - (r - 1)) * 34+:34] : csr_pmp_addr_i[(0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 34+:34]);
+ end
+ genvar b;
+ for (b = PMPGranularity + 2; b < 34; b = b + 1) begin : g_bitmask
+ if (b == 2) begin : g_bit0
+ assign region_addr_mask[r][b] = csr_pmp_cfg_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6) + 4-:2] != brq_pkg_PMP_MODE_NAPOT;
+ end
+ else begin : g_others
+ assign region_addr_mask[r][b] = (csr_pmp_cfg_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6) + 4-:2] != brq_pkg_PMP_MODE_NAPOT) | ~&csr_pmp_addr_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 34) + ((b - 1) >= (PMPGranularity + 1) ? b - 1 : ((b - 1) + ((b - 1) >= (PMPGranularity + 1) ? ((b - 1) - (PMPGranularity + 1)) + 1 : ((PMPGranularity + 1) - (b - 1)) + 1)) - 1)-:((b - 1) >= (PMPGranularity + 1) ? ((b - 1) - (PMPGranularity + 1)) + 1 : ((PMPGranularity + 1) - (b - 1)) + 1)];
+ end
+ end
+ end
+ endgenerate
+ localparam [1:0] brq_pkg_PMP_ACC_EXEC = 2'b00;
+ localparam [1:0] brq_pkg_PMP_ACC_READ = 2'b10;
+ localparam [1:0] brq_pkg_PMP_ACC_WRITE = 2'b01;
+ localparam [1:0] brq_pkg_PMP_MODE_NA4 = 2'b10;
+ localparam [1:0] brq_pkg_PMP_MODE_OFF = 2'b00;
+ localparam [1:0] brq_pkg_PRIV_LVL_M = 2'b11;
+ generate
+ genvar c;
+ for (c = 0; c < PMPNumChan; c = c + 1) begin : g_access_check
+ for (r = 0; r < PMPNumRegions; r = r + 1) begin : g_regions
+ assign region_match_eq[(c * PMPNumRegions) + r] = (pmp_req_addr_i[((0 >= (PMPNumChan - 1) ? c : (PMPNumChan - 1) - c) * 34) + (33 >= (PMPGranularity + 2) ? 33 : (33 + (33 >= (PMPGranularity + 2) ? 34 - (PMPGranularity + 2) : PMPGranularity - 30)) - 1)-:(33 >= (PMPGranularity + 2) ? 34 - (PMPGranularity + 2) : PMPGranularity - 30)] & region_addr_mask[r]) == (region_start_addr[r][33:PMPGranularity + 2] & region_addr_mask[r]);
+ assign region_match_gt[(c * PMPNumRegions) + r] = pmp_req_addr_i[((0 >= (PMPNumChan - 1) ? c : (PMPNumChan - 1) - c) * 34) + (33 >= (PMPGranularity + 2) ? 33 : (33 + (33 >= (PMPGranularity + 2) ? 34 - (PMPGranularity + 2) : PMPGranularity - 30)) - 1)-:(33 >= (PMPGranularity + 2) ? 34 - (PMPGranularity + 2) : PMPGranularity - 30)] > region_start_addr[r][33:PMPGranularity + 2];
+ assign region_match_lt[(c * PMPNumRegions) + r] = pmp_req_addr_i[((0 >= (PMPNumChan - 1) ? c : (PMPNumChan - 1) - c) * 34) + (33 >= (PMPGranularity + 2) ? 33 : (33 + (33 >= (PMPGranularity + 2) ? 34 - (PMPGranularity + 2) : PMPGranularity - 30)) - 1)-:(33 >= (PMPGranularity + 2) ? 34 - (PMPGranularity + 2) : PMPGranularity - 30)] < csr_pmp_addr_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 34) + (33 >= (PMPGranularity + 2) ? 33 : (33 + (33 >= (PMPGranularity + 2) ? 34 - (PMPGranularity + 2) : PMPGranularity - 30)) - 1)-:(33 >= (PMPGranularity + 2) ? 34 - (PMPGranularity + 2) : PMPGranularity - 30)];
+ always @(*) begin
+ region_match_all[(c * PMPNumRegions) + r] = 1'b0;
+ case (csr_pmp_cfg_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6) + 4-:2])
+ brq_pkg_PMP_MODE_OFF: region_match_all[(c * PMPNumRegions) + r] = 1'b0;
+ brq_pkg_PMP_MODE_NA4: region_match_all[(c * PMPNumRegions) + r] = region_match_eq[(c * PMPNumRegions) + r];
+ brq_pkg_PMP_MODE_NAPOT: region_match_all[(c * PMPNumRegions) + r] = region_match_eq[(c * PMPNumRegions) + r];
+ brq_pkg_PMP_MODE_TOR: region_match_all[(c * PMPNumRegions) + r] = (region_match_eq[(c * PMPNumRegions) + r] | region_match_gt[(c * PMPNumRegions) + r]) & region_match_lt[(c * PMPNumRegions) + r];
+ default: region_match_all[(c * PMPNumRegions) + r] = 1'b0;
+ endcase
+ end
+ assign region_perm_check[(c * PMPNumRegions) + r] = (((pmp_req_type_i[(0 >= (PMPNumChan - 1) ? c : (PMPNumChan - 1) - c) * 2+:2] == brq_pkg_PMP_ACC_EXEC) & csr_pmp_cfg_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6) + 2]) | ((pmp_req_type_i[(0 >= (PMPNumChan - 1) ? c : (PMPNumChan - 1) - c) * 2+:2] == brq_pkg_PMP_ACC_WRITE) & csr_pmp_cfg_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6) + 1])) | ((pmp_req_type_i[(0 >= (PMPNumChan - 1) ? c : (PMPNumChan - 1) - c) * 2+:2] == brq_pkg_PMP_ACC_READ) & csr_pmp_cfg_i[(0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6]);
+ end
+ always @(*) begin
+ access_fault[c] = priv_mode_i[(0 >= (PMPNumChan - 1) ? c : (PMPNumChan - 1) - c) * 2+:2] != brq_pkg_PRIV_LVL_M;
+ begin : sv2v_autoblock_98
+ reg signed [31:0] r;
+ for (r = PMPNumRegions - 1; r >= 0; r = r - 1)
+ if (region_match_all[(c * PMPNumRegions) + r])
+ access_fault[c] = (priv_mode_i[(0 >= (PMPNumChan - 1) ? c : (PMPNumChan - 1) - c) * 2+:2] == brq_pkg_PRIV_LVL_M ? csr_pmp_cfg_i[((0 >= (PMPNumRegions - 1) ? r : (PMPNumRegions - 1) - r) * 6) + 5] & ~region_perm_check[(c * PMPNumRegions) + r] : ~region_perm_check[(c * PMPNumRegions) + r]);
+ end
+ end
+ assign pmp_req_err_o[c] = access_fault[c];
+ end
+ endgenerate
+endmodule
+module brq_register_file_ff (
+ clk_i,
+ rst_ni,
+ dummy_instr_id_i,
+ raddr_a_i,
+ rdata_a_o,
+ raddr_b_i,
+ rdata_b_o,
+ waddr_a_i,
+ wdata_a_i,
+ we_a_i
+);
+ parameter [0:0] RV32E = 0;
+ parameter [31:0] DataWidth = 32;
+ parameter [0:0] DummyInstructions = 0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire dummy_instr_id_i;
+ input wire [4:0] raddr_a_i;
+ output wire [DataWidth - 1:0] rdata_a_o;
+ input wire [4:0] raddr_b_i;
+ output wire [DataWidth - 1:0] rdata_b_o;
+ input wire [4:0] waddr_a_i;
+ input wire [DataWidth - 1:0] wdata_a_i;
+ input wire we_a_i;
+ localparam [31:0] ADDR_WIDTH = (RV32E ? 4 : 5);
+ localparam [31:0] NUM_WORDS = 2 ** ADDR_WIDTH;
+ wire [(NUM_WORDS * DataWidth) - 1:0] rf_reg;
+ reg [((NUM_WORDS - 1) >= 1 ? ((NUM_WORDS - 1) * DataWidth) + (DataWidth - 1) : ((3 - NUM_WORDS) * DataWidth) + (((NUM_WORDS - 1) * DataWidth) - 1)):((NUM_WORDS - 1) >= 1 ? DataWidth : (NUM_WORDS - 1) * DataWidth)] rf_reg_q;
+ reg [NUM_WORDS - 1:1] we_a_dec;
+ function automatic [4:0] sv2v_cast_5;
+ input reg [4:0] inp;
+ sv2v_cast_5 = inp;
+ endfunction
+ always @(*) begin : we_a_decoder
+ begin : sv2v_autoblock_99
+ reg [31:0] i;
+ for (i = 1; i < NUM_WORDS; i = i + 1)
+ we_a_dec[i] = (waddr_a_i == sv2v_cast_5(i) ? we_a_i : 1'b0);
+ end
+ end
+ generate
+ genvar i;
+ for (i = 1; i < NUM_WORDS; i = i + 1) begin : g_rf_flops
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ rf_reg_q[((NUM_WORDS - 1) >= 1 ? i : 1 - (i - (NUM_WORDS - 1))) * DataWidth+:DataWidth] <= {DataWidth {1'sb0}};
+ else if (we_a_dec[i])
+ rf_reg_q[((NUM_WORDS - 1) >= 1 ? i : 1 - (i - (NUM_WORDS - 1))) * DataWidth+:DataWidth] <= wdata_a_i;
+ end
+ endgenerate
+ generate
+ if (DummyInstructions) begin : g_dummy_r0
+ wire we_r0_dummy;
+ reg [DataWidth - 1:0] rf_r0_q;
+ assign we_r0_dummy = we_a_i & dummy_instr_id_i;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ rf_r0_q <= {DataWidth {1'sb0}};
+ else if (we_r0_dummy)
+ rf_r0_q <= wdata_a_i;
+ assign rf_reg[0+:DataWidth] = (dummy_instr_id_i ? rf_r0_q : {DataWidth {1'sb0}});
+ end
+ else begin : g_normal_r0
+ wire unused_dummy_instr_id;
+ assign unused_dummy_instr_id = dummy_instr_id_i;
+ assign rf_reg[0+:DataWidth] = {DataWidth {1'sb0}};
+ end
+ endgenerate
+ assign rf_reg[DataWidth * (((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : ((NUM_WORDS - 1) + ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS)) - 1) - (((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS) - 1))+:DataWidth * ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS)] = rf_reg_q[DataWidth * ((NUM_WORDS - 1) >= 1 ? ((NUM_WORDS - 1) >= 1 ? ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : ((NUM_WORDS - 1) + ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS)) - 1) - (((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS) - 1) : ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : ((NUM_WORDS - 1) + ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS)) - 1)) : 1 - (((NUM_WORDS - 1) >= 1 ? ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : ((NUM_WORDS - 1) + ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS)) - 1) - (((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS) - 1) : ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : ((NUM_WORDS - 1) + ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS)) - 1)) - (NUM_WORDS - 1)))+:DataWidth * ((NUM_WORDS - 1) >= 1 ? NUM_WORDS - 1 : 3 - NUM_WORDS)];
+ assign rdata_a_o = rf_reg[raddr_a_i * DataWidth+:DataWidth];
+ assign rdata_b_o = rf_reg[raddr_b_i * DataWidth+:DataWidth];
+endmodule
+module brq_wbu (
+ clk_i,
+ rst_ni,
+ en_wb_i,
+ instr_type_wb_i,
+ pc_id_i,
+ instr_is_compressed_id_i,
+ instr_perf_count_id_i,
+ ready_wb_o,
+ rf_write_wb_o,
+ outstanding_load_wb_o,
+ outstanding_store_wb_o,
+ pc_wb_o,
+ perf_instr_ret_wb_o,
+ perf_instr_ret_compressed_wb_o,
+ rf_waddr_id_i,
+ rf_wdata_id_i,
+ rf_we_id_i,
+ rf_wdata_lsu_i,
+ rf_we_lsu_i,
+ rf_wdata_fwd_wb_o,
+ rf_waddr_wb_o,
+ rf_wdata_wb_o,
+ rf_we_wb_o,
+ lsu_resp_valid_i,
+ lsu_resp_err_i,
+ instr_done_wb_o,
+ fp_rf_write_wb_o,
+ fp_rf_wen_wb_o,
+ fp_rf_waddr_wb_o,
+ fp_rf_waddr_id_i,
+ fp_rf_wen_id_i,
+ fp_rf_wdata_wb_o,
+ fp_load_i
+);
+ parameter [0:0] WritebackStage = 1'b0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire en_wb_i;
+ input wire [1:0] instr_type_wb_i;
+ input wire [31:0] pc_id_i;
+ input wire instr_is_compressed_id_i;
+ input wire instr_perf_count_id_i;
+ output wire ready_wb_o;
+ output wire rf_write_wb_o;
+ output wire outstanding_load_wb_o;
+ output wire outstanding_store_wb_o;
+ output wire [31:0] pc_wb_o;
+ output wire perf_instr_ret_wb_o;
+ output wire perf_instr_ret_compressed_wb_o;
+ input wire [4:0] rf_waddr_id_i;
+ input wire [31:0] rf_wdata_id_i;
+ input wire rf_we_id_i;
+ input wire [31:0] rf_wdata_lsu_i;
+ input wire rf_we_lsu_i;
+ output wire [31:0] rf_wdata_fwd_wb_o;
+ output wire [4:0] rf_waddr_wb_o;
+ output wire [31:0] rf_wdata_wb_o;
+ output wire rf_we_wb_o;
+ input wire lsu_resp_valid_i;
+ input wire lsu_resp_err_i;
+ output wire instr_done_wb_o;
+ output wire fp_rf_write_wb_o;
+ output wire fp_rf_wen_wb_o;
+ output wire [4:0] fp_rf_waddr_wb_o;
+ input wire [4:0] fp_rf_waddr_id_i;
+ input wire fp_rf_wen_id_i;
+ output wire [31:0] fp_rf_wdata_wb_o;
+ input wire fp_load_i;
+ wire [31:0] rf_wdata_wb_mux [0:1];
+ wire [1:0] rf_wdata_wb_mux_we;
+ wire [31:0] fp_rf_wdata_wb_mux [0:1];
+ wire [1:0] fp_rf_wdata_wb_mux_we;
+ localparam [1:0] brq_pkg_WB_INSTR_LOAD = 0;
+ localparam [1:0] brq_pkg_WB_INSTR_OTHER = 2;
+ localparam [1:0] brq_pkg_WB_INSTR_STORE = 1;
+ generate
+ if (WritebackStage) begin : g_writeback_stage
+ reg [31:0] rf_wdata_wb_q;
+ reg rf_we_wb_q;
+ reg [4:0] rf_waddr_wb_q;
+ wire wb_done;
+ reg wb_valid_q;
+ reg [31:0] wb_pc_q;
+ reg wb_compressed_q;
+ reg wb_count_q;
+ reg [1:0] wb_instr_type_q;
+ wire wb_valid_d;
+ reg fp_rf_we_wb_q;
+ reg fp_load_q;
+ assign wb_valid_d = (en_wb_i & ready_wb_o) | (wb_valid_q & ~wb_done);
+ assign wb_done = (wb_instr_type_q == brq_pkg_WB_INSTR_OTHER) | lsu_resp_valid_i;
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni)
+ wb_valid_q <= 1'b0;
+ else
+ wb_valid_q <= wb_valid_d;
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni) begin
+ rf_we_wb_q <= 1'b0;
+ rf_waddr_wb_q <= {5 {1'sb0}};
+ rf_wdata_wb_q <= {32 {1'sb0}};
+ wb_instr_type_q <= {2 {1'sb0}};
+ wb_pc_q <= {32 {1'sb0}};
+ wb_compressed_q <= 1'b0;
+ wb_count_q <= 1'b0;
+ fp_rf_we_wb_q <= 1'b0;
+ fp_load_q <= 1'b0;
+ end
+ else if (en_wb_i) begin
+ rf_we_wb_q <= rf_we_id_i;
+ rf_waddr_wb_q <= rf_waddr_id_i;
+ rf_wdata_wb_q <= rf_wdata_id_i;
+ wb_instr_type_q <= instr_type_wb_i;
+ wb_pc_q <= pc_id_i;
+ wb_compressed_q <= instr_is_compressed_id_i;
+ wb_count_q <= instr_perf_count_id_i;
+ fp_rf_we_wb_q <= fp_rf_wen_id_i;
+ fp_load_q <= fp_load_i;
+ end
+ assign rf_waddr_wb_o = rf_waddr_wb_q;
+ assign rf_wdata_wb_mux[0] = rf_wdata_wb_q;
+ assign rf_wdata_wb_mux_we[0] = rf_we_wb_q & wb_valid_q;
+ assign fp_rf_waddr_wb_o = rf_waddr_wb_q;
+ assign fp_rf_wdata_wb_mux[0] = rf_wdata_wb_q;
+ assign fp_rf_wdata_wb_mux_we[0] = fp_rf_we_wb_q & wb_valid_q;
+ assign ready_wb_o = ~wb_valid_q | wb_done;
+ assign rf_write_wb_o = wb_valid_q & (rf_we_wb_q | (wb_instr_type_q == brq_pkg_WB_INSTR_LOAD));
+ assign fp_rf_write_wb_o = wb_valid_q & (fp_rf_we_wb_q | (wb_instr_type_q == brq_pkg_WB_INSTR_LOAD));
+ assign outstanding_load_wb_o = wb_valid_q & (wb_instr_type_q == brq_pkg_WB_INSTR_LOAD);
+ assign outstanding_store_wb_o = wb_valid_q & (wb_instr_type_q == brq_pkg_WB_INSTR_STORE);
+ assign pc_wb_o = wb_pc_q;
+ assign instr_done_wb_o = wb_valid_q & wb_done;
+ assign perf_instr_ret_wb_o = (instr_done_wb_o & wb_count_q) & ~(lsu_resp_valid_i & lsu_resp_err_i);
+ assign perf_instr_ret_compressed_wb_o = perf_instr_ret_wb_o & wb_compressed_q;
+ assign rf_wdata_fwd_wb_o = rf_wdata_wb_q;
+ assign rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
+ assign rf_wdata_wb_mux_we[1] = rf_we_lsu_i & ~fp_load_q;
+ assign fp_rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
+ assign fp_rf_wdata_wb_mux_we[1] = rf_we_lsu_i & fp_load_q;
+ end
+ else begin : g_bypass_wb
+ assign rf_waddr_wb_o = rf_waddr_id_i;
+ assign rf_wdata_wb_mux[0] = rf_wdata_id_i;
+ assign rf_wdata_wb_mux_we[0] = rf_we_id_i;
+ assign fp_rf_waddr_wb_o = rf_waddr_id_i;
+ assign fp_rf_wdata_wb_mux[0] = rf_wdata_id_i;
+ assign fp_rf_wdata_wb_mux_we[0] = fp_rf_wen_id_i;
+ assign perf_instr_ret_wb_o = (instr_perf_count_id_i & en_wb_i) & ~(lsu_resp_valid_i & lsu_resp_err_i);
+ assign perf_instr_ret_compressed_wb_o = perf_instr_ret_wb_o & instr_is_compressed_id_i;
+ assign ready_wb_o = 1'b1;
+ wire unused_clk;
+ wire unused_rst;
+ wire [1:0] unused_instr_type_wb;
+ wire [31:0] unused_pc_id;
+ assign unused_clk = clk_i;
+ assign unused_rst = rst_ni;
+ assign unused_instr_type_wb = instr_type_wb_i;
+ assign unused_pc_id = pc_id_i;
+ assign outstanding_load_wb_o = 1'b0;
+ assign outstanding_store_wb_o = 1'b0;
+ assign pc_wb_o = {32 {1'sb0}};
+ assign rf_write_wb_o = 1'b0;
+ assign rf_wdata_fwd_wb_o = 32'b00000000000000000000000000000000;
+ assign instr_done_wb_o = 1'b0;
+ assign rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
+ assign rf_wdata_wb_mux_we[1] = rf_we_lsu_i & ~fp_load_i;
+ assign fp_rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
+ assign fp_rf_wdata_wb_mux_we[1] = rf_we_lsu_i & fp_load_i;
+ end
+ endgenerate
+ assign rf_wdata_wb_o = (rf_wdata_wb_mux_we[0] ? rf_wdata_wb_mux[0] : rf_wdata_wb_mux[1]);
+ assign rf_we_wb_o = |rf_wdata_wb_mux_we;
+ assign fp_rf_wdata_wb_o = (fp_rf_wdata_wb_mux_we[0] ? fp_rf_wdata_wb_mux[0] : fp_rf_wdata_wb_mux[1]);
+ assign fp_rf_wen_wb_o = |fp_rf_wdata_wb_mux_we;
+endmodule
+module control_mvp (
+ Clk_CI,
+ Rst_RBI,
+ Div_start_SI,
+ Sqrt_start_SI,
+ Start_SI,
+ Kill_SI,
+ Special_case_SBI,
+ Special_case_dly_SBI,
+ Precision_ctl_SI,
+ Format_sel_SI,
+ Numerator_DI,
+ Exp_num_DI,
+ Denominator_DI,
+ Exp_den_DI,
+ Div_start_dly_SO,
+ Sqrt_start_dly_SO,
+ Div_enable_SO,
+ Sqrt_enable_SO,
+ Full_precision_SO,
+ FP32_SO,
+ FP64_SO,
+ FP16_SO,
+ FP16ALT_SO,
+ Ready_SO,
+ Done_SO,
+ Mant_result_prenorm_DO,
+ Exp_result_prenorm_DO
+);
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Div_start_SI;
+ input wire Sqrt_start_SI;
+ input wire Start_SI;
+ input wire Kill_SI;
+ input wire Special_case_SBI;
+ input wire Special_case_dly_SBI;
+ localparam defs_div_sqrt_mvp_C_PC = 6;
+ input wire [5:0] Precision_ctl_SI;
+ input wire [1:0] Format_sel_SI;
+ localparam defs_div_sqrt_mvp_C_MANT_FP64 = 52;
+ input wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Numerator_DI;
+ localparam defs_div_sqrt_mvp_C_EXP_FP64 = 11;
+ input wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_num_DI;
+ input wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Denominator_DI;
+ input wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_den_DI;
+ output wire Div_start_dly_SO;
+ output wire Sqrt_start_dly_SO;
+ output reg Div_enable_SO;
+ output reg Sqrt_enable_SO;
+ output wire Full_precision_SO;
+ output wire FP32_SO;
+ output wire FP64_SO;
+ output wire FP16_SO;
+ output wire FP16ALT_SO;
+ output reg Ready_SO;
+ output reg Done_SO;
+ output reg [56:0] Mant_result_prenorm_DO;
+ output wire [12:0] Exp_result_prenorm_DO;
+ reg [57:0] Partial_remainder_DN;
+ reg [57:0] Partial_remainder_DP;
+ reg [56:0] Quotient_DP;
+ wire [53:0] Numerator_se_D;
+ wire [53:0] Denominator_se_D;
+ reg [53:0] Denominator_se_DB;
+ assign Numerator_se_D = {1'b0, Numerator_DI};
+ assign Denominator_se_D = {1'b0, Denominator_DI};
+ localparam defs_div_sqrt_mvp_C_MANT_FP16 = 10;
+ localparam defs_div_sqrt_mvp_C_MANT_FP16ALT = 7;
+ localparam defs_div_sqrt_mvp_C_MANT_FP32 = 23;
+ always @(*)
+ if (FP32_SO)
+ Denominator_se_DB = {~Denominator_se_D[53:29], {29 {1'b0}}};
+ else if (FP64_SO)
+ Denominator_se_DB = ~Denominator_se_D;
+ else if (FP16_SO)
+ Denominator_se_DB = {~Denominator_se_D[53:42], {42 {1'b0}}};
+ else
+ Denominator_se_DB = {~Denominator_se_D[53:45], {45 {1'b0}}};
+ wire [53:0] Mant_D_sqrt_Norm;
+ assign Mant_D_sqrt_Norm = (Exp_num_DI[0] ? {1'b0, Numerator_DI} : {Numerator_DI, 1'b0});
+ reg [1:0] Format_sel_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Format_sel_S <= 'b0;
+ else if (Start_SI && Ready_SO)
+ Format_sel_S <= Format_sel_SI;
+ else
+ Format_sel_S <= Format_sel_S;
+ assign FP32_SO = Format_sel_S == 2'b00;
+ assign FP64_SO = Format_sel_S == 2'b01;
+ assign FP16_SO = Format_sel_S == 2'b10;
+ assign FP16ALT_SO = Format_sel_S == 2'b11;
+ reg [5:0] Precision_ctl_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Precision_ctl_S <= 'b0;
+ else if (Start_SI && Ready_SO)
+ Precision_ctl_S <= Precision_ctl_SI;
+ else
+ Precision_ctl_S <= Precision_ctl_S;
+ assign Full_precision_SO = Precision_ctl_S == 6'h00;
+ reg [5:0] State_ctl_S;
+ wire [5:0] State_Two_iteration_unit_S;
+ wire [5:0] State_Four_iteration_unit_S;
+ assign State_Two_iteration_unit_S = Precision_ctl_S[5:1];
+ assign State_Four_iteration_unit_S = Precision_ctl_S[5:2];
+ localparam defs_div_sqrt_mvp_Iteration_unit_num_S = 2'b10;
+ always @(*)
+ case (defs_div_sqrt_mvp_Iteration_unit_num_S)
+ 2'b00:
+ case (Format_sel_S)
+ 2'b00:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h1b;
+ else
+ State_ctl_S = Precision_ctl_S;
+ 2'b01:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h38;
+ else
+ State_ctl_S = Precision_ctl_S;
+ 2'b10:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h0e;
+ else
+ State_ctl_S = Precision_ctl_S;
+ 2'b11:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h0b;
+ else
+ State_ctl_S = Precision_ctl_S;
+ endcase
+ 2'b01:
+ case (Format_sel_S)
+ 2'b00:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h0d;
+ else
+ State_ctl_S = State_Two_iteration_unit_S;
+ 2'b01:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h1b;
+ else
+ State_ctl_S = State_Two_iteration_unit_S;
+ 2'b10:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h06;
+ else
+ State_ctl_S = State_Two_iteration_unit_S;
+ 2'b11:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h05;
+ else
+ State_ctl_S = State_Two_iteration_unit_S;
+ endcase
+ 2'b10:
+ case (Format_sel_S)
+ 2'b00:
+ case (Precision_ctl_S)
+ 6'h00: State_ctl_S = 6'h08;
+ 6'h06, 6'h07, 6'h08: State_ctl_S = 6'h02;
+ 6'h09, 6'h0a, 6'h0b: State_ctl_S = 6'h03;
+ 6'h0c, 6'h0d, 6'h0e: State_ctl_S = 6'h04;
+ 6'h0f, 6'h10, 6'h11: State_ctl_S = 6'h05;
+ 6'h12, 6'h13, 6'h14: State_ctl_S = 6'h06;
+ 6'h15, 6'h16, 6'h17: State_ctl_S = 6'h07;
+ default: State_ctl_S = 6'h08;
+ endcase
+ 2'b01:
+ case (Precision_ctl_S)
+ 6'h00: State_ctl_S = 6'h12;
+ 6'h06, 6'h07, 6'h08: State_ctl_S = 6'h02;
+ 6'h09, 6'h0a, 6'h0b: State_ctl_S = 6'h03;
+ 6'h0c, 6'h0d, 6'h0e: State_ctl_S = 6'h04;
+ 6'h0f, 6'h10, 6'h11: State_ctl_S = 6'h05;
+ 6'h12, 6'h13, 6'h14: State_ctl_S = 6'h06;
+ 6'h15, 6'h16, 6'h17: State_ctl_S = 6'h07;
+ 6'h18, 6'h19, 6'h1a: State_ctl_S = 6'h08;
+ 6'h1b, 6'h1c, 6'h1d: State_ctl_S = 6'h09;
+ 6'h1e, 6'h1f, 6'h20: State_ctl_S = 6'h0a;
+ 6'h21, 6'h22, 6'h23: State_ctl_S = 6'h0b;
+ 6'h24, 6'h25, 6'h26: State_ctl_S = 6'h0c;
+ 6'h27, 6'h28, 6'h29: State_ctl_S = 6'h0d;
+ 6'h2a, 6'h2b, 6'h2c: State_ctl_S = 6'h0e;
+ 6'h2d, 6'h2e, 6'h2f: State_ctl_S = 6'h0f;
+ 6'h30, 6'h31, 6'h32: State_ctl_S = 6'h10;
+ 6'h33, 6'h34, 6'h35: State_ctl_S = 6'h11;
+ default: State_ctl_S = 6'h12;
+ endcase
+ 2'b10:
+ case (Precision_ctl_S)
+ 6'h00: State_ctl_S = 6'h04;
+ 6'h06, 6'h07, 6'h08: State_ctl_S = 6'h02;
+ 6'h09, 6'h0a, 6'h0b: State_ctl_S = 6'h03;
+ default: State_ctl_S = 6'h04;
+ endcase
+ 2'b11:
+ case (Precision_ctl_S)
+ 6'h00: State_ctl_S = 6'h03;
+ 6'h06, 6'h07, 6'h08: State_ctl_S = 6'h02;
+ default: State_ctl_S = 6'h03;
+ endcase
+ endcase
+ 2'b11:
+ case (Format_sel_S)
+ 2'b00:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h06;
+ else
+ State_ctl_S = State_Four_iteration_unit_S;
+ 2'b01:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h0d;
+ else
+ State_ctl_S = State_Four_iteration_unit_S;
+ 2'b10:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h03;
+ else
+ State_ctl_S = State_Four_iteration_unit_S;
+ 2'b11:
+ if (Full_precision_SO)
+ State_ctl_S = 6'h02;
+ else
+ State_ctl_S = State_Four_iteration_unit_S;
+ endcase
+ endcase
+ reg Div_start_dly_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Div_start_dly_S <= 1'b0;
+ else if (Div_start_SI && Ready_SO)
+ Div_start_dly_S <= 1'b1;
+ else
+ Div_start_dly_S <= 1'b0;
+ assign Div_start_dly_SO = Div_start_dly_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Div_enable_SO <= 1'b0;
+ else if (Kill_SI)
+ Div_enable_SO <= 1'b0;
+ else if (Div_start_SI && Ready_SO)
+ Div_enable_SO <= 1'b1;
+ else if (Done_SO)
+ Div_enable_SO <= 1'b0;
+ else
+ Div_enable_SO <= Div_enable_SO;
+ reg Sqrt_start_dly_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Sqrt_start_dly_S <= 1'b0;
+ else if (Sqrt_start_SI && Ready_SO)
+ Sqrt_start_dly_S <= 1'b1;
+ else
+ Sqrt_start_dly_S <= 1'b0;
+ assign Sqrt_start_dly_SO = Sqrt_start_dly_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Sqrt_enable_SO <= 1'b0;
+ else if (Kill_SI)
+ Sqrt_enable_SO <= 1'b0;
+ else if (Sqrt_start_SI && Ready_SO)
+ Sqrt_enable_SO <= 1'b1;
+ else if (Done_SO)
+ Sqrt_enable_SO <= 1'b0;
+ else
+ Sqrt_enable_SO <= Sqrt_enable_SO;
+ reg [5:0] Crtl_cnt_S;
+ wire Start_dly_S;
+ assign Start_dly_S = Div_start_dly_S | Sqrt_start_dly_S;
+ wire Fsm_enable_S;
+ assign Fsm_enable_S = ((Start_dly_S | |Crtl_cnt_S) && ~Kill_SI) && Special_case_dly_SBI;
+ wire Final_state_S;
+ assign Final_state_S = Crtl_cnt_S == State_ctl_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Crtl_cnt_S <= {6 {1'sb0}};
+ else if (Final_state_S | Kill_SI)
+ Crtl_cnt_S <= {6 {1'sb0}};
+ else if (Fsm_enable_S)
+ Crtl_cnt_S <= Crtl_cnt_S + 1;
+ else
+ Crtl_cnt_S <= {6 {1'sb0}};
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Done_SO <= 1'b0;
+ else if (Start_SI && Ready_SO) begin
+ if (~Special_case_SBI)
+ Done_SO <= 1'b1;
+ else
+ Done_SO <= 1'b0;
+ end
+ else if (Final_state_S)
+ Done_SO <= 1'b1;
+ else
+ Done_SO <= 1'b0;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Ready_SO <= 1'b1;
+ else if (Start_SI && Ready_SO) begin
+ if (~Special_case_SBI)
+ Ready_SO <= 1'b1;
+ else
+ Ready_SO <= 1'b0;
+ end
+ else if (Final_state_S | Kill_SI)
+ Ready_SO <= 1'b1;
+ else
+ Ready_SO <= Ready_SO;
+ wire Qcnt_one_0;
+ wire Qcnt_one_1;
+ wire [1:0] Qcnt_one_2;
+ wire [2:0] Qcnt_one_3;
+ wire [3:0] Qcnt_one_4;
+ wire [4:0] Qcnt_one_5;
+ wire [5:0] Qcnt_one_6;
+ wire [6:0] Qcnt_one_7;
+ wire [7:0] Qcnt_one_8;
+ wire [8:0] Qcnt_one_9;
+ wire [9:0] Qcnt_one_10;
+ wire [10:0] Qcnt_one_11;
+ wire [11:0] Qcnt_one_12;
+ wire [12:0] Qcnt_one_13;
+ wire [13:0] Qcnt_one_14;
+ wire [14:0] Qcnt_one_15;
+ wire [15:0] Qcnt_one_16;
+ wire [16:0] Qcnt_one_17;
+ wire [17:0] Qcnt_one_18;
+ wire [18:0] Qcnt_one_19;
+ wire [19:0] Qcnt_one_20;
+ wire [20:0] Qcnt_one_21;
+ wire [21:0] Qcnt_one_22;
+ wire [22:0] Qcnt_one_23;
+ wire [23:0] Qcnt_one_24;
+ wire [24:0] Qcnt_one_25;
+ wire [25:0] Qcnt_one_26;
+ wire [26:0] Qcnt_one_27;
+ wire [27:0] Qcnt_one_28;
+ wire [28:0] Qcnt_one_29;
+ wire [29:0] Qcnt_one_30;
+ wire [30:0] Qcnt_one_31;
+ wire [31:0] Qcnt_one_32;
+ wire [32:0] Qcnt_one_33;
+ wire [33:0] Qcnt_one_34;
+ wire [34:0] Qcnt_one_35;
+ wire [35:0] Qcnt_one_36;
+ wire [36:0] Qcnt_one_37;
+ wire [37:0] Qcnt_one_38;
+ wire [38:0] Qcnt_one_39;
+ wire [39:0] Qcnt_one_40;
+ wire [40:0] Qcnt_one_41;
+ wire [41:0] Qcnt_one_42;
+ wire [42:0] Qcnt_one_43;
+ wire [43:0] Qcnt_one_44;
+ wire [44:0] Qcnt_one_45;
+ wire [45:0] Qcnt_one_46;
+ wire [46:0] Qcnt_one_47;
+ wire [47:0] Qcnt_one_48;
+ wire [48:0] Qcnt_one_49;
+ wire [49:0] Qcnt_one_50;
+ wire [50:0] Qcnt_one_51;
+ wire [51:0] Qcnt_one_52;
+ wire [52:0] Qcnt_one_53;
+ wire [53:0] Qcnt_one_54;
+ wire [54:0] Qcnt_one_55;
+ wire [55:0] Qcnt_one_56;
+ wire [56:0] Qcnt_one_57;
+ wire [57:0] Qcnt_one_58;
+ wire [58:0] Qcnt_one_59;
+ wire [59:0] Qcnt_one_60;
+ wire [1:0] Qcnt_two_0;
+ wire [2:0] Qcnt_two_1;
+ wire [4:0] Qcnt_two_2;
+ wire [6:0] Qcnt_two_3;
+ wire [8:0] Qcnt_two_4;
+ wire [10:0] Qcnt_two_5;
+ wire [12:0] Qcnt_two_6;
+ wire [14:0] Qcnt_two_7;
+ wire [16:0] Qcnt_two_8;
+ wire [18:0] Qcnt_two_9;
+ wire [20:0] Qcnt_two_10;
+ wire [22:0] Qcnt_two_11;
+ wire [24:0] Qcnt_two_12;
+ wire [26:0] Qcnt_two_13;
+ wire [28:0] Qcnt_two_14;
+ wire [30:0] Qcnt_two_15;
+ wire [32:0] Qcnt_two_16;
+ wire [34:0] Qcnt_two_17;
+ wire [36:0] Qcnt_two_18;
+ wire [38:0] Qcnt_two_19;
+ wire [40:0] Qcnt_two_20;
+ wire [42:0] Qcnt_two_21;
+ wire [44:0] Qcnt_two_22;
+ wire [46:0] Qcnt_two_23;
+ wire [48:0] Qcnt_two_24;
+ wire [50:0] Qcnt_two_25;
+ wire [52:0] Qcnt_two_26;
+ wire [54:0] Qcnt_two_27;
+ wire [56:0] Qcnt_two_28;
+ wire [2:0] Qcnt_three_0;
+ wire [4:0] Qcnt_three_1;
+ wire [7:0] Qcnt_three_2;
+ wire [10:0] Qcnt_three_3;
+ wire [13:0] Qcnt_three_4;
+ wire [16:0] Qcnt_three_5;
+ wire [19:0] Qcnt_three_6;
+ wire [22:0] Qcnt_three_7;
+ wire [25:0] Qcnt_three_8;
+ wire [28:0] Qcnt_three_9;
+ wire [31:0] Qcnt_three_10;
+ wire [34:0] Qcnt_three_11;
+ wire [37:0] Qcnt_three_12;
+ wire [40:0] Qcnt_three_13;
+ wire [43:0] Qcnt_three_14;
+ wire [46:0] Qcnt_three_15;
+ wire [49:0] Qcnt_three_16;
+ wire [52:0] Qcnt_three_17;
+ wire [55:0] Qcnt_three_18;
+ wire [58:0] Qcnt_three_19;
+ wire [61:0] Qcnt_three_20;
+ wire [3:0] Qcnt_four_0;
+ wire [6:0] Qcnt_four_1;
+ wire [10:0] Qcnt_four_2;
+ wire [14:0] Qcnt_four_3;
+ wire [18:0] Qcnt_four_4;
+ wire [22:0] Qcnt_four_5;
+ wire [26:0] Qcnt_four_6;
+ wire [30:0] Qcnt_four_7;
+ wire [34:0] Qcnt_four_8;
+ wire [38:0] Qcnt_four_9;
+ wire [42:0] Qcnt_four_10;
+ wire [46:0] Qcnt_four_11;
+ wire [50:0] Qcnt_four_12;
+ wire [54:0] Qcnt_four_13;
+ wire [58:0] Qcnt_four_14;
+ wire [57:0] Sqrt_R0;
+ reg [57:0] Sqrt_Q0;
+ reg [57:0] Q_sqrt0;
+ reg [57:0] Q_sqrt_com_0;
+ wire [57:0] Sqrt_R1;
+ reg [57:0] Sqrt_Q1;
+ reg [57:0] Q_sqrt1;
+ reg [57:0] Q_sqrt_com_1;
+ wire [57:0] Sqrt_R2;
+ reg [57:0] Sqrt_Q2;
+ reg [57:0] Q_sqrt2;
+ reg [57:0] Q_sqrt_com_2;
+ wire [57:0] Sqrt_R3;
+ reg [57:0] Sqrt_Q3;
+ reg [57:0] Q_sqrt3;
+ reg [57:0] Q_sqrt_com_3;
+ wire [57:0] Sqrt_R4;
+ reg [1:0] Sqrt_DI [3:0];
+ wire [1:0] Sqrt_DO [3:0];
+ wire Sqrt_carry_DO;
+ wire [57:0] Iteration_cell_a_D [3:0];
+ wire [57:0] Iteration_cell_b_D [3:0];
+ wire [57:0] Iteration_cell_a_BMASK_D [3:0];
+ wire [57:0] Iteration_cell_b_BMASK_D [3:0];
+ wire Iteration_cell_carry_D [3:0];
+ wire [57:0] Iteration_cell_sum_D [3:0];
+ wire [57:0] Iteration_cell_sum_AMASK_D [3:0];
+ reg [3:0] Sqrt_quotinent_S;
+ always @(*)
+ case (Format_sel_S)
+ 2'b00: begin
+ Sqrt_quotinent_S = {~Iteration_cell_sum_AMASK_D[0][28], ~Iteration_cell_sum_AMASK_D[1][28], ~Iteration_cell_sum_AMASK_D[2][28], ~Iteration_cell_sum_AMASK_D[3][28]};
+ Q_sqrt_com_0 = {{29 {1'b0}}, ~Q_sqrt0[28:0]};
+ Q_sqrt_com_1 = {{29 {1'b0}}, ~Q_sqrt1[28:0]};
+ Q_sqrt_com_2 = {{29 {1'b0}}, ~Q_sqrt2[28:0]};
+ Q_sqrt_com_3 = {{29 {1'b0}}, ~Q_sqrt3[28:0]};
+ end
+ 2'b01: begin
+ Sqrt_quotinent_S = {Iteration_cell_carry_D[0], Iteration_cell_carry_D[1], Iteration_cell_carry_D[2], Iteration_cell_carry_D[3]};
+ Q_sqrt_com_0 = ~Q_sqrt0;
+ Q_sqrt_com_1 = ~Q_sqrt1;
+ Q_sqrt_com_2 = ~Q_sqrt2;
+ Q_sqrt_com_3 = ~Q_sqrt3;
+ end
+ 2'b10: begin
+ Sqrt_quotinent_S = {~Iteration_cell_sum_AMASK_D[0][15], ~Iteration_cell_sum_AMASK_D[1][15], ~Iteration_cell_sum_AMASK_D[2][15], ~Iteration_cell_sum_AMASK_D[3][15]};
+ Q_sqrt_com_0 = {{42 {1'b0}}, ~Q_sqrt0[15:0]};
+ Q_sqrt_com_1 = {{42 {1'b0}}, ~Q_sqrt1[15:0]};
+ Q_sqrt_com_2 = {{42 {1'b0}}, ~Q_sqrt2[15:0]};
+ Q_sqrt_com_3 = {{42 {1'b0}}, ~Q_sqrt3[15:0]};
+ end
+ 2'b11: begin
+ Sqrt_quotinent_S = {~Iteration_cell_sum_AMASK_D[0][12], ~Iteration_cell_sum_AMASK_D[1][12], ~Iteration_cell_sum_AMASK_D[2][12], ~Iteration_cell_sum_AMASK_D[3][12]};
+ Q_sqrt_com_0 = {{45 {1'b0}}, ~Q_sqrt0[12:0]};
+ Q_sqrt_com_1 = {{45 {1'b0}}, ~Q_sqrt1[12:0]};
+ Q_sqrt_com_2 = {{45 {1'b0}}, ~Q_sqrt2[12:0]};
+ Q_sqrt_com_3 = {{45 {1'b0}}, ~Q_sqrt3[12:0]};
+ end
+ endcase
+ assign Qcnt_one_0 = 1'b0;
+ assign Qcnt_one_1 = {Quotient_DP[0]};
+ assign Qcnt_one_2 = {Quotient_DP[1:0]};
+ assign Qcnt_one_3 = {Quotient_DP[2:0]};
+ assign Qcnt_one_4 = {Quotient_DP[3:0]};
+ assign Qcnt_one_5 = {Quotient_DP[4:0]};
+ assign Qcnt_one_6 = {Quotient_DP[5:0]};
+ assign Qcnt_one_7 = {Quotient_DP[6:0]};
+ assign Qcnt_one_8 = {Quotient_DP[7:0]};
+ assign Qcnt_one_9 = {Quotient_DP[8:0]};
+ assign Qcnt_one_10 = {Quotient_DP[9:0]};
+ assign Qcnt_one_11 = {Quotient_DP[10:0]};
+ assign Qcnt_one_12 = {Quotient_DP[11:0]};
+ assign Qcnt_one_13 = {Quotient_DP[12:0]};
+ assign Qcnt_one_14 = {Quotient_DP[13:0]};
+ assign Qcnt_one_15 = {Quotient_DP[14:0]};
+ assign Qcnt_one_16 = {Quotient_DP[15:0]};
+ assign Qcnt_one_17 = {Quotient_DP[16:0]};
+ assign Qcnt_one_18 = {Quotient_DP[17:0]};
+ assign Qcnt_one_19 = {Quotient_DP[18:0]};
+ assign Qcnt_one_20 = {Quotient_DP[19:0]};
+ assign Qcnt_one_21 = {Quotient_DP[20:0]};
+ assign Qcnt_one_22 = {Quotient_DP[21:0]};
+ assign Qcnt_one_23 = {Quotient_DP[22:0]};
+ assign Qcnt_one_24 = {Quotient_DP[23:0]};
+ assign Qcnt_one_25 = {Quotient_DP[24:0]};
+ assign Qcnt_one_26 = {Quotient_DP[25:0]};
+ assign Qcnt_one_27 = {Quotient_DP[26:0]};
+ assign Qcnt_one_28 = {Quotient_DP[27:0]};
+ assign Qcnt_one_29 = {Quotient_DP[28:0]};
+ assign Qcnt_one_30 = {Quotient_DP[29:0]};
+ assign Qcnt_one_31 = {Quotient_DP[30:0]};
+ assign Qcnt_one_32 = {Quotient_DP[31:0]};
+ assign Qcnt_one_33 = {Quotient_DP[32:0]};
+ assign Qcnt_one_34 = {Quotient_DP[33:0]};
+ assign Qcnt_one_35 = {Quotient_DP[34:0]};
+ assign Qcnt_one_36 = {Quotient_DP[35:0]};
+ assign Qcnt_one_37 = {Quotient_DP[36:0]};
+ assign Qcnt_one_38 = {Quotient_DP[37:0]};
+ assign Qcnt_one_39 = {Quotient_DP[38:0]};
+ assign Qcnt_one_40 = {Quotient_DP[39:0]};
+ assign Qcnt_one_41 = {Quotient_DP[40:0]};
+ assign Qcnt_one_42 = {Quotient_DP[41:0]};
+ assign Qcnt_one_43 = {Quotient_DP[42:0]};
+ assign Qcnt_one_44 = {Quotient_DP[43:0]};
+ assign Qcnt_one_45 = {Quotient_DP[44:0]};
+ assign Qcnt_one_46 = {Quotient_DP[45:0]};
+ assign Qcnt_one_47 = {Quotient_DP[46:0]};
+ assign Qcnt_one_48 = {Quotient_DP[47:0]};
+ assign Qcnt_one_49 = {Quotient_DP[48:0]};
+ assign Qcnt_one_50 = {Quotient_DP[49:0]};
+ assign Qcnt_one_51 = {Quotient_DP[50:0]};
+ assign Qcnt_one_52 = {Quotient_DP[51:0]};
+ assign Qcnt_one_53 = {Quotient_DP[52:0]};
+ assign Qcnt_one_54 = {Quotient_DP[53:0]};
+ assign Qcnt_one_55 = {Quotient_DP[54:0]};
+ assign Qcnt_one_56 = {Quotient_DP[55:0]};
+ assign Qcnt_one_57 = {Quotient_DP[56:0]};
+ assign Qcnt_two_0 = {1'b0, Sqrt_quotinent_S[3]};
+ assign Qcnt_two_1 = {Quotient_DP[1:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_2 = {Quotient_DP[3:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_3 = {Quotient_DP[5:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_4 = {Quotient_DP[7:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_5 = {Quotient_DP[9:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_6 = {Quotient_DP[11:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_7 = {Quotient_DP[13:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_8 = {Quotient_DP[15:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_9 = {Quotient_DP[17:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_10 = {Quotient_DP[19:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_11 = {Quotient_DP[21:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_12 = {Quotient_DP[23:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_13 = {Quotient_DP[25:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_14 = {Quotient_DP[27:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_15 = {Quotient_DP[29:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_16 = {Quotient_DP[31:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_17 = {Quotient_DP[33:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_18 = {Quotient_DP[35:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_19 = {Quotient_DP[37:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_20 = {Quotient_DP[39:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_21 = {Quotient_DP[41:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_22 = {Quotient_DP[43:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_23 = {Quotient_DP[45:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_24 = {Quotient_DP[47:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_25 = {Quotient_DP[49:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_26 = {Quotient_DP[51:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_27 = {Quotient_DP[53:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_two_28 = {Quotient_DP[55:0], Sqrt_quotinent_S[3]};
+ assign Qcnt_three_0 = {1'b0, Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_1 = {Quotient_DP[2:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_2 = {Quotient_DP[5:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_3 = {Quotient_DP[8:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_4 = {Quotient_DP[11:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_5 = {Quotient_DP[14:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_6 = {Quotient_DP[17:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_7 = {Quotient_DP[20:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_8 = {Quotient_DP[23:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_9 = {Quotient_DP[26:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_10 = {Quotient_DP[29:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_11 = {Quotient_DP[32:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_12 = {Quotient_DP[35:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_13 = {Quotient_DP[38:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_14 = {Quotient_DP[41:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_15 = {Quotient_DP[44:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_16 = {Quotient_DP[47:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_17 = {Quotient_DP[50:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_18 = {Quotient_DP[53:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_three_19 = {Quotient_DP[56:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2]};
+ assign Qcnt_four_0 = {1'b0, Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_1 = {Quotient_DP[3:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_2 = {Quotient_DP[7:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_3 = {Quotient_DP[11:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_4 = {Quotient_DP[15:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_5 = {Quotient_DP[19:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_6 = {Quotient_DP[23:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_7 = {Quotient_DP[27:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_8 = {Quotient_DP[31:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_9 = {Quotient_DP[35:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_10 = {Quotient_DP[39:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_11 = {Quotient_DP[43:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_12 = {Quotient_DP[47:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_13 = {Quotient_DP[51:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ assign Qcnt_four_14 = {Quotient_DP[55:0], Sqrt_quotinent_S[3], Sqrt_quotinent_S[2], Sqrt_quotinent_S[1]};
+ always @(*)
+ case (defs_div_sqrt_mvp_Iteration_unit_num_S)
+ 2'b00:
+ case (Crtl_cnt_S)
+ 6'b000000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[53:defs_div_sqrt_mvp_C_MANT_FP64];
+ Q_sqrt0 = {{57 {1'b0}}, Qcnt_one_0};
+ Sqrt_Q0 = Q_sqrt_com_0;
+ end
+ 6'b000001: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[51:50];
+ Q_sqrt0 = {{57 {1'b0}}, Qcnt_one_1};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b000010: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[49:48];
+ Q_sqrt0 = {{56 {1'b0}}, Qcnt_one_2};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b000011: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[47:46];
+ Q_sqrt0 = {{55 {1'b0}}, Qcnt_one_3};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b000100: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[45:44];
+ Q_sqrt0 = {{54 {1'b0}}, Qcnt_one_4};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b000101: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[43:42];
+ Q_sqrt0 = {{53 {1'b0}}, Qcnt_one_5};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b000110: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[41:40];
+ Q_sqrt0 = {{defs_div_sqrt_mvp_C_MANT_FP64 {1'b0}}, Qcnt_one_6};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b000111: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[39:38];
+ Q_sqrt0 = {{51 {1'b0}}, Qcnt_one_7};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b001000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[37:36];
+ Q_sqrt0 = {{50 {1'b0}}, Qcnt_one_8};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b001001: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[35:34];
+ Q_sqrt0 = {{49 {1'b0}}, Qcnt_one_9};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b001010: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[33:32];
+ Q_sqrt0 = {{48 {1'b0}}, Qcnt_one_10};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b001011: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[31:30];
+ Q_sqrt0 = {{47 {1'b0}}, Qcnt_one_11};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b001100: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[29:28];
+ Q_sqrt0 = {{46 {1'b0}}, Qcnt_one_12};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b001101: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[27:26];
+ Q_sqrt0 = {{45 {1'b0}}, Qcnt_one_13};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b001110: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[25:24];
+ Q_sqrt0 = {{44 {1'b0}}, Qcnt_one_14};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b001111: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[23:22];
+ Q_sqrt0 = {{43 {1'b0}}, Qcnt_one_15};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b010000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[21:20];
+ Q_sqrt0 = {{42 {1'b0}}, Qcnt_one_16};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b010001: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[19:18];
+ Q_sqrt0 = {{41 {1'b0}}, Qcnt_one_17};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b010010: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[17:16];
+ Q_sqrt0 = {{40 {1'b0}}, Qcnt_one_18};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b010011: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[15:14];
+ Q_sqrt0 = {{39 {1'b0}}, Qcnt_one_19};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b010100: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[13:12];
+ Q_sqrt0 = {{38 {1'b0}}, Qcnt_one_20};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b010101: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[11:10];
+ Q_sqrt0 = {{37 {1'b0}}, Qcnt_one_21};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b010110: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[9:8];
+ Q_sqrt0 = {{36 {1'b0}}, Qcnt_one_22};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b010111: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[7:6];
+ Q_sqrt0 = {{35 {1'b0}}, Qcnt_one_23};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b011000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[5:4];
+ Q_sqrt0 = {{34 {1'b0}}, Qcnt_one_24};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b011001: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[3:2];
+ Q_sqrt0 = {{33 {1'b0}}, Qcnt_one_25};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b011010: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[1:0];
+ Q_sqrt0 = {{32 {1'b0}}, Qcnt_one_26};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b011011: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{31 {1'b0}}, Qcnt_one_27};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b011100: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{30 {1'b0}}, Qcnt_one_28};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b011101: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{29 {1'b0}}, Qcnt_one_29};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b011110: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{28 {1'b0}}, Qcnt_one_30};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b011111: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{27 {1'b0}}, Qcnt_one_31};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b100000: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{26 {1'b0}}, Qcnt_one_32};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b100001: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{25 {1'b0}}, Qcnt_one_33};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b100010: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{24 {1'b0}}, Qcnt_one_34};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b100011: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{23 {1'b0}}, Qcnt_one_35};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b100100: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{22 {1'b0}}, Qcnt_one_36};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b100101: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{21 {1'b0}}, Qcnt_one_37};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b100110: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{20 {1'b0}}, Qcnt_one_38};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b100111: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{19 {1'b0}}, Qcnt_one_39};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b101000: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{18 {1'b0}}, Qcnt_one_40};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b101001: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{17 {1'b0}}, Qcnt_one_41};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b101010: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{16 {1'b0}}, Qcnt_one_42};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b101011: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{15 {1'b0}}, Qcnt_one_43};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b101100: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{14 {1'b0}}, Qcnt_one_44};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b101101: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{13 {1'b0}}, Qcnt_one_45};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b101110: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{12 {1'b0}}, Qcnt_one_46};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b101111: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{11 {1'b0}}, Qcnt_one_47};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b110000: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{10 {1'b0}}, Qcnt_one_48};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b110001: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{9 {1'b0}}, Qcnt_one_49};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b110010: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{8 {1'b0}}, Qcnt_one_50};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b110011: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{7 {1'b0}}, Qcnt_one_51};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b110100: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{6 {1'b0}}, Qcnt_one_52};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b110101: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{5 {1'b0}}, Qcnt_one_53};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b110110: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{4 {1'b0}}, Qcnt_one_54};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b110111: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{3 {1'b0}}, Qcnt_one_55};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ 6'b111000: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{2 {1'b0}}, Qcnt_one_56};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ end
+ default: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {58 {1'sb0}};
+ Sqrt_Q0 = {58 {1'sb0}};
+ end
+ endcase
+ 2'b01:
+ case (Crtl_cnt_S)
+ 6'b000000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[53:defs_div_sqrt_mvp_C_MANT_FP64];
+ Q_sqrt0 = {{57 {1'b0}}, Qcnt_two_0[1]};
+ Sqrt_Q0 = Q_sqrt_com_0;
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[51:50];
+ Q_sqrt1 = {{56 {1'b0}}, Qcnt_two_0[1:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b000001: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[49:48];
+ Q_sqrt0 = {{56 {1'b0}}, Qcnt_two_1[2:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[47:46];
+ Q_sqrt1 = {{55 {1'b0}}, Qcnt_two_1[2:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b000010: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[45:44];
+ Q_sqrt0 = {{54 {1'b0}}, Qcnt_two_2[4:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[43:42];
+ Q_sqrt1 = {{53 {1'b0}}, Qcnt_two_2[4:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b000011: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[41:40];
+ Q_sqrt0 = {{defs_div_sqrt_mvp_C_MANT_FP64 {1'b0}}, Qcnt_two_3[6:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[39:38];
+ Q_sqrt1 = {{51 {1'b0}}, Qcnt_two_3[6:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b000100: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[37:36];
+ Q_sqrt0 = {{50 {1'b0}}, Qcnt_two_4[8:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[35:34];
+ Q_sqrt1 = {{49 {1'b0}}, Qcnt_two_4[8:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b000101: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[33:32];
+ Q_sqrt0 = {{48 {1'b0}}, Qcnt_two_5[10:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[31:30];
+ Q_sqrt1 = {{47 {1'b0}}, Qcnt_two_5[10:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b000110: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[29:28];
+ Q_sqrt0 = {{46 {1'b0}}, Qcnt_two_6[12:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[27:26];
+ Q_sqrt1 = {{45 {1'b0}}, Qcnt_two_6[12:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b000111: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[25:24];
+ Q_sqrt0 = {{44 {1'b0}}, Qcnt_two_7[14:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[23:22];
+ Q_sqrt1 = {{43 {1'b0}}, Qcnt_two_7[14:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b001000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[21:20];
+ Q_sqrt0 = {{42 {1'b0}}, Qcnt_two_8[16:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[19:18];
+ Q_sqrt1 = {{41 {1'b0}}, Qcnt_two_8[16:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b001001: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[17:16];
+ Q_sqrt0 = {{40 {1'b0}}, Qcnt_two_9[18:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[15:14];
+ Q_sqrt1 = {{39 {1'b0}}, Qcnt_two_9[18:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b001010: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[13:12];
+ Q_sqrt0 = {{38 {1'b0}}, Qcnt_two_10[20:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[11:10];
+ Q_sqrt1 = {{37 {1'b0}}, Qcnt_two_10[20:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b001011: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[9:8];
+ Q_sqrt0 = {{36 {1'b0}}, Qcnt_two_11[22:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[7:6];
+ Q_sqrt1 = {{35 {1'b0}}, Qcnt_two_11[22:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b001100: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[5:4];
+ Q_sqrt0 = {{34 {1'b0}}, Qcnt_two_12[24:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[3:2];
+ Q_sqrt1 = {{33 {1'b0}}, Qcnt_two_12[24:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b001101: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[1:0];
+ Q_sqrt0 = {{32 {1'b0}}, Qcnt_two_13[26:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{31 {1'b0}}, Qcnt_two_13[26:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b001110: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{30 {1'b0}}, Qcnt_two_14[28:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{29 {1'b0}}, Qcnt_two_14[28:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b001111: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{28 {1'b0}}, Qcnt_two_15[30:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{27 {1'b0}}, Qcnt_two_15[30:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b010000: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{26 {1'b0}}, Qcnt_two_16[32:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{25 {1'b0}}, Qcnt_two_16[32:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b010001: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{24 {1'b0}}, Qcnt_two_17[34:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{23 {1'b0}}, Qcnt_two_17[34:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b010010: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{22 {1'b0}}, Qcnt_two_18[36:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{21 {1'b0}}, Qcnt_two_18[36:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b010011: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{20 {1'b0}}, Qcnt_two_19[38:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{19 {1'b0}}, Qcnt_two_19[38:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b010100: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{18 {1'b0}}, Qcnt_two_20[40:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{17 {1'b0}}, Qcnt_two_20[40:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b010101: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{16 {1'b0}}, Qcnt_two_21[42:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{15 {1'b0}}, Qcnt_two_21[42:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b010110: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{14 {1'b0}}, Qcnt_two_22[44:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{13 {1'b0}}, Qcnt_two_22[44:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b010111: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{12 {1'b0}}, Qcnt_two_23[46:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{11 {1'b0}}, Qcnt_two_23[46:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b011000: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{10 {1'b0}}, Qcnt_two_24[48:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{9 {1'b0}}, Qcnt_two_24[48:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b011001: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{8 {1'b0}}, Qcnt_two_25[50:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{7 {1'b0}}, Qcnt_two_25[50:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b011010: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{6 {1'b0}}, Qcnt_two_26[52:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{5 {1'b0}}, Qcnt_two_26[52:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b011011: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{4 {1'b0}}, Qcnt_two_27[54:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{3 {1'b0}}, Qcnt_two_27[54:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ 6'b011100: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{2 {1'b0}}, Qcnt_two_28[56:1]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {1'b0, Qcnt_two_28[56:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ default: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[53:defs_div_sqrt_mvp_C_MANT_FP64];
+ Q_sqrt0 = {{57 {1'b0}}, Qcnt_two_0[1]};
+ Sqrt_Q0 = Q_sqrt_com_0;
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[51:50];
+ Q_sqrt1 = {{56 {1'b0}}, Qcnt_two_0[1:0]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ end
+ endcase
+ 2'b10:
+ case (Crtl_cnt_S)
+ 6'b000000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[53:defs_div_sqrt_mvp_C_MANT_FP64];
+ Q_sqrt0 = {{57 {1'b0}}, Qcnt_three_0[2]};
+ Sqrt_Q0 = Q_sqrt_com_0;
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[51:50];
+ Q_sqrt1 = {{56 {1'b0}}, Qcnt_three_0[2:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[49:48];
+ Q_sqrt2 = {{55 {1'b0}}, Qcnt_three_0[2:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b000001: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[47:46];
+ Q_sqrt0 = {{54 {1'b0}}, Qcnt_three_1[4:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[45:44];
+ Q_sqrt1 = {{53 {1'b0}}, Qcnt_three_1[4:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[43:42];
+ Q_sqrt2 = {{defs_div_sqrt_mvp_C_MANT_FP64 {1'b0}}, Qcnt_three_1[4:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b000010: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[41:40];
+ Q_sqrt0 = {{51 {1'b0}}, Qcnt_three_2[7:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[39:38];
+ Q_sqrt1 = {{50 {1'b0}}, Qcnt_three_2[7:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[37:36];
+ Q_sqrt2 = {{49 {1'b0}}, Qcnt_three_2[7:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b000011: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[35:34];
+ Q_sqrt0 = {{48 {1'b0}}, Qcnt_three_3[10:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[33:32];
+ Q_sqrt1 = {{47 {1'b0}}, Qcnt_three_3[10:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[31:30];
+ Q_sqrt2 = {{46 {1'b0}}, Qcnt_three_3[10:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b000100: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[29:28];
+ Q_sqrt0 = {{45 {1'b0}}, Qcnt_three_4[13:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[27:26];
+ Q_sqrt1 = {{44 {1'b0}}, Qcnt_three_4[13:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[25:24];
+ Q_sqrt2 = {{43 {1'b0}}, Qcnt_three_4[13:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b000101: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[23:22];
+ Q_sqrt0 = {{42 {1'b0}}, Qcnt_three_5[16:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[21:20];
+ Q_sqrt1 = {{41 {1'b0}}, Qcnt_three_5[16:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[19:18];
+ Q_sqrt2 = {{40 {1'b0}}, Qcnt_three_5[16:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b000110: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[17:16];
+ Q_sqrt0 = {{39 {1'b0}}, Qcnt_three_6[19:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[15:14];
+ Q_sqrt1 = {{38 {1'b0}}, Qcnt_three_6[19:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[13:12];
+ Q_sqrt2 = {{37 {1'b0}}, Qcnt_three_6[19:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b000111: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[11:10];
+ Q_sqrt0 = {{36 {1'b0}}, Qcnt_three_7[22:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[9:8];
+ Q_sqrt1 = {{35 {1'b0}}, Qcnt_three_7[22:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[7:6];
+ Q_sqrt2 = {{34 {1'b0}}, Qcnt_three_7[22:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b001000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[5:4];
+ Q_sqrt0 = {{33 {1'b0}}, Qcnt_three_8[25:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[3:2];
+ Q_sqrt1 = {{32 {1'b0}}, Qcnt_three_8[25:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[1:0];
+ Q_sqrt2 = {{31 {1'b0}}, Qcnt_three_8[25:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b001001: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{30 {1'b0}}, Qcnt_three_9[28:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{29 {1'b0}}, Qcnt_three_9[28:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{28 {1'b0}}, Qcnt_three_9[28:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b001010: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{27 {1'b0}}, Qcnt_three_10[31:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{26 {1'b0}}, Qcnt_three_10[31:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{25 {1'b0}}, Qcnt_three_10[31:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b001011: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{24 {1'b0}}, Qcnt_three_11[34:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{23 {1'b0}}, Qcnt_three_11[34:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{22 {1'b0}}, Qcnt_three_11[34:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b001100: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{21 {1'b0}}, Qcnt_three_12[37:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{20 {1'b0}}, Qcnt_three_12[37:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{19 {1'b0}}, Qcnt_three_12[37:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b001101: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{18 {1'b0}}, Qcnt_three_13[40:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{17 {1'b0}}, Qcnt_three_13[40:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{16 {1'b0}}, Qcnt_three_13[40:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b001110: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{15 {1'b0}}, Qcnt_three_14[43:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{14 {1'b0}}, Qcnt_three_14[43:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{13 {1'b0}}, Qcnt_three_14[43:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b001111: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{12 {1'b0}}, Qcnt_three_15[46:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{11 {1'b0}}, Qcnt_three_15[46:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{10 {1'b0}}, Qcnt_three_15[46:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b010000: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{9 {1'b0}}, Qcnt_three_16[49:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{8 {1'b0}}, Qcnt_three_16[49:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{7 {1'b0}}, Qcnt_three_16[49:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b010001: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{6 {1'b0}}, Qcnt_three_17[52:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{5 {1'b0}}, Qcnt_three_17[52:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{4 {1'b0}}, Qcnt_three_17[52:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ 6'b010010: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{3 {1'b0}}, Qcnt_three_18[55:2]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{2 {1'b0}}, Qcnt_three_18[55:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {1'b0, Qcnt_three_18[55:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ default: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[53:defs_div_sqrt_mvp_C_MANT_FP64];
+ Q_sqrt0 = {{57 {1'b0}}, Qcnt_three_0[2]};
+ Sqrt_Q0 = Q_sqrt_com_0;
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[51:50];
+ Q_sqrt1 = {{56 {1'b0}}, Qcnt_three_0[2:1]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[49:48];
+ Q_sqrt2 = {{55 {1'b0}}, Qcnt_three_0[2:0]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ end
+ endcase
+ 2'b11:
+ case (Crtl_cnt_S)
+ 6'b000000: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[53:defs_div_sqrt_mvp_C_MANT_FP64];
+ Q_sqrt0 = {{57 {1'b0}}, Qcnt_four_0[3]};
+ Sqrt_Q0 = Q_sqrt_com_0;
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[51:50];
+ Q_sqrt1 = {{56 {1'b0}}, Qcnt_four_0[3:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[49:48];
+ Q_sqrt2 = {{55 {1'b0}}, Qcnt_four_0[3:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = Mant_D_sqrt_Norm[47:46];
+ Q_sqrt3 = {{54 {1'b0}}, Qcnt_four_0[3:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b000001: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[45:44];
+ Q_sqrt0 = {{53 {1'b0}}, Qcnt_four_1[6:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[43:42];
+ Q_sqrt1 = {{defs_div_sqrt_mvp_C_MANT_FP64 {1'b0}}, Qcnt_four_1[6:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[41:40];
+ Q_sqrt2 = {{51 {1'b0}}, Qcnt_four_1[6:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = Mant_D_sqrt_Norm[39:38];
+ Q_sqrt3 = {{50 {1'b0}}, Qcnt_four_1[6:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b000010: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[37:36];
+ Q_sqrt0 = {{49 {1'b0}}, Qcnt_four_2[10:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[35:34];
+ Q_sqrt1 = {{48 {1'b0}}, Qcnt_four_2[10:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[33:32];
+ Q_sqrt2 = {{47 {1'b0}}, Qcnt_four_2[10:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = Mant_D_sqrt_Norm[31:30];
+ Q_sqrt3 = {{46 {1'b0}}, Qcnt_four_2[10:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b000011: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[29:28];
+ Q_sqrt0 = {{45 {1'b0}}, Qcnt_four_3[14:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[27:26];
+ Q_sqrt1 = {{44 {1'b0}}, Qcnt_four_3[14:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[25:24];
+ Q_sqrt2 = {{43 {1'b0}}, Qcnt_four_3[14:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = Mant_D_sqrt_Norm[23:22];
+ Q_sqrt3 = {{42 {1'b0}}, Qcnt_four_3[14:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b000100: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[21:20];
+ Q_sqrt0 = {{41 {1'b0}}, Qcnt_four_4[18:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[19:18];
+ Q_sqrt1 = {{40 {1'b0}}, Qcnt_four_4[18:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[17:16];
+ Q_sqrt2 = {{39 {1'b0}}, Qcnt_four_4[18:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = Mant_D_sqrt_Norm[15:14];
+ Q_sqrt3 = {{38 {1'b0}}, Qcnt_four_4[18:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b000101: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[13:12];
+ Q_sqrt0 = {{37 {1'b0}}, Qcnt_four_5[22:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[11:10];
+ Q_sqrt1 = {{36 {1'b0}}, Qcnt_four_5[22:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[9:8];
+ Q_sqrt2 = {{35 {1'b0}}, Qcnt_four_5[22:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = Mant_D_sqrt_Norm[7:6];
+ Q_sqrt3 = {{34 {1'b0}}, Qcnt_four_5[22:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b000110: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[5:4];
+ Q_sqrt0 = {{33 {1'b0}}, Qcnt_four_6[26:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[3:2];
+ Q_sqrt1 = {{32 {1'b0}}, Qcnt_four_6[26:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[1:0];
+ Q_sqrt2 = {{31 {1'b0}}, Qcnt_four_6[26:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = 2'b00;
+ Q_sqrt3 = {{30 {1'b0}}, Qcnt_four_6[26:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b000111: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{29 {1'b0}}, Qcnt_four_7[30:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{28 {1'b0}}, Qcnt_four_7[30:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{27 {1'b0}}, Qcnt_four_7[30:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = 2'b00;
+ Q_sqrt3 = {{26 {1'b0}}, Qcnt_four_7[30:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b001000: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{25 {1'b0}}, Qcnt_four_8[34:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{24 {1'b0}}, Qcnt_four_8[34:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{23 {1'b0}}, Qcnt_four_8[34:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = 2'b00;
+ Q_sqrt3 = {{22 {1'b0}}, Qcnt_four_8[34:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b001001: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{21 {1'b0}}, Qcnt_four_9[38:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{20 {1'b0}}, Qcnt_four_9[38:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{19 {1'b0}}, Qcnt_four_9[38:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = 2'b00;
+ Q_sqrt3 = {{18 {1'b0}}, Qcnt_four_9[38:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b001010: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{17 {1'b0}}, Qcnt_four_10[42:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{16 {1'b0}}, Qcnt_four_10[42:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{15 {1'b0}}, Qcnt_four_10[42:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = 2'b00;
+ Q_sqrt3 = {{14 {1'b0}}, Qcnt_four_10[42:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b001011: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{13 {1'b0}}, Qcnt_four_11[46:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{12 {1'b0}}, Qcnt_four_11[46:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{11 {1'b0}}, Qcnt_four_11[46:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = 2'b00;
+ Q_sqrt3 = {{10 {1'b0}}, Qcnt_four_11[46:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b001100: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{9 {1'b0}}, Qcnt_four_12[50:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{8 {1'b0}}, Qcnt_four_12[50:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{7 {1'b0}}, Qcnt_four_12[50:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = 2'b00;
+ Q_sqrt3 = {{6 {1'b0}}, Qcnt_four_12[50:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ 6'b001101: begin
+ Sqrt_DI[0] = 2'b00;
+ Q_sqrt0 = {{5 {1'b0}}, Qcnt_four_13[54:3]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_DI[1] = 2'b00;
+ Q_sqrt1 = {{4 {1'b0}}, Qcnt_four_13[54:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = 2'b00;
+ Q_sqrt2 = {{3 {1'b0}}, Qcnt_four_13[54:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = 2'b00;
+ Q_sqrt3 = {{2 {1'b0}}, Qcnt_four_13[54:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ default: begin
+ Sqrt_DI[0] = Mant_D_sqrt_Norm[53:defs_div_sqrt_mvp_C_MANT_FP64];
+ Q_sqrt0 = {{57 {1'b0}}, Qcnt_four_0[3]};
+ Sqrt_Q0 = Q_sqrt_com_0;
+ Sqrt_DI[1] = Mant_D_sqrt_Norm[51:50];
+ Q_sqrt1 = {{56 {1'b0}}, Qcnt_four_0[3:2]};
+ Sqrt_Q1 = (Sqrt_quotinent_S[3] ? Q_sqrt_com_1 : Q_sqrt1);
+ Sqrt_DI[2] = Mant_D_sqrt_Norm[49:48];
+ Q_sqrt2 = {{55 {1'b0}}, Qcnt_four_0[3:1]};
+ Sqrt_Q2 = (Sqrt_quotinent_S[2] ? Q_sqrt_com_2 : Q_sqrt2);
+ Sqrt_DI[3] = Mant_D_sqrt_Norm[47:46];
+ Q_sqrt3 = {{54 {1'b0}}, Qcnt_four_0[3:0]};
+ Sqrt_Q3 = (Sqrt_quotinent_S[1] ? Q_sqrt_com_3 : Q_sqrt3);
+ end
+ endcase
+ endcase
+ assign Sqrt_R0 = (Sqrt_start_dly_S ? {58 {1'sb0}} : {Partial_remainder_DP[57:0]});
+ assign Sqrt_R1 = {Iteration_cell_sum_AMASK_D[0][57], Iteration_cell_sum_AMASK_D[0][54:0], Sqrt_DO[0]};
+ assign Sqrt_R2 = {Iteration_cell_sum_AMASK_D[1][57], Iteration_cell_sum_AMASK_D[1][54:0], Sqrt_DO[1]};
+ assign Sqrt_R3 = {Iteration_cell_sum_AMASK_D[2][57], Iteration_cell_sum_AMASK_D[2][54:0], Sqrt_DO[2]};
+ assign Sqrt_R4 = {Iteration_cell_sum_AMASK_D[3][57], Iteration_cell_sum_AMASK_D[3][54:0], Sqrt_DO[3]};
+ wire [57:0] Denominator_se_format_DB;
+ assign Denominator_se_format_DB = {Denominator_se_DB[53:45], {(FP16ALT_SO ? FP16ALT_SO : Denominator_se_DB[44])}, Denominator_se_DB[43:42], {(FP16_SO ? FP16_SO : Denominator_se_DB[41])}, Denominator_se_DB[40:29], {(FP32_SO ? FP32_SO : Denominator_se_DB[28])}, Denominator_se_DB[27:0], FP64_SO, 3'b000};
+ wire [57:0] First_iteration_cell_div_a_D;
+ wire [57:0] First_iteration_cell_div_b_D;
+ wire Sel_b_for_first_S;
+ assign First_iteration_cell_div_a_D = (Div_start_dly_S ? {Numerator_se_D[53:45], {(FP16ALT_SO ? FP16ALT_SO : Numerator_se_D[44])}, Numerator_se_D[43:42], {(FP16_SO ? FP16_SO : Numerator_se_D[41])}, Numerator_se_D[40:29], {(FP32_SO ? FP32_SO : Numerator_se_D[28])}, Numerator_se_D[27:0], FP64_SO, 3'b000} : {Partial_remainder_DP[56:48], {(FP16ALT_SO ? Quotient_DP[0] : Partial_remainder_DP[47])}, Partial_remainder_DP[46:45], {(FP16_SO ? Quotient_DP[0] : Partial_remainder_DP[44])}, Partial_remainder_DP[43:32], {(FP32_SO ? Quotient_DP[0] : Partial_remainder_DP[31])}, Partial_remainder_DP[30:3], FP64_SO && Quotient_DP[0], 3'b000});
+ assign Sel_b_for_first_S = (Div_start_dly_S ? 1 : Quotient_DP[0]);
+ assign First_iteration_cell_div_b_D = (Sel_b_for_first_S ? Denominator_se_format_DB : {Denominator_se_D, 4'b0000});
+ assign Iteration_cell_a_BMASK_D[0] = (Sqrt_enable_SO ? Sqrt_R0 : {First_iteration_cell_div_a_D});
+ assign Iteration_cell_b_BMASK_D[0] = (Sqrt_enable_SO ? Sqrt_Q0 : {First_iteration_cell_div_b_D});
+ wire [57:0] Sec_iteration_cell_div_a_D;
+ wire [57:0] Sec_iteration_cell_div_b_D;
+ wire Sel_b_for_sec_S;
+ generate
+ if (|defs_div_sqrt_mvp_Iteration_unit_num_S) begin
+ assign Sel_b_for_sec_S = ~Iteration_cell_sum_AMASK_D[0][57];
+ assign Sec_iteration_cell_div_a_D = {Iteration_cell_sum_AMASK_D[0][56:48], {(FP16ALT_SO ? Sel_b_for_sec_S : Iteration_cell_sum_AMASK_D[0][47])}, Iteration_cell_sum_AMASK_D[0][46:45], {(FP16_SO ? Sel_b_for_sec_S : Iteration_cell_sum_AMASK_D[0][44])}, Iteration_cell_sum_AMASK_D[0][43:32], {(FP32_SO ? Sel_b_for_sec_S : Iteration_cell_sum_AMASK_D[0][31])}, Iteration_cell_sum_AMASK_D[0][30:3], FP64_SO && Sel_b_for_sec_S, 3'b000};
+ assign Sec_iteration_cell_div_b_D = (Sel_b_for_sec_S ? Denominator_se_format_DB : {Denominator_se_D, 4'b0000});
+ assign Iteration_cell_a_BMASK_D[1] = (Sqrt_enable_SO ? Sqrt_R1 : {Sec_iteration_cell_div_a_D});
+ assign Iteration_cell_b_BMASK_D[1] = (Sqrt_enable_SO ? Sqrt_Q1 : {Sec_iteration_cell_div_b_D});
+ end
+ endgenerate
+ wire [57:0] Thi_iteration_cell_div_a_D;
+ wire [57:0] Thi_iteration_cell_div_b_D;
+ wire Sel_b_for_thi_S;
+ generate
+ if ((defs_div_sqrt_mvp_Iteration_unit_num_S == 2'b10) | (defs_div_sqrt_mvp_Iteration_unit_num_S == 2'b11)) begin
+ assign Sel_b_for_thi_S = ~Iteration_cell_sum_AMASK_D[1][57];
+ assign Thi_iteration_cell_div_a_D = {Iteration_cell_sum_AMASK_D[1][56:48], {(FP16ALT_SO ? Sel_b_for_thi_S : Iteration_cell_sum_AMASK_D[1][47])}, Iteration_cell_sum_AMASK_D[1][46:45], {(FP16_SO ? Sel_b_for_thi_S : Iteration_cell_sum_AMASK_D[1][44])}, Iteration_cell_sum_AMASK_D[1][43:32], {(FP32_SO ? Sel_b_for_thi_S : Iteration_cell_sum_AMASK_D[1][31])}, Iteration_cell_sum_AMASK_D[1][30:3], FP64_SO && Sel_b_for_thi_S, 3'b000};
+ assign Thi_iteration_cell_div_b_D = (Sel_b_for_thi_S ? Denominator_se_format_DB : {Denominator_se_D, 4'b0000});
+ assign Iteration_cell_a_BMASK_D[2] = (Sqrt_enable_SO ? Sqrt_R2 : {Thi_iteration_cell_div_a_D});
+ assign Iteration_cell_b_BMASK_D[2] = (Sqrt_enable_SO ? Sqrt_Q2 : {Thi_iteration_cell_div_b_D});
+ end
+ endgenerate
+ wire [57:0] Fou_iteration_cell_div_a_D;
+ wire [57:0] Fou_iteration_cell_div_b_D;
+ wire Sel_b_for_fou_S;
+ generate
+ if (defs_div_sqrt_mvp_Iteration_unit_num_S == 2'b11) begin
+ assign Sel_b_for_fou_S = ~Iteration_cell_sum_AMASK_D[2][57];
+ assign Fou_iteration_cell_div_a_D = {Iteration_cell_sum_AMASK_D[2][56:48], {(FP16ALT_SO ? Sel_b_for_fou_S : Iteration_cell_sum_AMASK_D[2][47])}, Iteration_cell_sum_AMASK_D[2][46:45], {(FP16_SO ? Sel_b_for_fou_S : Iteration_cell_sum_AMASK_D[2][44])}, Iteration_cell_sum_AMASK_D[2][43:32], {(FP32_SO ? Sel_b_for_fou_S : Iteration_cell_sum_AMASK_D[2][31])}, Iteration_cell_sum_AMASK_D[2][30:3], FP64_SO && Sel_b_for_fou_S, 3'b000};
+ assign Fou_iteration_cell_div_b_D = (Sel_b_for_fou_S ? Denominator_se_format_DB : {Denominator_se_D, 4'b0000});
+ assign Iteration_cell_a_BMASK_D[3] = (Sqrt_enable_SO ? Sqrt_R3 : {Fou_iteration_cell_div_a_D});
+ assign Iteration_cell_b_BMASK_D[3] = (Sqrt_enable_SO ? Sqrt_Q3 : {Fou_iteration_cell_div_b_D});
+ end
+ endgenerate
+ wire [57:0] Mask_bits_ctl_S;
+ assign Mask_bits_ctl_S = 58'h3ffffffffffffff;
+ wire Div_enable_SI [3:0];
+ wire Div_start_dly_SI [3:0];
+ wire Sqrt_enable_SI [3:0];
+ generate
+ genvar i;
+ genvar j;
+ for (i = 0; i <= defs_div_sqrt_mvp_Iteration_unit_num_S; i = i + 1) begin
+ for (j = 0; j <= 57; j = j + 1) begin
+ assign Iteration_cell_a_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_a_BMASK_D[i][j];
+ assign Iteration_cell_b_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_b_BMASK_D[i][j];
+ assign Iteration_cell_sum_AMASK_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_sum_D[i][j];
+ end
+ assign Div_enable_SI[i] = Div_enable_SO;
+ assign Div_start_dly_SI[i] = Div_start_dly_S;
+ assign Sqrt_enable_SI[i] = Sqrt_enable_SO;
+ iteration_div_sqrt_mvp #(.WIDTH(58)) iteration_div_sqrt(
+ .A_DI(Iteration_cell_a_D[i]),
+ .B_DI(Iteration_cell_b_D[i]),
+ .Div_enable_SI(Div_enable_SI[i]),
+ .Div_start_dly_SI(Div_start_dly_SI[i]),
+ .Sqrt_enable_SI(Sqrt_enable_SI[i]),
+ .D_DI(Sqrt_DI[i]),
+ .D_DO(Sqrt_DO[i]),
+ .Sum_DO(Iteration_cell_sum_D[i]),
+ .Carry_out_DO(Iteration_cell_carry_D[i])
+ );
+ end
+ endgenerate
+ always @(*)
+ case (defs_div_sqrt_mvp_Iteration_unit_num_S)
+ 2'b00:
+ if (Fsm_enable_S)
+ Partial_remainder_DN = (Sqrt_enable_SO ? Sqrt_R1 : Iteration_cell_sum_AMASK_D[0]);
+ else
+ Partial_remainder_DN = Partial_remainder_DP;
+ 2'b01:
+ if (Fsm_enable_S)
+ Partial_remainder_DN = (Sqrt_enable_SO ? Sqrt_R2 : Iteration_cell_sum_AMASK_D[1]);
+ else
+ Partial_remainder_DN = Partial_remainder_DP;
+ 2'b10:
+ if (Fsm_enable_S)
+ Partial_remainder_DN = (Sqrt_enable_SO ? Sqrt_R3 : Iteration_cell_sum_AMASK_D[2]);
+ else
+ Partial_remainder_DN = Partial_remainder_DP;
+ 2'b11:
+ if (Fsm_enable_S)
+ Partial_remainder_DN = (Sqrt_enable_SO ? Sqrt_R4 : Iteration_cell_sum_AMASK_D[3]);
+ else
+ Partial_remainder_DN = Partial_remainder_DP;
+ endcase
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Partial_remainder_DP <= {58 {1'sb0}};
+ else
+ Partial_remainder_DP <= Partial_remainder_DN;
+ reg [56:0] Quotient_DN;
+ always @(*)
+ case (defs_div_sqrt_mvp_Iteration_unit_num_S)
+ 2'b00:
+ if (Fsm_enable_S)
+ Quotient_DN = (Sqrt_enable_SO ? {Quotient_DP[55:0], Sqrt_quotinent_S[3]} : {Quotient_DP[55:0], Iteration_cell_carry_D[0]});
+ else
+ Quotient_DN = Quotient_DP;
+ 2'b01:
+ if (Fsm_enable_S)
+ Quotient_DN = (Sqrt_enable_SO ? {Quotient_DP[54:0], Sqrt_quotinent_S[3:2]} : {Quotient_DP[54:0], Iteration_cell_carry_D[0], Iteration_cell_carry_D[1]});
+ else
+ Quotient_DN = Quotient_DP;
+ 2'b10:
+ if (Fsm_enable_S)
+ Quotient_DN = (Sqrt_enable_SO ? {Quotient_DP[53:0], Sqrt_quotinent_S[3:1]} : {Quotient_DP[53:0], Iteration_cell_carry_D[0], Iteration_cell_carry_D[1], Iteration_cell_carry_D[2]});
+ else
+ Quotient_DN = Quotient_DP;
+ 2'b11:
+ if (Fsm_enable_S)
+ Quotient_DN = (Sqrt_enable_SO ? {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP64:0], Sqrt_quotinent_S} : {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP64:0], Iteration_cell_carry_D[0], Iteration_cell_carry_D[1], Iteration_cell_carry_D[2], Iteration_cell_carry_D[3]});
+ else
+ Quotient_DN = Quotient_DP;
+ endcase
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Quotient_DP <= {57 {1'sb0}};
+ else
+ Quotient_DP <= Quotient_DN;
+ generate
+ if (defs_div_sqrt_mvp_Iteration_unit_num_S == 2'b00) always @(*)
+ case (Format_sel_S)
+ 2'b00:
+ case (Precision_ctl_S)
+ 6'h00: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ 6'h17: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP32:0], {33 {1'b0}}};
+ 6'h16: Mant_result_prenorm_DO = {Quotient_DP[22:0], {34 {1'b0}}};
+ 6'h15: Mant_result_prenorm_DO = {Quotient_DP[21:0], {35 {1'b0}}};
+ 6'h14: Mant_result_prenorm_DO = {Quotient_DP[20:0], {36 {1'b0}}};
+ 6'h13: Mant_result_prenorm_DO = {Quotient_DP[19:0], {37 {1'b0}}};
+ 6'h12: Mant_result_prenorm_DO = {Quotient_DP[18:0], {38 {1'b0}}};
+ 6'h11: Mant_result_prenorm_DO = {Quotient_DP[17:0], {39 {1'b0}}};
+ 6'h10: Mant_result_prenorm_DO = {Quotient_DP[16:0], {40 {1'b0}}};
+ 6'h0f: Mant_result_prenorm_DO = {Quotient_DP[15:0], {41 {1'b0}}};
+ 6'h0e: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ 6'h0d: Mant_result_prenorm_DO = {Quotient_DP[13:0], {43 {1'b0}}};
+ 6'h0c: Mant_result_prenorm_DO = {Quotient_DP[12:0], {44 {1'b0}}};
+ 6'h0b: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h0a: Mant_result_prenorm_DO = {Quotient_DP[10:0], {46 {1'b0}}};
+ 6'h09: Mant_result_prenorm_DO = {Quotient_DP[9:0], {47 {1'b0}}};
+ 6'h08: Mant_result_prenorm_DO = {Quotient_DP[8:0], {48 {1'b0}}};
+ 6'h07: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ endcase
+ 2'b01:
+ case (Precision_ctl_S)
+ 6'h00: Mant_result_prenorm_DO = Quotient_DP[56:0];
+ 6'h34: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP64:0], {4 {1'b0}}};
+ 6'h33: Mant_result_prenorm_DO = {Quotient_DP[51:0], {5 {1'b0}}};
+ 6'h32: Mant_result_prenorm_DO = {Quotient_DP[50:0], {6 {1'b0}}};
+ 6'h31: Mant_result_prenorm_DO = {Quotient_DP[49:0], {7 {1'b0}}};
+ 6'h30: Mant_result_prenorm_DO = {Quotient_DP[48:0], {8 {1'b0}}};
+ 6'h2f: Mant_result_prenorm_DO = {Quotient_DP[47:0], {9 {1'b0}}};
+ 6'h2e: Mant_result_prenorm_DO = {Quotient_DP[46:0], {10 {1'b0}}};
+ 6'h2d: Mant_result_prenorm_DO = {Quotient_DP[45:0], {11 {1'b0}}};
+ 6'h2c: Mant_result_prenorm_DO = {Quotient_DP[44:0], {12 {1'b0}}};
+ 6'h2b: Mant_result_prenorm_DO = {Quotient_DP[43:0], {13 {1'b0}}};
+ 6'h2a: Mant_result_prenorm_DO = {Quotient_DP[42:0], {14 {1'b0}}};
+ 6'h29: Mant_result_prenorm_DO = {Quotient_DP[41:0], {15 {1'b0}}};
+ 6'h28: Mant_result_prenorm_DO = {Quotient_DP[40:0], {16 {1'b0}}};
+ 6'h27: Mant_result_prenorm_DO = {Quotient_DP[39:0], {17 {1'b0}}};
+ 6'h26: Mant_result_prenorm_DO = {Quotient_DP[38:0], {18 {1'b0}}};
+ 6'h25: Mant_result_prenorm_DO = {Quotient_DP[37:0], {19 {1'b0}}};
+ 6'h24: Mant_result_prenorm_DO = {Quotient_DP[36:0], {20 {1'b0}}};
+ 6'h23: Mant_result_prenorm_DO = {Quotient_DP[35:0], {21 {1'b0}}};
+ 6'h22: Mant_result_prenorm_DO = {Quotient_DP[34:0], {22 {1'b0}}};
+ 6'h21: Mant_result_prenorm_DO = {Quotient_DP[33:0], {23 {1'b0}}};
+ 6'h20: Mant_result_prenorm_DO = {Quotient_DP[32:0], {24 {1'b0}}};
+ 6'h1f: Mant_result_prenorm_DO = {Quotient_DP[31:0], {25 {1'b0}}};
+ 6'h1e: Mant_result_prenorm_DO = {Quotient_DP[30:0], {26 {1'b0}}};
+ 6'h1d: Mant_result_prenorm_DO = {Quotient_DP[29:0], {27 {1'b0}}};
+ 6'h1c: Mant_result_prenorm_DO = {Quotient_DP[28:0], {28 {1'b0}}};
+ 6'h1b: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ 6'h1a: Mant_result_prenorm_DO = {Quotient_DP[26:0], {30 {1'b0}}};
+ 6'h19: Mant_result_prenorm_DO = {Quotient_DP[25:0], {31 {1'b0}}};
+ 6'h18: Mant_result_prenorm_DO = {Quotient_DP[24:0], {32 {1'b0}}};
+ 6'h17: Mant_result_prenorm_DO = {Quotient_DP[23:0], {33 {1'b0}}};
+ 6'h16: Mant_result_prenorm_DO = {Quotient_DP[22:0], {34 {1'b0}}};
+ 6'h15: Mant_result_prenorm_DO = {Quotient_DP[21:0], {35 {1'b0}}};
+ 6'h14: Mant_result_prenorm_DO = {Quotient_DP[20:0], {36 {1'b0}}};
+ 6'h13: Mant_result_prenorm_DO = {Quotient_DP[19:0], {37 {1'b0}}};
+ 6'h12: Mant_result_prenorm_DO = {Quotient_DP[18:0], {38 {1'b0}}};
+ 6'h11: Mant_result_prenorm_DO = {Quotient_DP[17:0], {39 {1'b0}}};
+ 6'h10: Mant_result_prenorm_DO = {Quotient_DP[16:0], {40 {1'b0}}};
+ 6'h0f: Mant_result_prenorm_DO = {Quotient_DP[15:0], {41 {1'b0}}};
+ 6'h0e: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ 6'h0d: Mant_result_prenorm_DO = {Quotient_DP[13:0], {43 {1'b0}}};
+ 6'h0c: Mant_result_prenorm_DO = {Quotient_DP[12:0], {44 {1'b0}}};
+ 6'h0b: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h0a: Mant_result_prenorm_DO = {Quotient_DP[10:0], {46 {1'b0}}};
+ 6'h09: Mant_result_prenorm_DO = {Quotient_DP[9:0], {47 {1'b0}}};
+ 6'h08: Mant_result_prenorm_DO = {Quotient_DP[8:0], {48 {1'b0}}};
+ 6'h07: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = Quotient_DP[56:0];
+ endcase
+ 2'b10:
+ case (Precision_ctl_S)
+ 6'b000000: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ 6'h0a: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP16:0], {46 {1'b0}}};
+ 6'h09: Mant_result_prenorm_DO = {Quotient_DP[9:0], {47 {1'b0}}};
+ 6'h08: Mant_result_prenorm_DO = {Quotient_DP[8:0], {48 {1'b0}}};
+ 6'h07: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ endcase
+ 2'b11:
+ case (Precision_ctl_S)
+ 6'b000000: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h07: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP16ALT:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ endcase
+ endcase
+ endgenerate
+ generate
+ if (defs_div_sqrt_mvp_Iteration_unit_num_S == 2'b01) always @(*)
+ case (Format_sel_S)
+ 2'b00:
+ case (Precision_ctl_S)
+ 6'h00: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ 6'h17, 6'h16: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP32:0], {33 {1'b0}}};
+ 6'h15, 6'h14: Mant_result_prenorm_DO = {Quotient_DP[21:0], {35 {1'b0}}};
+ 6'h13, 6'h12: Mant_result_prenorm_DO = {Quotient_DP[19:0], {37 {1'b0}}};
+ 6'h11, 6'h10: Mant_result_prenorm_DO = {Quotient_DP[17:0], {39 {1'b0}}};
+ 6'h0f, 6'h0e: Mant_result_prenorm_DO = {Quotient_DP[15:0], {41 {1'b0}}};
+ 6'h0d, 6'h0c: Mant_result_prenorm_DO = {Quotient_DP[13:0], {43 {1'b0}}};
+ 6'h0b, 6'h0a: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h09, 6'h08: Mant_result_prenorm_DO = {Quotient_DP[9:0], {47 {1'b0}}};
+ 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ endcase
+ 2'b01:
+ case (Precision_ctl_S)
+ 6'h00: Mant_result_prenorm_DO = {Quotient_DP[55:0], 1'b0};
+ 6'h34: Mant_result_prenorm_DO = {Quotient_DP[53:1], {4 {1'b0}}};
+ 6'h33, 6'h32: Mant_result_prenorm_DO = {Quotient_DP[51:0], {5 {1'b0}}};
+ 6'h31, 6'h30: Mant_result_prenorm_DO = {Quotient_DP[49:0], {7 {1'b0}}};
+ 6'h2f, 6'h2e: Mant_result_prenorm_DO = {Quotient_DP[47:0], {9 {1'b0}}};
+ 6'h2d, 6'h2c: Mant_result_prenorm_DO = {Quotient_DP[45:0], {11 {1'b0}}};
+ 6'h2b, 6'h2a: Mant_result_prenorm_DO = {Quotient_DP[43:0], {13 {1'b0}}};
+ 6'h29, 6'h28: Mant_result_prenorm_DO = {Quotient_DP[41:0], {15 {1'b0}}};
+ 6'h27, 6'h26: Mant_result_prenorm_DO = {Quotient_DP[39:0], {17 {1'b0}}};
+ 6'h25, 6'h24: Mant_result_prenorm_DO = {Quotient_DP[37:0], {19 {1'b0}}};
+ 6'h23, 6'h22: Mant_result_prenorm_DO = {Quotient_DP[35:0], {21 {1'b0}}};
+ 6'h21, 6'h20: Mant_result_prenorm_DO = {Quotient_DP[33:0], {23 {1'b0}}};
+ 6'h1f, 6'h1e: Mant_result_prenorm_DO = {Quotient_DP[31:0], {25 {1'b0}}};
+ 6'h1d, 6'h1c: Mant_result_prenorm_DO = {Quotient_DP[29:0], {27 {1'b0}}};
+ 6'h1b, 6'h1a: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ 6'h19, 6'h18: Mant_result_prenorm_DO = {Quotient_DP[25:0], {31 {1'b0}}};
+ 6'h17, 6'h16: Mant_result_prenorm_DO = {Quotient_DP[23:0], {33 {1'b0}}};
+ 6'h15, 6'h14: Mant_result_prenorm_DO = {Quotient_DP[21:0], {35 {1'b0}}};
+ 6'h13, 6'h12: Mant_result_prenorm_DO = {Quotient_DP[19:0], {37 {1'b0}}};
+ 6'h11, 6'h10: Mant_result_prenorm_DO = {Quotient_DP[17:0], {39 {1'b0}}};
+ 6'h0f, 6'h0e: Mant_result_prenorm_DO = {Quotient_DP[15:0], {41 {1'b0}}};
+ 6'h0d, 6'h0c: Mant_result_prenorm_DO = {Quotient_DP[13:0], {43 {1'b0}}};
+ 6'h0b, 6'h0a: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h09, 6'h08: Mant_result_prenorm_DO = {Quotient_DP[9:0], {47 {1'b0}}};
+ 6'h07: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[55:0], 1'b0};
+ endcase
+ 2'b10:
+ case (Precision_ctl_S)
+ 6'b000000: Mant_result_prenorm_DO = {Quotient_DP[13:0], {43 {1'b0}}};
+ 6'h0a: Mant_result_prenorm_DO = {Quotient_DP[11:1], {46 {1'b0}}};
+ 6'h09, 6'h08: Mant_result_prenorm_DO = {Quotient_DP[9:0], {47 {1'b0}}};
+ 6'h07: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ endcase
+ 2'b11:
+ case (Precision_ctl_S)
+ 6'b000000: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h07: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP16ALT:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ endcase
+ endcase
+ endgenerate
+ generate
+ if (defs_div_sqrt_mvp_Iteration_unit_num_S == 2'b10) always @(*)
+ case (Format_sel_S)
+ 2'b00:
+ case (Precision_ctl_S)
+ 6'h00: Mant_result_prenorm_DO = {Quotient_DP[26:0], {30 {1'b0}}};
+ 6'h17, 6'h16, 6'h15: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP32:0], {33 {1'b0}}};
+ 6'h14, 6'h13, 6'h12: Mant_result_prenorm_DO = {Quotient_DP[20:0], {36 {1'b0}}};
+ 6'h11, 6'h10, 6'h0f: Mant_result_prenorm_DO = {Quotient_DP[17:0], {39 {1'b0}}};
+ 6'h0e, 6'h0d, 6'h0c: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ 6'h0b, 6'h0a, 6'h09: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h08, 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[8:0], {48 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[26:0], {30 {1'b0}}};
+ endcase
+ 2'b01:
+ case (Precision_ctl_S)
+ 6'h00: Mant_result_prenorm_DO = Quotient_DP[56:0];
+ 6'h34, 6'h33: Mant_result_prenorm_DO = {Quotient_DP[53:1], {4 {1'b0}}};
+ 6'h32, 6'h31, 6'h30: Mant_result_prenorm_DO = {Quotient_DP[50:0], {6 {1'b0}}};
+ 6'h2f, 6'h2e, 6'h2d: Mant_result_prenorm_DO = {Quotient_DP[47:0], {9 {1'b0}}};
+ 6'h2c, 6'h2b, 6'h2a: Mant_result_prenorm_DO = {Quotient_DP[44:0], {12 {1'b0}}};
+ 6'h29, 6'h28, 6'h27: Mant_result_prenorm_DO = {Quotient_DP[41:0], {15 {1'b0}}};
+ 6'h26, 6'h25, 6'h24: Mant_result_prenorm_DO = {Quotient_DP[38:0], {18 {1'b0}}};
+ 6'h23, 6'h22, 6'h21: Mant_result_prenorm_DO = {Quotient_DP[35:0], {21 {1'b0}}};
+ 6'h20, 6'h1f, 6'h1e: Mant_result_prenorm_DO = {Quotient_DP[32:0], {24 {1'b0}}};
+ 6'h1d, 6'h1c, 6'h1b: Mant_result_prenorm_DO = {Quotient_DP[29:0], {27 {1'b0}}};
+ 6'h1a, 6'h19, 6'h18: Mant_result_prenorm_DO = {Quotient_DP[26:0], {30 {1'b0}}};
+ 6'h17, 6'h16, 6'h15: Mant_result_prenorm_DO = {Quotient_DP[23:0], {33 {1'b0}}};
+ 6'h14, 6'h13, 6'h12: Mant_result_prenorm_DO = {Quotient_DP[20:0], {36 {1'b0}}};
+ 6'h11, 6'h10, 6'h0f: Mant_result_prenorm_DO = {Quotient_DP[17:0], {39 {1'b0}}};
+ 6'h0e, 6'h0d, 6'h0c: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ 6'h0b, 6'h0a, 6'h09: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h08, 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[8:0], {48 {1'b0}}};
+ default: Mant_result_prenorm_DO = Quotient_DP[56:0];
+ endcase
+ 2'b10:
+ case (Precision_ctl_S)
+ 6'b000000: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ 6'h0a, 6'h09: Mant_result_prenorm_DO = {Quotient_DP[11:1], {46 {1'b0}}};
+ 6'h08, 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[8:0], {48 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[14:0], {42 {1'b0}}};
+ endcase
+ 2'b11:
+ case (Precision_ctl_S)
+ 6'b000000: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[8:1], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ endcase
+ endcase
+ endgenerate
+ generate
+ if (defs_div_sqrt_mvp_Iteration_unit_num_S == 2'b11) always @(*)
+ case (Format_sel_S)
+ 2'b00:
+ case (Precision_ctl_S)
+ 6'h00: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ 6'h17, 6'h16, 6'h15, 6'h14: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP32:0], {33 {1'b0}}};
+ 6'h13, 6'h12, 6'h11, 6'h10: Mant_result_prenorm_DO = {Quotient_DP[19:0], {37 {1'b0}}};
+ 6'h0f, 6'h0e, 6'h0d, 6'h0c: Mant_result_prenorm_DO = {Quotient_DP[15:0], {41 {1'b0}}};
+ 6'h0b, 6'h0a, 6'h09, 6'h08: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ endcase
+ 2'b01:
+ case (Precision_ctl_S)
+ 6'h00: Mant_result_prenorm_DO = {Quotient_DP[55:0], 1'b0};
+ 6'h34: Mant_result_prenorm_DO = {Quotient_DP[55:0], 1'b0};
+ 6'h33, 6'h32, 6'h31, 6'h30: Mant_result_prenorm_DO = {Quotient_DP[51:0], {5 {1'b0}}};
+ 6'h2f, 6'h2e, 6'h2d, 6'h2c: Mant_result_prenorm_DO = {Quotient_DP[47:0], {9 {1'b0}}};
+ 6'h2b, 6'h2a, 6'h29, 6'h28: Mant_result_prenorm_DO = {Quotient_DP[43:0], {13 {1'b0}}};
+ 6'h27, 6'h26, 6'h25, 6'h24: Mant_result_prenorm_DO = {Quotient_DP[39:0], {17 {1'b0}}};
+ 6'h23, 6'h22, 6'h21, 6'h20: Mant_result_prenorm_DO = {Quotient_DP[35:0], {21 {1'b0}}};
+ 6'h1f, 6'h1e, 6'h1d, 6'h1c: Mant_result_prenorm_DO = {Quotient_DP[31:0], {25 {1'b0}}};
+ 6'h1b, 6'h1a, 6'h19, 6'h18: Mant_result_prenorm_DO = {Quotient_DP[27:0], {29 {1'b0}}};
+ 6'h17, 6'h16, 6'h15, 6'h14: Mant_result_prenorm_DO = {Quotient_DP[23:0], {33 {1'b0}}};
+ 6'h13, 6'h12, 6'h11, 6'h10: Mant_result_prenorm_DO = {Quotient_DP[19:0], {37 {1'b0}}};
+ 6'h0f, 6'h0e, 6'h0d, 6'h0c: Mant_result_prenorm_DO = {Quotient_DP[15:0], {41 {1'b0}}};
+ 6'h0b, 6'h0a, 6'h09, 6'h08: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[55:0], 1'b0};
+ endcase
+ 2'b10:
+ case (Precision_ctl_S)
+ 6'b000000: Mant_result_prenorm_DO = {Quotient_DP[15:0], {41 {1'b0}}};
+ 6'h0a, 6'h09, 6'h08: Mant_result_prenorm_DO = {Quotient_DP[11:1], {46 {1'b0}}};
+ 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[7:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[15:0], {41 {1'b0}}};
+ endcase
+ 2'b11:
+ case (Precision_ctl_S)
+ 6'b000000: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ 6'h07, 6'h06: Mant_result_prenorm_DO = {Quotient_DP[defs_div_sqrt_mvp_C_MANT_FP16ALT:0], {49 {1'b0}}};
+ default: Mant_result_prenorm_DO = {Quotient_DP[11:0], {45 {1'b0}}};
+ endcase
+ endcase
+ endgenerate
+ wire [12:0] Exp_result_prenorm_DN;
+ reg [12:0] Exp_result_prenorm_DP;
+ wire [12:0] Exp_add_a_D;
+ wire [12:0] Exp_add_b_D;
+ wire [12:0] Exp_add_c_D;
+ integer C_BIAS_AONE;
+ integer C_HALF_BIAS;
+ localparam defs_div_sqrt_mvp_C_BIAS_AONE_FP16 = 5'h10;
+ localparam defs_div_sqrt_mvp_C_BIAS_AONE_FP16ALT = 8'h80;
+ localparam defs_div_sqrt_mvp_C_BIAS_AONE_FP32 = 8'h80;
+ localparam defs_div_sqrt_mvp_C_BIAS_AONE_FP64 = 11'h400;
+ localparam defs_div_sqrt_mvp_C_HALF_BIAS_FP16 = 7;
+ localparam defs_div_sqrt_mvp_C_HALF_BIAS_FP16ALT = 63;
+ localparam defs_div_sqrt_mvp_C_HALF_BIAS_FP32 = 63;
+ localparam defs_div_sqrt_mvp_C_HALF_BIAS_FP64 = 511;
+ always @(*)
+ case (Format_sel_S)
+ 2'b00: begin
+ C_BIAS_AONE = defs_div_sqrt_mvp_C_BIAS_AONE_FP32;
+ C_HALF_BIAS = defs_div_sqrt_mvp_C_HALF_BIAS_FP32;
+ end
+ 2'b01: begin
+ C_BIAS_AONE = defs_div_sqrt_mvp_C_BIAS_AONE_FP64;
+ C_HALF_BIAS = defs_div_sqrt_mvp_C_HALF_BIAS_FP64;
+ end
+ 2'b10: begin
+ C_BIAS_AONE = defs_div_sqrt_mvp_C_BIAS_AONE_FP16;
+ C_HALF_BIAS = defs_div_sqrt_mvp_C_HALF_BIAS_FP16;
+ end
+ 2'b11: begin
+ C_BIAS_AONE = defs_div_sqrt_mvp_C_BIAS_AONE_FP16ALT;
+ C_HALF_BIAS = defs_div_sqrt_mvp_C_HALF_BIAS_FP16ALT;
+ end
+ endcase
+ assign Exp_add_a_D = {(Sqrt_start_dly_S ? {Exp_num_DI[defs_div_sqrt_mvp_C_EXP_FP64], Exp_num_DI[defs_div_sqrt_mvp_C_EXP_FP64], Exp_num_DI[defs_div_sqrt_mvp_C_EXP_FP64], Exp_num_DI[defs_div_sqrt_mvp_C_EXP_FP64:1]} : {Exp_num_DI[defs_div_sqrt_mvp_C_EXP_FP64], Exp_num_DI[defs_div_sqrt_mvp_C_EXP_FP64], Exp_num_DI})};
+ localparam defs_div_sqrt_mvp_C_EXP_ZERO_FP64 = 11'h000;
+ assign Exp_add_b_D = {(Sqrt_start_dly_S ? {1'b0, {defs_div_sqrt_mvp_C_EXP_ZERO_FP64}, Exp_num_DI[0]} : {~Exp_den_DI[defs_div_sqrt_mvp_C_EXP_FP64], ~Exp_den_DI[defs_div_sqrt_mvp_C_EXP_FP64], ~Exp_den_DI})};
+ assign Exp_add_c_D = {(Div_start_dly_S ? {C_BIAS_AONE} : {C_HALF_BIAS})};
+ assign Exp_result_prenorm_DN = (Start_dly_S ? {(Exp_add_a_D + Exp_add_b_D) + Exp_add_c_D} : Exp_result_prenorm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Exp_result_prenorm_DP <= {13 {1'sb0}};
+ else
+ Exp_result_prenorm_DP <= Exp_result_prenorm_DN;
+ assign Exp_result_prenorm_DO = Exp_result_prenorm_DP;
+endmodule
+module data_mem_top (
+ clk_i,
+ rst_ni,
+ tl_d_i,
+ tl_d_o,
+ csb,
+ addr_o,
+ wdata_o,
+ wmask_o,
+ we_o,
+ rdata_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_d_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_d_o;
+ output wire csb;
+ output wire [11:0] addr_o;
+ output wire [31:0] wdata_o;
+ output wire [3:0] wmask_o;
+ output wire we_o;
+ input wire [31:0] rdata_i;
+ wire tl_req;
+ wire [31:0] tl_wmask;
+ wire we_i;
+ reg rvalid_o;
+ assign wmask_o[0] = (tl_wmask[7:0] != 8'b00000000 ? 1'b1 : 1'b0);
+ assign wmask_o[1] = (tl_wmask[15:8] != 8'b00000000 ? 1'b1 : 1'b0);
+ assign wmask_o[2] = (tl_wmask[23:16] != 8'b00000000 ? 1'b1 : 1'b0);
+ assign wmask_o[3] = (tl_wmask[31:24] != 8'b00000000 ? 1'b1 : 1'b0);
+ assign we_o = ~we_i;
+ assign csb = ~tl_req;
+ tlul_sram_adapter #(
+ .SramAw(12),
+ .SramDw(32),
+ .Outstanding(4),
+ .ByteAccess(1),
+ .ErrOnWrite(0),
+ .ErrOnRead(0)
+ ) data_mem(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_d_i),
+ .tl_o(tl_d_o),
+ .req_o(tl_req),
+ .gnt_i(1'b1),
+ .we_o(we_i),
+ .addr_o(addr_o),
+ .wdata_o(wdata_o),
+ .wmask_o(tl_wmask),
+ .rdata_i((rst_ni ? rdata_i : {32 {1'sb0}})),
+ .rvalid_i(rvalid_o),
+ .rerror_i(2'b00)
+ );
+ always @(posedge clk_i)
+ if (!rst_ni)
+ rvalid_o <= 1'b0;
+ else if (we_i)
+ rvalid_o <= 1'b0;
+ else
+ rvalid_o <= tl_req;
+endmodule
+module debug_rom_one_scratch (
+ clk_i,
+ req_i,
+ addr_i,
+ rdata_o
+);
+ input wire clk_i;
+ input wire req_i;
+ input wire [63:0] addr_i;
+ output reg [63:0] rdata_o;
+ localparam [31:0] RomSize = 13;
+ wire [831:0] mem;
+ assign mem = 832'h7b2000737b20247310802423f1402473ab1ff06f7b20247310002223001000737b20247310002623fddff06ffc0418e30024741340044403f140247302041263001474134004440310802023f14024737b2410730ff0000f0340006f0500006f00c0006f;
+ reg [3:0] addr_q;
+ always @(posedge clk_i)
+ if (req_i)
+ addr_q <= addr_i[6:3];
+ function automatic [3:0] sv2v_cast_EB05F;
+ input reg [3:0] inp;
+ sv2v_cast_EB05F = inp;
+ endfunction
+ always @(*) begin : p_outmux
+ rdata_o = {64 {1'sb0}};
+ if (addr_q < sv2v_cast_EB05F(RomSize))
+ rdata_o = mem[addr_q * 64+:64];
+ end
+endmodule
+module debug_rom (
+ clk_i,
+ req_i,
+ addr_i,
+ rdata_o
+);
+ input wire clk_i;
+ input wire req_i;
+ input wire [63:0] addr_i;
+ output reg [63:0] rdata_o;
+ localparam [31:0] RomSize = 19;
+ wire [1215:0] mem;
+ assign mem = 1216'h7b2000737b2024737b30257310852423f1402473a85ff06f7b2024737b30257310052223001000737b2024737b3025731005262300c5151300c5551300000517fd5ff06ffa041ce3002474134004440300a40433f140247302041c63001474134004440300a4043310852023f140247300c5151300c55513000005177b3510737b2410730ff0000f04c0006f07c0006f00c0006f;
+ reg [4:0] addr_q;
+ always @(posedge clk_i)
+ if (req_i)
+ addr_q <= addr_i[7:3];
+ function automatic [4:0] sv2v_cast_2C22F;
+ input reg [4:0] inp;
+ sv2v_cast_2C22F = inp;
+ endfunction
+ always @(*) begin : p_outmux
+ rdata_o = {64 {1'sb0}};
+ if (addr_q < sv2v_cast_2C22F(RomSize))
+ rdata_o = mem[addr_q * 64+:64];
+ end
+endmodule
+module div_sqrt_top_mvp (
+ Clk_CI,
+ Rst_RBI,
+ Div_start_SI,
+ Sqrt_start_SI,
+ Operand_a_DI,
+ Operand_b_DI,
+ RM_SI,
+ Precision_ctl_SI,
+ Format_sel_SI,
+ Kill_SI,
+ Result_DO,
+ Fflags_SO,
+ Ready_SO,
+ Done_SO
+);
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Div_start_SI;
+ input wire Sqrt_start_SI;
+ localparam defs_div_sqrt_mvp_C_OP_FP64 = 64;
+ input wire [63:0] Operand_a_DI;
+ input wire [63:0] Operand_b_DI;
+ localparam defs_div_sqrt_mvp_C_RM = 3;
+ input wire [2:0] RM_SI;
+ localparam defs_div_sqrt_mvp_C_PC = 6;
+ input wire [5:0] Precision_ctl_SI;
+ localparam defs_div_sqrt_mvp_C_FS = 2;
+ input wire [1:0] Format_sel_SI;
+ input wire Kill_SI;
+ output wire [63:0] Result_DO;
+ output wire [4:0] Fflags_SO;
+ output wire Ready_SO;
+ output wire Done_SO;
+ localparam defs_div_sqrt_mvp_C_EXP_FP64 = 11;
+ wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_a_D;
+ wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_b_D;
+ localparam defs_div_sqrt_mvp_C_MANT_FP64 = 52;
+ wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_a_D;
+ wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_b_D;
+ wire [12:0] Exp_z_D;
+ wire [56:0] Mant_z_D;
+ wire Sign_z_D;
+ wire Start_S;
+ wire [2:0] RM_dly_S;
+ wire Div_enable_S;
+ wire Sqrt_enable_S;
+ wire Inf_a_S;
+ wire Inf_b_S;
+ wire Zero_a_S;
+ wire Zero_b_S;
+ wire NaN_a_S;
+ wire NaN_b_S;
+ wire SNaN_S;
+ wire Special_case_SB;
+ wire Special_case_dly_SB;
+ wire Full_precision_S;
+ wire FP32_S;
+ wire FP64_S;
+ wire FP16_S;
+ wire FP16ALT_S;
+ preprocess_mvp preprocess_U0(
+ .Clk_CI(Clk_CI),
+ .Rst_RBI(Rst_RBI),
+ .Div_start_SI(Div_start_SI),
+ .Sqrt_start_SI(Sqrt_start_SI),
+ .Ready_SI(Ready_SO),
+ .Operand_a_DI(Operand_a_DI),
+ .Operand_b_DI(Operand_b_DI),
+ .RM_SI(RM_SI),
+ .Format_sel_SI(Format_sel_SI),
+ .Start_SO(Start_S),
+ .Exp_a_DO_norm(Exp_a_D),
+ .Exp_b_DO_norm(Exp_b_D),
+ .Mant_a_DO_norm(Mant_a_D),
+ .Mant_b_DO_norm(Mant_b_D),
+ .RM_dly_SO(RM_dly_S),
+ .Sign_z_DO(Sign_z_D),
+ .Inf_a_SO(Inf_a_S),
+ .Inf_b_SO(Inf_b_S),
+ .Zero_a_SO(Zero_a_S),
+ .Zero_b_SO(Zero_b_S),
+ .NaN_a_SO(NaN_a_S),
+ .NaN_b_SO(NaN_b_S),
+ .SNaN_SO(SNaN_S),
+ .Special_case_SBO(Special_case_SB),
+ .Special_case_dly_SBO(Special_case_dly_SB)
+ );
+ nrbd_nrsc_mvp nrbd_nrsc_U0(
+ .Clk_CI(Clk_CI),
+ .Rst_RBI(Rst_RBI),
+ .Div_start_SI(Div_start_SI),
+ .Sqrt_start_SI(Sqrt_start_SI),
+ .Start_SI(Start_S),
+ .Kill_SI(Kill_SI),
+ .Special_case_SBI(Special_case_SB),
+ .Special_case_dly_SBI(Special_case_dly_SB),
+ .Div_enable_SO(Div_enable_S),
+ .Sqrt_enable_SO(Sqrt_enable_S),
+ .Precision_ctl_SI(Precision_ctl_SI),
+ .Format_sel_SI(Format_sel_SI),
+ .Exp_a_DI(Exp_a_D),
+ .Exp_b_DI(Exp_b_D),
+ .Mant_a_DI(Mant_a_D),
+ .Mant_b_DI(Mant_b_D),
+ .Full_precision_SO(Full_precision_S),
+ .FP32_SO(FP32_S),
+ .FP64_SO(FP64_S),
+ .FP16_SO(FP16_S),
+ .FP16ALT_SO(FP16ALT_S),
+ .Ready_SO(Ready_SO),
+ .Done_SO(Done_SO),
+ .Exp_z_DO(Exp_z_D),
+ .Mant_z_DO(Mant_z_D)
+ );
+ norm_div_sqrt_mvp fpu_norm_U0(
+ .Mant_in_DI(Mant_z_D),
+ .Exp_in_DI(Exp_z_D),
+ .Sign_in_DI(Sign_z_D),
+ .Div_enable_SI(Div_enable_S),
+ .Sqrt_enable_SI(Sqrt_enable_S),
+ .Inf_a_SI(Inf_a_S),
+ .Inf_b_SI(Inf_b_S),
+ .Zero_a_SI(Zero_a_S),
+ .Zero_b_SI(Zero_b_S),
+ .NaN_a_SI(NaN_a_S),
+ .NaN_b_SI(NaN_b_S),
+ .SNaN_SI(SNaN_S),
+ .RM_SI(RM_dly_S),
+ .Full_precision_SI(Full_precision_S),
+ .FP32_SI(FP32_S),
+ .FP64_SI(FP64_S),
+ .FP16_SI(FP16_S),
+ .FP16ALT_SI(FP16ALT_S),
+ .Result_DO(Result_DO),
+ .Fflags_SO(Fflags_SO)
+ );
+endmodule
+module dm_csrs (
+ clk_i,
+ rst_ni,
+ testmode_i,
+ dmi_rst_ni,
+ dmi_req_valid_i,
+ dmi_req_ready_o,
+ dmi_req_i,
+ dmi_resp_valid_o,
+ dmi_resp_ready_i,
+ dmi_resp_o,
+ ndmreset_o,
+ dmactive_o,
+ hartinfo_i,
+ halted_i,
+ unavailable_i,
+ resumeack_i,
+ hartsel_o,
+ haltreq_o,
+ resumereq_o,
+ clear_resumeack_o,
+ cmd_valid_o,
+ cmd_o,
+ cmderror_valid_i,
+ cmderror_i,
+ cmdbusy_i,
+ progbuf_o,
+ data_o,
+ data_i,
+ data_valid_i,
+ sbaddress_o,
+ sbaddress_i,
+ sbaddress_write_valid_o,
+ sbreadonaddr_o,
+ sbautoincrement_o,
+ sbaccess_o,
+ sbreadondata_o,
+ sbdata_o,
+ sbdata_read_valid_o,
+ sbdata_write_valid_o,
+ sbdata_i,
+ sbdata_valid_i,
+ sbbusy_i,
+ sberror_valid_i,
+ sberror_i
+);
+ parameter [31:0] NrHarts = 1;
+ parameter [31:0] BusWidth = 32;
+ parameter [NrHarts - 1:0] SelectableHarts = {NrHarts {1'b1}};
+ input wire clk_i;
+ input wire rst_ni;
+ input wire testmode_i;
+ input wire dmi_rst_ni;
+ input wire dmi_req_valid_i;
+ output wire dmi_req_ready_o;
+ input wire [40:0] dmi_req_i;
+ output wire dmi_resp_valid_o;
+ input wire dmi_resp_ready_i;
+ output wire [33:0] dmi_resp_o;
+ output wire ndmreset_o;
+ output wire dmactive_o;
+ input wire [(NrHarts * 32) - 1:0] hartinfo_i;
+ input wire [NrHarts - 1:0] halted_i;
+ input wire [NrHarts - 1:0] unavailable_i;
+ input wire [NrHarts - 1:0] resumeack_i;
+ output wire [19:0] hartsel_o;
+ output reg [NrHarts - 1:0] haltreq_o;
+ output reg [NrHarts - 1:0] resumereq_o;
+ output reg clear_resumeack_o;
+ output wire cmd_valid_o;
+ output wire [31:0] cmd_o;
+ input wire cmderror_valid_i;
+ input wire [2:0] cmderror_i;
+ input wire cmdbusy_i;
+ localparam [4:0] dm_ProgBufSize = 5'h08;
+ output wire [(dm_ProgBufSize * 32) - 1:0] progbuf_o;
+ localparam [3:0] dm_DataCount = 4'h2;
+ output wire [(dm_DataCount * 32) - 1:0] data_o;
+ input wire [(dm_DataCount * 32) - 1:0] data_i;
+ input wire data_valid_i;
+ output wire [BusWidth - 1:0] sbaddress_o;
+ input wire [BusWidth - 1:0] sbaddress_i;
+ output reg sbaddress_write_valid_o;
+ output wire sbreadonaddr_o;
+ output wire sbautoincrement_o;
+ output wire [2:0] sbaccess_o;
+ output wire sbreadondata_o;
+ output wire [BusWidth - 1:0] sbdata_o;
+ output reg sbdata_read_valid_o;
+ output reg sbdata_write_valid_o;
+ input wire [BusWidth - 1:0] sbdata_i;
+ input wire sbdata_valid_i;
+ input wire sbbusy_i;
+ input wire sberror_valid_i;
+ input wire [2:0] sberror_i;
+ localparam [31:0] HartSelLen = (NrHarts == 1 ? 1 : $clog2(NrHarts));
+ localparam [31:0] NrHartsAligned = 2 ** HartSelLen;
+ wire [1:0] dtm_op;
+ function automatic [1:0] sv2v_cast_2;
+ input reg [1:0] inp;
+ sv2v_cast_2 = inp;
+ endfunction
+ assign dtm_op = sv2v_cast_2(dmi_req_i[33-:2]);
+ reg [31:0] resp_queue_data;
+ localparam [7:0] dm_Data0 = 8'h04;
+ function automatic [7:0] sv2v_cast_8;
+ input reg [7:0] inp;
+ sv2v_cast_8 = inp;
+ endfunction
+ localparam [7:0] DataEnd = sv2v_cast_8((dm_Data0 + {4'h0, dm_DataCount}) - 8'h01);
+ localparam [7:0] dm_ProgBuf0 = 8'h20;
+ localparam [7:0] ProgBufEnd = sv2v_cast_8((dm_ProgBuf0 + {4'h0, dm_ProgBufSize}) - 8'h01);
+ reg [31:0] haltsum0;
+ reg [31:0] haltsum1;
+ reg [31:0] haltsum2;
+ reg [31:0] haltsum3;
+ reg [((((NrHarts - 1) / 32) + 1) * 32) - 1:0] halted;
+ reg [(((NrHarts - 1) / 32) >= 0 ? ((((NrHarts - 1) / 32) + 1) * 32) - 1 : ((1 - ((NrHarts - 1) / 32)) * 32) + ((((NrHarts - 1) / 32) * 32) - 1)):(((NrHarts - 1) / 32) >= 0 ? 0 : ((NrHarts - 1) / 32) * 32)] halted_reshaped0;
+ reg [(((NrHarts - 1) / 1024) >= 0 ? ((((NrHarts - 1) / 1024) + 1) * 32) - 1 : ((1 - ((NrHarts - 1) / 1024)) * 32) + ((((NrHarts - 1) / 1024) * 32) - 1)):(((NrHarts - 1) / 1024) >= 0 ? 0 : ((NrHarts - 1) / 1024) * 32)] halted_reshaped1;
+ reg [(((NrHarts - 1) / 32768) >= 0 ? ((((NrHarts - 1) / 32768) + 1) * 32) - 1 : ((1 - ((NrHarts - 1) / 32768)) * 32) + ((((NrHarts - 1) / 32768) * 32) - 1)):(((NrHarts - 1) / 32768) >= 0 ? 0 : ((NrHarts - 1) / 32768) * 32)] halted_reshaped2;
+ reg [((((NrHarts - 1) / 1024) + 1) * 32) - 1:0] halted_flat1;
+ reg [((((NrHarts - 1) / 32768) + 1) * 32) - 1:0] halted_flat2;
+ reg [31:0] halted_flat3;
+ reg [14:0] hartsel_idx0;
+ function automatic [14:0] sv2v_cast_15;
+ input reg [14:0] inp;
+ sv2v_cast_15 = inp;
+ endfunction
+ always @(*) begin : p_haltsum0
+ halted = {(((NrHarts - 1) / 32) + 1) * 32 {1'sb0}};
+ haltsum0 = {32 {1'sb0}};
+ hartsel_idx0 = hartsel_o[19:5];
+ halted[NrHarts - 1:0] = halted_i;
+ halted_reshaped0 = halted;
+ if (hartsel_idx0 < sv2v_cast_15(((NrHarts - 1) / 32) + 1))
+ haltsum0 = halted_reshaped0[(((NrHarts - 1) / 32) >= 0 ? hartsel_idx0 : ((NrHarts - 1) / 32) - hartsel_idx0) * 32+:32];
+ end
+ reg [9:0] hartsel_idx1;
+ function automatic [9:0] sv2v_cast_10;
+ input reg [9:0] inp;
+ sv2v_cast_10 = inp;
+ endfunction
+ always @(*) begin : p_reduction1
+ halted_flat1 = {(((NrHarts - 1) / 1024) + 1) * 32 {1'sb0}};
+ haltsum1 = {32 {1'sb0}};
+ hartsel_idx1 = hartsel_o[19:10];
+ begin : sv2v_autoblock_100
+ reg [31:0] k;
+ for (k = 0; k < (((NrHarts - 1) / 32) + 1); k = k + 1)
+ halted_flat1[k] = |halted_reshaped0[(((NrHarts - 1) / 32) >= 0 ? k : ((NrHarts - 1) / 32) - k) * 32+:32];
+ end
+ halted_reshaped1 = halted_flat1;
+ if (hartsel_idx1 < sv2v_cast_10(((NrHarts - 1) / 1024) + 1))
+ haltsum1 = halted_reshaped1[(((NrHarts - 1) / 1024) >= 0 ? hartsel_idx1 : ((NrHarts - 1) / 1024) - hartsel_idx1) * 32+:32];
+ end
+ reg [4:0] hartsel_idx2;
+ function automatic [4:0] sv2v_cast_5;
+ input reg [4:0] inp;
+ sv2v_cast_5 = inp;
+ endfunction
+ always @(*) begin : p_reduction2
+ halted_flat2 = {(((NrHarts - 1) / 32768) + 1) * 32 {1'sb0}};
+ haltsum2 = {32 {1'sb0}};
+ hartsel_idx2 = hartsel_o[19:15];
+ begin : sv2v_autoblock_101
+ reg [31:0] k;
+ for (k = 0; k < (((NrHarts - 1) / 1024) + 1); k = k + 1)
+ halted_flat2[k] = |halted_reshaped1[(((NrHarts - 1) / 1024) >= 0 ? k : ((NrHarts - 1) / 1024) - k) * 32+:32];
+ end
+ halted_reshaped2 = halted_flat2;
+ if (hartsel_idx2 < sv2v_cast_5(((NrHarts - 1) / 32768) + 1))
+ haltsum2 = halted_reshaped2[(((NrHarts - 1) / 32768) >= 0 ? hartsel_idx2 : ((NrHarts - 1) / 32768) - hartsel_idx2) * 32+:32];
+ end
+ always @(*) begin : p_reduction3
+ halted_flat3 = {32 {1'sb0}};
+ begin : sv2v_autoblock_102
+ reg [31:0] k;
+ for (k = 0; k < ((NrHarts / 32768) + 1); k = k + 1)
+ halted_flat3[k] = |halted_reshaped2[(((NrHarts - 1) / 32768) >= 0 ? k : ((NrHarts - 1) / 32768) - k) * 32+:32];
+ end
+ haltsum3 = halted_flat3;
+ end
+ reg [31:0] dmstatus;
+ reg [31:0] dmcontrol_d;
+ reg [31:0] dmcontrol_q;
+ reg [31:0] abstractcs;
+ reg [2:0] cmderr_d;
+ reg [2:0] cmderr_q;
+ reg [31:0] command_d;
+ reg [31:0] command_q;
+ reg cmd_valid_d;
+ reg cmd_valid_q;
+ reg [31:0] abstractauto_d;
+ reg [31:0] abstractauto_q;
+ reg [31:0] sbcs_d;
+ reg [31:0] sbcs_q;
+ reg [63:0] sbaddr_d;
+ reg [63:0] sbaddr_q;
+ reg [63:0] sbdata_d;
+ reg [63:0] sbdata_q;
+ wire [NrHarts - 1:0] havereset_d;
+ reg [NrHarts - 1:0] havereset_q;
+ reg [(dm_ProgBufSize * 32) - 1:0] progbuf_d;
+ reg [(dm_ProgBufSize * 32) - 1:0] progbuf_q;
+ reg [(dm_DataCount * 32) - 1:0] data_d;
+ reg [(dm_DataCount * 32) - 1:0] data_q;
+ reg [HartSelLen - 1:0] selected_hart;
+ localparam [1:0] dm_DTM_SUCCESS = 2'h0;
+ assign dmi_resp_o[1-:2] = dm_DTM_SUCCESS;
+ assign sbautoincrement_o = sbcs_q[16];
+ assign sbreadonaddr_o = sbcs_q[20];
+ assign sbreadondata_o = sbcs_q[15];
+ assign sbaccess_o = sbcs_q[19-:3];
+ assign sbdata_o = sbdata_q[BusWidth - 1:0];
+ assign sbaddress_o = sbaddr_q[BusWidth - 1:0];
+ assign hartsel_o = {dmcontrol_q[15-:10], dmcontrol_q[25-:10]};
+ reg [NrHartsAligned - 1:0] havereset_d_aligned;
+ wire [NrHartsAligned - 1:0] havereset_q_aligned;
+ wire [NrHartsAligned - 1:0] resumeack_aligned;
+ wire [NrHartsAligned - 1:0] unavailable_aligned;
+ wire [NrHartsAligned - 1:0] halted_aligned;
+ function automatic [NrHartsAligned - 1:0] sv2v_cast_C60B8;
+ input reg [NrHartsAligned - 1:0] inp;
+ sv2v_cast_C60B8 = inp;
+ endfunction
+ assign resumeack_aligned = sv2v_cast_C60B8(resumeack_i);
+ assign unavailable_aligned = sv2v_cast_C60B8(unavailable_i);
+ assign halted_aligned = sv2v_cast_C60B8(halted_i);
+ function automatic [NrHarts - 1:0] sv2v_cast_25FFB;
+ input reg [NrHarts - 1:0] inp;
+ sv2v_cast_25FFB = inp;
+ endfunction
+ assign havereset_d = sv2v_cast_25FFB(havereset_d_aligned);
+ assign havereset_q_aligned = sv2v_cast_C60B8(havereset_q);
+ reg [(NrHartsAligned * 32) - 1:0] hartinfo_aligned;
+ always @(*) begin : p_hartinfo_align
+ hartinfo_aligned = {NrHartsAligned * 32 {1'sb0}};
+ hartinfo_aligned[32 * ((NrHarts - 1) - (NrHarts - 1))+:32 * NrHarts] = hartinfo_i;
+ end
+ wire [7:0] dm_csr_addr;
+ reg [31:0] sbcs;
+ reg [31:0] a_abstractcs;
+ wire [3:0] autoexecdata_idx;
+ assign dm_csr_addr = sv2v_cast_8({1'b0, dmi_req_i[40-:7]});
+ function automatic [3:0] sv2v_cast_4;
+ input reg [3:0] inp;
+ sv2v_cast_4 = inp;
+ endfunction
+ assign autoexecdata_idx = sv2v_cast_4({dm_csr_addr} - {dm_Data0});
+ localparam [3:0] dm_DbgVersion013 = 4'h2;
+ localparam [7:0] dm_AbstractAuto = 8'h18;
+ localparam [7:0] dm_AbstractCS = 8'h16;
+ localparam [2:0] dm_CmdErrBusy = 1;
+ localparam [2:0] dm_CmdErrNone = 0;
+ localparam [7:0] dm_Command = 8'h17;
+ localparam [7:0] dm_DMControl = 8'h10;
+ localparam [7:0] dm_DMStatus = 8'h11;
+ localparam [1:0] dm_DTM_READ = 2'h1;
+ localparam [1:0] dm_DTM_WRITE = 2'h2;
+ localparam [7:0] dm_HaltSum0 = 8'h40;
+ localparam [7:0] dm_HaltSum1 = 8'h13;
+ localparam [7:0] dm_HaltSum2 = 8'h34;
+ localparam [7:0] dm_HaltSum3 = 8'h35;
+ localparam [7:0] dm_Hartinfo = 8'h12;
+ localparam [7:0] dm_SBAddress0 = 8'h39;
+ localparam [7:0] dm_SBAddress1 = 8'h3a;
+ localparam [7:0] dm_SBCS = 8'h38;
+ localparam [7:0] dm_SBData0 = 8'h3c;
+ localparam [7:0] dm_SBData1 = 8'h3d;
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ function automatic [63:0] sv2v_cast_64;
+ input reg [63:0] inp;
+ sv2v_cast_64 = inp;
+ endfunction
+ function automatic [$clog2(4'h2) - 1:0] sv2v_cast_BB9EC;
+ input reg [$clog2(4'h2) - 1:0] inp;
+ sv2v_cast_BB9EC = inp;
+ endfunction
+ function automatic [2:0] sv2v_cast_3;
+ input reg [2:0] inp;
+ sv2v_cast_3 = inp;
+ endfunction
+ function automatic [11:0] sv2v_cast_12;
+ input reg [11:0] inp;
+ sv2v_cast_12 = inp;
+ endfunction
+ function automatic [15:0] sv2v_cast_16;
+ input reg [15:0] inp;
+ sv2v_cast_16 = inp;
+ endfunction
+ function automatic [6:0] sv2v_cast_F50EE;
+ input reg [6:0] inp;
+ sv2v_cast_F50EE = inp;
+ endfunction
+ always @(*) begin : csr_read_write
+ dmstatus = {32 {1'sb0}};
+ dmstatus[3-:4] = dm_DbgVersion013;
+ dmstatus[7] = 1'b1;
+ dmstatus[5] = 1'b0;
+ dmstatus[19] = havereset_q_aligned[selected_hart];
+ dmstatus[18] = havereset_q_aligned[selected_hart];
+ dmstatus[17] = resumeack_aligned[selected_hart];
+ dmstatus[16] = resumeack_aligned[selected_hart];
+ dmstatus[13] = unavailable_aligned[selected_hart];
+ dmstatus[12] = unavailable_aligned[selected_hart];
+ dmstatus[15] = sv2v_cast_32(hartsel_o) > (NrHarts - 32'sd1);
+ dmstatus[14] = sv2v_cast_32(hartsel_o) > (NrHarts - 32'sd1);
+ dmstatus[9] = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
+ dmstatus[8] = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
+ dmstatus[11] = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
+ dmstatus[10] = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
+ abstractcs = {32 {1'sb0}};
+ abstractcs[3-:4] = dm_DataCount;
+ abstractcs[28-:5] = dm_ProgBufSize;
+ abstractcs[12] = cmdbusy_i;
+ abstractcs[10-:3] = cmderr_q;
+ abstractauto_d = abstractauto_q;
+ abstractauto_d[15-:4] = {4 {1'sb0}};
+ havereset_d_aligned = sv2v_cast_C60B8(havereset_q);
+ dmcontrol_d = dmcontrol_q;
+ cmderr_d = cmderr_q;
+ command_d = command_q;
+ progbuf_d = progbuf_q;
+ data_d = data_q;
+ sbcs_d = sbcs_q;
+ sbaddr_d = sv2v_cast_64(sbaddress_i);
+ sbdata_d = sbdata_q;
+ resp_queue_data = 32'h00000000;
+ cmd_valid_d = 1'b0;
+ sbaddress_write_valid_o = 1'b0;
+ sbdata_read_valid_o = 1'b0;
+ sbdata_write_valid_o = 1'b0;
+ clear_resumeack_o = 1'b0;
+ sbcs = {32 {1'sb0}};
+ a_abstractcs = {32 {1'sb0}};
+ if ((dmi_req_ready_o && dmi_req_valid_i) && (dtm_op == dm_DTM_READ))
+ if ((dm_Data0 <= dm_csr_addr) && (DataEnd >= dm_csr_addr)) begin
+ resp_queue_data = data_q[sv2v_cast_BB9EC(autoexecdata_idx) * 32+:32];
+ if (!cmdbusy_i)
+ cmd_valid_d = abstractauto_q[autoexecdata_idx];
+ else if (cmderr_q == dm_CmdErrNone)
+ cmderr_d = dm_CmdErrBusy;
+ end
+ else if (dm_csr_addr == dm_DMControl)
+ resp_queue_data = dmcontrol_q;
+ else if (dm_csr_addr == dm_DMStatus)
+ resp_queue_data = dmstatus;
+ else if (dm_csr_addr == dm_Hartinfo)
+ resp_queue_data = hartinfo_aligned[selected_hart * 32+:32];
+ else if (dm_csr_addr == dm_AbstractCS)
+ resp_queue_data = abstractcs;
+ else if (dm_csr_addr == dm_AbstractAuto)
+ resp_queue_data = abstractauto_q;
+ else if (dm_csr_addr == dm_Command)
+ resp_queue_data = {32 {1'sb0}};
+ else if ((dm_ProgBuf0 <= dm_csr_addr) && (ProgBufEnd >= dm_csr_addr)) begin
+ resp_queue_data = progbuf_q[dmi_req_i[$clog2(5'h08) + 33:34] * 32+:32];
+ if (!cmdbusy_i)
+ cmd_valid_d = abstractauto_q[{1'b1, dmi_req_i[37:34]}];
+ else if (cmderr_q == dm_CmdErrNone)
+ cmderr_d = dm_CmdErrBusy;
+ end
+ else if (dm_csr_addr == dm_HaltSum0)
+ resp_queue_data = haltsum0;
+ else if (dm_csr_addr == dm_HaltSum1)
+ resp_queue_data = haltsum1;
+ else if (dm_csr_addr == dm_HaltSum2)
+ resp_queue_data = haltsum2;
+ else if (dm_csr_addr == dm_HaltSum3)
+ resp_queue_data = haltsum3;
+ else if (dm_csr_addr == dm_SBCS)
+ resp_queue_data = sbcs_q;
+ else if (dm_csr_addr == dm_SBAddress0)
+ resp_queue_data = sbaddr_q[31:0];
+ else if (dm_csr_addr == dm_SBAddress1)
+ resp_queue_data = sbaddr_q[63:32];
+ else if (dm_csr_addr == dm_SBData0) begin
+ if (sbbusy_i || sbcs_q[22])
+ sbcs_d[22] = 1'b1;
+ else begin
+ sbdata_read_valid_o = sbcs_q[14-:3] == {3 {1'sb0}};
+ resp_queue_data = sbdata_q[31:0];
+ end
+ end
+ else if (dm_csr_addr == dm_SBData1)
+ if (sbbusy_i || sbcs_q[22])
+ sbcs_d[22] = 1'b1;
+ else
+ resp_queue_data = sbdata_q[63:32];
+ if ((dmi_req_ready_o && dmi_req_valid_i) && (dtm_op == dm_DTM_WRITE))
+ if ((dm_Data0 <= dm_csr_addr) && (DataEnd >= dm_csr_addr)) begin
+ if (dm_DataCount > 0)
+ if (!cmdbusy_i) begin
+ data_d[dmi_req_i[$clog2(4'h2) + 33:34] * 32+:32] = dmi_req_i[31-:32];
+ cmd_valid_d = abstractauto_q[autoexecdata_idx];
+ end
+ else if (cmderr_q == dm_CmdErrNone)
+ cmderr_d = dm_CmdErrBusy;
+ end
+ else if (dm_csr_addr == dm_DMControl) begin
+ dmcontrol_d = dmi_req_i[31-:32];
+ if (dmcontrol_d[28])
+ havereset_d_aligned[selected_hart] = 1'b0;
+ end
+ else if (dm_csr_addr == dm_DMStatus)
+ ;
+ else if (dm_csr_addr == dm_Hartinfo)
+ ;
+ else if (dm_csr_addr == dm_AbstractCS) begin
+ a_abstractcs = sv2v_cast_32(dmi_req_i[31-:32]);
+ if (!cmdbusy_i)
+ cmderr_d = sv2v_cast_3(~a_abstractcs[10-:3] & cmderr_q);
+ else if (cmderr_q == dm_CmdErrNone)
+ cmderr_d = dm_CmdErrBusy;
+ end
+ else if (dm_csr_addr == dm_Command) begin
+ if (!cmdbusy_i) begin
+ cmd_valid_d = 1'b1;
+ command_d = sv2v_cast_32(dmi_req_i[31-:32]);
+ end
+ else if (cmderr_q == dm_CmdErrNone)
+ cmderr_d = dm_CmdErrBusy;
+ end
+ else if (dm_csr_addr == dm_AbstractAuto) begin
+ if (!cmdbusy_i) begin
+ abstractauto_d = 32'h00000000;
+ abstractauto_d[11-:12] = sv2v_cast_12(dmi_req_i[dm_DataCount - 1:0]);
+ abstractauto_d[31-:16] = sv2v_cast_16(dmi_req_i[dm_ProgBufSize + 15:16]);
+ end
+ else if (cmderr_q == dm_CmdErrNone)
+ cmderr_d = dm_CmdErrBusy;
+ end
+ else if ((dm_ProgBuf0 <= dm_csr_addr) && (ProgBufEnd >= dm_csr_addr)) begin
+ if (!cmdbusy_i) begin
+ progbuf_d[dmi_req_i[$clog2(5'h08) + 33:34] * 32+:32] = dmi_req_i[31-:32];
+ cmd_valid_d = abstractauto_q[{1'b1, dmi_req_i[37:34]}];
+ end
+ else if (cmderr_q == dm_CmdErrNone)
+ cmderr_d = dm_CmdErrBusy;
+ end
+ else if (dm_csr_addr == dm_SBCS) begin
+ if (sbbusy_i)
+ sbcs_d[22] = 1'b1;
+ else begin
+ sbcs = sv2v_cast_32(dmi_req_i[31-:32]);
+ sbcs_d = sbcs;
+ sbcs_d[22] = sbcs_q[22] & ~sbcs[22];
+ sbcs_d[14-:3] = sbcs_q[14-:3] & ~sbcs[14-:3];
+ end
+ end
+ else if (dm_csr_addr == dm_SBAddress0) begin
+ if (sbbusy_i || sbcs_q[22])
+ sbcs_d[22] = 1'b1;
+ else begin
+ sbaddr_d[31:0] = dmi_req_i[31-:32];
+ sbaddress_write_valid_o = sbcs_q[14-:3] == {3 {1'sb0}};
+ end
+ end
+ else if (dm_csr_addr == dm_SBAddress1) begin
+ if (sbbusy_i || sbcs_q[22])
+ sbcs_d[22] = 1'b1;
+ else
+ sbaddr_d[63:32] = dmi_req_i[31-:32];
+ end
+ else if (dm_csr_addr == dm_SBData0) begin
+ if (sbbusy_i || sbcs_q[22])
+ sbcs_d[22] = 1'b1;
+ else begin
+ sbdata_d[31:0] = dmi_req_i[31-:32];
+ sbdata_write_valid_o = sbcs_q[14-:3] == {3 {1'sb0}};
+ end
+ end
+ else if (dm_csr_addr == dm_SBData1)
+ if (sbbusy_i || sbcs_q[22])
+ sbcs_d[22] = 1'b1;
+ else
+ sbdata_d[63:32] = dmi_req_i[31-:32];
+ if (cmderror_valid_i)
+ cmderr_d = cmderror_i;
+ if (data_valid_i)
+ data_d = data_i;
+ if (ndmreset_o)
+ havereset_d_aligned[NrHarts - 1:0] = {NrHarts {1'sb1}};
+ if (sberror_valid_i)
+ sbcs_d[14-:3] = sberror_i;
+ if (sbdata_valid_i)
+ sbdata_d = sv2v_cast_64(sbdata_i);
+ dmcontrol_d[26] = 1'b0;
+ dmcontrol_d[29] = 1'b0;
+ dmcontrol_d[3] = 1'b0;
+ dmcontrol_d[2] = 1'b0;
+ dmcontrol_d[27] = 1'b0;
+ dmcontrol_d[5-:2] = {2 {1'sb0}};
+ dmcontrol_d[28] = 1'b0;
+ if (!dmcontrol_q[30] && dmcontrol_d[30])
+ clear_resumeack_o = 1'b1;
+ if (dmcontrol_q[30] && resumeack_i)
+ dmcontrol_d[30] = 1'b0;
+ sbcs_d[31-:3] = 3'd1;
+ sbcs_d[21] = sbbusy_i;
+ sbcs_d[11-:7] = sv2v_cast_F50EE(BusWidth);
+ sbcs_d[4] = 1'b0;
+ sbcs_d[3] = BusWidth == 32'd64;
+ sbcs_d[2] = BusWidth == 32'd32;
+ sbcs_d[1] = 1'b0;
+ sbcs_d[0] = 1'b0;
+ sbcs_d[19-:3] = (BusWidth == 32'd64 ? 3'd3 : 3'd2);
+ end
+ function automatic [HartSelLen - 1:0] sv2v_cast_41A1E;
+ input reg [HartSelLen - 1:0] inp;
+ sv2v_cast_41A1E = inp;
+ endfunction
+ always @(*) begin : p_outmux
+ selected_hart = hartsel_o[HartSelLen - 1:0];
+ haltreq_o = {NrHarts {1'sb0}};
+ resumereq_o = {NrHarts {1'sb0}};
+ if (selected_hart <= sv2v_cast_41A1E(NrHarts - 1)) begin
+ haltreq_o[selected_hart] = dmcontrol_q[31];
+ resumereq_o[selected_hart] = dmcontrol_q[30];
+ end
+ end
+ assign dmactive_o = dmcontrol_q[0];
+ assign cmd_o = command_q;
+ assign cmd_valid_o = cmd_valid_q;
+ assign progbuf_o = progbuf_q;
+ assign data_o = data_q;
+ assign ndmreset_o = dmcontrol_q[1];
+ wire unused_testmode;
+ assign unused_testmode = testmode_i;
+ fifo_sync #(
+ .Width(32),
+ .Pass(1'b0),
+ .Depth(2)
+ ) i_fifo(
+ .clk_i(clk_i),
+ .rst_ni(dmi_rst_ni),
+ .clr_i(1'b0),
+ .wdata_i(resp_queue_data),
+ .wvalid_i(dmi_req_valid_i),
+ .wready_o(dmi_req_ready_o),
+ .rdata_o(dmi_resp_o[33-:32]),
+ .rvalid_o(dmi_resp_valid_o),
+ .rready_i(dmi_resp_ready_i),
+ .full_o(),
+ .depth_o()
+ );
+ always @(posedge clk_i or negedge rst_ni) begin : p_regs
+ if (!rst_ni) begin
+ dmcontrol_q <= {32 {1'sb0}};
+ cmderr_q <= dm_CmdErrNone;
+ command_q <= {32 {1'sb0}};
+ cmd_valid_q <= 1'b0;
+ abstractauto_q <= {32 {1'sb0}};
+ progbuf_q <= {dm_ProgBufSize * 32 {1'sb0}};
+ data_q <= {dm_DataCount * 32 {1'sb0}};
+ sbcs_q <= {32 {1'sb0}};
+ sbaddr_q <= {64 {1'sb0}};
+ sbdata_q <= {64 {1'sb0}};
+ havereset_q <= {NrHarts {1'sb1}};
+ end
+ else begin
+ havereset_q <= SelectableHarts & havereset_d;
+ if (!dmcontrol_q[0]) begin
+ dmcontrol_q[31] <= 1'b0;
+ dmcontrol_q[30] <= 1'b0;
+ dmcontrol_q[29] <= 1'b0;
+ dmcontrol_q[28] <= 1'b0;
+ dmcontrol_q[27] <= 1'b0;
+ dmcontrol_q[26] <= 1'b0;
+ dmcontrol_q[25-:10] <= {10 {1'sb0}};
+ dmcontrol_q[15-:10] <= {10 {1'sb0}};
+ dmcontrol_q[5-:2] <= {2 {1'sb0}};
+ dmcontrol_q[3] <= 1'b0;
+ dmcontrol_q[2] <= 1'b0;
+ dmcontrol_q[1] <= 1'b0;
+ dmcontrol_q[0] <= dmcontrol_d[0];
+ cmderr_q <= dm_CmdErrNone;
+ command_q <= {32 {1'sb0}};
+ cmd_valid_q <= 1'b0;
+ abstractauto_q <= {32 {1'sb0}};
+ progbuf_q <= {dm_ProgBufSize * 32 {1'sb0}};
+ data_q <= {dm_DataCount * 32 {1'sb0}};
+ sbcs_q <= {32 {1'sb0}};
+ sbaddr_q <= {64 {1'sb0}};
+ sbdata_q <= {64 {1'sb0}};
+ end
+ else begin
+ dmcontrol_q <= dmcontrol_d;
+ cmderr_q <= cmderr_d;
+ command_q <= command_d;
+ cmd_valid_q <= cmd_valid_d;
+ abstractauto_q <= abstractauto_d;
+ progbuf_q <= progbuf_d;
+ data_q <= data_d;
+ sbcs_q <= sbcs_d;
+ sbaddr_q <= sbaddr_d;
+ sbdata_q <= sbdata_d;
+ end
+ end
+ end
+endmodule
+module dmi_cdc (
+ tck_i,
+ trst_ni,
+ jtag_dmi_req_i,
+ jtag_dmi_ready_o,
+ jtag_dmi_valid_i,
+ jtag_dmi_resp_o,
+ jtag_dmi_valid_o,
+ jtag_dmi_ready_i,
+ clk_i,
+ rst_ni,
+ core_dmi_req_o,
+ core_dmi_valid_o,
+ core_dmi_ready_i,
+ core_dmi_resp_i,
+ core_dmi_ready_o,
+ core_dmi_valid_i
+);
+ input wire tck_i;
+ input wire trst_ni;
+ input wire [40:0] jtag_dmi_req_i;
+ output wire jtag_dmi_ready_o;
+ input wire jtag_dmi_valid_i;
+ output wire [33:0] jtag_dmi_resp_o;
+ output wire jtag_dmi_valid_o;
+ input wire jtag_dmi_ready_i;
+ input wire clk_i;
+ input wire rst_ni;
+ output wire [40:0] core_dmi_req_o;
+ output wire core_dmi_valid_o;
+ input wire core_dmi_ready_i;
+ input wire [33:0] core_dmi_resp_i;
+ output wire core_dmi_ready_o;
+ input wire core_dmi_valid_i;
+ fifo_async #(
+ .Width(41),
+ .Depth(4)
+ ) i_cdc_req(
+ .clk_wr_i(tck_i),
+ .rst_wr_ni(trst_ni),
+ .wvalid_i(jtag_dmi_valid_i),
+ .wready_o(jtag_dmi_ready_o),
+ .wdata_i(jtag_dmi_req_i),
+ .wdepth_o(),
+ .clk_rd_i(clk_i),
+ .rst_rd_ni(rst_ni),
+ .rvalid_o(core_dmi_valid_o),
+ .rready_i(core_dmi_ready_i),
+ .rdata_o(core_dmi_req_o),
+ .rdepth_o()
+ );
+ fifo_async #(
+ .Width(34),
+ .Depth(4)
+ ) i_cdc_resp(
+ .clk_wr_i(clk_i),
+ .rst_wr_ni(rst_ni),
+ .wvalid_i(core_dmi_valid_i),
+ .wready_o(core_dmi_ready_o),
+ .wdata_i(core_dmi_resp_i),
+ .wdepth_o(),
+ .clk_rd_i(tck_i),
+ .rst_rd_ni(trst_ni),
+ .rvalid_o(jtag_dmi_valid_o),
+ .rready_i(jtag_dmi_ready_i),
+ .rdata_o(jtag_dmi_resp_o),
+ .rdepth_o()
+ );
+endmodule
+module dmi_jtag (
+ clk_i,
+ rst_ni,
+ testmode_i,
+ dmi_rst_no,
+ dmi_req_o,
+ dmi_req_valid_o,
+ dmi_req_ready_i,
+ dmi_resp_i,
+ dmi_resp_ready_o,
+ dmi_resp_valid_i,
+ tck_i,
+ tms_i,
+ trst_ni,
+ td_i,
+ td_o,
+ tdo_oe_o
+);
+ parameter [31:0] IdcodeValue = 32'h00000001;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire testmode_i;
+ output wire dmi_rst_no;
+ output wire [40:0] dmi_req_o;
+ output wire dmi_req_valid_o;
+ input wire dmi_req_ready_i;
+ input wire [33:0] dmi_resp_i;
+ output wire dmi_resp_ready_o;
+ input wire dmi_resp_valid_i;
+ input wire tck_i;
+ input wire tms_i;
+ input wire trst_ni;
+ input wire td_i;
+ output wire td_o;
+ output wire tdo_oe_o;
+ assign dmi_rst_no = rst_ni;
+ wire test_logic_reset;
+ wire shift_dr;
+ wire update_dr;
+ wire capture_dr;
+ wire dmi_access;
+ wire dtmcs_select;
+ wire dmi_reset;
+ wire dmi_tdi;
+ wire dmi_tdo;
+ wire [40:0] dmi_req;
+ wire dmi_req_ready;
+ reg dmi_req_valid;
+ wire [33:0] dmi_resp;
+ wire dmi_resp_valid;
+ wire dmi_resp_ready;
+ reg [2:0] state_d;
+ reg [2:0] state_q;
+ reg [40:0] dr_d;
+ reg [40:0] dr_q;
+ reg [6:0] address_d;
+ reg [6:0] address_q;
+ reg [31:0] data_d;
+ reg [31:0] data_q;
+ wire [40:0] dmi;
+ assign dmi = dr_q;
+ assign dmi_req[40-:7] = address_q;
+ assign dmi_req[31-:32] = data_q;
+ localparam [2:0] Write = 3;
+ localparam [1:0] dm_DTM_READ = 2'h1;
+ localparam [1:0] dm_DTM_WRITE = 2'h2;
+ assign dmi_req[33-:2] = (state_q == Write ? dm_DTM_WRITE : dm_DTM_READ);
+ assign dmi_resp_ready = 1'b1;
+ reg error_dmi_busy;
+ reg [1:0] error_d;
+ reg [1:0] error_q;
+ localparam [1:0] DMIBusy = 2'h3;
+ localparam [1:0] DMINoError = 2'h0;
+ localparam [2:0] Idle = 0;
+ localparam [2:0] Read = 1;
+ localparam [2:0] WaitReadValid = 2;
+ localparam [2:0] WaitWriteValid = 4;
+ function automatic [1:0] sv2v_cast_2;
+ input reg [1:0] inp;
+ sv2v_cast_2 = inp;
+ endfunction
+ always @(*) begin : p_fsm
+ error_dmi_busy = 1'b0;
+ state_d = state_q;
+ address_d = address_q;
+ data_d = data_q;
+ error_d = error_q;
+ dmi_req_valid = 1'b0;
+ case (state_q)
+ Idle:
+ if ((dmi_access && update_dr) && (error_q == DMINoError)) begin
+ address_d = dmi[40-:7];
+ data_d = dmi[33-:32];
+ if (sv2v_cast_2(dmi[1-:2]) == dm_DTM_READ)
+ state_d = Read;
+ else if (sv2v_cast_2(dmi[1-:2]) == dm_DTM_WRITE)
+ state_d = Write;
+ end
+ Read: begin
+ dmi_req_valid = 1'b1;
+ if (dmi_req_ready)
+ state_d = WaitReadValid;
+ end
+ WaitReadValid:
+ if (dmi_resp_valid) begin
+ data_d = dmi_resp[33-:32];
+ state_d = Idle;
+ end
+ Write: begin
+ dmi_req_valid = 1'b1;
+ if (dmi_req_ready)
+ state_d = WaitWriteValid;
+ end
+ WaitWriteValid:
+ if (dmi_resp_valid)
+ state_d = Idle;
+ default:
+ if (dmi_resp_valid)
+ state_d = Idle;
+ endcase
+ if (update_dr && (state_q != Idle))
+ error_dmi_busy = 1'b1;
+ if (capture_dr && |{state_q == Read, state_q == WaitReadValid})
+ error_dmi_busy = 1'b1;
+ if (error_dmi_busy)
+ error_d = DMIBusy;
+ if ((update_dr && dmi_reset) && dtmcs_select)
+ error_d = DMINoError;
+ end
+ assign dmi_tdo = dr_q[0];
+ always @(*) begin : p_shift
+ dr_d = dr_q;
+ if (capture_dr)
+ if (dmi_access)
+ if ((error_q == DMINoError) && !error_dmi_busy)
+ dr_d = {address_q, data_q, DMINoError};
+ else if ((error_q == DMIBusy) || error_dmi_busy)
+ dr_d = {address_q, data_q, DMIBusy};
+ if (shift_dr)
+ if (dmi_access)
+ dr_d = {dmi_tdi, dr_q[40:1]};
+ if (test_logic_reset)
+ dr_d = {41 {1'sb0}};
+ end
+ always @(posedge tck_i or negedge trst_ni) begin : p_regs
+ if (!trst_ni) begin
+ dr_q <= {41 {1'sb0}};
+ state_q <= Idle;
+ address_q <= {7 {1'sb0}};
+ data_q <= {32 {1'sb0}};
+ error_q <= DMINoError;
+ end
+ else begin
+ dr_q <= dr_d;
+ state_q <= state_d;
+ address_q <= address_d;
+ data_q <= data_d;
+ error_q <= error_d;
+ end
+ end
+ dmi_jtag_tap #(
+ .IrLength(5),
+ .IdcodeValue(IdcodeValue)
+ ) i_dmi_jtag_tap(
+ .tck_i(tck_i),
+ .tms_i(tms_i),
+ .trst_ni(trst_ni),
+ .td_i(td_i),
+ .td_o(td_o),
+ .tdo_oe_o(tdo_oe_o),
+ .testmode_i(testmode_i),
+ .test_logic_reset_o(test_logic_reset),
+ .shift_dr_o(shift_dr),
+ .update_dr_o(update_dr),
+ .capture_dr_o(capture_dr),
+ .dmi_access_o(dmi_access),
+ .dtmcs_select_o(dtmcs_select),
+ .dmi_reset_o(dmi_reset),
+ .dmi_error_i(error_q),
+ .dmi_tdi_o(dmi_tdi),
+ .dmi_tdo_i(dmi_tdo)
+ );
+ dmi_cdc i_dmi_cdc(
+ .tck_i(tck_i),
+ .trst_ni(trst_ni),
+ .jtag_dmi_req_i(dmi_req),
+ .jtag_dmi_ready_o(dmi_req_ready),
+ .jtag_dmi_valid_i(dmi_req_valid),
+ .jtag_dmi_resp_o(dmi_resp),
+ .jtag_dmi_valid_o(dmi_resp_valid),
+ .jtag_dmi_ready_i(dmi_resp_ready),
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .core_dmi_req_o(dmi_req_o),
+ .core_dmi_valid_o(dmi_req_valid_o),
+ .core_dmi_ready_i(dmi_req_ready_i),
+ .core_dmi_resp_i(dmi_resp_i),
+ .core_dmi_ready_o(dmi_resp_ready_o),
+ .core_dmi_valid_i(dmi_resp_valid_i)
+ );
+endmodule
+module dmi_jtag_tap (
+ tck_i,
+ tms_i,
+ trst_ni,
+ td_i,
+ td_o,
+ tdo_oe_o,
+ testmode_i,
+ test_logic_reset_o,
+ shift_dr_o,
+ update_dr_o,
+ capture_dr_o,
+ dmi_access_o,
+ dtmcs_select_o,
+ dmi_reset_o,
+ dmi_error_i,
+ dmi_tdi_o,
+ dmi_tdo_i
+);
+ parameter [31:0] IrLength = 5;
+ parameter [31:0] IdcodeValue = 32'h00000001;
+ input wire tck_i;
+ input wire tms_i;
+ input wire trst_ni;
+ input wire td_i;
+ output reg td_o;
+ output reg tdo_oe_o;
+ input wire testmode_i;
+ output reg test_logic_reset_o;
+ output reg shift_dr_o;
+ output reg update_dr_o;
+ output reg capture_dr_o;
+ output reg dmi_access_o;
+ output reg dtmcs_select_o;
+ output wire dmi_reset_o;
+ input wire [1:0] dmi_error_i;
+ output wire dmi_tdi_o;
+ input wire dmi_tdo_i;
+ assign dmi_tdi_o = td_i;
+ reg [3:0] tap_state_q;
+ reg [3:0] tap_state_d;
+ reg [IrLength - 1:0] jtag_ir_shift_d;
+ reg [IrLength - 1:0] jtag_ir_shift_q;
+ reg [IrLength - 1:0] jtag_ir_d;
+ reg [IrLength - 1:0] jtag_ir_q;
+ reg capture_ir;
+ reg shift_ir;
+ reg update_ir;
+ localparam [IrLength - 1:0] IDCODE = 'h1;
+ function automatic [IrLength - 1:0] sv2v_cast_42A93;
+ input reg [IrLength - 1:0] inp;
+ sv2v_cast_42A93 = inp;
+ endfunction
+ always @(*) begin : p_jtag
+ jtag_ir_shift_d = jtag_ir_shift_q;
+ jtag_ir_d = jtag_ir_q;
+ if (shift_ir)
+ jtag_ir_shift_d = {td_i, jtag_ir_shift_q[IrLength - 1:1]};
+ if (capture_ir)
+ jtag_ir_shift_d = sv2v_cast_42A93(4'b0101);
+ if (update_ir)
+ jtag_ir_d = jtag_ir_shift_q;
+ if (test_logic_reset_o) begin
+ jtag_ir_shift_d = {IrLength {1'sb0}};
+ jtag_ir_d = IDCODE;
+ end
+ end
+ always @(posedge tck_i or negedge trst_ni) begin : p_jtag_ir_reg
+ if (!trst_ni) begin
+ jtag_ir_shift_q <= {IrLength {1'sb0}};
+ jtag_ir_q <= IDCODE;
+ end
+ else begin
+ jtag_ir_shift_q <= jtag_ir_shift_d;
+ jtag_ir_q <= jtag_ir_d;
+ end
+ end
+ reg [31:0] idcode_d;
+ reg [31:0] idcode_q;
+ reg idcode_select;
+ reg bypass_select;
+ reg [31:0] dtmcs_d;
+ reg [31:0] dtmcs_q;
+ reg bypass_d;
+ reg bypass_q;
+ assign dmi_reset_o = dtmcs_q[16];
+ function automatic [30:0] sv2v_cast_31;
+ input reg [30:0] inp;
+ sv2v_cast_31 = inp;
+ endfunction
+ always @(*) begin
+ idcode_d = idcode_q;
+ bypass_d = bypass_q;
+ dtmcs_d = dtmcs_q;
+ if (capture_dr_o) begin
+ if (idcode_select)
+ idcode_d = IdcodeValue;
+ if (bypass_select)
+ bypass_d = 1'b0;
+ if (dtmcs_select_o)
+ dtmcs_d = {20'b00000000000000000001, dmi_error_i, 6'd7, 4'd1};
+ end
+ if (shift_dr_o) begin
+ if (idcode_select)
+ idcode_d = {td_i, sv2v_cast_31(idcode_q >> 1)};
+ if (bypass_select)
+ bypass_d = td_i;
+ if (dtmcs_select_o)
+ dtmcs_d = {td_i, sv2v_cast_31(dtmcs_q >> 1)};
+ end
+ if (test_logic_reset_o) begin
+ idcode_d = IdcodeValue;
+ bypass_d = 1'b0;
+ end
+ end
+ localparam [IrLength - 1:0] BYPASS0 = 'h0;
+ localparam [IrLength - 1:0] BYPASS1 = 'h1f;
+ localparam [IrLength - 1:0] DMIACCESS = 'h11;
+ localparam [IrLength - 1:0] DTMCSR = 'h10;
+ always @(*) begin : p_data_reg_sel
+ dmi_access_o = 1'b0;
+ dtmcs_select_o = 1'b0;
+ idcode_select = 1'b0;
+ bypass_select = 1'b0;
+ case (jtag_ir_q)
+ BYPASS0: bypass_select = 1'b1;
+ IDCODE: idcode_select = 1'b1;
+ DTMCSR: dtmcs_select_o = 1'b1;
+ DMIACCESS: dmi_access_o = 1'b1;
+ BYPASS1: bypass_select = 1'b1;
+ default: bypass_select = 1'b1;
+ endcase
+ end
+ reg tdo_mux;
+ always @(*) begin : p_out_sel
+ if (shift_ir)
+ tdo_mux = jtag_ir_shift_q[0];
+ else
+ case (jtag_ir_q)
+ IDCODE: tdo_mux = idcode_q[0];
+ DTMCSR: tdo_mux = dtmcs_q[0];
+ DMIACCESS: tdo_mux = dmi_tdo_i;
+ default: tdo_mux = bypass_q;
+ endcase
+ end
+ wire tck_n;
+ prim_generic_clock_inv #(.HasScanMode(1'b1)) i_tck_inv(
+ .clk_i(tck_i),
+ .clk_no(tck_n),
+ .scanmode_i(testmode_i)
+ );
+ always @(posedge tck_n or negedge trst_ni) begin : p_tdo_regs
+ if (!trst_ni) begin
+ td_o <= 1'b0;
+ tdo_oe_o <= 1'b0;
+ end
+ else begin
+ td_o <= tdo_mux;
+ tdo_oe_o <= shift_ir | shift_dr_o;
+ end
+ end
+ localparam [3:0] CaptureDr = 3;
+ localparam [3:0] CaptureIr = 10;
+ localparam [3:0] Exit1Dr = 5;
+ localparam [3:0] Exit1Ir = 12;
+ localparam [3:0] Exit2Dr = 7;
+ localparam [3:0] Exit2Ir = 14;
+ localparam [3:0] PauseDr = 6;
+ localparam [3:0] PauseIr = 13;
+ localparam [3:0] RunTestIdle = 1;
+ localparam [3:0] SelectDrScan = 2;
+ localparam [3:0] SelectIrScan = 9;
+ localparam [3:0] ShiftDr = 4;
+ localparam [3:0] ShiftIr = 11;
+ localparam [3:0] TestLogicReset = 0;
+ localparam [3:0] UpdateDr = 8;
+ localparam [3:0] UpdateIr = 15;
+ always @(*) begin : p_tap_fsm
+ test_logic_reset_o = 1'b0;
+ capture_dr_o = 1'b0;
+ shift_dr_o = 1'b0;
+ update_dr_o = 1'b0;
+ capture_ir = 1'b0;
+ shift_ir = 1'b0;
+ update_ir = 1'b0;
+ case (tap_state_q)
+ TestLogicReset: begin
+ tap_state_d = (tms_i ? TestLogicReset : RunTestIdle);
+ test_logic_reset_o = 1'b1;
+ end
+ RunTestIdle: tap_state_d = (tms_i ? SelectDrScan : RunTestIdle);
+ SelectDrScan: tap_state_d = (tms_i ? SelectIrScan : CaptureDr);
+ CaptureDr: begin
+ capture_dr_o = 1'b1;
+ tap_state_d = (tms_i ? Exit1Dr : ShiftDr);
+ end
+ ShiftDr: begin
+ shift_dr_o = 1'b1;
+ tap_state_d = (tms_i ? Exit1Dr : ShiftDr);
+ end
+ Exit1Dr: tap_state_d = (tms_i ? UpdateDr : PauseDr);
+ PauseDr: tap_state_d = (tms_i ? Exit2Dr : PauseDr);
+ Exit2Dr: tap_state_d = (tms_i ? UpdateDr : ShiftDr);
+ UpdateDr: begin
+ update_dr_o = 1'b1;
+ tap_state_d = (tms_i ? SelectDrScan : RunTestIdle);
+ end
+ SelectIrScan: tap_state_d = (tms_i ? TestLogicReset : CaptureIr);
+ CaptureIr: begin
+ capture_ir = 1'b1;
+ tap_state_d = (tms_i ? Exit1Ir : ShiftIr);
+ end
+ ShiftIr: begin
+ shift_ir = 1'b1;
+ tap_state_d = (tms_i ? Exit1Ir : ShiftIr);
+ end
+ Exit1Ir: tap_state_d = (tms_i ? UpdateIr : PauseIr);
+ PauseIr: tap_state_d = (tms_i ? Exit2Ir : PauseIr);
+ Exit2Ir: tap_state_d = (tms_i ? UpdateIr : ShiftIr);
+ UpdateIr: begin
+ update_ir = 1'b1;
+ tap_state_d = (tms_i ? SelectDrScan : RunTestIdle);
+ end
+ default:
+ ;
+ endcase
+ end
+ always @(posedge tck_i or negedge trst_ni) begin : p_regs
+ if (!trst_ni) begin
+ tap_state_q <= RunTestIdle;
+ idcode_q <= IdcodeValue;
+ bypass_q <= 1'b0;
+ dtmcs_q <= {32 {1'sb0}};
+ end
+ else begin
+ tap_state_q <= tap_state_d;
+ idcode_q <= idcode_d;
+ bypass_q <= bypass_d;
+ dtmcs_q <= dtmcs_d;
+ end
+ end
+endmodule
+module dm_mem (
+ clk_i,
+ rst_ni,
+ debug_req_o,
+ hartsel_i,
+ haltreq_i,
+ resumereq_i,
+ clear_resumeack_i,
+ halted_o,
+ resuming_o,
+ progbuf_i,
+ data_i,
+ data_o,
+ data_valid_o,
+ cmd_valid_i,
+ cmd_i,
+ cmderror_valid_o,
+ cmderror_o,
+ cmdbusy_o,
+ req_i,
+ we_i,
+ addr_i,
+ wdata_i,
+ be_i,
+ rdata_o
+);
+ parameter [31:0] NrHarts = 1;
+ parameter [31:0] BusWidth = 32;
+ parameter [NrHarts - 1:0] SelectableHarts = {NrHarts {1'b1}};
+ parameter [31:0] DmBaseAddress = 1'sb0;
+ input wire clk_i;
+ input wire rst_ni;
+ output wire [NrHarts - 1:0] debug_req_o;
+ input wire [19:0] hartsel_i;
+ input wire [NrHarts - 1:0] haltreq_i;
+ input wire [NrHarts - 1:0] resumereq_i;
+ input wire clear_resumeack_i;
+ output wire [NrHarts - 1:0] halted_o;
+ output wire [NrHarts - 1:0] resuming_o;
+ localparam [4:0] dm_ProgBufSize = 5'h08;
+ input wire [(dm_ProgBufSize * 32) - 1:0] progbuf_i;
+ localparam [3:0] dm_DataCount = 4'h2;
+ input wire [(dm_DataCount * 32) - 1:0] data_i;
+ output reg [(dm_DataCount * 32) - 1:0] data_o;
+ output reg data_valid_o;
+ input wire cmd_valid_i;
+ input wire [31:0] cmd_i;
+ output reg cmderror_valid_o;
+ output reg [2:0] cmderror_o;
+ output reg cmdbusy_o;
+ input wire req_i;
+ input wire we_i;
+ input wire [BusWidth - 1:0] addr_i;
+ input wire [BusWidth - 1:0] wdata_i;
+ input wire [(BusWidth / 8) - 1:0] be_i;
+ output wire [BusWidth - 1:0] rdata_o;
+ localparam [31:0] DbgAddressBits = 12;
+ localparam [31:0] HartSelLen = (NrHarts == 1 ? 1 : $clog2(NrHarts));
+ localparam [31:0] NrHartsAligned = 2 ** HartSelLen;
+ localparam [31:0] MaxAar = (BusWidth == 64 ? 4 : 3);
+ localparam [0:0] HasSndScratch = DmBaseAddress != 0;
+ localparam [4:0] LoadBaseAddr = (DmBaseAddress == 0 ? 5'd0 : 5'd10);
+ localparam [11:0] dm_DataAddr = 12'h380;
+ localparam [11:0] DataBaseAddr = dm_DataAddr;
+ localparam [11:0] DataEndAddr = (dm_DataAddr + (4 * dm_DataCount)) - 1;
+ localparam [11:0] ProgBufBaseAddr = dm_DataAddr - (4 * dm_ProgBufSize);
+ localparam [11:0] ProgBufEndAddr = dm_DataAddr - 1;
+ localparam [11:0] AbstractCmdBaseAddr = ProgBufBaseAddr - 40;
+ localparam [11:0] AbstractCmdEndAddr = ProgBufBaseAddr - 1;
+ localparam [11:0] WhereToAddr = 'h300;
+ localparam [11:0] FlagsBaseAddr = 'h400;
+ localparam [11:0] FlagsEndAddr = 'h7ff;
+ localparam [11:0] HaltedAddr = 'h100;
+ localparam [11:0] GoingAddr = 'h104;
+ localparam [11:0] ResumingAddr = 'h108;
+ localparam [11:0] ExceptionAddr = 'h10c;
+ wire [((dm_ProgBufSize / 2) * 64) - 1:0] progbuf;
+ reg [511:0] abstract_cmd;
+ wire [NrHarts - 1:0] halted_d;
+ reg [NrHarts - 1:0] halted_q;
+ wire [NrHarts - 1:0] resuming_d;
+ reg [NrHarts - 1:0] resuming_q;
+ reg resume;
+ reg go;
+ reg going;
+ reg exception;
+ reg unsupported_command;
+ wire [63:0] rom_rdata;
+ reg [63:0] rdata_d;
+ reg [63:0] rdata_q;
+ reg word_enable32_q;
+ wire [HartSelLen - 1:0] hartsel;
+ wire [HartSelLen - 1:0] wdata_hartsel;
+ assign hartsel = hartsel_i[HartSelLen - 1:0];
+ assign wdata_hartsel = wdata_i[HartSelLen - 1:0];
+ wire [NrHartsAligned - 1:0] resumereq_aligned;
+ wire [NrHartsAligned - 1:0] haltreq_aligned;
+ reg [NrHartsAligned - 1:0] halted_d_aligned;
+ wire [NrHartsAligned - 1:0] halted_q_aligned;
+ reg [NrHartsAligned - 1:0] halted_aligned;
+ wire [NrHartsAligned - 1:0] resumereq_wdata_aligned;
+ reg [NrHartsAligned - 1:0] resuming_d_aligned;
+ wire [NrHartsAligned - 1:0] resuming_q_aligned;
+ function automatic [NrHartsAligned - 1:0] sv2v_cast_C60B8;
+ input reg [NrHartsAligned - 1:0] inp;
+ sv2v_cast_C60B8 = inp;
+ endfunction
+ assign resumereq_aligned = sv2v_cast_C60B8(resumereq_i);
+ assign haltreq_aligned = sv2v_cast_C60B8(haltreq_i);
+ assign resumereq_wdata_aligned = sv2v_cast_C60B8(resumereq_i);
+ assign halted_q_aligned = sv2v_cast_C60B8(halted_q);
+ function automatic [NrHarts - 1:0] sv2v_cast_25FFB;
+ input reg [NrHarts - 1:0] inp;
+ sv2v_cast_25FFB = inp;
+ endfunction
+ assign halted_d = sv2v_cast_25FFB(halted_d_aligned);
+ assign resuming_q_aligned = sv2v_cast_C60B8(resuming_q);
+ assign resuming_d = sv2v_cast_25FFB(resuming_d_aligned);
+ wire fwd_rom_d;
+ reg fwd_rom_q;
+ wire [23:0] ac_ar;
+ function automatic [23:0] sv2v_cast_24;
+ input reg [23:0] inp;
+ sv2v_cast_24 = inp;
+ endfunction
+ assign ac_ar = sv2v_cast_24(cmd_i[23-:24]);
+ assign debug_req_o = haltreq_i;
+ assign halted_o = halted_q;
+ assign resuming_o = resuming_q;
+ assign progbuf = progbuf_i;
+ reg [1:0] state_d;
+ reg [1:0] state_q;
+ localparam [1:0] CmdExecuting = 3;
+ localparam [1:0] Go = 1;
+ localparam [1:0] Idle = 0;
+ localparam [1:0] Resume = 2;
+ localparam [2:0] dm_CmdErrNone = 0;
+ localparam [2:0] dm_CmdErrNotSupported = 2;
+ localparam [2:0] dm_CmdErrorException = 3;
+ localparam [2:0] dm_CmdErrorHaltResume = 4;
+ always @(*) begin : p_hart_ctrl_queue
+ cmderror_valid_o = 1'b0;
+ cmderror_o = dm_CmdErrNone;
+ state_d = state_q;
+ go = 1'b0;
+ resume = 1'b0;
+ cmdbusy_o = 1'b1;
+ case (state_q)
+ Idle: begin
+ cmdbusy_o = 1'b0;
+ if ((cmd_valid_i && halted_q_aligned[hartsel]) && !unsupported_command)
+ state_d = Go;
+ else if (cmd_valid_i) begin
+ cmderror_valid_o = 1'b1;
+ cmderror_o = dm_CmdErrorHaltResume;
+ end
+ if (((resumereq_aligned[hartsel] && !resuming_q_aligned[hartsel]) && !haltreq_aligned[hartsel]) && halted_q_aligned[hartsel])
+ state_d = Resume;
+ end
+ Go: begin
+ cmdbusy_o = 1'b1;
+ go = 1'b1;
+ if (going)
+ state_d = CmdExecuting;
+ end
+ Resume: begin
+ cmdbusy_o = 1'b1;
+ resume = 1'b1;
+ if (resuming_q_aligned[hartsel])
+ state_d = Idle;
+ end
+ CmdExecuting: begin
+ cmdbusy_o = 1'b1;
+ go = 1'b0;
+ if (halted_aligned[hartsel])
+ state_d = Idle;
+ end
+ default:
+ ;
+ endcase
+ if (unsupported_command && cmd_valid_i) begin
+ cmderror_valid_o = 1'b1;
+ cmderror_o = dm_CmdErrNotSupported;
+ end
+ if (exception) begin
+ cmderror_valid_o = 1'b1;
+ cmderror_o = dm_CmdErrorException;
+ end
+ end
+ wire [63:0] word_mux;
+ assign word_mux = (fwd_rom_q ? rom_rdata : rdata_q);
+ generate
+ if (BusWidth == 64) begin : gen_word_mux64
+ assign rdata_o = word_mux;
+ end
+ else begin : gen_word_mux32
+ assign rdata_o = (word_enable32_q ? word_mux[32+:32] : word_mux[0+:32]);
+ end
+ endgenerate
+ reg [63:0] data_bits;
+ reg [63:0] rdata;
+ localparam [63:0] dm_HaltAddress = 64'h0000000000000800;
+ localparam [63:0] dm_ResumeAddress = dm_HaltAddress + 4;
+ function automatic [31:0] dm_jal;
+ input reg [4:0] rd;
+ input reg [20:0] imm;
+ dm_jal = {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h6f};
+ endfunction
+ localparam [7:0] dm_AccessRegister = 8'h00;
+ function automatic [20:0] sv2v_cast_21;
+ input reg [20:0] inp;
+ sv2v_cast_21 = inp;
+ endfunction
+ function automatic [$clog2(5'h08) - 1:0] sv2v_cast_2F779;
+ input reg [$clog2(5'h08) - 1:0] inp;
+ sv2v_cast_2F779 = inp;
+ endfunction
+ function automatic [2:0] sv2v_cast_3;
+ input reg [2:0] inp;
+ sv2v_cast_3 = inp;
+ endfunction
+ function automatic [11:0] sv2v_cast_9D1F2;
+ input reg [11:0] inp;
+ sv2v_cast_9D1F2 = inp;
+ endfunction
+ always @(*) begin : p_rw_logic
+ halted_d_aligned = sv2v_cast_C60B8(halted_q);
+ resuming_d_aligned = sv2v_cast_C60B8(resuming_q);
+ rdata_d = rdata_q;
+ data_bits = data_i;
+ rdata = {64 {1'sb0}};
+ data_valid_o = 1'b0;
+ exception = 1'b0;
+ halted_aligned = {NrHartsAligned {1'sb0}};
+ going = 1'b0;
+ if (clear_resumeack_i)
+ resuming_d_aligned[hartsel] = 1'b0;
+ if (req_i)
+ if (we_i) begin
+ if (addr_i[11:0] == HaltedAddr) begin
+ halted_aligned[wdata_hartsel] = 1'b1;
+ halted_d_aligned[wdata_hartsel] = 1'b1;
+ end
+ else if (addr_i[11:0] == GoingAddr)
+ going = 1'b1;
+ else if (addr_i[11:0] == ResumingAddr) begin
+ halted_d_aligned[wdata_hartsel] = 1'b0;
+ resuming_d_aligned[wdata_hartsel] = 1'b1;
+ end
+ else if (addr_i[11:0] == ExceptionAddr)
+ exception = 1'b1;
+ else if ((DataBaseAddr <= addr_i[11:0]) && (DataEndAddr >= addr_i[11:0])) begin
+ data_valid_o = 1'b1;
+ begin : sv2v_autoblock_103
+ reg signed [31:0] i;
+ for (i = 0; i < (BusWidth / 8); i = i + 1)
+ if (be_i[i])
+ data_bits[i * 8+:8] = wdata_i[i * 8+:8];
+ end
+ end
+ end
+ else if (addr_i[11:0] == WhereToAddr) begin
+ if (resumereq_wdata_aligned[wdata_hartsel])
+ rdata_d = {32'b00000000000000000000000000000000, dm_jal(1'sb0, sv2v_cast_21(dm_ResumeAddress[11:0]) - sv2v_cast_21(WhereToAddr))};
+ if (cmdbusy_o)
+ if (((cmd_i[31-:8] == dm_AccessRegister) && !ac_ar[17]) && ac_ar[18])
+ rdata_d = {32'b00000000000000000000000000000000, dm_jal(1'sb0, sv2v_cast_21(ProgBufBaseAddr) - sv2v_cast_21(WhereToAddr))};
+ else
+ rdata_d = {32'b00000000000000000000000000000000, dm_jal(1'sb0, sv2v_cast_21(AbstractCmdBaseAddr) - sv2v_cast_21(WhereToAddr))};
+ end
+ else if ((DataBaseAddr <= addr_i[11:0]) && (DataEndAddr >= addr_i[11:0]))
+ rdata_d = {data_i[sv2v_cast_2F779((addr_i[11:3] - DataBaseAddr[11:3]) + 1'b1) * 32+:32], data_i[sv2v_cast_2F779(addr_i[11:3] - DataBaseAddr[11:3]) * 32+:32]};
+ else if ((ProgBufBaseAddr <= addr_i[11:0]) && (ProgBufEndAddr >= addr_i[11:0]))
+ rdata_d = progbuf[sv2v_cast_2F779(addr_i[11:3] - ProgBufBaseAddr[11:3]) * 64+:64];
+ else if ((AbstractCmdBaseAddr <= addr_i[11:0]) && (AbstractCmdEndAddr >= addr_i[11:0]))
+ rdata_d = abstract_cmd[sv2v_cast_3(addr_i[11:3] - AbstractCmdBaseAddr[11:3]) * 64+:64];
+ else if ((FlagsBaseAddr <= addr_i[11:0]) && (FlagsEndAddr >= addr_i[11:0])) begin
+ if (({addr_i[11:3], 3'b000} - FlagsBaseAddr[11:0]) == (sv2v_cast_9D1F2(hartsel) & {{9 {1'b1}}, 3'b000}))
+ rdata[(sv2v_cast_9D1F2(hartsel) & sv2v_cast_9D1F2(3'b111)) * 8+:8] = {6'b000000, resume, go};
+ rdata_d = rdata;
+ end
+ data_o = data_bits;
+ end
+ function automatic [31:0] dm_auipc;
+ input reg [4:0] rd;
+ input reg [20:0] imm;
+ dm_auipc = {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h17};
+ endfunction
+ function automatic [31:0] dm_csrr;
+ input reg [11:0] csr;
+ input reg [4:0] dest;
+ dm_csrr = {csr, 5'h00, 3'h2, dest, 7'h73};
+ endfunction
+ function automatic [31:0] dm_csrw;
+ input reg [11:0] csr;
+ input reg [4:0] rs1;
+ dm_csrw = {csr, rs1, 3'h1, 5'h00, 7'h73};
+ endfunction
+ function automatic [31:0] dm_ebreak;
+ input reg _sv2v_unused;
+ dm_ebreak = 32'h00100073;
+ endfunction
+ function automatic [31:0] dm_float_load;
+ input reg [2:0] size;
+ input reg [4:0] dest;
+ input reg [4:0] base;
+ input reg [11:0] offset;
+ dm_float_load = {offset[11:0], base, size, dest, 7'b0000111};
+ endfunction
+ function automatic [31:0] dm_float_store;
+ input reg [2:0] size;
+ input reg [4:0] src;
+ input reg [4:0] base;
+ input reg [11:0] offset;
+ dm_float_store = {offset[11:5], src, base, size, offset[4:0], 7'b0100111};
+ endfunction
+ function automatic [31:0] dm_illegal;
+ input reg _sv2v_unused;
+ dm_illegal = 32'h00000000;
+ endfunction
+ function automatic [31:0] dm_load;
+ input reg [2:0] size;
+ input reg [4:0] dest;
+ input reg [4:0] base;
+ input reg [11:0] offset;
+ dm_load = {offset[11:0], base, size, dest, 7'h03};
+ endfunction
+ function automatic [31:0] dm_nop;
+ input reg _sv2v_unused;
+ dm_nop = 32'h00000013;
+ endfunction
+ function automatic [31:0] dm_slli;
+ input reg [4:0] rd;
+ input reg [4:0] rs1;
+ input reg [5:0] shamt;
+ dm_slli = {6'b000000, shamt[5:0], rs1, 3'h1, rd, 7'h13};
+ endfunction
+ function automatic [31:0] dm_srli;
+ input reg [4:0] rd;
+ input reg [4:0] rs1;
+ input reg [5:0] shamt;
+ dm_srli = {6'b000000, shamt[5:0], rs1, 3'h5, rd, 7'h13};
+ endfunction
+ function automatic [31:0] dm_store;
+ input reg [2:0] size;
+ input reg [4:0] src;
+ input reg [4:0] base;
+ input reg [11:0] offset;
+ dm_store = {offset[11:5], src, base, size, offset[4:0], 7'h23};
+ endfunction
+ localparam [11:0] dm_CSR_DSCRATCH0 = 12'h7b2;
+ localparam [11:0] dm_CSR_DSCRATCH1 = 12'h7b3;
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ always @(*) begin : p_abstract_cmd_rom
+ unsupported_command = 1'b0;
+ abstract_cmd[31-:32] = dm_illegal(0);
+ abstract_cmd[63-:32] = (HasSndScratch ? dm_auipc(5'd10, 1'sb0) : dm_nop(0));
+ abstract_cmd[95-:32] = (HasSndScratch ? dm_srli(5'd10, 5'd10, 6'd12) : dm_nop(0));
+ abstract_cmd[127-:32] = (HasSndScratch ? dm_slli(5'd10, 5'd10, 6'd12) : dm_nop(0));
+ abstract_cmd[159-:32] = dm_nop(0);
+ abstract_cmd[191-:32] = dm_nop(0);
+ abstract_cmd[223-:32] = dm_nop(0);
+ abstract_cmd[255-:32] = dm_nop(0);
+ abstract_cmd[287-:32] = (HasSndScratch ? dm_csrr(dm_CSR_DSCRATCH1, 5'd10) : dm_nop(0));
+ abstract_cmd[319-:32] = dm_ebreak(0);
+ abstract_cmd[320+:192] = {192 {1'sb0}};
+ case (cmd_i[31-:8])
+ dm_AccessRegister: begin
+ if (((sv2v_cast_32(ac_ar[22-:3]) < MaxAar) && ac_ar[17]) && ac_ar[16]) begin
+ abstract_cmd[31-:32] = (HasSndScratch ? dm_csrw(dm_CSR_DSCRATCH1, 5'd10) : dm_nop(0));
+ if (ac_ar[15:14] != {2 {1'sb0}}) begin
+ abstract_cmd[31-:32] = dm_ebreak(0);
+ unsupported_command = 1'b1;
+ end
+ else if (((HasSndScratch && ac_ar[12]) && !ac_ar[5]) && (ac_ar[4:0] == 5'd10)) begin
+ abstract_cmd[159-:32] = dm_csrw(dm_CSR_DSCRATCH0, 5'd8);
+ abstract_cmd[191-:32] = dm_load(ac_ar[22-:3], 5'd8, LoadBaseAddr, dm_DataAddr);
+ abstract_cmd[223-:32] = dm_csrw(dm_CSR_DSCRATCH1, 5'd8);
+ abstract_cmd[255-:32] = dm_csrr(dm_CSR_DSCRATCH0, 5'd8);
+ end
+ else if (ac_ar[12]) begin
+ if (ac_ar[5])
+ abstract_cmd[159-:32] = dm_float_load(ac_ar[22-:3], ac_ar[4:0], LoadBaseAddr, dm_DataAddr);
+ else
+ abstract_cmd[159-:32] = dm_load(ac_ar[22-:3], ac_ar[4:0], LoadBaseAddr, dm_DataAddr);
+ end
+ else begin
+ abstract_cmd[159-:32] = dm_csrw(dm_CSR_DSCRATCH0, 5'd8);
+ abstract_cmd[191-:32] = dm_load(ac_ar[22-:3], 5'd8, LoadBaseAddr, dm_DataAddr);
+ abstract_cmd[223-:32] = dm_csrw(ac_ar[11:0], 5'd8);
+ abstract_cmd[255-:32] = dm_csrr(dm_CSR_DSCRATCH0, 5'd8);
+ end
+ end
+ else if (((sv2v_cast_32(ac_ar[22-:3]) < MaxAar) && ac_ar[17]) && !ac_ar[16]) begin
+ abstract_cmd[31-:32] = (HasSndScratch ? dm_csrw(dm_CSR_DSCRATCH1, LoadBaseAddr) : dm_nop(0));
+ if (ac_ar[15:14] != {2 {1'sb0}}) begin
+ abstract_cmd[31-:32] = dm_ebreak(0);
+ unsupported_command = 1'b1;
+ end
+ else if (((HasSndScratch && ac_ar[12]) && !ac_ar[5]) && (ac_ar[4:0] == 5'd10)) begin
+ abstract_cmd[159-:32] = dm_csrw(dm_CSR_DSCRATCH0, 5'd8);
+ abstract_cmd[191-:32] = dm_csrr(dm_CSR_DSCRATCH1, 5'd8);
+ abstract_cmd[223-:32] = dm_store(ac_ar[22-:3], 5'd8, LoadBaseAddr, dm_DataAddr);
+ abstract_cmd[255-:32] = dm_csrr(dm_CSR_DSCRATCH0, 5'd8);
+ end
+ else if (ac_ar[12]) begin
+ if (ac_ar[5])
+ abstract_cmd[159-:32] = dm_float_store(ac_ar[22-:3], ac_ar[4:0], LoadBaseAddr, dm_DataAddr);
+ else
+ abstract_cmd[159-:32] = dm_store(ac_ar[22-:3], ac_ar[4:0], LoadBaseAddr, dm_DataAddr);
+ end
+ else begin
+ abstract_cmd[159-:32] = dm_csrw(dm_CSR_DSCRATCH0, 5'd8);
+ abstract_cmd[191-:32] = dm_csrr(ac_ar[11:0], 5'd8);
+ abstract_cmd[223-:32] = dm_store(ac_ar[22-:3], 5'd8, LoadBaseAddr, dm_DataAddr);
+ abstract_cmd[255-:32] = dm_csrr(dm_CSR_DSCRATCH0, 5'd8);
+ end
+ end
+ else if ((sv2v_cast_32(ac_ar[22-:3]) >= MaxAar) || (ac_ar[19] == 1'b1)) begin
+ abstract_cmd[31-:32] = dm_ebreak(0);
+ unsupported_command = 1'b1;
+ end
+ if (ac_ar[18] && !unsupported_command)
+ abstract_cmd[319-:32] = dm_nop(0);
+ end
+ default: begin
+ abstract_cmd[31-:32] = dm_ebreak(0);
+ unsupported_command = 1'b1;
+ end
+ endcase
+ end
+ wire [63:0] rom_addr;
+ function automatic [63:0] sv2v_cast_64;
+ input reg [63:0] inp;
+ sv2v_cast_64 = inp;
+ endfunction
+ assign rom_addr = sv2v_cast_64(addr_i);
+ generate
+ if (HasSndScratch) begin : gen_rom_snd_scratch
+ debug_rom i_debug_rom(
+ .clk_i(clk_i),
+ .req_i(req_i),
+ .addr_i(rom_addr),
+ .rdata_o(rom_rdata)
+ );
+ end
+ else begin : gen_rom_one_scratch
+ debug_rom_one_scratch i_debug_rom(
+ .clk_i(clk_i),
+ .req_i(req_i),
+ .addr_i(rom_addr),
+ .rdata_o(rom_rdata)
+ );
+ end
+ endgenerate
+ assign fwd_rom_d = addr_i[11:0] >= dm_HaltAddress[11:0];
+ always @(posedge clk_i or negedge rst_ni) begin : p_regs
+ if (!rst_ni) begin
+ fwd_rom_q <= 1'b0;
+ rdata_q <= {64 {1'sb0}};
+ state_q <= Idle;
+ word_enable32_q <= 1'b0;
+ end
+ else begin
+ fwd_rom_q <= fwd_rom_d;
+ rdata_q <= rdata_d;
+ state_q <= state_d;
+ word_enable32_q <= addr_i[2];
+ end
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ halted_q <= 1'b0;
+ resuming_q <= 1'b0;
+ end
+ else begin
+ halted_q <= SelectableHarts & halted_d;
+ resuming_q <= SelectableHarts & resuming_d;
+ end
+endmodule
+module dm_sba (
+ clk_i,
+ rst_ni,
+ dmactive_i,
+ master_req_o,
+ master_add_o,
+ master_we_o,
+ master_wdata_o,
+ master_be_o,
+ master_gnt_i,
+ master_r_valid_i,
+ master_r_rdata_i,
+ sbaddress_i,
+ sbaddress_write_valid_i,
+ sbreadonaddr_i,
+ sbaddress_o,
+ sbautoincrement_i,
+ sbaccess_i,
+ sbreadondata_i,
+ sbdata_i,
+ sbdata_read_valid_i,
+ sbdata_write_valid_i,
+ sbdata_o,
+ sbdata_valid_o,
+ sbbusy_o,
+ sberror_valid_o,
+ sberror_o
+);
+ parameter [31:0] BusWidth = 32;
+ parameter [0:0] ReadByteEnable = 1;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire dmactive_i;
+ output wire master_req_o;
+ output wire [BusWidth - 1:0] master_add_o;
+ output wire master_we_o;
+ output wire [BusWidth - 1:0] master_wdata_o;
+ output wire [(BusWidth / 8) - 1:0] master_be_o;
+ input wire master_gnt_i;
+ input wire master_r_valid_i;
+ input wire [BusWidth - 1:0] master_r_rdata_i;
+ input wire [BusWidth - 1:0] sbaddress_i;
+ input wire sbaddress_write_valid_i;
+ input wire sbreadonaddr_i;
+ output reg [BusWidth - 1:0] sbaddress_o;
+ input wire sbautoincrement_i;
+ input wire [2:0] sbaccess_i;
+ input wire sbreadondata_i;
+ input wire [BusWidth - 1:0] sbdata_i;
+ input wire sbdata_read_valid_i;
+ input wire sbdata_write_valid_i;
+ output wire [BusWidth - 1:0] sbdata_o;
+ output wire sbdata_valid_o;
+ output wire sbbusy_o;
+ output reg sberror_valid_o;
+ output reg [2:0] sberror_o;
+ reg [2:0] state_d;
+ reg [2:0] state_q;
+ reg [BusWidth - 1:0] address;
+ reg req;
+ wire gnt;
+ reg we;
+ reg [(BusWidth / 8) - 1:0] be;
+ reg [(BusWidth / 8) - 1:0] be_mask;
+ reg [$clog2(BusWidth / 8) - 1:0] be_idx;
+ localparam [2:0] dm_Idle = 0;
+ assign sbbusy_o = state_q != dm_Idle;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ always @(*) begin : p_be_mask
+ be_mask = {BusWidth / 8 {1'sb0}};
+ case (sbaccess_i)
+ 3'b000: be_mask[be_idx] = 1'b1;
+ 3'b001: be_mask[sv2v_cast_32_signed({be_idx[$clog2(BusWidth / 8) - 1:1], 1'b0})+:2] = {2 {1'sb1}};
+ 3'b010:
+ if (BusWidth == 32'd64)
+ be_mask[sv2v_cast_32_signed({be_idx[$clog2(BusWidth / 8) - 1], 2'h0})+:4] = {4 {1'sb1}};
+ else
+ be_mask = {BusWidth / 8 {1'sb1}};
+ 3'b011: be_mask = {BusWidth / 8 {1'sb1}};
+ default:
+ ;
+ endcase
+ end
+ localparam [2:0] dm_Read = 1;
+ localparam [2:0] dm_WaitRead = 3;
+ localparam [2:0] dm_WaitWrite = 4;
+ localparam [2:0] dm_Write = 2;
+ always @(*) begin : p_fsm
+ req = 1'b0;
+ address = sbaddress_i;
+ we = 1'b0;
+ be = {BusWidth / 8 {1'sb0}};
+ be_idx = sbaddress_i[$clog2(BusWidth / 8) - 1:0];
+ sberror_o = {3 {1'sb0}};
+ sberror_valid_o = 1'b0;
+ sbaddress_o = sbaddress_i;
+ state_d = state_q;
+ case (state_q)
+ dm_Idle: begin
+ if (sbaddress_write_valid_i && sbreadonaddr_i)
+ state_d = dm_Read;
+ if (sbdata_write_valid_i)
+ state_d = dm_Write;
+ if (sbdata_read_valid_i && sbreadondata_i)
+ state_d = dm_Read;
+ end
+ dm_Read: begin
+ req = 1'b1;
+ if (ReadByteEnable)
+ be = be_mask;
+ if (gnt)
+ state_d = dm_WaitRead;
+ end
+ dm_Write: begin
+ req = 1'b1;
+ we = 1'b1;
+ be = be_mask;
+ if (gnt)
+ state_d = dm_WaitWrite;
+ end
+ dm_WaitRead:
+ if (sbdata_valid_o) begin
+ state_d = dm_Idle;
+ if (sbautoincrement_i)
+ sbaddress_o = sbaddress_i + (32'h00000001 << sbaccess_i);
+ end
+ dm_WaitWrite:
+ if (sbdata_valid_o) begin
+ state_d = dm_Idle;
+ if (sbautoincrement_i)
+ sbaddress_o = sbaddress_i + (32'h00000001 << sbaccess_i);
+ end
+ default: state_d = dm_Idle;
+ endcase
+ if ((sbaccess_i > 3) && (state_q != dm_Idle)) begin
+ req = 1'b0;
+ state_d = dm_Idle;
+ sberror_valid_o = 1'b1;
+ sberror_o = 3'd3;
+ end
+ end
+ always @(posedge clk_i or negedge rst_ni) begin : p_regs
+ if (!rst_ni)
+ state_q <= dm_Idle;
+ else
+ state_q <= state_d;
+ end
+ assign master_req_o = req;
+ assign master_add_o = address[BusWidth - 1:0];
+ assign master_we_o = we;
+ assign master_wdata_o = sbdata_i[BusWidth - 1:0];
+ assign master_be_o = be[(BusWidth / 8) - 1:0];
+ assign gnt = master_gnt_i;
+ assign sbdata_valid_o = master_r_valid_i;
+ assign sbdata_o = master_r_rdata_i[BusWidth - 1:0];
+endmodule
+module fifo_async (
+ clk_wr_i,
+ rst_wr_ni,
+ wvalid_i,
+ wready_o,
+ wdata_i,
+ wdepth_o,
+ clk_rd_i,
+ rst_rd_ni,
+ rvalid_o,
+ rready_i,
+ rdata_o,
+ rdepth_o
+);
+ parameter [31:0] Width = 16;
+ parameter [31:0] Depth = 3;
+ localparam [31:0] DepthW = $clog2(Depth + 1);
+ input wire clk_wr_i;
+ input wire rst_wr_ni;
+ input wire wvalid_i;
+ output wire wready_o;
+ input wire [Width - 1:0] wdata_i;
+ output wire [DepthW - 1:0] wdepth_o;
+ input wire clk_rd_i;
+ input wire rst_rd_ni;
+ output wire rvalid_o;
+ input wire rready_i;
+ output wire [Width - 1:0] rdata_o;
+ output wire [DepthW - 1:0] rdepth_o;
+ localparam [31:0] PTRV_W = $clog2(Depth);
+ function automatic [PTRV_W - 1:0] sv2v_cast_E27C2;
+ input reg [PTRV_W - 1:0] inp;
+ sv2v_cast_E27C2 = inp;
+ endfunction
+ localparam [PTRV_W - 1:0] DepthMinus1 = sv2v_cast_E27C2(Depth - 1);
+ localparam [31:0] PTR_WIDTH = PTRV_W + 1;
+ reg [PTR_WIDTH - 1:0] fifo_wptr;
+ reg [PTR_WIDTH - 1:0] fifo_rptr;
+ wire [PTR_WIDTH - 1:0] fifo_wptr_sync_combi;
+ reg [PTR_WIDTH - 1:0] fifo_rptr_sync;
+ wire [PTR_WIDTH - 1:0] fifo_wptr_gray_sync;
+ wire [PTR_WIDTH - 1:0] fifo_rptr_gray_sync;
+ reg [PTR_WIDTH - 1:0] fifo_wptr_gray;
+ reg [PTR_WIDTH - 1:0] fifo_rptr_gray;
+ wire fifo_incr_wptr;
+ wire fifo_incr_rptr;
+ wire empty;
+ wire full_wclk;
+ wire full_rclk;
+ assign wready_o = !full_wclk;
+ assign rvalid_o = !empty;
+ assign fifo_incr_wptr = wvalid_i & wready_o;
+ assign fifo_incr_rptr = rvalid_o & rready_i;
+ always @(posedge clk_wr_i or negedge rst_wr_ni)
+ if (!rst_wr_ni)
+ fifo_wptr <= {PTR_WIDTH {1'b0}};
+ else if (fifo_incr_wptr)
+ if (fifo_wptr[PTR_WIDTH - 2:0] == DepthMinus1)
+ fifo_wptr <= {~fifo_wptr[PTR_WIDTH - 1], {PTR_WIDTH - 1 {1'b0}}};
+ else
+ fifo_wptr <= fifo_wptr + {{PTR_WIDTH - 1 {1'b0}}, 1'b1};
+ function automatic [PTR_WIDTH - 1:0] sv2v_cast_88E25;
+ input reg [PTR_WIDTH - 1:0] inp;
+ sv2v_cast_88E25 = inp;
+ endfunction
+ function automatic [PTR_WIDTH - 1:0] dec2gray;
+ input reg [PTR_WIDTH - 1:0] decval;
+ reg [PTR_WIDTH - 1:0] decval_sub;
+ reg [PTR_WIDTH - 2:0] decval_in;
+ reg unused_decval_msb;
+ begin
+ decval_sub = (sv2v_cast_88E25(Depth) - {1'b0, decval[PTR_WIDTH - 2:0]}) - 1'b1;
+ {unused_decval_msb, decval_in} = (decval[PTR_WIDTH - 1] ? decval_sub : decval);
+ dec2gray = {decval[PTR_WIDTH - 1], {1'b0, decval_in[PTR_WIDTH - 2:1]} ^ decval_in[PTR_WIDTH - 2:0]};
+ end
+ endfunction
+ always @(posedge clk_wr_i or negedge rst_wr_ni)
+ if (!rst_wr_ni)
+ fifo_wptr_gray <= {PTR_WIDTH {1'b0}};
+ else if (fifo_incr_wptr)
+ if (fifo_wptr[PTR_WIDTH - 2:0] == DepthMinus1)
+ fifo_wptr_gray <= dec2gray({~fifo_wptr[PTR_WIDTH - 1], {PTR_WIDTH - 1 {1'b0}}});
+ else
+ fifo_wptr_gray <= dec2gray(fifo_wptr + {{PTR_WIDTH - 1 {1'b0}}, 1'b1});
+ prim_generic_flop_2sync #(.Width(PTR_WIDTH)) sync_wptr(
+ .clk_i(clk_rd_i),
+ .rst_ni(rst_rd_ni),
+ .d_i(fifo_wptr_gray),
+ .q_o(fifo_wptr_gray_sync)
+ );
+ function automatic [((PTR_WIDTH - 2) >= 0 ? PTR_WIDTH - 1 : 3 - PTR_WIDTH) - 1:0] sv2v_cast_F9964;
+ input reg [((PTR_WIDTH - 2) >= 0 ? PTR_WIDTH - 1 : 3 - PTR_WIDTH) - 1:0] inp;
+ sv2v_cast_F9964 = inp;
+ endfunction
+ function automatic [PTR_WIDTH - 1:0] gray2dec;
+ input reg [PTR_WIDTH - 1:0] grayval;
+ reg [PTR_WIDTH - 2:0] dec_tmp;
+ reg [PTR_WIDTH - 2:0] dec_tmp_sub;
+ reg unused_decsub_msb;
+ begin
+ dec_tmp[PTR_WIDTH - 2] = grayval[PTR_WIDTH - 2];
+ begin : sv2v_autoblock_104
+ reg signed [31:0] i;
+ for (i = PTR_WIDTH - 3; i >= 0; i = i - 1)
+ dec_tmp[i] = dec_tmp[i + 1] ^ grayval[i];
+ end
+ {unused_decsub_msb, dec_tmp_sub} = (sv2v_cast_F9964(Depth) - {1'b0, dec_tmp}) - 1'b1;
+ if (grayval[PTR_WIDTH - 1])
+ gray2dec = {1'b1, dec_tmp_sub};
+ else
+ gray2dec = {1'b0, dec_tmp};
+ end
+ endfunction
+ assign fifo_wptr_sync_combi = gray2dec(fifo_wptr_gray_sync);
+ always @(posedge clk_rd_i or negedge rst_rd_ni)
+ if (!rst_rd_ni)
+ fifo_rptr <= {PTR_WIDTH {1'b0}};
+ else if (fifo_incr_rptr)
+ if (fifo_rptr[PTR_WIDTH - 2:0] == DepthMinus1)
+ fifo_rptr <= {~fifo_rptr[PTR_WIDTH - 1], {PTR_WIDTH - 1 {1'b0}}};
+ else
+ fifo_rptr <= fifo_rptr + {{PTR_WIDTH - 1 {1'b0}}, 1'b1};
+ always @(posedge clk_rd_i or negedge rst_rd_ni)
+ if (!rst_rd_ni)
+ fifo_rptr_gray <= {PTR_WIDTH {1'b0}};
+ else if (fifo_incr_rptr)
+ if (fifo_rptr[PTR_WIDTH - 2:0] == DepthMinus1)
+ fifo_rptr_gray <= dec2gray({~fifo_rptr[PTR_WIDTH - 1], {PTR_WIDTH - 1 {1'b0}}});
+ else
+ fifo_rptr_gray <= dec2gray(fifo_rptr + {{PTR_WIDTH - 1 {1'b0}}, 1'b1});
+ prim_generic_flop_2sync #(.Width(PTR_WIDTH)) sync_rptr(
+ .clk_i(clk_wr_i),
+ .rst_ni(rst_wr_ni),
+ .d_i(fifo_rptr_gray),
+ .q_o(fifo_rptr_gray_sync)
+ );
+ always @(posedge clk_wr_i or negedge rst_wr_ni)
+ if (!rst_wr_ni)
+ fifo_rptr_sync <= {PTR_WIDTH {1'b0}};
+ else
+ fifo_rptr_sync <= gray2dec(fifo_rptr_gray_sync);
+ assign full_wclk = fifo_wptr == (fifo_rptr_sync ^ {1'b1, {PTR_WIDTH - 1 {1'b0}}});
+ assign full_rclk = fifo_wptr_sync_combi == (fifo_rptr ^ {1'b1, {PTR_WIDTH - 1 {1'b0}}});
+ wire wptr_msb;
+ wire rptr_sync_msb;
+ wire [PTRV_W - 1:0] wptr_value;
+ wire [PTRV_W - 1:0] rptr_sync_value;
+ assign wptr_msb = fifo_wptr[PTR_WIDTH - 1];
+ assign rptr_sync_msb = fifo_rptr_sync[PTR_WIDTH - 1];
+ assign wptr_value = fifo_wptr[0+:PTRV_W];
+ assign rptr_sync_value = fifo_rptr_sync[0+:PTRV_W];
+ function automatic [DepthW - 1:0] sv2v_cast_703F8;
+ input reg [DepthW - 1:0] inp;
+ sv2v_cast_703F8 = inp;
+ endfunction
+ assign wdepth_o = (full_wclk ? sv2v_cast_703F8(Depth) : (wptr_msb == rptr_sync_msb ? sv2v_cast_703F8(wptr_value) - sv2v_cast_703F8(rptr_sync_value) : (sv2v_cast_703F8(Depth) - sv2v_cast_703F8(rptr_sync_value)) + sv2v_cast_703F8(wptr_value)));
+ assign empty = fifo_wptr_sync_combi == fifo_rptr;
+ wire rptr_msb;
+ wire wptr_sync_msb;
+ wire [PTRV_W - 1:0] rptr_value;
+ wire [PTRV_W - 1:0] wptr_sync_value;
+ assign wptr_sync_msb = fifo_wptr_sync_combi[PTR_WIDTH - 1];
+ assign rptr_msb = fifo_rptr[PTR_WIDTH - 1];
+ assign wptr_sync_value = fifo_wptr_sync_combi[0+:PTRV_W];
+ assign rptr_value = fifo_rptr[0+:PTRV_W];
+ assign rdepth_o = (full_rclk ? sv2v_cast_703F8(Depth) : (wptr_sync_msb == rptr_msb ? sv2v_cast_703F8(wptr_sync_value) - sv2v_cast_703F8(rptr_value) : (sv2v_cast_703F8(Depth) - sv2v_cast_703F8(rptr_value)) + sv2v_cast_703F8(wptr_sync_value)));
+ reg [Width - 1:0] storage [0:Depth - 1];
+ always @(posedge clk_wr_i)
+ if (fifo_incr_wptr)
+ storage[fifo_wptr[PTR_WIDTH - 2:0]] <= wdata_i;
+ assign rdata_o = storage[fifo_rptr[PTR_WIDTH - 2:0]];
+endmodule
+module fifo_sync (
+ clk_i,
+ rst_ni,
+ clr_i,
+ wvalid_i,
+ wready_o,
+ wdata_i,
+ rvalid_o,
+ rready_i,
+ rdata_o,
+ full_o,
+ depth_o
+);
+ parameter [31:0] Width = 16;
+ parameter [0:0] Pass = 1'b1;
+ parameter [31:0] Depth = 4;
+ parameter [0:0] OutputZeroIfEmpty = 1'b1;
+ function automatic integer prim_util_pkg_vbits;
+ input integer value;
+ prim_util_pkg_vbits = (value == 1 ? 1 : $clog2(value));
+ endfunction
+ localparam signed [31:0] DepthW = prim_util_pkg_vbits(Depth + 1);
+ input clk_i;
+ input rst_ni;
+ input clr_i;
+ input wvalid_i;
+ output wready_o;
+ input [Width - 1:0] wdata_i;
+ output rvalid_o;
+ input rready_i;
+ output [Width - 1:0] rdata_o;
+ output full_o;
+ output [DepthW - 1:0] depth_o;
+ generate
+ if (Depth == 0) begin : gen_passthru_fifo
+ assign depth_o = 1'b0;
+ assign rvalid_o = wvalid_i;
+ assign rdata_o = wdata_i;
+ assign wready_o = rready_i;
+ assign full_o = rready_i;
+ wire unused_clr;
+ assign unused_clr = clr_i;
+ end
+ else begin : gen_normal_fifo
+ localparam [31:0] PTRV_W = prim_util_pkg_vbits(Depth);
+ localparam [31:0] PTR_WIDTH = PTRV_W + 1;
+ reg [PTR_WIDTH - 1:0] fifo_wptr;
+ reg [PTR_WIDTH - 1:0] fifo_rptr;
+ wire fifo_incr_wptr;
+ wire fifo_incr_rptr;
+ wire fifo_empty;
+ reg under_rst;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ under_rst <= 1'b1;
+ else if (under_rst)
+ under_rst <= ~under_rst;
+ wire full;
+ wire empty;
+ wire wptr_msb;
+ wire rptr_msb;
+ wire [PTRV_W - 1:0] wptr_value;
+ wire [PTRV_W - 1:0] rptr_value;
+ assign wptr_msb = fifo_wptr[PTR_WIDTH - 1];
+ assign rptr_msb = fifo_rptr[PTR_WIDTH - 1];
+ assign wptr_value = fifo_wptr[0+:PTRV_W];
+ assign rptr_value = fifo_rptr[0+:PTRV_W];
+ function automatic [DepthW - 1:0] sv2v_cast_703F8;
+ input reg [DepthW - 1:0] inp;
+ sv2v_cast_703F8 = inp;
+ endfunction
+ assign depth_o = (full ? sv2v_cast_703F8(Depth) : (wptr_msb == rptr_msb ? sv2v_cast_703F8(wptr_value) - sv2v_cast_703F8(rptr_value) : (sv2v_cast_703F8(Depth) - sv2v_cast_703F8(rptr_value)) + sv2v_cast_703F8(wptr_value)));
+ assign fifo_incr_wptr = (wvalid_i & wready_o) & ~under_rst;
+ assign fifo_incr_rptr = (rvalid_o & rready_i) & ~under_rst;
+ assign wready_o = ~full & ~under_rst;
+ assign full_o = full;
+ assign rvalid_o = ~empty & ~under_rst;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ fifo_wptr <= {PTR_WIDTH {1'b0}};
+ else if (clr_i)
+ fifo_wptr <= {PTR_WIDTH {1'b0}};
+ else if (fifo_incr_wptr) begin : sv2v_autoblock_105
+ reg [((PTR_WIDTH - 2) >= 0 ? PTR_WIDTH - 1 : 3 - PTR_WIDTH) - 1:0] sv2v_tmp_cast;
+ sv2v_tmp_cast = Depth - 1;
+ if (fifo_wptr[PTR_WIDTH - 2:0] == sv2v_tmp_cast)
+ fifo_wptr <= {~fifo_wptr[PTR_WIDTH - 1], {PTR_WIDTH - 1 {1'b0}}};
+ else
+ fifo_wptr <= fifo_wptr + {{PTR_WIDTH - 1 {1'b0}}, 1'b1};
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ fifo_rptr <= {PTR_WIDTH {1'b0}};
+ else if (clr_i)
+ fifo_rptr <= {PTR_WIDTH {1'b0}};
+ else if (fifo_incr_rptr) begin : sv2v_autoblock_106
+ reg [((PTR_WIDTH - 2) >= 0 ? PTR_WIDTH - 1 : 3 - PTR_WIDTH) - 1:0] sv2v_tmp_cast_1;
+ sv2v_tmp_cast_1 = Depth - 1;
+ if (fifo_rptr[PTR_WIDTH - 2:0] == sv2v_tmp_cast_1)
+ fifo_rptr <= {~fifo_rptr[PTR_WIDTH - 1], {PTR_WIDTH - 1 {1'b0}}};
+ else
+ fifo_rptr <= fifo_rptr + {{PTR_WIDTH - 1 {1'b0}}, 1'b1};
+ end
+ assign full = fifo_wptr == (fifo_rptr ^ {1'b1, {PTR_WIDTH - 1 {1'b0}}});
+ assign fifo_empty = fifo_wptr == fifo_rptr;
+ reg [(Depth * Width) - 1:0] storage;
+ wire [Width - 1:0] storage_rdata;
+ if (Depth == 1) begin : gen_depth_eq1
+ assign storage_rdata = storage[0+:Width];
+ always @(posedge clk_i)
+ if (fifo_incr_wptr)
+ storage[0+:Width] <= wdata_i;
+ end
+ else begin : gen_depth_gt1
+ assign storage_rdata = storage[fifo_rptr[PTR_WIDTH - 2:0] * Width+:Width];
+ always @(posedge clk_i)
+ if (fifo_incr_wptr)
+ storage[fifo_wptr[PTR_WIDTH - 2:0] * Width+:Width] <= wdata_i;
+ end
+ wire [Width - 1:0] rdata_int;
+ if (Pass == 1'b1) begin : gen_pass
+ assign rdata_int = (fifo_empty && wvalid_i ? wdata_i : storage_rdata);
+ assign empty = fifo_empty & ~wvalid_i;
+ end
+ else begin : gen_nopass
+ assign rdata_int = storage_rdata;
+ assign empty = fifo_empty;
+ end
+ if (OutputZeroIfEmpty == 1'b1) begin : gen_output_zero
+ assign rdata_o = (empty ? 'b0 : rdata_int);
+ end
+ else begin : gen_no_output_zero
+ assign rdata_o = rdata_int;
+ end
+ end
+ endgenerate
+endmodule
+module fpnew_cast_multi_8A35C_87530 (
+ clk_i,
+ rst_ni,
+ operands_i,
+ is_boxed_i,
+ rnd_mode_i,
+ op_i,
+ op_mod_i,
+ src_fmt_i,
+ dst_fmt_i,
+ int_fmt_i,
+ tag_i,
+ aux_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ extension_bit_o,
+ tag_o,
+ aux_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ parameter [31:0] AuxType_AUX_BITS = 0;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ parameter [0:0] FpFmtConfig = 1'sb1;
+ localparam [31:0] fpnew_pkg_NUM_INT_FORMATS = 1;
+ parameter [0:0] IntFmtConfig = 1'sb1;
+ parameter [31:0] NumPipeRegs = 0;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ parameter [1:0] PipeConfig = fpnew_pkg_BEFORE;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ function automatic signed [31:0] fpnew_pkg_maximum;
+ input reg signed [31:0] a;
+ input reg signed [31:0] b;
+ fpnew_pkg_maximum = (a > b ? a : b);
+ endfunction
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_9359B;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_9359B = inp;
+ endfunction
+ function automatic [31:0] fpnew_pkg_max_fp_width;
+ input reg [0:0] cfg;
+ reg [31:0] res;
+ begin
+ res = 0;
+ begin : sv2v_autoblock_107
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (cfg[i])
+ res = $unsigned(fpnew_pkg_maximum(res, fpnew_pkg_fp_width(sv2v_cast_9359B(i))));
+ end
+ fpnew_pkg_max_fp_width = res;
+ end
+ endfunction
+ localparam [31:0] fpnew_pkg_INT_FORMAT_BITS = 0;
+ localparam [fpnew_pkg_INT_FORMAT_BITS - 1:0] fpnew_pkg_INT32 = 0;
+ function automatic [31:0] fpnew_pkg_int_width;
+ input reg [fpnew_pkg_INT_FORMAT_BITS - 1:0] ifmt;
+ case (ifmt)
+ fpnew_pkg_INT32: fpnew_pkg_int_width = 32;
+ endcase
+ endfunction
+ function automatic [fpnew_pkg_INT_FORMAT_BITS - 1:0] sv2v_cast_D812A;
+ input reg [fpnew_pkg_INT_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_D812A = inp;
+ endfunction
+ function automatic [31:0] fpnew_pkg_max_int_width;
+ input reg [0:0] cfg;
+ reg [31:0] res;
+ begin
+ res = 0;
+ begin : sv2v_autoblock_108
+ reg signed [31:0] ifmt;
+ for (ifmt = 0; ifmt < fpnew_pkg_NUM_INT_FORMATS; ifmt = ifmt + 1)
+ if (cfg[ifmt])
+ res = fpnew_pkg_maximum(res, fpnew_pkg_int_width(sv2v_cast_D812A(ifmt)));
+ end
+ fpnew_pkg_max_int_width = res;
+ end
+ endfunction
+ localparam [31:0] WIDTH = fpnew_pkg_maximum(fpnew_pkg_max_fp_width(FpFmtConfig), fpnew_pkg_max_int_width(IntFmtConfig));
+ localparam [31:0] NUM_FORMATS = fpnew_pkg_NUM_FP_FORMATS;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [WIDTH - 1:0] operands_i;
+ input wire [0:0] is_boxed_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire op_mod_i;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] src_fmt_i;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_i;
+ input wire [fpnew_pkg_INT_FORMAT_BITS - 1:0] int_fmt_i;
+ input wire tag_i;
+ input wire [AuxType_AUX_BITS - 1:0] aux_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [WIDTH - 1:0] result_o;
+ output wire [4:0] status_o;
+ output wire extension_bit_o;
+ output wire tag_o;
+ output wire [AuxType_AUX_BITS - 1:0] aux_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ always @(posedge __clk or negedge __arst_n)
+ if (!__arst_n)
+ __q <= __reset_value;
+ else
+ __q <= (__clear ? __reset_value : (__load ? __d : __q));
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ __q <= __reset_value;
+ else
+ __q <= (__load ? __d : __q);
+ localparam [31:0] NUM_INT_FORMATS = fpnew_pkg_NUM_INT_FORMATS;
+ localparam [31:0] MAX_INT_WIDTH = fpnew_pkg_max_int_width(IntFmtConfig);
+ function automatic [31:0] fpnew_pkg_exp_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_exp_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32];
+ endfunction
+ function automatic [31:0] fpnew_pkg_man_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_man_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32];
+ endfunction
+ function automatic [63:0] fpnew_pkg_super_format;
+ input reg [0:0] cfg;
+ reg [63:0] res;
+ begin
+ res = {64 {1'sb0}};
+ begin : sv2v_autoblock_109
+ reg [31:0] fmt;
+ for (fmt = 0; fmt < fpnew_pkg_NUM_FP_FORMATS; fmt = fmt + 1)
+ if (cfg[fmt]) begin
+ res[63-:32] = $unsigned(fpnew_pkg_maximum(res[63-:32], fpnew_pkg_exp_bits(sv2v_cast_9359B(fmt))));
+ res[31-:32] = $unsigned(fpnew_pkg_maximum(res[31-:32], fpnew_pkg_man_bits(sv2v_cast_9359B(fmt))));
+ end
+ end
+ fpnew_pkg_super_format = res;
+ end
+ endfunction
+ localparam [63:0] SUPER_FORMAT = fpnew_pkg_super_format(FpFmtConfig);
+ localparam [31:0] SUPER_EXP_BITS = SUPER_FORMAT[63-:32];
+ localparam [31:0] SUPER_MAN_BITS = SUPER_FORMAT[31-:32];
+ localparam [31:0] SUPER_BIAS = (2 ** (SUPER_EXP_BITS - 1)) - 1;
+ localparam [31:0] INT_MAN_WIDTH = fpnew_pkg_maximum(SUPER_MAN_BITS + 1, MAX_INT_WIDTH);
+ localparam [31:0] LZC_RESULT_WIDTH = $clog2(INT_MAN_WIDTH);
+ localparam [31:0] INT_EXP_WIDTH = fpnew_pkg_maximum($clog2(MAX_INT_WIDTH), fpnew_pkg_maximum(SUPER_EXP_BITS, $clog2(SUPER_BIAS + SUPER_MAN_BITS))) + 1;
+ localparam [1:0] fpnew_pkg_DISTRIBUTED = 3;
+ localparam NUM_INP_REGS = (PipeConfig == fpnew_pkg_BEFORE ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? (NumPipeRegs + 1) / 3 : 0));
+ localparam [1:0] fpnew_pkg_INSIDE = 2;
+ localparam NUM_MID_REGS = (PipeConfig == fpnew_pkg_INSIDE ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? (NumPipeRegs + 2) / 3 : 0));
+ localparam [1:0] fpnew_pkg_AFTER = 1;
+ localparam NUM_OUT_REGS = (PipeConfig == fpnew_pkg_AFTER ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? NumPipeRegs / 3 : 0));
+ wire [WIDTH - 1:0] operands_q;
+ wire [0:0] is_boxed_q;
+ wire op_mod_q;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] src_fmt_q;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_q;
+ wire [fpnew_pkg_INT_FORMAT_BITS - 1:0] int_fmt_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * WIDTH) + ((NUM_INP_REGS * WIDTH) - 1) : ((NUM_INP_REGS + 1) * WIDTH) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * WIDTH : 0)] inp_pipe_operands_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * NUM_FORMATS) + ((NUM_INP_REGS * NUM_FORMATS) - 1) : ((NUM_INP_REGS + 1) * NUM_FORMATS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * NUM_FORMATS : 0)] inp_pipe_is_boxed_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0)] inp_pipe_rnd_mode_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * fpnew_pkg_OP_BITS) + ((NUM_INP_REGS * fpnew_pkg_OP_BITS) - 1) : ((NUM_INP_REGS + 1) * fpnew_pkg_OP_BITS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * fpnew_pkg_OP_BITS : 0)] inp_pipe_op_q;
+ wire [0:NUM_INP_REGS] inp_pipe_op_mod_q;
+ wire [(0 >= NUM_INP_REGS ? -1 : -1):(0 >= NUM_INP_REGS ? 0 : 0)] inp_pipe_src_fmt_q;
+ wire [(0 >= NUM_INP_REGS ? -1 : -1):(0 >= NUM_INP_REGS ? 0 : 0)] inp_pipe_dst_fmt_q;
+ wire [(0 >= NUM_INP_REGS ? -1 : -1):(0 >= NUM_INP_REGS ? 0 : 0)] inp_pipe_int_fmt_q;
+ wire [0:NUM_INP_REGS] inp_pipe_tag_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * AuxType_AUX_BITS) + ((NUM_INP_REGS * AuxType_AUX_BITS) - 1) : ((NUM_INP_REGS + 1) * AuxType_AUX_BITS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * AuxType_AUX_BITS : 0)] inp_pipe_aux_q;
+ wire [0:NUM_INP_REGS] inp_pipe_valid_q;
+ wire [0:NUM_INP_REGS] inp_pipe_ready;
+ assign inp_pipe_operands_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * WIDTH+:WIDTH] = operands_i;
+ assign inp_pipe_is_boxed_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * NUM_FORMATS+:NUM_FORMATS] = is_boxed_i;
+ assign inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3+:3] = rnd_mode_i;
+ assign inp_pipe_op_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS] = op_i;
+ assign inp_pipe_op_mod_q[0] = op_mod_i;
+ assign inp_pipe_src_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS] = src_fmt_i;
+ assign inp_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS] = dst_fmt_i;
+ assign inp_pipe_int_fmt_q[0+:fpnew_pkg_INT_FORMAT_BITS] = int_fmt_i;
+ assign inp_pipe_tag_q[0] = tag_i;
+ assign inp_pipe_aux_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS] = aux_i;
+ assign inp_pipe_valid_q[0] = in_valid_i;
+ assign in_ready_o = inp_pipe_ready[0];
+ generate
+ genvar i;
+ for (i = 0; i < NUM_INP_REGS; i = i + 1) begin : gen_input_pipeline
+ wire reg_ena;
+ assign inp_pipe_ready[i] = inp_pipe_ready[i + 1] | ~inp_pipe_valid_q[i + 1];
+ assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
+ end
+ endgenerate
+ assign operands_q = inp_pipe_operands_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * WIDTH+:WIDTH];
+ assign is_boxed_q = inp_pipe_is_boxed_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * NUM_FORMATS+:NUM_FORMATS];
+ assign op_mod_q = inp_pipe_op_mod_q[NUM_INP_REGS];
+ assign src_fmt_q = inp_pipe_src_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS];
+ assign dst_fmt_q = inp_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS];
+ assign int_fmt_q = inp_pipe_int_fmt_q[0+:fpnew_pkg_INT_FORMAT_BITS];
+ wire src_is_int;
+ wire dst_is_int;
+ localparam [3:0] fpnew_pkg_I2F = 12;
+ assign src_is_int = inp_pipe_op_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS] == fpnew_pkg_I2F;
+ localparam [3:0] fpnew_pkg_F2I = 11;
+ assign dst_is_int = inp_pipe_op_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS] == fpnew_pkg_F2I;
+ wire [INT_MAN_WIDTH - 1:0] encoded_mant;
+ wire [0:0] fmt_sign;
+ wire signed [(NUM_FORMATS * INT_EXP_WIDTH) - 1:0] fmt_exponent;
+ wire [(NUM_FORMATS * INT_MAN_WIDTH) - 1:0] fmt_mantissa;
+ wire signed [(NUM_FORMATS * INT_EXP_WIDTH) - 1:0] fmt_shift_compensation;
+ wire [7:0] info;
+ reg [(NUM_INT_FORMATS * INT_MAN_WIDTH) - 1:0] ifmt_input_val;
+ wire int_sign;
+ wire [INT_MAN_WIDTH - 1:0] int_value;
+ wire [INT_MAN_WIDTH - 1:0] int_mantissa;
+ localparam [0:0] fpnew_pkg_DONT_CARE = 1'b1;
+ generate
+ genvar fmt;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : fmt_init_inputs
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_9359B;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_9359B = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_9359B(fmt));
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(sv2v_cast_9359B(fmt));
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(sv2v_cast_9359B(fmt));
+ if (FpFmtConfig[fmt]) begin : active_format
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_9359B;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_9359B = inp;
+ endfunction
+ fpnew_classifier #(
+ .FpFormat(sv2v_cast_9359B(fmt)),
+ .NumOperands(1)
+ ) i_fpnew_classifier(
+ .operands_i(operands_q[FP_WIDTH - 1:0]),
+ .is_boxed_i(is_boxed_q[fmt]),
+ .info_o(info[fmt * 8+:8])
+ );
+ assign fmt_sign[fmt] = operands_q[FP_WIDTH - 1];
+ assign fmt_exponent[fmt * INT_EXP_WIDTH+:INT_EXP_WIDTH] = $signed({1'b0, operands_q[MAN_BITS+:EXP_BITS]});
+ assign fmt_mantissa[fmt * INT_MAN_WIDTH+:INT_MAN_WIDTH] = {info[(fmt * 8) + 7], operands_q[MAN_BITS - 1:0]};
+ assign fmt_shift_compensation[fmt * INT_EXP_WIDTH+:INT_EXP_WIDTH] = $signed((INT_MAN_WIDTH - 1) - MAN_BITS);
+ end
+ else begin : inactive_format
+ assign info[fmt * 8+:8] = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ assign fmt_sign[fmt] = fpnew_pkg_DONT_CARE;
+ function automatic signed [0:0] sv2v_cast_1_signed;
+ input reg signed [0:0] inp;
+ sv2v_cast_1_signed = inp;
+ endfunction
+ assign fmt_exponent[fmt * INT_EXP_WIDTH+:INT_EXP_WIDTH] = {INT_EXP_WIDTH {sv2v_cast_1_signed(fpnew_pkg_DONT_CARE)}};
+ assign fmt_mantissa[fmt * INT_MAN_WIDTH+:INT_MAN_WIDTH] = {INT_MAN_WIDTH {fpnew_pkg_DONT_CARE}};
+ assign fmt_shift_compensation[fmt * INT_EXP_WIDTH+:INT_EXP_WIDTH] = {INT_EXP_WIDTH {sv2v_cast_1_signed(fpnew_pkg_DONT_CARE)}};
+ end
+ end
+ endgenerate
+ generate
+ genvar ifmt;
+ for (ifmt = 0; ifmt < sv2v_cast_32_signed(NUM_INT_FORMATS); ifmt = ifmt + 1) begin : gen_sign_extend_int
+ function automatic [fpnew_pkg_INT_FORMAT_BITS - 1:0] sv2v_cast_D812A;
+ input reg [fpnew_pkg_INT_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_D812A = inp;
+ endfunction
+ localparam [31:0] INT_WIDTH = fpnew_pkg_int_width(sv2v_cast_D812A(ifmt));
+ if (IntFmtConfig[ifmt]) begin : active_format
+ function automatic [0:0] sv2v_cast_1;
+ input reg [0:0] inp;
+ sv2v_cast_1 = inp;
+ endfunction
+ always @(*) begin : sign_ext_input
+ ifmt_input_val[ifmt * INT_MAN_WIDTH+:INT_MAN_WIDTH] = {INT_MAN_WIDTH {sv2v_cast_1(operands_q[INT_WIDTH - 1] & ~op_mod_q)}};
+ ifmt_input_val[(ifmt * INT_MAN_WIDTH) + (INT_WIDTH - 1)-:INT_WIDTH] = operands_q[INT_WIDTH - 1:0];
+ end
+ end
+ else begin : inactive_format
+ wire [INT_MAN_WIDTH:1] sv2v_tmp_F538F;
+ assign sv2v_tmp_F538F = {INT_MAN_WIDTH {fpnew_pkg_DONT_CARE}};
+ always @(*) ifmt_input_val[ifmt * INT_MAN_WIDTH+:INT_MAN_WIDTH] = sv2v_tmp_F538F;
+ end
+ end
+ endgenerate
+ assign int_value = ifmt_input_val[int_fmt_q * INT_MAN_WIDTH+:INT_MAN_WIDTH];
+ assign int_sign = int_value[INT_MAN_WIDTH - 1] & ~op_mod_q;
+ assign int_mantissa = (int_sign ? $unsigned(-int_value) : int_value);
+ assign encoded_mant = (src_is_int ? int_mantissa : fmt_mantissa[src_fmt_q * INT_MAN_WIDTH+:INT_MAN_WIDTH]);
+ wire signed [INT_EXP_WIDTH - 1:0] src_bias;
+ wire signed [INT_EXP_WIDTH - 1:0] src_exp;
+ wire signed [INT_EXP_WIDTH - 1:0] src_subnormal;
+ wire signed [INT_EXP_WIDTH - 1:0] src_offset;
+ function automatic [31:0] fpnew_pkg_bias;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_bias = $unsigned((2 ** (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] - 1)) - 1);
+ endfunction
+ assign src_bias = $signed(fpnew_pkg_bias(src_fmt_q));
+ assign src_exp = fmt_exponent[src_fmt_q * INT_EXP_WIDTH+:INT_EXP_WIDTH];
+ assign src_subnormal = $signed({1'b0, info[(src_fmt_q * 8) + 6]});
+ assign src_offset = fmt_shift_compensation[src_fmt_q * INT_EXP_WIDTH+:INT_EXP_WIDTH];
+ wire input_sign;
+ wire signed [INT_EXP_WIDTH - 1:0] input_exp;
+ wire [INT_MAN_WIDTH - 1:0] input_mant;
+ wire mant_is_zero;
+ wire signed [INT_EXP_WIDTH - 1:0] fp_input_exp;
+ wire signed [INT_EXP_WIDTH - 1:0] int_input_exp;
+ wire [LZC_RESULT_WIDTH - 1:0] renorm_shamt;
+ wire [LZC_RESULT_WIDTH:0] renorm_shamt_sgn;
+ lzc #(
+ .WIDTH(INT_MAN_WIDTH),
+ .MODE(1)
+ ) i_lzc(
+ .in_i(encoded_mant),
+ .cnt_o(renorm_shamt),
+ .empty_o(mant_is_zero)
+ );
+ assign renorm_shamt_sgn = $signed({1'b0, renorm_shamt});
+ assign input_sign = (src_is_int ? int_sign : fmt_sign[src_fmt_q]);
+ assign input_mant = encoded_mant << renorm_shamt;
+ assign fp_input_exp = $signed((((src_exp + src_subnormal) - src_bias) - renorm_shamt_sgn) + src_offset);
+ assign int_input_exp = $signed((INT_MAN_WIDTH - 1) - renorm_shamt_sgn);
+ assign input_exp = (src_is_int ? int_input_exp : fp_input_exp);
+ wire signed [INT_EXP_WIDTH - 1:0] destination_exp;
+ assign destination_exp = input_exp + $signed(fpnew_pkg_bias(dst_fmt_q));
+ wire input_sign_q;
+ wire signed [INT_EXP_WIDTH - 1:0] input_exp_q;
+ wire [INT_MAN_WIDTH - 1:0] input_mant_q;
+ wire signed [INT_EXP_WIDTH - 1:0] destination_exp_q;
+ wire src_is_int_q;
+ wire dst_is_int_q;
+ wire [7:0] info_q;
+ wire mant_is_zero_q;
+ wire op_mod_q2;
+ wire [2:0] rnd_mode_q;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] src_fmt_q2;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_q2;
+ wire [fpnew_pkg_INT_FORMAT_BITS - 1:0] int_fmt_q2;
+ wire [0:NUM_MID_REGS] mid_pipe_input_sign_q;
+ wire signed [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * INT_EXP_WIDTH) + ((NUM_MID_REGS * INT_EXP_WIDTH) - 1) : ((NUM_MID_REGS + 1) * INT_EXP_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * INT_EXP_WIDTH : 0)] mid_pipe_input_exp_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * INT_MAN_WIDTH) + ((NUM_MID_REGS * INT_MAN_WIDTH) - 1) : ((NUM_MID_REGS + 1) * INT_MAN_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * INT_MAN_WIDTH : 0)] mid_pipe_input_mant_q;
+ wire signed [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * INT_EXP_WIDTH) + ((NUM_MID_REGS * INT_EXP_WIDTH) - 1) : ((NUM_MID_REGS + 1) * INT_EXP_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * INT_EXP_WIDTH : 0)] mid_pipe_dest_exp_q;
+ wire [0:NUM_MID_REGS] mid_pipe_src_is_int_q;
+ wire [0:NUM_MID_REGS] mid_pipe_dst_is_int_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * 8) + ((NUM_MID_REGS * 8) - 1) : ((NUM_MID_REGS + 1) * 8) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * 8 : 0)] mid_pipe_info_q;
+ wire [0:NUM_MID_REGS] mid_pipe_mant_zero_q;
+ wire [0:NUM_MID_REGS] mid_pipe_op_mod_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * 3) + ((NUM_MID_REGS * 3) - 1) : ((NUM_MID_REGS + 1) * 3) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * 3 : 0)] mid_pipe_rnd_mode_q;
+ wire [(0 >= NUM_MID_REGS ? -1 : -1):(0 >= NUM_MID_REGS ? 0 : 0)] mid_pipe_src_fmt_q;
+ wire [(0 >= NUM_MID_REGS ? -1 : -1):(0 >= NUM_MID_REGS ? 0 : 0)] mid_pipe_dst_fmt_q;
+ wire [(0 >= NUM_MID_REGS ? -1 : -1):(0 >= NUM_MID_REGS ? 0 : 0)] mid_pipe_int_fmt_q;
+ wire [0:NUM_MID_REGS] mid_pipe_tag_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * AuxType_AUX_BITS) + ((NUM_MID_REGS * AuxType_AUX_BITS) - 1) : ((NUM_MID_REGS + 1) * AuxType_AUX_BITS) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * AuxType_AUX_BITS : 0)] mid_pipe_aux_q;
+ wire [0:NUM_MID_REGS] mid_pipe_valid_q;
+ wire [0:NUM_MID_REGS] mid_pipe_ready;
+ assign mid_pipe_input_sign_q[0] = input_sign;
+ assign mid_pipe_input_exp_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * INT_EXP_WIDTH+:INT_EXP_WIDTH] = input_exp;
+ assign mid_pipe_input_mant_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * INT_MAN_WIDTH+:INT_MAN_WIDTH] = input_mant;
+ assign mid_pipe_dest_exp_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * INT_EXP_WIDTH+:INT_EXP_WIDTH] = destination_exp;
+ assign mid_pipe_src_is_int_q[0] = src_is_int;
+ assign mid_pipe_dst_is_int_q[0] = dst_is_int;
+ assign mid_pipe_info_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * 8+:8] = info[src_fmt_q * 8+:8];
+ assign mid_pipe_mant_zero_q[0] = mant_is_zero;
+ assign mid_pipe_op_mod_q[0] = op_mod_q;
+ assign mid_pipe_rnd_mode_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * 3+:3] = inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3+:3];
+ assign mid_pipe_src_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS] = src_fmt_q;
+ assign mid_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS] = dst_fmt_q;
+ assign mid_pipe_int_fmt_q[0+:fpnew_pkg_INT_FORMAT_BITS] = int_fmt_q;
+ assign mid_pipe_tag_q[0] = inp_pipe_tag_q[NUM_INP_REGS];
+ assign mid_pipe_aux_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS] = inp_pipe_aux_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS];
+ assign mid_pipe_valid_q[0] = inp_pipe_valid_q[NUM_INP_REGS];
+ assign inp_pipe_ready[NUM_INP_REGS] = mid_pipe_ready[0];
+ generate
+ for (i = 0; i < NUM_MID_REGS; i = i + 1) begin : gen_inside_pipeline
+ wire reg_ena;
+ assign mid_pipe_ready[i] = mid_pipe_ready[i + 1] | ~mid_pipe_valid_q[i + 1];
+ assign reg_ena = mid_pipe_ready[i] & mid_pipe_valid_q[i];
+ end
+ endgenerate
+ assign input_sign_q = mid_pipe_input_sign_q[NUM_MID_REGS];
+ assign input_exp_q = mid_pipe_input_exp_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * INT_EXP_WIDTH+:INT_EXP_WIDTH];
+ assign input_mant_q = mid_pipe_input_mant_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * INT_MAN_WIDTH+:INT_MAN_WIDTH];
+ assign destination_exp_q = mid_pipe_dest_exp_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * INT_EXP_WIDTH+:INT_EXP_WIDTH];
+ assign src_is_int_q = mid_pipe_src_is_int_q[NUM_MID_REGS];
+ assign dst_is_int_q = mid_pipe_dst_is_int_q[NUM_MID_REGS];
+ assign info_q = mid_pipe_info_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * 8+:8];
+ assign mant_is_zero_q = mid_pipe_mant_zero_q[NUM_MID_REGS];
+ assign op_mod_q2 = mid_pipe_op_mod_q[NUM_MID_REGS];
+ assign rnd_mode_q = mid_pipe_rnd_mode_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * 3+:3];
+ assign src_fmt_q2 = mid_pipe_src_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS];
+ assign dst_fmt_q2 = mid_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS];
+ assign int_fmt_q2 = mid_pipe_int_fmt_q[0+:fpnew_pkg_INT_FORMAT_BITS];
+ reg [INT_EXP_WIDTH - 1:0] final_exp;
+ reg [2 * INT_MAN_WIDTH:0] preshift_mant;
+ wire [2 * INT_MAN_WIDTH:0] destination_mant;
+ wire [SUPER_MAN_BITS - 1:0] final_mant;
+ wire [MAX_INT_WIDTH - 1:0] final_int;
+ reg [$clog2(INT_MAN_WIDTH + 1) - 1:0] denorm_shamt;
+ wire [1:0] fp_round_sticky_bits;
+ wire [1:0] int_round_sticky_bits;
+ wire [1:0] round_sticky_bits;
+ reg of_before_round;
+ reg uf_before_round;
+ always @(*) begin : cast_value
+ final_exp = $unsigned(destination_exp_q);
+ preshift_mant = {((2 * INT_MAN_WIDTH) >= 0 ? (2 * INT_MAN_WIDTH) + 1 : 1 - (2 * INT_MAN_WIDTH)) {1'sb0}};
+ denorm_shamt = SUPER_MAN_BITS - fpnew_pkg_man_bits(dst_fmt_q2);
+ of_before_round = 1'b0;
+ uf_before_round = 1'b0;
+ preshift_mant = input_mant_q << (INT_MAN_WIDTH + 1);
+ if (dst_is_int_q) begin
+ denorm_shamt = $unsigned((MAX_INT_WIDTH - 1) - input_exp_q);
+ if (input_exp_q >= $signed((fpnew_pkg_int_width(int_fmt_q2) - 1) + op_mod_q2)) begin
+ denorm_shamt = {$clog2(INT_MAN_WIDTH + 1) {1'sb0}};
+ of_before_round = 1'b1;
+ end
+ else if (input_exp_q < -1) begin
+ denorm_shamt = MAX_INT_WIDTH + 1;
+ uf_before_round = 1'b1;
+ end
+ end
+ else if ((destination_exp_q >= ($signed(2 ** fpnew_pkg_exp_bits(dst_fmt_q2)) - 1)) || (~src_is_int_q && info_q[4])) begin
+ final_exp = $unsigned((2 ** fpnew_pkg_exp_bits(dst_fmt_q2)) - 2);
+ preshift_mant = {((2 * INT_MAN_WIDTH) >= 0 ? (2 * INT_MAN_WIDTH) + 1 : 1 - (2 * INT_MAN_WIDTH)) {1'sb1}};
+ of_before_round = 1'b1;
+ end
+ else if ((destination_exp_q < 1) && (destination_exp_q >= -$signed(fpnew_pkg_man_bits(dst_fmt_q2)))) begin
+ final_exp = {INT_EXP_WIDTH {1'sb0}};
+ denorm_shamt = $unsigned((denorm_shamt + 1) - destination_exp_q);
+ uf_before_round = 1'b1;
+ end
+ else if (destination_exp_q < -$signed(fpnew_pkg_man_bits(dst_fmt_q2))) begin
+ final_exp = {INT_EXP_WIDTH {1'sb0}};
+ denorm_shamt = $unsigned((denorm_shamt + 2) + fpnew_pkg_man_bits(dst_fmt_q2));
+ uf_before_round = 1'b1;
+ end
+ end
+ localparam NUM_FP_STICKY = ((2 * INT_MAN_WIDTH) - SUPER_MAN_BITS) - 1;
+ localparam NUM_INT_STICKY = (2 * INT_MAN_WIDTH) - MAX_INT_WIDTH;
+ assign destination_mant = preshift_mant >> denorm_shamt;
+ assign {final_mant, fp_round_sticky_bits[1]} = destination_mant[(2 * INT_MAN_WIDTH) - 1-:SUPER_MAN_BITS + 1];
+ assign {final_int, int_round_sticky_bits[1]} = destination_mant[2 * INT_MAN_WIDTH-:MAX_INT_WIDTH + 1];
+ assign fp_round_sticky_bits[0] = |{destination_mant[NUM_FP_STICKY - 1:0]};
+ assign int_round_sticky_bits[0] = |{destination_mant[NUM_INT_STICKY - 1:0]};
+ assign round_sticky_bits = (dst_is_int_q ? int_round_sticky_bits : fp_round_sticky_bits);
+ wire [WIDTH - 1:0] pre_round_abs;
+ wire of_after_round;
+ wire uf_after_round;
+ reg [(NUM_FORMATS * WIDTH) - 1:0] fmt_pre_round_abs;
+ reg [0:0] fmt_of_after_round;
+ reg [0:0] fmt_uf_after_round;
+ reg [(NUM_INT_FORMATS * WIDTH) - 1:0] ifmt_pre_round_abs;
+ wire rounded_sign;
+ wire [WIDTH - 1:0] rounded_abs;
+ wire result_true_zero;
+ wire [WIDTH - 1:0] rounded_int_res;
+ wire rounded_int_res_zero;
+ generate
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : gen_res_assemble
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_9359B;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_9359B = inp;
+ endfunction
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(sv2v_cast_9359B(fmt));
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(sv2v_cast_9359B(fmt));
+ if (FpFmtConfig[fmt]) begin : active_format
+ always @(*) begin : assemble_result
+ fmt_pre_round_abs[fmt * WIDTH+:WIDTH] = {final_exp[EXP_BITS - 1:0], final_mant[MAN_BITS - 1:0]};
+ end
+ end
+ else begin : inactive_format
+ wire [WIDTH:1] sv2v_tmp_4020A;
+ assign sv2v_tmp_4020A = {WIDTH {fpnew_pkg_DONT_CARE}};
+ always @(*) fmt_pre_round_abs[fmt * WIDTH+:WIDTH] = sv2v_tmp_4020A;
+ end
+ end
+ endgenerate
+ generate
+ for (ifmt = 0; ifmt < sv2v_cast_32_signed(NUM_INT_FORMATS); ifmt = ifmt + 1) begin : gen_int_res_sign_ext
+ function automatic [fpnew_pkg_INT_FORMAT_BITS - 1:0] sv2v_cast_D812A;
+ input reg [fpnew_pkg_INT_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_D812A = inp;
+ endfunction
+ localparam [31:0] INT_WIDTH = fpnew_pkg_int_width(sv2v_cast_D812A(ifmt));
+ if (IntFmtConfig[ifmt]) begin : active_format
+ always @(*) begin : assemble_result
+ ifmt_pre_round_abs[ifmt * WIDTH+:WIDTH] = {WIDTH {final_int[INT_WIDTH - 1]}};
+ ifmt_pre_round_abs[(ifmt * WIDTH) + (INT_WIDTH - 1)-:INT_WIDTH] = final_int[INT_WIDTH - 1:0];
+ end
+ end
+ else begin : inactive_format
+ wire [WIDTH:1] sv2v_tmp_D81CB;
+ assign sv2v_tmp_D81CB = {WIDTH {fpnew_pkg_DONT_CARE}};
+ always @(*) ifmt_pre_round_abs[ifmt * WIDTH+:WIDTH] = sv2v_tmp_D81CB;
+ end
+ end
+ endgenerate
+ assign pre_round_abs = (dst_is_int_q ? ifmt_pre_round_abs[int_fmt_q2 * WIDTH+:WIDTH] : fmt_pre_round_abs[dst_fmt_q2 * WIDTH+:WIDTH]);
+ fpnew_rounding #(.AbsWidth(WIDTH)) i_fpnew_rounding(
+ .abs_value_i(pre_round_abs),
+ .sign_i(input_sign_q),
+ .round_sticky_bits_i(round_sticky_bits),
+ .rnd_mode_i(rnd_mode_q),
+ .effective_subtraction_i(1'b0),
+ .abs_rounded_o(rounded_abs),
+ .sign_o(rounded_sign),
+ .exact_zero_o(result_true_zero)
+ );
+ reg [(NUM_FORMATS * WIDTH) - 1:0] fmt_result;
+ generate
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : gen_sign_inject
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_9359B;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_9359B = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_9359B(fmt));
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(sv2v_cast_9359B(fmt));
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(sv2v_cast_9359B(fmt));
+ if (FpFmtConfig[fmt]) begin : active_format
+ always @(*) begin : post_process
+ fmt_uf_after_round[fmt] = rounded_abs[(EXP_BITS + MAN_BITS) - 1:MAN_BITS] == {(((EXP_BITS + MAN_BITS) - 1) >= MAN_BITS ? (((EXP_BITS + MAN_BITS) - 1) - MAN_BITS) + 1 : (MAN_BITS - ((EXP_BITS + MAN_BITS) - 1)) + 1) {1'sb0}};
+ fmt_of_after_round[fmt] = rounded_abs[(EXP_BITS + MAN_BITS) - 1:MAN_BITS] == {(((EXP_BITS + MAN_BITS) - 1) >= MAN_BITS ? (((EXP_BITS + MAN_BITS) - 1) - MAN_BITS) + 1 : (MAN_BITS - ((EXP_BITS + MAN_BITS) - 1)) + 1) {1'sb1}};
+ fmt_result[fmt * WIDTH+:WIDTH] = {WIDTH {1'sb1}};
+ fmt_result[(fmt * WIDTH) + (FP_WIDTH - 1)-:FP_WIDTH] = (src_is_int_q & mant_is_zero_q ? {FP_WIDTH {1'sb0}} : {rounded_sign, rounded_abs[(EXP_BITS + MAN_BITS) - 1:0]});
+ end
+ end
+ else begin : inactive_format
+ wire [1:1] sv2v_tmp_78FCE;
+ assign sv2v_tmp_78FCE = fpnew_pkg_DONT_CARE;
+ always @(*) fmt_uf_after_round[fmt] = sv2v_tmp_78FCE;
+ wire [1:1] sv2v_tmp_C5A3B;
+ assign sv2v_tmp_C5A3B = fpnew_pkg_DONT_CARE;
+ always @(*) fmt_of_after_round[fmt] = sv2v_tmp_C5A3B;
+ wire [WIDTH:1] sv2v_tmp_4A6B1;
+ assign sv2v_tmp_4A6B1 = {WIDTH {fpnew_pkg_DONT_CARE}};
+ always @(*) fmt_result[fmt * WIDTH+:WIDTH] = sv2v_tmp_4A6B1;
+ end
+ end
+ endgenerate
+ assign uf_after_round = fmt_uf_after_round[dst_fmt_q2];
+ assign of_after_round = fmt_of_after_round[dst_fmt_q2];
+ assign rounded_int_res = (rounded_sign ? $unsigned(-rounded_abs) : rounded_abs);
+ assign rounded_int_res_zero = rounded_int_res == {WIDTH {1'sb0}};
+ wire [WIDTH - 1:0] fp_special_result;
+ wire [4:0] fp_special_status;
+ wire fp_result_is_special;
+ reg [(NUM_FORMATS * WIDTH) - 1:0] fmt_special_result;
+ generate
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : gen_special_results
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_9359B;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_9359B = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_9359B(fmt));
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(sv2v_cast_9359B(fmt));
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(sv2v_cast_9359B(fmt));
+ localparam [EXP_BITS - 1:0] QNAN_EXPONENT = 1'sb1;
+ localparam [MAN_BITS - 1:0] QNAN_MANTISSA = 2 ** (MAN_BITS - 1);
+ if (FpFmtConfig[fmt]) begin : active_format
+ always @(*) begin : special_results
+ reg [FP_WIDTH - 1:0] special_res;
+ special_res = (info_q[5] ? input_sign_q << (FP_WIDTH - 1) : {1'b0, QNAN_EXPONENT, QNAN_MANTISSA});
+ fmt_special_result[fmt * WIDTH+:WIDTH] = {WIDTH {1'sb1}};
+ fmt_special_result[(fmt * WIDTH) + (FP_WIDTH - 1)-:FP_WIDTH] = special_res;
+ end
+ end
+ else begin : inactive_format
+ wire [WIDTH:1] sv2v_tmp_E5F3D;
+ assign sv2v_tmp_E5F3D = {WIDTH {fpnew_pkg_DONT_CARE}};
+ always @(*) fmt_special_result[fmt * WIDTH+:WIDTH] = sv2v_tmp_E5F3D;
+ end
+ end
+ endgenerate
+ assign fp_result_is_special = ~src_is_int_q & ((info_q[5] | info_q[3]) | ~info_q[0]);
+ assign fp_special_status = {info_q[2], 1'b0, 1'b0, 1'b0, 1'b0};
+ assign fp_special_result = fmt_special_result[dst_fmt_q2 * WIDTH+:WIDTH];
+ wire [WIDTH - 1:0] int_special_result;
+ wire [4:0] int_special_status;
+ wire int_result_is_special;
+ reg [(NUM_INT_FORMATS * WIDTH) - 1:0] ifmt_special_result;
+ generate
+ for (ifmt = 0; ifmt < sv2v_cast_32_signed(NUM_INT_FORMATS); ifmt = ifmt + 1) begin : gen_special_results_int
+ function automatic [fpnew_pkg_INT_FORMAT_BITS - 1:0] sv2v_cast_D812A;
+ input reg [fpnew_pkg_INT_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_D812A = inp;
+ endfunction
+ localparam [31:0] INT_WIDTH = fpnew_pkg_int_width(sv2v_cast_D812A(ifmt));
+ if (IntFmtConfig[ifmt]) begin : active_format
+ always @(*) begin : special_results
+ reg [INT_WIDTH - 1:0] special_res;
+ special_res[INT_WIDTH - 2:0] = {((INT_WIDTH - 2) >= 0 ? INT_WIDTH - 1 : 3 - INT_WIDTH) {1'sb1}};
+ special_res[INT_WIDTH - 1] = op_mod_q2;
+ if (input_sign_q && !info_q[3])
+ special_res = ~special_res;
+ ifmt_special_result[ifmt * WIDTH+:WIDTH] = {WIDTH {special_res[INT_WIDTH - 1]}};
+ ifmt_special_result[(ifmt * WIDTH) + (INT_WIDTH - 1)-:INT_WIDTH] = special_res;
+ end
+ end
+ else begin : inactive_format
+ wire [WIDTH:1] sv2v_tmp_B8B30;
+ assign sv2v_tmp_B8B30 = {WIDTH {fpnew_pkg_DONT_CARE}};
+ always @(*) ifmt_special_result[ifmt * WIDTH+:WIDTH] = sv2v_tmp_B8B30;
+ end
+ end
+ endgenerate
+ assign int_result_is_special = (((info_q[3] | info_q[4]) | of_before_round) | ~info_q[0]) | ((input_sign_q & op_mod_q2) & ~rounded_int_res_zero);
+ assign int_special_status = 5'b10000;
+ assign int_special_result = ifmt_special_result[int_fmt_q2 * WIDTH+:WIDTH];
+ wire [4:0] int_regular_status;
+ wire [4:0] fp_regular_status;
+ wire [WIDTH - 1:0] fp_result;
+ wire [WIDTH - 1:0] int_result;
+ wire [4:0] fp_status;
+ wire [4:0] int_status;
+ assign fp_regular_status[4] = src_is_int_q & (of_before_round | of_after_round);
+ assign fp_regular_status[3] = 1'b0;
+ assign fp_regular_status[2] = ~src_is_int_q & (~info_q[4] & (of_before_round | of_after_round));
+ assign fp_regular_status[1] = uf_after_round & fp_regular_status[0];
+ assign fp_regular_status[0] = (src_is_int_q ? |fp_round_sticky_bits : |fp_round_sticky_bits | (~info_q[4] & (of_before_round | of_after_round)));
+ assign int_regular_status = {4'b0000, |int_round_sticky_bits};
+ assign fp_result = (fp_result_is_special ? fp_special_result : fmt_result[dst_fmt_q2 * WIDTH+:WIDTH]);
+ assign fp_status = (fp_result_is_special ? fp_special_status : fp_regular_status);
+ assign int_result = (int_result_is_special ? int_special_result : rounded_int_res);
+ assign int_status = (int_result_is_special ? int_special_status : int_regular_status);
+ wire [WIDTH - 1:0] result_d;
+ wire [4:0] status_d;
+ wire extension_bit;
+ assign result_d = (dst_is_int_q ? int_result : fp_result);
+ assign status_d = (dst_is_int_q ? int_status : fp_status);
+ assign extension_bit = (dst_is_int_q ? int_result[WIDTH - 1] : 1'b1);
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * WIDTH) + ((NUM_OUT_REGS * WIDTH) - 1) : ((NUM_OUT_REGS + 1) * WIDTH) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * WIDTH : 0)] out_pipe_result_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * 5) + ((NUM_OUT_REGS * 5) - 1) : ((NUM_OUT_REGS + 1) * 5) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * 5 : 0)] out_pipe_status_q;
+ wire [0:NUM_OUT_REGS] out_pipe_ext_bit_q;
+ wire [0:NUM_OUT_REGS] out_pipe_tag_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * AuxType_AUX_BITS) + ((NUM_OUT_REGS * AuxType_AUX_BITS) - 1) : ((NUM_OUT_REGS + 1) * AuxType_AUX_BITS) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * AuxType_AUX_BITS : 0)] out_pipe_aux_q;
+ wire [0:NUM_OUT_REGS] out_pipe_valid_q;
+ wire [0:NUM_OUT_REGS] out_pipe_ready;
+ assign out_pipe_result_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * WIDTH+:WIDTH] = result_d;
+ assign out_pipe_status_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * 5+:5] = status_d;
+ assign out_pipe_ext_bit_q[0] = extension_bit;
+ assign out_pipe_tag_q[0] = mid_pipe_tag_q[NUM_MID_REGS];
+ assign out_pipe_aux_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS] = mid_pipe_aux_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS];
+ assign out_pipe_valid_q[0] = mid_pipe_valid_q[NUM_MID_REGS];
+ assign mid_pipe_ready[NUM_MID_REGS] = out_pipe_ready[0];
+ generate
+ for (i = 0; i < NUM_OUT_REGS; i = i + 1) begin : gen_output_pipeline
+ wire reg_ena;
+ assign out_pipe_ready[i] = out_pipe_ready[i + 1] | ~out_pipe_valid_q[i + 1];
+ assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
+ end
+ endgenerate
+ assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
+ assign result_o = out_pipe_result_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * WIDTH+:WIDTH];
+ assign status_o = out_pipe_status_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * 5+:5];
+ assign extension_bit_o = out_pipe_ext_bit_q[NUM_OUT_REGS];
+ assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
+ assign aux_o = out_pipe_aux_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS];
+ assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
+ assign busy_o = |{inp_pipe_valid_q, mid_pipe_valid_q, out_pipe_valid_q};
+endmodule
+module fpnew_classifier (
+ operands_i,
+ is_boxed_i,
+ info_o
+);
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_9E068;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_9E068 = inp;
+ endfunction
+ parameter [fpnew_pkg_FP_FORMAT_BITS - 1:0] FpFormat = sv2v_cast_9E068(0);
+ parameter [31:0] NumOperands = 1;
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ localparam [31:0] WIDTH = fpnew_pkg_fp_width(FpFormat);
+ input wire [(NumOperands * WIDTH) - 1:0] operands_i;
+ input wire [NumOperands - 1:0] is_boxed_i;
+ output reg [(NumOperands * 8) - 1:0] info_o;
+ function automatic [31:0] fpnew_pkg_exp_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_exp_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32];
+ endfunction
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(FpFormat);
+ function automatic [31:0] fpnew_pkg_man_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_man_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32];
+ endfunction
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(FpFormat);
+ generate
+ genvar op;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ for (op = 0; op < sv2v_cast_32_signed(NumOperands); op = op + 1) begin : gen_num_values
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] value;
+ reg is_boxed;
+ reg is_normal;
+ reg is_inf;
+ reg is_nan;
+ reg is_signalling;
+ reg is_quiet;
+ reg is_zero;
+ reg is_subnormal;
+ always @(*) begin : classify_input
+ value = operands_i[op * WIDTH+:WIDTH];
+ is_boxed = is_boxed_i[op];
+ is_normal = (is_boxed && (value[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)] != {((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1) {1'sb0}})) && (value[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)] != {((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1) {1'sb1}});
+ is_zero = (is_boxed && (value[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)] == {((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1) {1'sb0}})) && (value[MAN_BITS - 1-:MAN_BITS] == {MAN_BITS {1'sb0}});
+ is_subnormal = (is_boxed && (value[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)] == {((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1) {1'sb0}})) && !is_zero;
+ is_inf = is_boxed && ((value[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)] == {((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1) {1'sb1}}) && (value[MAN_BITS - 1-:MAN_BITS] == {MAN_BITS {1'sb0}}));
+ is_nan = !is_boxed || ((value[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)] == {((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1) {1'sb1}}) && (value[MAN_BITS - 1-:MAN_BITS] != {MAN_BITS {1'sb0}}));
+ is_signalling = (is_boxed && is_nan) && (value[(MAN_BITS - 1) - ((MAN_BITS - 1) - (MAN_BITS - 1))] == 1'b0);
+ is_quiet = is_nan && !is_signalling;
+ info_o[(op * 8) + 7] = is_normal;
+ info_o[(op * 8) + 6] = is_subnormal;
+ info_o[(op * 8) + 5] = is_zero;
+ info_o[(op * 8) + 4] = is_inf;
+ info_o[(op * 8) + 3] = is_nan;
+ info_o[(op * 8) + 2] = is_signalling;
+ info_o[(op * 8) + 1] = is_quiet;
+ info_o[op * 8] = is_boxed;
+ end
+ end
+ endgenerate
+endmodule
+module fpnew_divsqrt_multi_28154_735ED (
+ clk_i,
+ rst_ni,
+ operands_i,
+ is_boxed_i,
+ rnd_mode_i,
+ op_i,
+ dst_fmt_i,
+ tag_i,
+ aux_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ extension_bit_o,
+ tag_o,
+ aux_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ parameter [31:0] AuxType_AUX_BITS = 0;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ parameter [0:0] FpFmtConfig = 1'sb1;
+ parameter [31:0] NumPipeRegs = 0;
+ localparam [1:0] fpnew_pkg_AFTER = 1;
+ parameter [1:0] PipeConfig = fpnew_pkg_AFTER;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ function automatic signed [31:0] fpnew_pkg_maximum;
+ input reg signed [31:0] a;
+ input reg signed [31:0] b;
+ fpnew_pkg_maximum = (a > b ? a : b);
+ endfunction
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_8C7A2;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_8C7A2 = inp;
+ endfunction
+ function automatic [31:0] fpnew_pkg_max_fp_width;
+ input reg [0:0] cfg;
+ reg [31:0] res;
+ begin
+ res = 0;
+ begin : sv2v_autoblock_110
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (cfg[i])
+ res = $unsigned(fpnew_pkg_maximum(res, fpnew_pkg_fp_width(sv2v_cast_8C7A2(i))));
+ end
+ fpnew_pkg_max_fp_width = res;
+ end
+ endfunction
+ localparam [31:0] WIDTH = fpnew_pkg_max_fp_width(FpFmtConfig);
+ localparam [31:0] NUM_FORMATS = fpnew_pkg_NUM_FP_FORMATS;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(2 * WIDTH) - 1:0] operands_i;
+ input wire [1:0] is_boxed_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_i;
+ input wire tag_i;
+ input wire [AuxType_AUX_BITS - 1:0] aux_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [WIDTH - 1:0] result_o;
+ output wire [4:0] status_o;
+ output wire extension_bit_o;
+ output wire tag_o;
+ output wire [AuxType_AUX_BITS - 1:0] aux_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ localparam [1:0] fpnew_pkg_DISTRIBUTED = 3;
+ localparam NUM_INP_REGS = (PipeConfig == fpnew_pkg_BEFORE ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? NumPipeRegs / 2 : 0));
+ localparam [1:0] fpnew_pkg_INSIDE = 2;
+ localparam NUM_OUT_REGS = ((PipeConfig == fpnew_pkg_AFTER) || (PipeConfig == fpnew_pkg_INSIDE) ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? (NumPipeRegs + 1) / 2 : 0));
+ wire [(2 * WIDTH) - 1:0] operands_q;
+ wire [2:0] rnd_mode_q;
+ wire [3:0] op_q;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_q;
+ wire in_valid_q;
+ wire [((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? ((((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) - (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0)) + 1) * WIDTH) + (((0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) * WIDTH) - 1) : ((((0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1)) + 1) * WIDTH) + (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) * WIDTH) - 1)):((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) * WIDTH : (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) * WIDTH)] inp_pipe_operands_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0)] inp_pipe_rnd_mode_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * fpnew_pkg_OP_BITS) + ((NUM_INP_REGS * fpnew_pkg_OP_BITS) - 1) : ((NUM_INP_REGS + 1) * fpnew_pkg_OP_BITS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * fpnew_pkg_OP_BITS : 0)] inp_pipe_op_q;
+ wire [(0 >= NUM_INP_REGS ? -1 : -1):(0 >= NUM_INP_REGS ? 0 : 0)] inp_pipe_dst_fmt_q;
+ wire [0:NUM_INP_REGS] inp_pipe_tag_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * AuxType_AUX_BITS) + ((NUM_INP_REGS * AuxType_AUX_BITS) - 1) : ((NUM_INP_REGS + 1) * AuxType_AUX_BITS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * AuxType_AUX_BITS : 0)] inp_pipe_aux_q;
+ wire [0:NUM_INP_REGS] inp_pipe_valid_q;
+ wire [0:NUM_INP_REGS] inp_pipe_ready;
+ assign inp_pipe_operands_q[WIDTH * ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2 : ((0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2) + 1) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) - (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2 : ((0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2) + 1) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1)))+:WIDTH * 2] = operands_i;
+ assign inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3+:3] = rnd_mode_i;
+ assign inp_pipe_op_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS] = op_i;
+ assign inp_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS] = dst_fmt_i;
+ assign inp_pipe_tag_q[0] = tag_i;
+ assign inp_pipe_aux_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS] = aux_i;
+ assign inp_pipe_valid_q[0] = in_valid_i;
+ assign in_ready_o = inp_pipe_ready[0];
+ generate
+ genvar i;
+ for (i = 0; i < NUM_INP_REGS; i = i + 1) begin : gen_input_pipeline
+ wire reg_ena;
+ assign inp_pipe_ready[i] = inp_pipe_ready[i + 1] | ~inp_pipe_valid_q[i + 1];
+ assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
+ end
+ endgenerate
+ assign operands_q = inp_pipe_operands_q[WIDTH * ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2 : ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2) + 1) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) - (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2 : ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2) + 1) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1)))+:WIDTH * 2];
+ assign rnd_mode_q = inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3+:3];
+ assign op_q = inp_pipe_op_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS];
+ assign dst_fmt_q = inp_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS];
+ assign in_valid_q = inp_pipe_valid_q[NUM_INP_REGS];
+ reg [1:0] divsqrt_fmt;
+ reg [127:0] divsqrt_operands;
+ reg input_is_fp8;
+ localparam [fpnew_pkg_FP_FORMAT_BITS - 1:0] fpnew_pkg_FP32 = 'd0;
+ always @(*) begin : translate_fmt
+ case (dst_fmt_q)
+ fpnew_pkg_FP32: divsqrt_fmt = 2'b00;
+ default: divsqrt_fmt = 2'b10;
+ endcase
+ input_is_fp8 = 1'b0;
+ divsqrt_operands[0+:64] = operands_q[0+:WIDTH];
+ divsqrt_operands[64+:64] = operands_q[WIDTH+:WIDTH];
+ end
+ reg in_ready;
+ wire div_valid;
+ wire sqrt_valid;
+ wire unit_ready;
+ wire unit_done;
+ wire op_starting;
+ reg out_valid;
+ wire out_ready;
+ reg hold_result;
+ reg data_is_held;
+ reg unit_busy;
+ wire [1:0] state_q;
+ reg [1:0] state_d;
+ assign inp_pipe_ready[NUM_INP_REGS] = in_ready;
+ localparam [3:0] fpnew_pkg_DIV = 4;
+ assign div_valid = ((in_valid_q & (op_q == fpnew_pkg_DIV)) & in_ready) & ~flush_i;
+ assign sqrt_valid = ((in_valid_q & (op_q != fpnew_pkg_DIV)) & in_ready) & ~flush_i;
+ assign op_starting = div_valid | sqrt_valid;
+ localparam [1:0] BUSY = 1;
+ localparam [1:0] HOLD = 2;
+ localparam [1:0] IDLE = 0;
+ always @(*) begin : flag_fsm
+ in_ready = 1'b0;
+ out_valid = 1'b0;
+ hold_result = 1'b0;
+ data_is_held = 1'b0;
+ unit_busy = 1'b0;
+ state_d = state_q;
+ case (state_q)
+ IDLE: begin
+ in_ready = 1'b1;
+ if (in_valid_q && unit_ready)
+ state_d = BUSY;
+ end
+ BUSY: begin
+ unit_busy = 1'b1;
+ if (unit_done) begin
+ out_valid = 1'b1;
+ if (out_ready) begin
+ state_d = IDLE;
+ if (in_valid_q && unit_ready) begin
+ in_ready = 1'b1;
+ state_d = BUSY;
+ end
+ end
+ else begin
+ hold_result = 1'b1;
+ state_d = HOLD;
+ end
+ end
+ end
+ HOLD: begin
+ unit_busy = 1'b1;
+ data_is_held = 1'b1;
+ out_valid = 1'b1;
+ if (out_ready) begin
+ state_d = IDLE;
+ if (in_valid_q && unit_ready) begin
+ in_ready = 1'b1;
+ state_d = BUSY;
+ end
+ end
+ end
+ default: state_d = IDLE;
+ endcase
+ if (flush_i) begin
+ unit_busy = 1'b0;
+ out_valid = 1'b0;
+ state_d = IDLE;
+ end
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ __q <= __reset_value;
+ else
+ __q <= __d;
+ wire result_is_fp8_q;
+ wire result_tag_q;
+ wire [AuxType_AUX_BITS - 1:0] result_aux_q;
+ wire [63:0] unit_result;
+ wire [WIDTH - 1:0] adjusted_result;
+ wire [WIDTH - 1:0] held_result_q;
+ wire [4:0] unit_status;
+ wire [4:0] held_status_q;
+ div_sqrt_top_mvp i_divsqrt_lei(
+ .Clk_CI(clk_i),
+ .Rst_RBI(rst_ni),
+ .Div_start_SI(div_valid),
+ .Sqrt_start_SI(sqrt_valid),
+ .Operand_a_DI(divsqrt_operands[0+:64]),
+ .Operand_b_DI(divsqrt_operands[64+:64]),
+ .RM_SI(rnd_mode_q),
+ .Precision_ctl_SI({6 {1'sb0}}),
+ .Format_sel_SI(divsqrt_fmt),
+ .Kill_SI(flush_i),
+ .Result_DO(unit_result),
+ .Fflags_SO(unit_status),
+ .Ready_SO(unit_ready),
+ .Done_SO(unit_done)
+ );
+ assign adjusted_result = (result_is_fp8_q ? unit_result >> 8 : unit_result);
+ always @(posedge __clk) __q <= (__load ? __d : __q);
+ wire [WIDTH - 1:0] result_d;
+ wire [4:0] status_d;
+ assign result_d = (data_is_held ? held_result_q : adjusted_result);
+ assign status_d = (data_is_held ? held_status_q : unit_status);
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * WIDTH) + ((NUM_OUT_REGS * WIDTH) - 1) : ((NUM_OUT_REGS + 1) * WIDTH) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * WIDTH : 0)] out_pipe_result_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * 5) + ((NUM_OUT_REGS * 5) - 1) : ((NUM_OUT_REGS + 1) * 5) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * 5 : 0)] out_pipe_status_q;
+ wire [0:NUM_OUT_REGS] out_pipe_tag_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * AuxType_AUX_BITS) + ((NUM_OUT_REGS * AuxType_AUX_BITS) - 1) : ((NUM_OUT_REGS + 1) * AuxType_AUX_BITS) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * AuxType_AUX_BITS : 0)] out_pipe_aux_q;
+ wire [0:NUM_OUT_REGS] out_pipe_valid_q;
+ wire [0:NUM_OUT_REGS] out_pipe_ready;
+ assign out_pipe_result_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * WIDTH+:WIDTH] = result_d;
+ assign out_pipe_status_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * 5+:5] = status_d;
+ assign out_pipe_tag_q[0] = result_tag_q;
+ assign out_pipe_aux_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS] = result_aux_q;
+ assign out_pipe_valid_q[0] = out_valid;
+ assign out_ready = out_pipe_ready[0];
+ generate
+ for (i = 0; i < NUM_OUT_REGS; i = i + 1) begin : gen_output_pipeline
+ wire reg_ena;
+ assign out_pipe_ready[i] = out_pipe_ready[i + 1] | ~out_pipe_valid_q[i + 1];
+ assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
+ end
+ endgenerate
+ assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
+ assign result_o = out_pipe_result_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * WIDTH+:WIDTH];
+ assign status_o = out_pipe_status_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * 5+:5];
+ assign extension_bit_o = 1'b1;
+ assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
+ assign aux_o = out_pipe_aux_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS];
+ assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
+ assign busy_o = |{inp_pipe_valid_q, unit_busy, out_pipe_valid_q};
+endmodule
+module fpnew_fma_multi_E4D0A_BE123 (
+ clk_i,
+ rst_ni,
+ operands_i,
+ is_boxed_i,
+ rnd_mode_i,
+ op_i,
+ op_mod_i,
+ src_fmt_i,
+ dst_fmt_i,
+ tag_i,
+ aux_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ extension_bit_o,
+ tag_o,
+ aux_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ parameter [31:0] AuxType_AUX_BITS = 0;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ parameter [0:0] FpFmtConfig = 1'sb1;
+ parameter [31:0] NumPipeRegs = 0;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ parameter [1:0] PipeConfig = fpnew_pkg_BEFORE;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ function automatic signed [31:0] fpnew_pkg_maximum;
+ input reg signed [31:0] a;
+ input reg signed [31:0] b;
+ fpnew_pkg_maximum = (a > b ? a : b);
+ endfunction
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_3AA4D;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_3AA4D = inp;
+ endfunction
+ function automatic [31:0] fpnew_pkg_max_fp_width;
+ input reg [0:0] cfg;
+ reg [31:0] res;
+ begin
+ res = 0;
+ begin : sv2v_autoblock_111
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (cfg[i])
+ res = $unsigned(fpnew_pkg_maximum(res, fpnew_pkg_fp_width(sv2v_cast_3AA4D(i))));
+ end
+ fpnew_pkg_max_fp_width = res;
+ end
+ endfunction
+ localparam [31:0] WIDTH = fpnew_pkg_max_fp_width(FpFmtConfig);
+ localparam [31:0] NUM_FORMATS = fpnew_pkg_NUM_FP_FORMATS;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(3 * WIDTH) - 1:0] operands_i;
+ input wire [2:0] is_boxed_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire op_mod_i;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] src_fmt_i;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_i;
+ input wire tag_i;
+ input wire [AuxType_AUX_BITS - 1:0] aux_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [WIDTH - 1:0] result_o;
+ output wire [4:0] status_o;
+ output wire extension_bit_o;
+ output wire tag_o;
+ output wire [AuxType_AUX_BITS - 1:0] aux_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ function automatic [31:0] fpnew_pkg_exp_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_exp_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32];
+ endfunction
+ function automatic [31:0] fpnew_pkg_man_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_man_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32];
+ endfunction
+ function automatic [63:0] fpnew_pkg_super_format;
+ input reg [0:0] cfg;
+ reg [63:0] res;
+ begin
+ res = {64 {1'sb0}};
+ begin : sv2v_autoblock_112
+ reg [31:0] fmt;
+ for (fmt = 0; fmt < fpnew_pkg_NUM_FP_FORMATS; fmt = fmt + 1)
+ if (cfg[fmt]) begin
+ res[63-:32] = $unsigned(fpnew_pkg_maximum(res[63-:32], fpnew_pkg_exp_bits(sv2v_cast_3AA4D(fmt))));
+ res[31-:32] = $unsigned(fpnew_pkg_maximum(res[31-:32], fpnew_pkg_man_bits(sv2v_cast_3AA4D(fmt))));
+ end
+ end
+ fpnew_pkg_super_format = res;
+ end
+ endfunction
+ localparam [63:0] SUPER_FORMAT = fpnew_pkg_super_format(FpFmtConfig);
+ localparam [31:0] SUPER_EXP_BITS = SUPER_FORMAT[63-:32];
+ localparam [31:0] SUPER_MAN_BITS = SUPER_FORMAT[31-:32];
+ localparam [31:0] PRECISION_BITS = SUPER_MAN_BITS + 1;
+ localparam [31:0] LOWER_SUM_WIDTH = (2 * PRECISION_BITS) + 3;
+ localparam [31:0] LZC_RESULT_WIDTH = $clog2(LOWER_SUM_WIDTH);
+ localparam [31:0] EXP_WIDTH = fpnew_pkg_maximum(SUPER_EXP_BITS + 2, LZC_RESULT_WIDTH);
+ localparam [31:0] SHIFT_AMOUNT_WIDTH = $clog2((3 * PRECISION_BITS) + 3);
+ localparam [1:0] fpnew_pkg_DISTRIBUTED = 3;
+ localparam NUM_INP_REGS = (PipeConfig == fpnew_pkg_BEFORE ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? (NumPipeRegs + 1) / 3 : 0));
+ localparam [1:0] fpnew_pkg_INSIDE = 2;
+ localparam NUM_MID_REGS = (PipeConfig == fpnew_pkg_INSIDE ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? (NumPipeRegs + 2) / 3 : 0));
+ localparam [1:0] fpnew_pkg_AFTER = 1;
+ localparam NUM_OUT_REGS = (PipeConfig == fpnew_pkg_AFTER ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? NumPipeRegs / 3 : 0));
+ wire [(3 * WIDTH) - 1:0] operands_q;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] src_fmt_q;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_q;
+ wire [((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? ((((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) - (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0)) + 1) * WIDTH) + (((0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) * WIDTH) - 1) : ((((0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1)) + 1) * WIDTH) + (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) * WIDTH) - 1)):((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) * WIDTH : (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) * WIDTH)] inp_pipe_operands_q;
+ wire [((0 >= NUM_INP_REGS ? (1 - NUM_INP_REGS) + (NUM_INP_REGS - 1) : NUM_INP_REGS) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS : 0) ? ((((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * NUM_FORMATS) + ((NUM_INP_REGS * NUM_FORMATS) - 1) : ((NUM_INP_REGS + 1) * NUM_FORMATS) - 1) - (0 >= NUM_INP_REGS ? NUM_INP_REGS * NUM_FORMATS : 0)) + 1) * 3) + (((0 >= NUM_INP_REGS ? NUM_INP_REGS * NUM_FORMATS : 0) * 3) - 1) : ((((0 >= NUM_INP_REGS ? NUM_INP_REGS * NUM_FORMATS : 0) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * NUM_FORMATS) + ((NUM_INP_REGS * NUM_FORMATS) - 1) : ((NUM_INP_REGS + 1) * NUM_FORMATS) - 1)) + 1) * 3) + (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * NUM_FORMATS) + ((NUM_INP_REGS * NUM_FORMATS) - 1) : ((NUM_INP_REGS + 1) * NUM_FORMATS) - 1) * 3) - 1)):((0 >= NUM_INP_REGS ? (1 - NUM_INP_REGS) + (NUM_INP_REGS - 1) : NUM_INP_REGS) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS * NUM_FORMATS : 0) * 3 : (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * NUM_FORMATS) + ((NUM_INP_REGS * NUM_FORMATS) - 1) : ((NUM_INP_REGS + 1) * NUM_FORMATS) - 1) * 3)] inp_pipe_is_boxed_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0)] inp_pipe_rnd_mode_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * fpnew_pkg_OP_BITS) + ((NUM_INP_REGS * fpnew_pkg_OP_BITS) - 1) : ((NUM_INP_REGS + 1) * fpnew_pkg_OP_BITS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * fpnew_pkg_OP_BITS : 0)] inp_pipe_op_q;
+ wire [0:NUM_INP_REGS] inp_pipe_op_mod_q;
+ wire [(0 >= NUM_INP_REGS ? -1 : -1):(0 >= NUM_INP_REGS ? 0 : 0)] inp_pipe_src_fmt_q;
+ wire [(0 >= NUM_INP_REGS ? -1 : -1):(0 >= NUM_INP_REGS ? 0 : 0)] inp_pipe_dst_fmt_q;
+ wire [0:NUM_INP_REGS] inp_pipe_tag_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * AuxType_AUX_BITS) + ((NUM_INP_REGS * AuxType_AUX_BITS) - 1) : ((NUM_INP_REGS + 1) * AuxType_AUX_BITS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * AuxType_AUX_BITS : 0)] inp_pipe_aux_q;
+ wire [0:NUM_INP_REGS] inp_pipe_valid_q;
+ wire [0:NUM_INP_REGS] inp_pipe_ready;
+ assign inp_pipe_operands_q[WIDTH * ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3 : ((0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3) + 2) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3 : ((0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3) + 2) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1)))+:WIDTH * 3] = operands_i;
+ assign inp_pipe_is_boxed_q[3 * ((0 >= NUM_INP_REGS ? (1 - NUM_INP_REGS) + (NUM_INP_REGS - 1) : NUM_INP_REGS) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS : 0) ? ((0 >= NUM_INP_REGS ? (1 - NUM_INP_REGS) + (NUM_INP_REGS - 1) : NUM_INP_REGS) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * NUM_FORMATS : (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * NUM_FORMATS) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * NUM_FORMATS : 0) - (((0 >= NUM_INP_REGS ? (1 - NUM_INP_REGS) + (NUM_INP_REGS - 1) : NUM_INP_REGS) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * NUM_FORMATS : (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * NUM_FORMATS) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * NUM_FORMATS) + ((NUM_INP_REGS * NUM_FORMATS) - 1) : ((NUM_INP_REGS + 1) * NUM_FORMATS) - 1)))+:3] = is_boxed_i;
+ assign inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3+:3] = rnd_mode_i;
+ assign inp_pipe_op_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS] = op_i;
+ assign inp_pipe_op_mod_q[0] = op_mod_i;
+ assign inp_pipe_src_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS] = src_fmt_i;
+ assign inp_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS] = dst_fmt_i;
+ assign inp_pipe_tag_q[0] = tag_i;
+ assign inp_pipe_aux_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS] = aux_i;
+ assign inp_pipe_valid_q[0] = in_valid_i;
+ assign in_ready_o = inp_pipe_ready[0];
+ generate
+ genvar i;
+ for (i = 0; i < NUM_INP_REGS; i = i + 1) begin : gen_input_pipeline
+ wire reg_ena;
+ assign inp_pipe_ready[i] = inp_pipe_ready[i + 1] | ~inp_pipe_valid_q[i + 1];
+ assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
+ end
+ endgenerate
+ assign operands_q = inp_pipe_operands_q[WIDTH * ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3 : ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) + 2) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3 : ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) + 2) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1)))+:WIDTH * 3];
+ assign src_fmt_q = inp_pipe_src_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS];
+ assign dst_fmt_q = inp_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS];
+ wire [2:0] fmt_sign;
+ wire signed [(3 * SUPER_EXP_BITS) - 1:0] fmt_exponent;
+ wire [(3 * SUPER_MAN_BITS) - 1:0] fmt_mantissa;
+ wire [23:0] info_q;
+ localparam [0:0] fpnew_pkg_DONT_CARE = 1'b1;
+ generate
+ genvar fmt;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : fmt_init_inputs
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_3AA4D;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_3AA4D = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_3AA4D(fmt));
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(sv2v_cast_3AA4D(fmt));
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(sv2v_cast_3AA4D(fmt));
+ if (FpFmtConfig[fmt]) begin : active_format
+ wire [(3 * FP_WIDTH) - 1:0] trimmed_ops;
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_3AA4D;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_3AA4D = inp;
+ endfunction
+ fpnew_classifier #(
+ .FpFormat(sv2v_cast_3AA4D(fmt)),
+ .NumOperands(3)
+ ) i_fpnew_classifier(
+ .operands_i(trimmed_ops),
+ .is_boxed_i(inp_pipe_is_boxed_q[((0 >= NUM_INP_REGS ? (1 - NUM_INP_REGS) + (NUM_INP_REGS - 1) : NUM_INP_REGS) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS : 0) ? ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * NUM_FORMATS) + fmt : (0 >= NUM_INP_REGS ? NUM_INP_REGS * NUM_FORMATS : 0) - ((((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * NUM_FORMATS) + fmt) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * NUM_FORMATS) + ((NUM_INP_REGS * NUM_FORMATS) - 1) : ((NUM_INP_REGS + 1) * NUM_FORMATS) - 1))) * 3+:3]),
+ .info_o(info_q[8 * (fmt * 3)+:24])
+ );
+ genvar op;
+ for (op = 0; op < 3; op = op + 1) begin : gen_operands
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ assign trimmed_ops[op * sv2v_cast_32(fpnew_pkg_fp_width(sv2v_cast_3AA4D(fmt)))+:sv2v_cast_32(fpnew_pkg_fp_width(sv2v_cast_3AA4D(fmt)))] = operands_q[(op * WIDTH) + (FP_WIDTH - 1)-:FP_WIDTH];
+ assign fmt_sign[(fmt * 3) + op] = operands_q[(op * WIDTH) + (FP_WIDTH - 1)];
+ assign fmt_exponent[((fmt * 3) + op) * SUPER_EXP_BITS+:SUPER_EXP_BITS] = $signed({1'b0, operands_q[(op * WIDTH) + MAN_BITS+:EXP_BITS]});
+ assign fmt_mantissa[((fmt * 3) + op) * SUPER_MAN_BITS+:SUPER_MAN_BITS] = {info_q[(((fmt * 3) + op) * 8) + 7], operands_q[(op * WIDTH) + (MAN_BITS - 1)-:MAN_BITS]} << (SUPER_MAN_BITS - MAN_BITS);
+ end
+ end
+ else begin : inactive_format
+ function automatic [7:0] sv2v_cast_8;
+ input reg [7:0] inp;
+ sv2v_cast_8 = inp;
+ endfunction
+ assign info_q[8 * (fmt * 3)+:24] = {3 {sv2v_cast_8(fpnew_pkg_DONT_CARE)}};
+ assign fmt_sign[fmt * 3+:3] = fpnew_pkg_DONT_CARE;
+ function automatic signed [SUPER_EXP_BITS - 1:0] sv2v_cast_153A8_signed;
+ input reg signed [SUPER_EXP_BITS - 1:0] inp;
+ sv2v_cast_153A8_signed = inp;
+ endfunction
+ assign fmt_exponent[SUPER_EXP_BITS * (fmt * 3)+:SUPER_EXP_BITS * 3] = {3 {sv2v_cast_153A8_signed(fpnew_pkg_DONT_CARE)}};
+ function automatic [SUPER_MAN_BITS - 1:0] sv2v_cast_C630A;
+ input reg [SUPER_MAN_BITS - 1:0] inp;
+ sv2v_cast_C630A = inp;
+ endfunction
+ assign fmt_mantissa[SUPER_MAN_BITS * (fmt * 3)+:SUPER_MAN_BITS * 3] = {3 {sv2v_cast_C630A(fpnew_pkg_DONT_CARE)}};
+ end
+ end
+ endgenerate
+ reg [((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS) - 1:0] operand_a;
+ reg [((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS) - 1:0] operand_b;
+ reg [((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS) - 1:0] operand_c;
+ reg [7:0] info_a;
+ reg [7:0] info_b;
+ reg [7:0] info_c;
+ function automatic [31:0] fpnew_pkg_bias;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_bias = $unsigned((2 ** (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] - 1)) - 1);
+ endfunction
+ localparam [3:0] fpnew_pkg_ADD = 2;
+ localparam [3:0] fpnew_pkg_FMADD = 0;
+ localparam [3:0] fpnew_pkg_FNMSUB = 1;
+ localparam [3:0] fpnew_pkg_MUL = 3;
+ function automatic [SUPER_EXP_BITS - 1:0] sv2v_cast_153A8;
+ input reg [SUPER_EXP_BITS - 1:0] inp;
+ sv2v_cast_153A8 = inp;
+ endfunction
+ function automatic [SUPER_MAN_BITS - 1:0] sv2v_cast_C630A;
+ input reg [SUPER_MAN_BITS - 1:0] inp;
+ sv2v_cast_C630A = inp;
+ endfunction
+ always @(*) begin : op_select
+ operand_a = {fmt_sign[src_fmt_q * 3], fmt_exponent[(src_fmt_q * 3) * SUPER_EXP_BITS+:SUPER_EXP_BITS], fmt_mantissa[(src_fmt_q * 3) * SUPER_MAN_BITS+:SUPER_MAN_BITS]};
+ operand_b = {fmt_sign[(src_fmt_q * 3) + 1], fmt_exponent[((src_fmt_q * 3) + 1) * SUPER_EXP_BITS+:SUPER_EXP_BITS], fmt_mantissa[((src_fmt_q * 3) + 1) * SUPER_MAN_BITS+:SUPER_MAN_BITS]};
+ operand_c = {fmt_sign[(dst_fmt_q * 3) + 2], fmt_exponent[((dst_fmt_q * 3) + 2) * SUPER_EXP_BITS+:SUPER_EXP_BITS], fmt_mantissa[((dst_fmt_q * 3) + 2) * SUPER_MAN_BITS+:SUPER_MAN_BITS]};
+ info_a = info_q[(src_fmt_q * 3) * 8+:8];
+ info_b = info_q[((src_fmt_q * 3) + 1) * 8+:8];
+ info_c = info_q[((dst_fmt_q * 3) + 2) * 8+:8];
+ operand_c[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))] = operand_c[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))] ^ inp_pipe_op_mod_q[NUM_INP_REGS];
+ case (inp_pipe_op_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS])
+ fpnew_pkg_FMADD:
+ ;
+ fpnew_pkg_FNMSUB: operand_a[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))] = ~operand_a[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))];
+ fpnew_pkg_ADD: begin
+ operand_a = {1'b0, sv2v_cast_153A8(fpnew_pkg_bias(src_fmt_q)), sv2v_cast_C630A(1'sb0)};
+ info_a = 8'b10000001;
+ end
+ fpnew_pkg_MUL: begin
+ operand_c = {1'b1, sv2v_cast_153A8(1'sb0), sv2v_cast_C630A(1'sb0)};
+ info_c = 8'b00100001;
+ end
+ default: begin
+ operand_a = {fpnew_pkg_DONT_CARE, sv2v_cast_153A8(fpnew_pkg_DONT_CARE), sv2v_cast_C630A(fpnew_pkg_DONT_CARE)};
+ operand_b = {fpnew_pkg_DONT_CARE, sv2v_cast_153A8(fpnew_pkg_DONT_CARE), sv2v_cast_C630A(fpnew_pkg_DONT_CARE)};
+ operand_c = {fpnew_pkg_DONT_CARE, sv2v_cast_153A8(fpnew_pkg_DONT_CARE), sv2v_cast_C630A(fpnew_pkg_DONT_CARE)};
+ info_a = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ info_b = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ info_c = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ end
+ endcase
+ end
+ wire any_operand_inf;
+ wire any_operand_nan;
+ wire signalling_nan;
+ wire effective_subtraction;
+ wire tentative_sign;
+ assign any_operand_inf = |{info_a[4], info_b[4], info_c[4]};
+ assign any_operand_nan = |{info_a[3], info_b[3], info_c[3]};
+ assign signalling_nan = |{info_a[2], info_b[2], info_c[2]};
+ assign effective_subtraction = (operand_a[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))] ^ operand_b[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))]) ^ operand_c[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))];
+ assign tentative_sign = operand_a[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))] ^ operand_b[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))];
+ wire [WIDTH - 1:0] special_result;
+ wire [4:0] special_status;
+ wire result_is_special;
+ reg [(NUM_FORMATS * WIDTH) - 1:0] fmt_special_result;
+ reg [4:0] fmt_special_status;
+ reg [0:0] fmt_result_is_special;
+ generate
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : gen_special_results
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_3AA4D;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_3AA4D = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_3AA4D(fmt));
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(sv2v_cast_3AA4D(fmt));
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(sv2v_cast_3AA4D(fmt));
+ localparam [EXP_BITS - 1:0] QNAN_EXPONENT = 1'sb1;
+ localparam [MAN_BITS - 1:0] QNAN_MANTISSA = 2 ** (MAN_BITS - 1);
+ localparam [MAN_BITS - 1:0] ZERO_MANTISSA = 1'sb0;
+ if (FpFmtConfig[fmt]) begin : active_format
+ always @(*) begin : special_results
+ reg [FP_WIDTH - 1:0] special_res;
+ special_res = {1'b0, QNAN_EXPONENT, QNAN_MANTISSA};
+ fmt_special_status[fmt * 5+:5] = {5 {1'sb0}};
+ fmt_result_is_special[fmt] = 1'b0;
+ if ((info_a[4] && info_b[5]) || (info_a[5] && info_b[4])) begin
+ fmt_result_is_special[fmt] = 1'b1;
+ fmt_special_status[(fmt * 5) + 4] = 1'b1;
+ end
+ else if (any_operand_nan) begin
+ fmt_result_is_special[fmt] = 1'b1;
+ fmt_special_status[(fmt * 5) + 4] = signalling_nan;
+ end
+ else if (any_operand_inf) begin
+ fmt_result_is_special[fmt] = 1'b1;
+ if (((info_a[4] || info_b[4]) && info_c[4]) && effective_subtraction)
+ fmt_special_status[(fmt * 5) + 4] = 1'b1;
+ else if (info_a[4] || info_b[4])
+ special_res = {operand_a[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))] ^ operand_b[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))], QNAN_EXPONENT, ZERO_MANTISSA};
+ else if (info_c[4])
+ special_res = {operand_c[1 + (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))], QNAN_EXPONENT, ZERO_MANTISSA};
+ end
+ fmt_special_result[fmt * WIDTH+:WIDTH] = {WIDTH {1'sb1}};
+ fmt_special_result[(fmt * WIDTH) + (FP_WIDTH - 1)-:FP_WIDTH] = special_res;
+ end
+ end
+ else begin : inactive_format
+ wire [WIDTH:1] sv2v_tmp_2DFD8;
+ assign sv2v_tmp_2DFD8 = {WIDTH {fpnew_pkg_DONT_CARE}};
+ always @(*) fmt_special_result[fmt * WIDTH+:WIDTH] = sv2v_tmp_2DFD8;
+ wire [5:1] sv2v_tmp_1FB62;
+ assign sv2v_tmp_1FB62 = {5 {1'sb0}};
+ always @(*) fmt_special_status[fmt * 5+:5] = sv2v_tmp_1FB62;
+ wire [1:1] sv2v_tmp_7823E;
+ assign sv2v_tmp_7823E = 1'b0;
+ always @(*) fmt_result_is_special[fmt] = sv2v_tmp_7823E;
+ end
+ end
+ endgenerate
+ assign result_is_special = fmt_result_is_special[dst_fmt_q];
+ assign special_status = fmt_special_status[dst_fmt_q * 5+:5];
+ assign special_result = fmt_special_result[dst_fmt_q * WIDTH+:WIDTH];
+ wire signed [EXP_WIDTH - 1:0] exponent_a;
+ wire signed [EXP_WIDTH - 1:0] exponent_b;
+ wire signed [EXP_WIDTH - 1:0] exponent_c;
+ wire signed [EXP_WIDTH - 1:0] exponent_addend;
+ wire signed [EXP_WIDTH - 1:0] exponent_product;
+ wire signed [EXP_WIDTH - 1:0] exponent_difference;
+ wire signed [EXP_WIDTH - 1:0] tentative_exponent;
+ assign exponent_a = $signed({1'b0, operand_a[SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)-:((SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)) >= SUPER_MAN_BITS ? ((SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)) - SUPER_MAN_BITS) + 1 : (SUPER_MAN_BITS - (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))) + 1)]});
+ assign exponent_b = $signed({1'b0, operand_b[SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)-:((SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)) >= SUPER_MAN_BITS ? ((SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)) - SUPER_MAN_BITS) + 1 : (SUPER_MAN_BITS - (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))) + 1)]});
+ assign exponent_c = $signed({1'b0, operand_c[SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)-:((SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)) >= SUPER_MAN_BITS ? ((SUPER_EXP_BITS + (SUPER_MAN_BITS - 1)) - SUPER_MAN_BITS) + 1 : (SUPER_MAN_BITS - (SUPER_EXP_BITS + (SUPER_MAN_BITS - 1))) + 1)]});
+ assign exponent_addend = $signed(exponent_c + $signed({1'b0, ~info_c[7]}));
+ assign exponent_product = (info_a[5] || info_b[5] ? 2 - $signed(fpnew_pkg_bias(dst_fmt_q)) : $signed(((((exponent_a + info_a[6]) + exponent_b) + info_b[6]) - (2 * $signed(fpnew_pkg_bias(src_fmt_q)))) + $signed(fpnew_pkg_bias(dst_fmt_q))));
+ assign exponent_difference = exponent_addend - exponent_product;
+ assign tentative_exponent = (exponent_difference > 0 ? exponent_addend : exponent_product);
+ reg [SHIFT_AMOUNT_WIDTH - 1:0] addend_shamt;
+ always @(*) begin : addend_shift_amount
+ if (exponent_difference <= $signed((-2 * PRECISION_BITS) - 1))
+ addend_shamt = (3 * PRECISION_BITS) + 4;
+ else if (exponent_difference <= $signed(PRECISION_BITS + 2))
+ addend_shamt = $unsigned(($signed(PRECISION_BITS) + 3) - exponent_difference);
+ else
+ addend_shamt = 0;
+ end
+ wire [PRECISION_BITS - 1:0] mantissa_a;
+ wire [PRECISION_BITS - 1:0] mantissa_b;
+ wire [PRECISION_BITS - 1:0] mantissa_c;
+ wire [(2 * PRECISION_BITS) - 1:0] product;
+ wire [(3 * PRECISION_BITS) + 3:0] product_shifted;
+ assign mantissa_a = {info_a[7], operand_a[SUPER_MAN_BITS - 1-:SUPER_MAN_BITS]};
+ assign mantissa_b = {info_b[7], operand_b[SUPER_MAN_BITS - 1-:SUPER_MAN_BITS]};
+ assign mantissa_c = {info_c[7], operand_c[SUPER_MAN_BITS - 1-:SUPER_MAN_BITS]};
+ assign product = mantissa_a * mantissa_b;
+ assign product_shifted = product << 2;
+ wire [(3 * PRECISION_BITS) + 3:0] addend_after_shift;
+ wire [PRECISION_BITS - 1:0] addend_sticky_bits;
+ wire sticky_before_add;
+ wire [(3 * PRECISION_BITS) + 3:0] addend_shifted;
+ wire inject_carry_in;
+ assign {addend_after_shift, addend_sticky_bits} = (mantissa_c << ((3 * PRECISION_BITS) + 4)) >> addend_shamt;
+ assign sticky_before_add = |addend_sticky_bits;
+ assign addend_shifted = (effective_subtraction ? ~addend_after_shift : addend_after_shift);
+ assign inject_carry_in = effective_subtraction & ~sticky_before_add;
+ wire [(3 * PRECISION_BITS) + 4:0] sum_raw;
+ wire sum_carry;
+ wire [(3 * PRECISION_BITS) + 3:0] sum;
+ wire final_sign;
+ assign sum_raw = (product_shifted + addend_shifted) + inject_carry_in;
+ assign sum_carry = sum_raw[(3 * PRECISION_BITS) + 4];
+ assign sum = (effective_subtraction && ~sum_carry ? -sum_raw : sum_raw);
+ assign final_sign = (effective_subtraction && (sum_carry == tentative_sign) ? 1'b1 : (effective_subtraction ? 1'b0 : tentative_sign));
+ wire effective_subtraction_q;
+ wire signed [EXP_WIDTH - 1:0] exponent_product_q;
+ wire signed [EXP_WIDTH - 1:0] exponent_difference_q;
+ wire signed [EXP_WIDTH - 1:0] tentative_exponent_q;
+ wire [SHIFT_AMOUNT_WIDTH - 1:0] addend_shamt_q;
+ wire sticky_before_add_q;
+ wire [(3 * PRECISION_BITS) + 3:0] sum_q;
+ wire final_sign_q;
+ wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_q2;
+ wire [2:0] rnd_mode_q;
+ wire result_is_special_q;
+ wire [((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS) - 1:0] special_result_q;
+ wire [4:0] special_status_q;
+ wire [0:NUM_MID_REGS] mid_pipe_eff_sub_q;
+ wire signed [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * EXP_WIDTH) + ((NUM_MID_REGS * EXP_WIDTH) - 1) : ((NUM_MID_REGS + 1) * EXP_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * EXP_WIDTH : 0)] mid_pipe_exp_prod_q;
+ wire signed [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * EXP_WIDTH) + ((NUM_MID_REGS * EXP_WIDTH) - 1) : ((NUM_MID_REGS + 1) * EXP_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * EXP_WIDTH : 0)] mid_pipe_exp_diff_q;
+ wire signed [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * EXP_WIDTH) + ((NUM_MID_REGS * EXP_WIDTH) - 1) : ((NUM_MID_REGS + 1) * EXP_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * EXP_WIDTH : 0)] mid_pipe_tent_exp_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * SHIFT_AMOUNT_WIDTH) + ((NUM_MID_REGS * SHIFT_AMOUNT_WIDTH) - 1) : ((NUM_MID_REGS + 1) * SHIFT_AMOUNT_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * SHIFT_AMOUNT_WIDTH : 0)] mid_pipe_add_shamt_q;
+ wire [0:NUM_MID_REGS] mid_pipe_sticky_q;
+ wire [(0 >= NUM_MID_REGS ? (((3 * PRECISION_BITS) + 3) >= 0 ? ((1 - NUM_MID_REGS) * ((3 * PRECISION_BITS) + 4)) + ((NUM_MID_REGS * ((3 * PRECISION_BITS) + 4)) - 1) : ((1 - NUM_MID_REGS) * (1 - ((3 * PRECISION_BITS) + 3))) + ((((3 * PRECISION_BITS) + 3) + (NUM_MID_REGS * (1 - ((3 * PRECISION_BITS) + 3)))) - 1)) : (((3 * PRECISION_BITS) + 3) >= 0 ? ((NUM_MID_REGS + 1) * ((3 * PRECISION_BITS) + 4)) - 1 : ((NUM_MID_REGS + 1) * (1 - ((3 * PRECISION_BITS) + 3))) + ((3 * PRECISION_BITS) + 2))):(0 >= NUM_MID_REGS ? (((3 * PRECISION_BITS) + 3) >= 0 ? NUM_MID_REGS * ((3 * PRECISION_BITS) + 4) : ((3 * PRECISION_BITS) + 3) + (NUM_MID_REGS * (1 - ((3 * PRECISION_BITS) + 3)))) : (((3 * PRECISION_BITS) + 3) >= 0 ? 0 : (3 * PRECISION_BITS) + 3))] mid_pipe_sum_q;
+ wire [0:NUM_MID_REGS] mid_pipe_final_sign_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * 3) + ((NUM_MID_REGS * 3) - 1) : ((NUM_MID_REGS + 1) * 3) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * 3 : 0)] mid_pipe_rnd_mode_q;
+ wire [(0 >= NUM_MID_REGS ? -1 : -1):(0 >= NUM_MID_REGS ? 0 : 0)] mid_pipe_dst_fmt_q;
+ wire [0:NUM_MID_REGS] mid_pipe_res_is_spec_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * ((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS)) + ((NUM_MID_REGS * ((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS)) - 1) : ((NUM_MID_REGS + 1) * ((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS)) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * ((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS) : 0)] mid_pipe_spec_res_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * 5) + ((NUM_MID_REGS * 5) - 1) : ((NUM_MID_REGS + 1) * 5) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * 5 : 0)] mid_pipe_spec_stat_q;
+ wire [0:NUM_MID_REGS] mid_pipe_tag_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * AuxType_AUX_BITS) + ((NUM_MID_REGS * AuxType_AUX_BITS) - 1) : ((NUM_MID_REGS + 1) * AuxType_AUX_BITS) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * AuxType_AUX_BITS : 0)] mid_pipe_aux_q;
+ wire [0:NUM_MID_REGS] mid_pipe_valid_q;
+ wire [0:NUM_MID_REGS] mid_pipe_ready;
+ assign mid_pipe_eff_sub_q[0] = effective_subtraction;
+ assign mid_pipe_exp_prod_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH] = exponent_product;
+ assign mid_pipe_exp_diff_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH] = exponent_difference;
+ assign mid_pipe_tent_exp_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH] = tentative_exponent;
+ assign mid_pipe_add_shamt_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * SHIFT_AMOUNT_WIDTH+:SHIFT_AMOUNT_WIDTH] = addend_shamt;
+ assign mid_pipe_sticky_q[0] = sticky_before_add;
+ assign mid_pipe_sum_q[(((3 * PRECISION_BITS) + 3) >= 0 ? 0 : (3 * PRECISION_BITS) + 3) + ((0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * (((3 * PRECISION_BITS) + 3) >= 0 ? (3 * PRECISION_BITS) + 4 : 1 - ((3 * PRECISION_BITS) + 3)))+:(((3 * PRECISION_BITS) + 3) >= 0 ? (3 * PRECISION_BITS) + 4 : 1 - ((3 * PRECISION_BITS) + 3))] = sum;
+ assign mid_pipe_final_sign_q[0] = final_sign;
+ assign mid_pipe_rnd_mode_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * 3+:3] = inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3+:3];
+ assign mid_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS] = dst_fmt_q;
+ assign mid_pipe_res_is_spec_q[0] = result_is_special;
+ assign mid_pipe_spec_res_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * ((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS)+:(1 + SUPER_EXP_BITS) + SUPER_MAN_BITS] = special_result;
+ assign mid_pipe_spec_stat_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * 5+:5] = special_status;
+ assign mid_pipe_tag_q[0] = inp_pipe_tag_q[NUM_INP_REGS];
+ assign mid_pipe_aux_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS] = inp_pipe_aux_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS];
+ assign mid_pipe_valid_q[0] = inp_pipe_valid_q[NUM_INP_REGS];
+ assign inp_pipe_ready[NUM_INP_REGS] = mid_pipe_ready[0];
+ generate
+ for (i = 0; i < NUM_MID_REGS; i = i + 1) begin : gen_inside_pipeline
+ wire reg_ena;
+ assign mid_pipe_ready[i] = mid_pipe_ready[i + 1] | ~mid_pipe_valid_q[i + 1];
+ assign reg_ena = mid_pipe_ready[i] & mid_pipe_valid_q[i];
+ end
+ endgenerate
+ assign effective_subtraction_q = mid_pipe_eff_sub_q[NUM_MID_REGS];
+ assign exponent_product_q = mid_pipe_exp_prod_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH];
+ assign exponent_difference_q = mid_pipe_exp_diff_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH];
+ assign tentative_exponent_q = mid_pipe_tent_exp_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH];
+ assign addend_shamt_q = mid_pipe_add_shamt_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * SHIFT_AMOUNT_WIDTH+:SHIFT_AMOUNT_WIDTH];
+ assign sticky_before_add_q = mid_pipe_sticky_q[NUM_MID_REGS];
+ assign sum_q = mid_pipe_sum_q[(((3 * PRECISION_BITS) + 3) >= 0 ? 0 : (3 * PRECISION_BITS) + 3) + ((0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * (((3 * PRECISION_BITS) + 3) >= 0 ? (3 * PRECISION_BITS) + 4 : 1 - ((3 * PRECISION_BITS) + 3)))+:(((3 * PRECISION_BITS) + 3) >= 0 ? (3 * PRECISION_BITS) + 4 : 1 - ((3 * PRECISION_BITS) + 3))];
+ assign final_sign_q = mid_pipe_final_sign_q[NUM_MID_REGS];
+ assign rnd_mode_q = mid_pipe_rnd_mode_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * 3+:3];
+ assign dst_fmt_q2 = mid_pipe_dst_fmt_q[0+:fpnew_pkg_FP_FORMAT_BITS];
+ assign result_is_special_q = mid_pipe_res_is_spec_q[NUM_MID_REGS];
+ assign special_result_q = mid_pipe_spec_res_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * ((1 + SUPER_EXP_BITS) + SUPER_MAN_BITS)+:(1 + SUPER_EXP_BITS) + SUPER_MAN_BITS];
+ assign special_status_q = mid_pipe_spec_stat_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * 5+:5];
+ wire [LOWER_SUM_WIDTH - 1:0] sum_lower;
+ wire [LZC_RESULT_WIDTH - 1:0] leading_zero_count;
+ wire signed [LZC_RESULT_WIDTH:0] leading_zero_count_sgn;
+ wire lzc_zeroes;
+ reg [SHIFT_AMOUNT_WIDTH - 1:0] norm_shamt;
+ reg signed [EXP_WIDTH - 1:0] normalized_exponent;
+ wire [(3 * PRECISION_BITS) + 4:0] sum_shifted;
+ reg [PRECISION_BITS:0] final_mantissa;
+ reg [(2 * PRECISION_BITS) + 2:0] sum_sticky_bits;
+ wire sticky_after_norm;
+ reg signed [EXP_WIDTH - 1:0] final_exponent;
+ assign sum_lower = sum_q[LOWER_SUM_WIDTH - 1:0];
+ lzc #(
+ .WIDTH(LOWER_SUM_WIDTH),
+ .MODE(1)
+ ) i_lzc(
+ .in_i(sum_lower),
+ .cnt_o(leading_zero_count),
+ .empty_o(lzc_zeroes)
+ );
+ assign leading_zero_count_sgn = $signed({1'b0, leading_zero_count});
+ always @(*) begin : norm_shift_amount
+ if ((exponent_difference_q <= 0) || (effective_subtraction_q && (exponent_difference_q <= 2))) begin
+ if ((((exponent_product_q - leading_zero_count_sgn) + 1) >= 0) && !lzc_zeroes) begin
+ norm_shamt = (PRECISION_BITS + 2) + leading_zero_count;
+ normalized_exponent = (exponent_product_q - leading_zero_count_sgn) + 1;
+ end
+ else begin
+ norm_shamt = $unsigned($signed((PRECISION_BITS + 2) + exponent_product_q));
+ normalized_exponent = 0;
+ end
+ end
+ else begin
+ norm_shamt = addend_shamt_q;
+ normalized_exponent = tentative_exponent_q;
+ end
+ end
+ assign sum_shifted = sum_q << norm_shamt;
+ always @(*) begin : small_norm
+ {final_mantissa, sum_sticky_bits} = sum_shifted;
+ final_exponent = normalized_exponent;
+ if (sum_shifted[(3 * PRECISION_BITS) + 4]) begin
+ {final_mantissa, sum_sticky_bits} = sum_shifted >> 1;
+ final_exponent = normalized_exponent + 1;
+ end
+ else if (sum_shifted[(3 * PRECISION_BITS) + 3])
+ ;
+ else if (normalized_exponent > 1) begin
+ {final_mantissa, sum_sticky_bits} = sum_shifted << 1;
+ final_exponent = normalized_exponent - 1;
+ end
+ else
+ final_exponent = {EXP_WIDTH {1'sb0}};
+ end
+ assign sticky_after_norm = |{sum_sticky_bits} | sticky_before_add_q;
+ wire pre_round_sign;
+ wire [(SUPER_EXP_BITS + SUPER_MAN_BITS) - 1:0] pre_round_abs;
+ wire [1:0] round_sticky_bits;
+ wire of_before_round;
+ wire of_after_round;
+ wire uf_before_round;
+ wire uf_after_round;
+ wire [(NUM_FORMATS * (SUPER_EXP_BITS + SUPER_MAN_BITS)) - 1:0] fmt_pre_round_abs;
+ wire [1:0] fmt_round_sticky_bits;
+ reg [0:0] fmt_of_after_round;
+ reg [0:0] fmt_uf_after_round;
+ wire rounded_sign;
+ wire [(SUPER_EXP_BITS + SUPER_MAN_BITS) - 1:0] rounded_abs;
+ wire result_zero;
+ assign of_before_round = final_exponent >= ((2 ** fpnew_pkg_exp_bits(dst_fmt_q2)) - 1);
+ assign uf_before_round = final_exponent == 0;
+ generate
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : gen_res_assemble
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_3AA4D;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_3AA4D = inp;
+ endfunction
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(sv2v_cast_3AA4D(fmt));
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(sv2v_cast_3AA4D(fmt));
+ wire [EXP_BITS - 1:0] pre_round_exponent;
+ wire [MAN_BITS - 1:0] pre_round_mantissa;
+ if (FpFmtConfig[fmt]) begin : active_format
+ assign pre_round_exponent = (of_before_round ? (2 ** EXP_BITS) - 2 : final_exponent[EXP_BITS - 1:0]);
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ assign pre_round_mantissa = (of_before_round ? {sv2v_cast_32(fpnew_pkg_man_bits(sv2v_cast_3AA4D(fmt))) {1'sb1}} : final_mantissa[SUPER_MAN_BITS-:MAN_BITS]);
+ assign fmt_pre_round_abs[fmt * (SUPER_EXP_BITS + SUPER_MAN_BITS)+:SUPER_EXP_BITS + SUPER_MAN_BITS] = {pre_round_exponent, pre_round_mantissa};
+ assign fmt_round_sticky_bits[(fmt * 2) + 1] = final_mantissa[SUPER_MAN_BITS - MAN_BITS] | of_before_round;
+ if (MAN_BITS < SUPER_MAN_BITS) begin : narrow_sticky
+ assign fmt_round_sticky_bits[fmt * 2] = (|final_mantissa[(SUPER_MAN_BITS - MAN_BITS) - 1:0] | sticky_after_norm) | of_before_round;
+ end
+ else begin : normal_sticky
+ assign fmt_round_sticky_bits[fmt * 2] = sticky_after_norm | of_before_round;
+ end
+ end
+ else begin : inactive_format
+ assign fmt_pre_round_abs[fmt * (SUPER_EXP_BITS + SUPER_MAN_BITS)+:SUPER_EXP_BITS + SUPER_MAN_BITS] = {SUPER_EXP_BITS + SUPER_MAN_BITS {fpnew_pkg_DONT_CARE}};
+ assign fmt_round_sticky_bits[fmt * 2+:2] = {2 {fpnew_pkg_DONT_CARE}};
+ end
+ end
+ endgenerate
+ assign pre_round_sign = final_sign_q;
+ assign pre_round_abs = fmt_pre_round_abs[dst_fmt_q2 * (SUPER_EXP_BITS + SUPER_MAN_BITS)+:SUPER_EXP_BITS + SUPER_MAN_BITS];
+ assign round_sticky_bits = fmt_round_sticky_bits[dst_fmt_q2 * 2+:2];
+ fpnew_rounding #(.AbsWidth(SUPER_EXP_BITS + SUPER_MAN_BITS)) i_fpnew_rounding(
+ .abs_value_i(pre_round_abs),
+ .sign_i(pre_round_sign),
+ .round_sticky_bits_i(round_sticky_bits),
+ .rnd_mode_i(rnd_mode_q),
+ .effective_subtraction_i(effective_subtraction_q),
+ .abs_rounded_o(rounded_abs),
+ .sign_o(rounded_sign),
+ .exact_zero_o(result_zero)
+ );
+ reg [(NUM_FORMATS * WIDTH) - 1:0] fmt_result;
+ generate
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : gen_sign_inject
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_3AA4D;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_3AA4D = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_3AA4D(fmt));
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(sv2v_cast_3AA4D(fmt));
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(sv2v_cast_3AA4D(fmt));
+ if (FpFmtConfig[fmt]) begin : active_format
+ always @(*) begin : post_process
+ fmt_uf_after_round[fmt] = rounded_abs[(EXP_BITS + MAN_BITS) - 1:MAN_BITS] == {(((EXP_BITS + MAN_BITS) - 1) >= MAN_BITS ? (((EXP_BITS + MAN_BITS) - 1) - MAN_BITS) + 1 : (MAN_BITS - ((EXP_BITS + MAN_BITS) - 1)) + 1) {1'sb0}};
+ fmt_of_after_round[fmt] = rounded_abs[(EXP_BITS + MAN_BITS) - 1:MAN_BITS] == {(((EXP_BITS + MAN_BITS) - 1) >= MAN_BITS ? (((EXP_BITS + MAN_BITS) - 1) - MAN_BITS) + 1 : (MAN_BITS - ((EXP_BITS + MAN_BITS) - 1)) + 1) {1'sb1}};
+ fmt_result[fmt * WIDTH+:WIDTH] = {WIDTH {1'sb1}};
+ fmt_result[(fmt * WIDTH) + (FP_WIDTH - 1)-:FP_WIDTH] = {rounded_sign, rounded_abs[(EXP_BITS + MAN_BITS) - 1:0]};
+ end
+ end
+ else begin : inactive_format
+ wire [1:1] sv2v_tmp_78FCE;
+ assign sv2v_tmp_78FCE = fpnew_pkg_DONT_CARE;
+ always @(*) fmt_uf_after_round[fmt] = sv2v_tmp_78FCE;
+ wire [1:1] sv2v_tmp_C5A3B;
+ assign sv2v_tmp_C5A3B = fpnew_pkg_DONT_CARE;
+ always @(*) fmt_of_after_round[fmt] = sv2v_tmp_C5A3B;
+ wire [WIDTH:1] sv2v_tmp_E2871;
+ assign sv2v_tmp_E2871 = {WIDTH {fpnew_pkg_DONT_CARE}};
+ always @(*) fmt_result[fmt * WIDTH+:WIDTH] = sv2v_tmp_E2871;
+ end
+ end
+ endgenerate
+ assign uf_after_round = fmt_uf_after_round[dst_fmt_q2];
+ assign of_after_round = fmt_of_after_round[dst_fmt_q2];
+ wire [WIDTH - 1:0] regular_result;
+ wire [4:0] regular_status;
+ assign regular_result = fmt_result[dst_fmt_q2 * WIDTH+:WIDTH];
+ assign regular_status[4] = 1'b0;
+ assign regular_status[3] = 1'b0;
+ assign regular_status[2] = of_before_round | of_after_round;
+ assign regular_status[1] = uf_after_round & regular_status[0];
+ assign regular_status[0] = (|round_sticky_bits | of_before_round) | of_after_round;
+ wire [WIDTH - 1:0] result_d;
+ wire [4:0] status_d;
+ assign result_d = (result_is_special_q ? special_result_q : regular_result);
+ assign status_d = (result_is_special_q ? special_status_q : regular_status);
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * WIDTH) + ((NUM_OUT_REGS * WIDTH) - 1) : ((NUM_OUT_REGS + 1) * WIDTH) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * WIDTH : 0)] out_pipe_result_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * 5) + ((NUM_OUT_REGS * 5) - 1) : ((NUM_OUT_REGS + 1) * 5) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * 5 : 0)] out_pipe_status_q;
+ wire [0:NUM_OUT_REGS] out_pipe_tag_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * AuxType_AUX_BITS) + ((NUM_OUT_REGS * AuxType_AUX_BITS) - 1) : ((NUM_OUT_REGS + 1) * AuxType_AUX_BITS) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * AuxType_AUX_BITS : 0)] out_pipe_aux_q;
+ wire [0:NUM_OUT_REGS] out_pipe_valid_q;
+ wire [0:NUM_OUT_REGS] out_pipe_ready;
+ assign out_pipe_result_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * WIDTH+:WIDTH] = result_d;
+ assign out_pipe_status_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * 5+:5] = status_d;
+ assign out_pipe_tag_q[0] = mid_pipe_tag_q[NUM_MID_REGS];
+ assign out_pipe_aux_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS] = mid_pipe_aux_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS];
+ assign out_pipe_valid_q[0] = mid_pipe_valid_q[NUM_MID_REGS];
+ assign mid_pipe_ready[NUM_MID_REGS] = out_pipe_ready[0];
+ generate
+ for (i = 0; i < NUM_OUT_REGS; i = i + 1) begin : gen_output_pipeline
+ wire reg_ena;
+ assign out_pipe_ready[i] = out_pipe_ready[i + 1] | ~out_pipe_valid_q[i + 1];
+ assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
+ end
+ endgenerate
+ assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
+ assign result_o = out_pipe_result_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * WIDTH+:WIDTH];
+ assign status_o = out_pipe_status_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * 5+:5];
+ assign extension_bit_o = 1'b1;
+ assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
+ assign aux_o = out_pipe_aux_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * AuxType_AUX_BITS+:AuxType_AUX_BITS];
+ assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
+ assign busy_o = |{inp_pipe_valid_q, mid_pipe_valid_q, out_pipe_valid_q};
+endmodule
+module fpnew_fma_B2D03 (
+ clk_i,
+ rst_ni,
+ operands_i,
+ is_boxed_i,
+ rnd_mode_i,
+ op_i,
+ op_mod_i,
+ tag_i,
+ aux_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ extension_bit_o,
+ tag_o,
+ aux_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_1ED13;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_1ED13 = inp;
+ endfunction
+ parameter [fpnew_pkg_FP_FORMAT_BITS - 1:0] FpFormat = sv2v_cast_1ED13(0);
+ parameter [31:0] NumPipeRegs = 0;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ parameter [1:0] PipeConfig = fpnew_pkg_BEFORE;
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ localparam [31:0] WIDTH = fpnew_pkg_fp_width(FpFormat);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(3 * WIDTH) - 1:0] operands_i;
+ input wire [2:0] is_boxed_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire op_mod_i;
+ input wire tag_i;
+ input wire aux_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [WIDTH - 1:0] result_o;
+ output wire [4:0] status_o;
+ output wire extension_bit_o;
+ output wire tag_o;
+ output wire aux_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ function automatic [31:0] fpnew_pkg_exp_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_exp_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32];
+ endfunction
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(FpFormat);
+ function automatic [31:0] fpnew_pkg_man_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_man_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32];
+ endfunction
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(FpFormat);
+ function automatic [31:0] fpnew_pkg_bias;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_bias = $unsigned((2 ** (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] - 1)) - 1);
+ endfunction
+ localparam [31:0] BIAS = fpnew_pkg_bias(FpFormat);
+ localparam [31:0] PRECISION_BITS = MAN_BITS + 1;
+ localparam [31:0] LOWER_SUM_WIDTH = (2 * PRECISION_BITS) + 3;
+ localparam [31:0] LZC_RESULT_WIDTH = $clog2(LOWER_SUM_WIDTH);
+ function automatic signed [31:0] fpnew_pkg_maximum;
+ input reg signed [31:0] a;
+ input reg signed [31:0] b;
+ fpnew_pkg_maximum = (a > b ? a : b);
+ endfunction
+ localparam [31:0] EXP_WIDTH = $unsigned(fpnew_pkg_maximum(EXP_BITS + 2, LZC_RESULT_WIDTH));
+ localparam [31:0] SHIFT_AMOUNT_WIDTH = $clog2((3 * PRECISION_BITS) + 3);
+ localparam [1:0] fpnew_pkg_DISTRIBUTED = 3;
+ localparam NUM_INP_REGS = (PipeConfig == fpnew_pkg_BEFORE ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? (NumPipeRegs + 1) / 3 : 0));
+ localparam [1:0] fpnew_pkg_INSIDE = 2;
+ localparam NUM_MID_REGS = (PipeConfig == fpnew_pkg_INSIDE ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? (NumPipeRegs + 2) / 3 : 0));
+ localparam [1:0] fpnew_pkg_AFTER = 1;
+ localparam NUM_OUT_REGS = (PipeConfig == fpnew_pkg_AFTER ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? NumPipeRegs / 3 : 0));
+ wire [((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? ((((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) - (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0)) + 1) * WIDTH) + (((0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) * WIDTH) - 1) : ((((0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1)) + 1) * WIDTH) + (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) * WIDTH) - 1)):((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) * WIDTH : (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) * WIDTH)] inp_pipe_operands_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0)] inp_pipe_is_boxed_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0)] inp_pipe_rnd_mode_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * fpnew_pkg_OP_BITS) + ((NUM_INP_REGS * fpnew_pkg_OP_BITS) - 1) : ((NUM_INP_REGS + 1) * fpnew_pkg_OP_BITS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * fpnew_pkg_OP_BITS : 0)] inp_pipe_op_q;
+ wire [0:NUM_INP_REGS] inp_pipe_op_mod_q;
+ wire [0:NUM_INP_REGS] inp_pipe_tag_q;
+ wire [0:NUM_INP_REGS] inp_pipe_aux_q;
+ wire [0:NUM_INP_REGS] inp_pipe_valid_q;
+ wire [0:NUM_INP_REGS] inp_pipe_ready;
+ assign inp_pipe_operands_q[WIDTH * ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3 : ((0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3) + 2) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3 : ((0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3) + 2) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1)))+:WIDTH * 3] = operands_i;
+ assign inp_pipe_is_boxed_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3+:3] = is_boxed_i;
+ assign inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3+:3] = rnd_mode_i;
+ assign inp_pipe_op_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS] = op_i;
+ assign inp_pipe_op_mod_q[0] = op_mod_i;
+ assign inp_pipe_tag_q[0] = tag_i;
+ assign inp_pipe_aux_q[0] = aux_i;
+ assign inp_pipe_valid_q[0] = in_valid_i;
+ assign in_ready_o = inp_pipe_ready[0];
+ generate
+ genvar i;
+ for (i = 0; i < NUM_INP_REGS; i = i + 1) begin : gen_input_pipeline
+ wire reg_ena;
+ assign inp_pipe_ready[i] = inp_pipe_ready[i + 1] | ~inp_pipe_valid_q[i + 1];
+ assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
+ end
+ endgenerate
+ wire [23:0] info_q;
+ fpnew_classifier #(
+ .FpFormat(FpFormat),
+ .NumOperands(3)
+ ) i_class_inputs(
+ .operands_i(inp_pipe_operands_q[WIDTH * ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3 : ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) + 2) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3 : ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) + 2) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1)))+:WIDTH * 3]),
+ .is_boxed_i(inp_pipe_is_boxed_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3+:3]),
+ .info_o(info_q)
+ );
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] operand_a;
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] operand_b;
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] operand_c;
+ reg [7:0] info_a;
+ reg [7:0] info_b;
+ reg [7:0] info_c;
+ localparam [0:0] fpnew_pkg_DONT_CARE = 1'b1;
+ localparam [3:0] fpnew_pkg_ADD = 2;
+ localparam [3:0] fpnew_pkg_FMADD = 0;
+ localparam [3:0] fpnew_pkg_FNMSUB = 1;
+ localparam [3:0] fpnew_pkg_MUL = 3;
+ function automatic [EXP_BITS - 1:0] sv2v_cast_93512;
+ input reg [EXP_BITS - 1:0] inp;
+ sv2v_cast_93512 = inp;
+ endfunction
+ function automatic [MAN_BITS - 1:0] sv2v_cast_2A6A2;
+ input reg [MAN_BITS - 1:0] inp;
+ sv2v_cast_2A6A2 = inp;
+ endfunction
+ always @(*) begin : op_select
+ operand_a = inp_pipe_operands_q[((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3 : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - (((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1))) * WIDTH+:WIDTH];
+ operand_b = inp_pipe_operands_q[((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) + 1 : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - ((((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) + 1) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1))) * WIDTH+:WIDTH];
+ operand_c = inp_pipe_operands_q[((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) ? ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) + 2 : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0) - ((((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3) + 2) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1))) * WIDTH+:WIDTH];
+ info_a = info_q[0+:8];
+ info_b = info_q[8+:8];
+ info_c = info_q[16+:8];
+ operand_c[1 + (EXP_BITS + (MAN_BITS - 1))] = operand_c[1 + (EXP_BITS + (MAN_BITS - 1))] ^ inp_pipe_op_mod_q[NUM_INP_REGS];
+ case (inp_pipe_op_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS])
+ fpnew_pkg_FMADD:
+ ;
+ fpnew_pkg_FNMSUB: operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] = ~operand_a[1 + (EXP_BITS + (MAN_BITS - 1))];
+ fpnew_pkg_ADD: begin
+ operand_a = {1'b0, sv2v_cast_93512(BIAS), sv2v_cast_2A6A2(1'sb0)};
+ info_a = 8'b10000001;
+ end
+ fpnew_pkg_MUL: begin
+ operand_c = {1'b1, sv2v_cast_93512(1'sb0), sv2v_cast_2A6A2(1'sb0)};
+ info_c = 8'b00100001;
+ end
+ default: begin
+ operand_a = {fpnew_pkg_DONT_CARE, sv2v_cast_93512(fpnew_pkg_DONT_CARE), sv2v_cast_2A6A2(fpnew_pkg_DONT_CARE)};
+ operand_b = {fpnew_pkg_DONT_CARE, sv2v_cast_93512(fpnew_pkg_DONT_CARE), sv2v_cast_2A6A2(fpnew_pkg_DONT_CARE)};
+ operand_c = {fpnew_pkg_DONT_CARE, sv2v_cast_93512(fpnew_pkg_DONT_CARE), sv2v_cast_2A6A2(fpnew_pkg_DONT_CARE)};
+ info_a = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ info_b = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ info_c = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ end
+ endcase
+ end
+ wire any_operand_inf;
+ wire any_operand_nan;
+ wire signalling_nan;
+ wire effective_subtraction;
+ wire tentative_sign;
+ assign any_operand_inf = |{info_a[4], info_b[4], info_c[4]};
+ assign any_operand_nan = |{info_a[3], info_b[3], info_c[3]};
+ assign signalling_nan = |{info_a[2], info_b[2], info_c[2]};
+ assign effective_subtraction = (operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] ^ operand_b[1 + (EXP_BITS + (MAN_BITS - 1))]) ^ operand_c[1 + (EXP_BITS + (MAN_BITS - 1))];
+ assign tentative_sign = operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] ^ operand_b[1 + (EXP_BITS + (MAN_BITS - 1))];
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] special_result;
+ reg [4:0] special_status;
+ reg result_is_special;
+ always @(*) begin : special_cases
+ special_result = {1'b0, sv2v_cast_93512(1'sb1), sv2v_cast_2A6A2(2 ** (MAN_BITS - 1))};
+ special_status = {5 {1'sb0}};
+ result_is_special = 1'b0;
+ if ((info_a[4] && info_b[5]) || (info_a[5] && info_b[4])) begin
+ result_is_special = 1'b1;
+ special_status[4] = 1'b1;
+ end
+ else if (any_operand_nan) begin
+ result_is_special = 1'b1;
+ special_status[4] = signalling_nan;
+ end
+ else if (any_operand_inf) begin
+ result_is_special = 1'b1;
+ if (((info_a[4] || info_b[4]) && info_c[4]) && effective_subtraction)
+ special_status[4] = 1'b1;
+ else if (info_a[4] || info_b[4])
+ special_result = {operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] ^ operand_b[1 + (EXP_BITS + (MAN_BITS - 1))], sv2v_cast_93512(1'sb1), sv2v_cast_2A6A2(1'sb0)};
+ else if (info_c[4])
+ special_result = {operand_c[1 + (EXP_BITS + (MAN_BITS - 1))], sv2v_cast_93512(1'sb1), sv2v_cast_2A6A2(1'sb0)};
+ end
+ end
+ wire signed [EXP_WIDTH - 1:0] exponent_a;
+ wire signed [EXP_WIDTH - 1:0] exponent_b;
+ wire signed [EXP_WIDTH - 1:0] exponent_c;
+ wire signed [EXP_WIDTH - 1:0] exponent_addend;
+ wire signed [EXP_WIDTH - 1:0] exponent_product;
+ wire signed [EXP_WIDTH - 1:0] exponent_difference;
+ wire signed [EXP_WIDTH - 1:0] tentative_exponent;
+ assign exponent_a = $signed({1'b0, operand_a[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)]});
+ assign exponent_b = $signed({1'b0, operand_b[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)]});
+ assign exponent_c = $signed({1'b0, operand_c[EXP_BITS + (MAN_BITS - 1)-:((EXP_BITS + (MAN_BITS - 1)) >= MAN_BITS ? ((EXP_BITS + (MAN_BITS - 1)) - MAN_BITS) + 1 : (MAN_BITS - (EXP_BITS + (MAN_BITS - 1))) + 1)]});
+ assign exponent_addend = $signed(exponent_c + $signed({1'b0, ~info_c[7]}));
+ assign exponent_product = (info_a[5] || info_b[5] ? 2 - $signed(BIAS) : $signed((((exponent_a + info_a[6]) + exponent_b) + info_b[6]) - $signed(BIAS)));
+ assign exponent_difference = exponent_addend - exponent_product;
+ assign tentative_exponent = (exponent_difference > 0 ? exponent_addend : exponent_product);
+ reg [SHIFT_AMOUNT_WIDTH - 1:0] addend_shamt;
+ always @(*) begin : addend_shift_amount
+ if (exponent_difference <= $signed((-2 * PRECISION_BITS) - 1))
+ addend_shamt = (3 * PRECISION_BITS) + 4;
+ else if (exponent_difference <= $signed(PRECISION_BITS + 2))
+ addend_shamt = $unsigned(($signed(PRECISION_BITS) + 3) - exponent_difference);
+ else
+ addend_shamt = 0;
+ end
+ wire [PRECISION_BITS - 1:0] mantissa_a;
+ wire [PRECISION_BITS - 1:0] mantissa_b;
+ wire [PRECISION_BITS - 1:0] mantissa_c;
+ wire [(2 * PRECISION_BITS) - 1:0] product;
+ wire [(3 * PRECISION_BITS) + 3:0] product_shifted;
+ assign mantissa_a = {info_a[7], operand_a[MAN_BITS - 1-:MAN_BITS]};
+ assign mantissa_b = {info_b[7], operand_b[MAN_BITS - 1-:MAN_BITS]};
+ assign mantissa_c = {info_c[7], operand_c[MAN_BITS - 1-:MAN_BITS]};
+ assign product = mantissa_a * mantissa_b;
+ assign product_shifted = product << 2;
+ wire [(3 * PRECISION_BITS) + 3:0] addend_after_shift;
+ wire [PRECISION_BITS - 1:0] addend_sticky_bits;
+ wire sticky_before_add;
+ wire [(3 * PRECISION_BITS) + 3:0] addend_shifted;
+ wire inject_carry_in;
+ assign {addend_after_shift, addend_sticky_bits} = (mantissa_c << ((3 * PRECISION_BITS) + 4)) >> addend_shamt;
+ assign sticky_before_add = |addend_sticky_bits;
+ assign addend_shifted = (effective_subtraction ? ~addend_after_shift : addend_after_shift);
+ assign inject_carry_in = effective_subtraction & ~sticky_before_add;
+ wire [(3 * PRECISION_BITS) + 4:0] sum_raw;
+ wire sum_carry;
+ wire [(3 * PRECISION_BITS) + 3:0] sum;
+ wire final_sign;
+ assign sum_raw = (product_shifted + addend_shifted) + inject_carry_in;
+ assign sum_carry = sum_raw[(3 * PRECISION_BITS) + 4];
+ assign sum = (effective_subtraction && ~sum_carry ? -sum_raw : sum_raw);
+ assign final_sign = (effective_subtraction && (sum_carry == tentative_sign) ? 1'b1 : (effective_subtraction ? 1'b0 : tentative_sign));
+ wire effective_subtraction_q;
+ wire signed [EXP_WIDTH - 1:0] exponent_product_q;
+ wire signed [EXP_WIDTH - 1:0] exponent_difference_q;
+ wire signed [EXP_WIDTH - 1:0] tentative_exponent_q;
+ wire [SHIFT_AMOUNT_WIDTH - 1:0] addend_shamt_q;
+ wire sticky_before_add_q;
+ wire [(3 * PRECISION_BITS) + 3:0] sum_q;
+ wire final_sign_q;
+ wire [2:0] rnd_mode_q;
+ wire result_is_special_q;
+ wire [((1 + EXP_BITS) + MAN_BITS) - 1:0] special_result_q;
+ wire [4:0] special_status_q;
+ wire [0:NUM_MID_REGS] mid_pipe_eff_sub_q;
+ wire signed [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * EXP_WIDTH) + ((NUM_MID_REGS * EXP_WIDTH) - 1) : ((NUM_MID_REGS + 1) * EXP_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * EXP_WIDTH : 0)] mid_pipe_exp_prod_q;
+ wire signed [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * EXP_WIDTH) + ((NUM_MID_REGS * EXP_WIDTH) - 1) : ((NUM_MID_REGS + 1) * EXP_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * EXP_WIDTH : 0)] mid_pipe_exp_diff_q;
+ wire signed [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * EXP_WIDTH) + ((NUM_MID_REGS * EXP_WIDTH) - 1) : ((NUM_MID_REGS + 1) * EXP_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * EXP_WIDTH : 0)] mid_pipe_tent_exp_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * SHIFT_AMOUNT_WIDTH) + ((NUM_MID_REGS * SHIFT_AMOUNT_WIDTH) - 1) : ((NUM_MID_REGS + 1) * SHIFT_AMOUNT_WIDTH) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * SHIFT_AMOUNT_WIDTH : 0)] mid_pipe_add_shamt_q;
+ wire [0:NUM_MID_REGS] mid_pipe_sticky_q;
+ wire [(0 >= NUM_MID_REGS ? (((3 * PRECISION_BITS) + 3) >= 0 ? ((1 - NUM_MID_REGS) * ((3 * PRECISION_BITS) + 4)) + ((NUM_MID_REGS * ((3 * PRECISION_BITS) + 4)) - 1) : ((1 - NUM_MID_REGS) * (1 - ((3 * PRECISION_BITS) + 3))) + ((((3 * PRECISION_BITS) + 3) + (NUM_MID_REGS * (1 - ((3 * PRECISION_BITS) + 3)))) - 1)) : (((3 * PRECISION_BITS) + 3) >= 0 ? ((NUM_MID_REGS + 1) * ((3 * PRECISION_BITS) + 4)) - 1 : ((NUM_MID_REGS + 1) * (1 - ((3 * PRECISION_BITS) + 3))) + ((3 * PRECISION_BITS) + 2))):(0 >= NUM_MID_REGS ? (((3 * PRECISION_BITS) + 3) >= 0 ? NUM_MID_REGS * ((3 * PRECISION_BITS) + 4) : ((3 * PRECISION_BITS) + 3) + (NUM_MID_REGS * (1 - ((3 * PRECISION_BITS) + 3)))) : (((3 * PRECISION_BITS) + 3) >= 0 ? 0 : (3 * PRECISION_BITS) + 3))] mid_pipe_sum_q;
+ wire [0:NUM_MID_REGS] mid_pipe_final_sign_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * 3) + ((NUM_MID_REGS * 3) - 1) : ((NUM_MID_REGS + 1) * 3) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * 3 : 0)] mid_pipe_rnd_mode_q;
+ wire [0:NUM_MID_REGS] mid_pipe_res_is_spec_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * ((1 + EXP_BITS) + MAN_BITS)) + ((NUM_MID_REGS * ((1 + EXP_BITS) + MAN_BITS)) - 1) : ((NUM_MID_REGS + 1) * ((1 + EXP_BITS) + MAN_BITS)) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * ((1 + EXP_BITS) + MAN_BITS) : 0)] mid_pipe_spec_res_q;
+ wire [(0 >= NUM_MID_REGS ? ((1 - NUM_MID_REGS) * 5) + ((NUM_MID_REGS * 5) - 1) : ((NUM_MID_REGS + 1) * 5) - 1):(0 >= NUM_MID_REGS ? NUM_MID_REGS * 5 : 0)] mid_pipe_spec_stat_q;
+ wire [0:NUM_MID_REGS] mid_pipe_tag_q;
+ wire [0:NUM_MID_REGS] mid_pipe_aux_q;
+ wire [0:NUM_MID_REGS] mid_pipe_valid_q;
+ wire [0:NUM_MID_REGS] mid_pipe_ready;
+ assign mid_pipe_eff_sub_q[0] = effective_subtraction;
+ assign mid_pipe_exp_prod_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH] = exponent_product;
+ assign mid_pipe_exp_diff_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH] = exponent_difference;
+ assign mid_pipe_tent_exp_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH] = tentative_exponent;
+ assign mid_pipe_add_shamt_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * SHIFT_AMOUNT_WIDTH+:SHIFT_AMOUNT_WIDTH] = addend_shamt;
+ assign mid_pipe_sticky_q[0] = sticky_before_add;
+ assign mid_pipe_sum_q[(((3 * PRECISION_BITS) + 3) >= 0 ? 0 : (3 * PRECISION_BITS) + 3) + ((0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * (((3 * PRECISION_BITS) + 3) >= 0 ? (3 * PRECISION_BITS) + 4 : 1 - ((3 * PRECISION_BITS) + 3)))+:(((3 * PRECISION_BITS) + 3) >= 0 ? (3 * PRECISION_BITS) + 4 : 1 - ((3 * PRECISION_BITS) + 3))] = sum;
+ assign mid_pipe_final_sign_q[0] = final_sign;
+ assign mid_pipe_rnd_mode_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * 3+:3] = inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3+:3];
+ assign mid_pipe_res_is_spec_q[0] = result_is_special;
+ assign mid_pipe_spec_res_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * ((1 + EXP_BITS) + MAN_BITS)+:(1 + EXP_BITS) + MAN_BITS] = special_result;
+ assign mid_pipe_spec_stat_q[(0 >= NUM_MID_REGS ? 0 : NUM_MID_REGS) * 5+:5] = special_status;
+ assign mid_pipe_tag_q[0] = inp_pipe_tag_q[NUM_INP_REGS];
+ assign mid_pipe_aux_q[0] = inp_pipe_aux_q[NUM_INP_REGS];
+ assign mid_pipe_valid_q[0] = inp_pipe_valid_q[NUM_INP_REGS];
+ assign inp_pipe_ready[NUM_INP_REGS] = mid_pipe_ready[0];
+ generate
+ for (i = 0; i < NUM_MID_REGS; i = i + 1) begin : gen_inside_pipeline
+ wire reg_ena;
+ assign mid_pipe_ready[i] = mid_pipe_ready[i + 1] | ~mid_pipe_valid_q[i + 1];
+ assign reg_ena = mid_pipe_ready[i] & mid_pipe_valid_q[i];
+ end
+ endgenerate
+ assign effective_subtraction_q = mid_pipe_eff_sub_q[NUM_MID_REGS];
+ assign exponent_product_q = mid_pipe_exp_prod_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH];
+ assign exponent_difference_q = mid_pipe_exp_diff_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH];
+ assign tentative_exponent_q = mid_pipe_tent_exp_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * EXP_WIDTH+:EXP_WIDTH];
+ assign addend_shamt_q = mid_pipe_add_shamt_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * SHIFT_AMOUNT_WIDTH+:SHIFT_AMOUNT_WIDTH];
+ assign sticky_before_add_q = mid_pipe_sticky_q[NUM_MID_REGS];
+ assign sum_q = mid_pipe_sum_q[(((3 * PRECISION_BITS) + 3) >= 0 ? 0 : (3 * PRECISION_BITS) + 3) + ((0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * (((3 * PRECISION_BITS) + 3) >= 0 ? (3 * PRECISION_BITS) + 4 : 1 - ((3 * PRECISION_BITS) + 3)))+:(((3 * PRECISION_BITS) + 3) >= 0 ? (3 * PRECISION_BITS) + 4 : 1 - ((3 * PRECISION_BITS) + 3))];
+ assign final_sign_q = mid_pipe_final_sign_q[NUM_MID_REGS];
+ assign rnd_mode_q = mid_pipe_rnd_mode_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * 3+:3];
+ assign result_is_special_q = mid_pipe_res_is_spec_q[NUM_MID_REGS];
+ assign special_result_q = mid_pipe_spec_res_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * ((1 + EXP_BITS) + MAN_BITS)+:(1 + EXP_BITS) + MAN_BITS];
+ assign special_status_q = mid_pipe_spec_stat_q[(0 >= NUM_MID_REGS ? NUM_MID_REGS : NUM_MID_REGS - NUM_MID_REGS) * 5+:5];
+ wire [LOWER_SUM_WIDTH - 1:0] sum_lower;
+ wire [LZC_RESULT_WIDTH - 1:0] leading_zero_count;
+ wire signed [LZC_RESULT_WIDTH:0] leading_zero_count_sgn;
+ wire lzc_zeroes;
+ reg [SHIFT_AMOUNT_WIDTH - 1:0] norm_shamt;
+ reg signed [EXP_WIDTH - 1:0] normalized_exponent;
+ wire [(3 * PRECISION_BITS) + 4:0] sum_shifted;
+ reg [PRECISION_BITS:0] final_mantissa;
+ reg [(2 * PRECISION_BITS) + 2:0] sum_sticky_bits;
+ wire sticky_after_norm;
+ reg signed [EXP_WIDTH - 1:0] final_exponent;
+ assign sum_lower = sum_q[LOWER_SUM_WIDTH - 1:0];
+ lzc #(
+ .WIDTH(LOWER_SUM_WIDTH),
+ .MODE(1)
+ ) i_lzc(
+ .in_i(sum_lower),
+ .cnt_o(leading_zero_count),
+ .empty_o(lzc_zeroes)
+ );
+ assign leading_zero_count_sgn = $signed({1'b0, leading_zero_count});
+ always @(*) begin : norm_shift_amount
+ if ((exponent_difference_q <= 0) || (effective_subtraction_q && (exponent_difference_q <= 2))) begin
+ if ((((exponent_product_q - leading_zero_count_sgn) + 1) >= 0) && !lzc_zeroes) begin
+ norm_shamt = (PRECISION_BITS + 2) + leading_zero_count;
+ normalized_exponent = (exponent_product_q - leading_zero_count_sgn) + 1;
+ end
+ else begin
+ norm_shamt = $unsigned(($signed(PRECISION_BITS) + 2) + exponent_product_q);
+ normalized_exponent = 0;
+ end
+ end
+ else begin
+ norm_shamt = addend_shamt_q;
+ normalized_exponent = tentative_exponent_q;
+ end
+ end
+ assign sum_shifted = sum_q << norm_shamt;
+ always @(*) begin : small_norm
+ {final_mantissa[23:0], sum_sticky_bits} = sum_shifted;
+ final_exponent = normalized_exponent;
+ if (sum_shifted[(3 * PRECISION_BITS) + 4]) begin
+ {final_mantissa, sum_sticky_bits} = sum_shifted >> 1;
+ final_exponent = normalized_exponent + 1;
+ end
+ else if (sum_shifted[(3 * PRECISION_BITS) + 3])
+ ;
+ else if (normalized_exponent > 1) begin
+ {final_mantissa, sum_sticky_bits} = sum_shifted << 1;
+ final_exponent = normalized_exponent - 1;
+ end
+ else
+ final_exponent = {EXP_WIDTH {1'sb0}};
+ end
+ assign sticky_after_norm = |{sum_sticky_bits} | sticky_before_add_q;
+ wire pre_round_sign;
+ wire [EXP_BITS - 1:0] pre_round_exponent;
+ wire [MAN_BITS - 1:0] pre_round_mantissa;
+ wire [(EXP_BITS + MAN_BITS) - 1:0] pre_round_abs;
+ wire [1:0] round_sticky_bits;
+ wire of_before_round;
+ wire of_after_round;
+ wire uf_before_round;
+ wire uf_after_round;
+ wire result_zero;
+ wire rounded_sign;
+ wire [(EXP_BITS + MAN_BITS) - 1:0] rounded_abs;
+ assign of_before_round = final_exponent >= ((2 ** EXP_BITS) - 1);
+ assign uf_before_round = final_exponent == 0;
+ assign pre_round_sign = final_sign_q;
+ assign pre_round_exponent = (of_before_round ? (2 ** EXP_BITS) - 2 : $unsigned(final_exponent[EXP_BITS - 1:0]));
+ assign pre_round_mantissa = (of_before_round ? {MAN_BITS {1'sb1}} : final_mantissa[MAN_BITS:1]);
+ assign pre_round_abs = {pre_round_exponent, pre_round_mantissa};
+ assign round_sticky_bits = (of_before_round ? 2'b11 : {final_mantissa[0], sticky_after_norm});
+ fpnew_rounding #(.AbsWidth(EXP_BITS + MAN_BITS)) i_fpnew_rounding(
+ .abs_value_i(pre_round_abs),
+ .sign_i(pre_round_sign),
+ .round_sticky_bits_i(round_sticky_bits),
+ .rnd_mode_i(rnd_mode_q),
+ .effective_subtraction_i(effective_subtraction_q),
+ .abs_rounded_o(rounded_abs),
+ .sign_o(rounded_sign),
+ .exact_zero_o(result_zero)
+ );
+ assign uf_after_round = rounded_abs[(EXP_BITS + MAN_BITS) - 1:MAN_BITS] == {(((EXP_BITS + MAN_BITS) - 1) >= MAN_BITS ? (((EXP_BITS + MAN_BITS) - 1) - MAN_BITS) + 1 : (MAN_BITS - ((EXP_BITS + MAN_BITS) - 1)) + 1) {1'sb0}};
+ assign of_after_round = rounded_abs[(EXP_BITS + MAN_BITS) - 1:MAN_BITS] == {(((EXP_BITS + MAN_BITS) - 1) >= MAN_BITS ? (((EXP_BITS + MAN_BITS) - 1) - MAN_BITS) + 1 : (MAN_BITS - ((EXP_BITS + MAN_BITS) - 1)) + 1) {1'sb1}};
+ wire [WIDTH - 1:0] regular_result;
+ wire [4:0] regular_status;
+ assign regular_result = {rounded_sign, rounded_abs};
+ assign regular_status[4] = 1'b0;
+ assign regular_status[3] = 1'b0;
+ assign regular_status[2] = of_before_round | of_after_round;
+ assign regular_status[1] = uf_after_round & regular_status[0];
+ assign regular_status[0] = (|round_sticky_bits | of_before_round) | of_after_round;
+ wire [((1 + EXP_BITS) + MAN_BITS) - 1:0] result_d;
+ wire [4:0] status_d;
+ assign result_d = (result_is_special_q ? special_result_q : regular_result);
+ assign status_d = (result_is_special_q ? special_status_q : regular_status);
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * ((1 + EXP_BITS) + MAN_BITS)) + ((NUM_OUT_REGS * ((1 + EXP_BITS) + MAN_BITS)) - 1) : ((NUM_OUT_REGS + 1) * ((1 + EXP_BITS) + MAN_BITS)) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * ((1 + EXP_BITS) + MAN_BITS) : 0)] out_pipe_result_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * 5) + ((NUM_OUT_REGS * 5) - 1) : ((NUM_OUT_REGS + 1) * 5) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * 5 : 0)] out_pipe_status_q;
+ wire [0:NUM_OUT_REGS] out_pipe_tag_q;
+ wire [0:NUM_OUT_REGS] out_pipe_aux_q;
+ wire [0:NUM_OUT_REGS] out_pipe_valid_q;
+ wire [0:NUM_OUT_REGS] out_pipe_ready;
+ assign out_pipe_result_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * ((1 + EXP_BITS) + MAN_BITS)+:(1 + EXP_BITS) + MAN_BITS] = result_d;
+ assign out_pipe_status_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * 5+:5] = status_d;
+ assign out_pipe_tag_q[0] = mid_pipe_tag_q[NUM_MID_REGS];
+ assign out_pipe_aux_q[0] = mid_pipe_aux_q[NUM_MID_REGS];
+ assign out_pipe_valid_q[0] = mid_pipe_valid_q[NUM_MID_REGS];
+ assign mid_pipe_ready[NUM_MID_REGS] = out_pipe_ready[0];
+ generate
+ for (i = 0; i < NUM_OUT_REGS; i = i + 1) begin : gen_output_pipeline
+ wire reg_ena;
+ assign out_pipe_ready[i] = out_pipe_ready[i + 1] | ~out_pipe_valid_q[i + 1];
+ assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
+ end
+ endgenerate
+ assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
+ assign result_o = out_pipe_result_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * ((1 + EXP_BITS) + MAN_BITS)+:(1 + EXP_BITS) + MAN_BITS];
+ assign status_o = out_pipe_status_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * 5+:5];
+ assign extension_bit_o = 1'b1;
+ assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
+ assign aux_o = out_pipe_aux_q[NUM_OUT_REGS];
+ assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
+ assign busy_o = |{inp_pipe_valid_q, mid_pipe_valid_q, out_pipe_valid_q};
+endmodule
+module fpnew_noncomp_6DFAC (
+ clk_i,
+ rst_ni,
+ operands_i,
+ is_boxed_i,
+ rnd_mode_i,
+ op_i,
+ op_mod_i,
+ tag_i,
+ aux_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ extension_bit_o,
+ class_mask_o,
+ is_class_o,
+ tag_o,
+ aux_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_F7742;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_F7742 = inp;
+ endfunction
+ parameter [fpnew_pkg_FP_FORMAT_BITS - 1:0] FpFormat = sv2v_cast_F7742(0);
+ parameter [31:0] NumPipeRegs = 0;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ parameter [1:0] PipeConfig = fpnew_pkg_BEFORE;
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ localparam [31:0] WIDTH = fpnew_pkg_fp_width(FpFormat);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(2 * WIDTH) - 1:0] operands_i;
+ input wire [1:0] is_boxed_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire op_mod_i;
+ input wire tag_i;
+ input wire aux_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [WIDTH - 1:0] result_o;
+ output wire [4:0] status_o;
+ output wire extension_bit_o;
+ output wire [9:0] class_mask_o;
+ output wire is_class_o;
+ output wire tag_o;
+ output wire aux_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ function automatic [31:0] fpnew_pkg_exp_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_exp_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32];
+ endfunction
+ localparam [31:0] EXP_BITS = fpnew_pkg_exp_bits(FpFormat);
+ function automatic [31:0] fpnew_pkg_man_bits;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_man_bits = fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32];
+ endfunction
+ localparam [31:0] MAN_BITS = fpnew_pkg_man_bits(FpFormat);
+ localparam [1:0] fpnew_pkg_DISTRIBUTED = 3;
+ localparam [1:0] fpnew_pkg_INSIDE = 2;
+ localparam NUM_INP_REGS = ((PipeConfig == fpnew_pkg_BEFORE) || (PipeConfig == fpnew_pkg_INSIDE) ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? (NumPipeRegs + 1) / 2 : 0));
+ localparam [1:0] fpnew_pkg_AFTER = 1;
+ localparam NUM_OUT_REGS = (PipeConfig == fpnew_pkg_AFTER ? NumPipeRegs : (PipeConfig == fpnew_pkg_DISTRIBUTED ? NumPipeRegs / 2 : 0));
+ wire [((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? ((((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) - (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0)) + 1) * WIDTH) + (((0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) * WIDTH) - 1) : ((((0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1)) + 1) * WIDTH) + (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) * WIDTH) - 1)):((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) * WIDTH : (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) * WIDTH)] inp_pipe_operands_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0)] inp_pipe_is_boxed_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 3) + ((NUM_INP_REGS * 3) - 1) : ((NUM_INP_REGS + 1) * 3) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * 3 : 0)] inp_pipe_rnd_mode_q;
+ wire [(0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * fpnew_pkg_OP_BITS) + ((NUM_INP_REGS * fpnew_pkg_OP_BITS) - 1) : ((NUM_INP_REGS + 1) * fpnew_pkg_OP_BITS) - 1):(0 >= NUM_INP_REGS ? NUM_INP_REGS * fpnew_pkg_OP_BITS : 0)] inp_pipe_op_q;
+ wire [0:NUM_INP_REGS] inp_pipe_op_mod_q;
+ wire [0:NUM_INP_REGS] inp_pipe_tag_q;
+ wire [0:NUM_INP_REGS] inp_pipe_aux_q;
+ wire [0:NUM_INP_REGS] inp_pipe_valid_q;
+ wire [0:NUM_INP_REGS] inp_pipe_ready;
+ assign inp_pipe_operands_q[WIDTH * ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2 : ((0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2) + 1) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) - (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2 : ((0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2) + 1) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1)))+:WIDTH * 2] = operands_i;
+ assign inp_pipe_is_boxed_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 2+:2] = is_boxed_i;
+ assign inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * 3+:3] = rnd_mode_i;
+ assign inp_pipe_op_q[(0 >= NUM_INP_REGS ? 0 : NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS] = op_i;
+ assign inp_pipe_op_mod_q[0] = op_mod_i;
+ assign inp_pipe_tag_q[0] = tag_i;
+ assign inp_pipe_aux_q[0] = aux_i;
+ assign inp_pipe_valid_q[0] = in_valid_i;
+ assign in_ready_o = inp_pipe_ready[0];
+ generate
+ genvar i;
+ for (i = 0; i < NUM_INP_REGS; i = i + 1) begin : gen_input_pipeline
+ wire reg_ena;
+ assign inp_pipe_ready[i] = inp_pipe_ready[i + 1] | ~inp_pipe_valid_q[i + 1];
+ assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
+ end
+ endgenerate
+ wire [15:0] info_q;
+ fpnew_classifier #(
+ .FpFormat(FpFormat),
+ .NumOperands(2)
+ ) i_class_a(
+ .operands_i(inp_pipe_operands_q[WIDTH * ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? ((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2 : ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2) + 1) : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) - (((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2 : ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2) + 1) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1)))+:WIDTH * 2]),
+ .is_boxed_i(inp_pipe_is_boxed_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2+:2]),
+ .info_o(info_q)
+ );
+ wire [((1 + EXP_BITS) + MAN_BITS) - 1:0] operand_a;
+ wire [((1 + EXP_BITS) + MAN_BITS) - 1:0] operand_b;
+ wire [7:0] info_a;
+ wire [7:0] info_b;
+ assign operand_a = inp_pipe_operands_q[((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? (0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2 : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) - (((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1))) * WIDTH+:WIDTH];
+ assign operand_b = inp_pipe_operands_q[((0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1) >= (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) ? ((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2) + 1 : (0 >= NUM_INP_REGS ? NUM_INP_REGS * 2 : 0) - ((((0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 2) + 1) - (0 >= NUM_INP_REGS ? ((1 - NUM_INP_REGS) * 2) + ((NUM_INP_REGS * 2) - 1) : ((NUM_INP_REGS + 1) * 2) - 1))) * WIDTH+:WIDTH];
+ assign info_a = info_q[0+:8];
+ assign info_b = info_q[8+:8];
+ wire any_operand_inf;
+ wire any_operand_nan;
+ wire signalling_nan;
+ assign any_operand_inf = |{info_a[4], info_b[4]};
+ assign any_operand_nan = |{info_a[3], info_b[3]};
+ assign signalling_nan = |{info_a[2], info_b[2]};
+ wire operands_equal;
+ wire operand_a_smaller;
+ assign operands_equal = (operand_a == operand_b) || (info_a[5] && info_b[5]);
+ assign operand_a_smaller = (operand_a < operand_b) ^ (operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] || operand_b[1 + (EXP_BITS + (MAN_BITS - 1))]);
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] sgnj_result;
+ wire [4:0] sgnj_status;
+ wire sgnj_extension_bit;
+ localparam [0:0] fpnew_pkg_DONT_CARE = 1'b1;
+ localparam [2:0] fpnew_pkg_RDN = 3'b010;
+ localparam [2:0] fpnew_pkg_RNE = 3'b000;
+ localparam [2:0] fpnew_pkg_RTZ = 3'b001;
+ localparam [2:0] fpnew_pkg_RUP = 3'b011;
+ function automatic [EXP_BITS - 1:0] sv2v_cast_92F9C;
+ input reg [EXP_BITS - 1:0] inp;
+ sv2v_cast_92F9C = inp;
+ endfunction
+ function automatic [MAN_BITS - 1:0] sv2v_cast_5145F;
+ input reg [MAN_BITS - 1:0] inp;
+ sv2v_cast_5145F = inp;
+ endfunction
+ always @(*) begin : sign_injections
+ reg sign_a;
+ reg sign_b;
+ sgnj_result = operand_a;
+ if (!info_a[0])
+ sgnj_result = {1'b0, sv2v_cast_92F9C(1'sb1), sv2v_cast_5145F(2 ** (MAN_BITS - 1))};
+ sign_a = operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] & info_a[0];
+ sign_b = operand_b[1 + (EXP_BITS + (MAN_BITS - 1))] & info_b[0];
+ case (inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3+:3])
+ fpnew_pkg_RNE: sgnj_result[1 + (EXP_BITS + (MAN_BITS - 1))] = sign_b;
+ fpnew_pkg_RTZ: sgnj_result[1 + (EXP_BITS + (MAN_BITS - 1))] = ~sign_b;
+ fpnew_pkg_RDN: sgnj_result[1 + (EXP_BITS + (MAN_BITS - 1))] = sign_a ^ sign_b;
+ fpnew_pkg_RUP: sgnj_result = operand_a;
+ default: sgnj_result = {fpnew_pkg_DONT_CARE, sv2v_cast_92F9C(fpnew_pkg_DONT_CARE), sv2v_cast_5145F(fpnew_pkg_DONT_CARE)};
+ endcase
+ end
+ assign sgnj_status = {5 {1'sb0}};
+ assign sgnj_extension_bit = (inp_pipe_op_mod_q[NUM_INP_REGS] ? sgnj_result[1 + (EXP_BITS + (MAN_BITS - 1))] : 1'b1);
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] minmax_result;
+ reg [4:0] minmax_status;
+ wire minmax_extension_bit;
+ always @(*) begin : min_max
+ minmax_status = {5 {1'sb0}};
+ minmax_status[4] = signalling_nan;
+ if (info_a[3] && info_b[3])
+ minmax_result = {1'b0, sv2v_cast_92F9C(1'sb1), sv2v_cast_5145F(2 ** (MAN_BITS - 1))};
+ else if (info_a[3])
+ minmax_result = operand_b;
+ else if (info_b[3])
+ minmax_result = operand_a;
+ else
+ case (inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3+:3])
+ fpnew_pkg_RNE: minmax_result = (operand_a_smaller ? operand_a : operand_b);
+ fpnew_pkg_RTZ: minmax_result = (operand_a_smaller ? operand_b : operand_a);
+ default: minmax_result = {fpnew_pkg_DONT_CARE, sv2v_cast_92F9C(fpnew_pkg_DONT_CARE), sv2v_cast_5145F(fpnew_pkg_DONT_CARE)};
+ endcase
+ end
+ assign minmax_extension_bit = 1'b1;
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] cmp_result;
+ reg [4:0] cmp_status;
+ wire cmp_extension_bit;
+ always @(*) begin : comparisons
+ cmp_result = {(1 + EXP_BITS) + MAN_BITS {1'sb0}};
+ cmp_status = {5 {1'sb0}};
+ if (signalling_nan)
+ cmp_status[4] = 1'b1;
+ else
+ case (inp_pipe_rnd_mode_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * 3+:3])
+ fpnew_pkg_RNE:
+ if (any_operand_nan)
+ cmp_status[4] = 1'b1;
+ else
+ cmp_result = (operand_a_smaller | operands_equal) ^ inp_pipe_op_mod_q[NUM_INP_REGS];
+ fpnew_pkg_RTZ:
+ if (any_operand_nan)
+ cmp_status[4] = 1'b1;
+ else
+ cmp_result = (operand_a_smaller & ~operands_equal) ^ inp_pipe_op_mod_q[NUM_INP_REGS];
+ fpnew_pkg_RDN:
+ if (any_operand_nan)
+ cmp_result = inp_pipe_op_mod_q[NUM_INP_REGS];
+ else
+ cmp_result = operands_equal ^ inp_pipe_op_mod_q[NUM_INP_REGS];
+ default: cmp_result = {fpnew_pkg_DONT_CARE, sv2v_cast_92F9C(fpnew_pkg_DONT_CARE), sv2v_cast_5145F(fpnew_pkg_DONT_CARE)};
+ endcase
+ end
+ assign cmp_extension_bit = 1'b0;
+ wire [4:0] class_status;
+ wire class_extension_bit;
+ reg [9:0] class_mask_d;
+ localparam [9:0] fpnew_pkg_NEGINF = 10'b0000000001;
+ localparam [9:0] fpnew_pkg_NEGNORM = 10'b0000000010;
+ localparam [9:0] fpnew_pkg_NEGSUBNORM = 10'b0000000100;
+ localparam [9:0] fpnew_pkg_NEGZERO = 10'b0000001000;
+ localparam [9:0] fpnew_pkg_POSINF = 10'b0010000000;
+ localparam [9:0] fpnew_pkg_POSNORM = 10'b0001000000;
+ localparam [9:0] fpnew_pkg_POSSUBNORM = 10'b0000100000;
+ localparam [9:0] fpnew_pkg_POSZERO = 10'b0000010000;
+ localparam [9:0] fpnew_pkg_QNAN = 10'b1000000000;
+ localparam [9:0] fpnew_pkg_SNAN = 10'b0100000000;
+ always @(*) begin : classify
+ if (info_a[7])
+ class_mask_d = (operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] ? fpnew_pkg_NEGNORM : fpnew_pkg_POSNORM);
+ else if (info_a[6])
+ class_mask_d = (operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] ? fpnew_pkg_NEGSUBNORM : fpnew_pkg_POSSUBNORM);
+ else if (info_a[5])
+ class_mask_d = (operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] ? fpnew_pkg_NEGZERO : fpnew_pkg_POSZERO);
+ else if (info_a[4])
+ class_mask_d = (operand_a[1 + (EXP_BITS + (MAN_BITS - 1))] ? fpnew_pkg_NEGINF : fpnew_pkg_POSINF);
+ else if (info_a[3])
+ class_mask_d = (info_a[2] ? fpnew_pkg_SNAN : fpnew_pkg_QNAN);
+ else
+ class_mask_d = fpnew_pkg_QNAN;
+ end
+ assign class_status = {5 {1'sb0}};
+ assign class_extension_bit = 1'b0;
+ reg [((1 + EXP_BITS) + MAN_BITS) - 1:0] result_d;
+ reg [4:0] status_d;
+ reg extension_bit_d;
+ wire is_class_d;
+ localparam [3:0] fpnew_pkg_CLASSIFY = 9;
+ localparam [3:0] fpnew_pkg_CMP = 8;
+ localparam [3:0] fpnew_pkg_MINMAX = 7;
+ localparam [3:0] fpnew_pkg_SGNJ = 6;
+ always @(*) begin : select_result
+ case (inp_pipe_op_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS])
+ fpnew_pkg_SGNJ: begin
+ result_d = sgnj_result;
+ status_d = sgnj_status;
+ extension_bit_d = sgnj_extension_bit;
+ end
+ fpnew_pkg_MINMAX: begin
+ result_d = minmax_result;
+ status_d = minmax_status;
+ extension_bit_d = minmax_extension_bit;
+ end
+ fpnew_pkg_CMP: begin
+ result_d = cmp_result;
+ status_d = cmp_status;
+ extension_bit_d = cmp_extension_bit;
+ end
+ fpnew_pkg_CLASSIFY: begin
+ result_d = {fpnew_pkg_DONT_CARE, sv2v_cast_92F9C(fpnew_pkg_DONT_CARE), sv2v_cast_5145F(fpnew_pkg_DONT_CARE)};
+ status_d = class_status;
+ extension_bit_d = class_extension_bit;
+ end
+ default: begin
+ result_d = {fpnew_pkg_DONT_CARE, sv2v_cast_92F9C(fpnew_pkg_DONT_CARE), sv2v_cast_5145F(fpnew_pkg_DONT_CARE)};
+ status_d = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ extension_bit_d = fpnew_pkg_DONT_CARE;
+ end
+ endcase
+ end
+ assign is_class_d = inp_pipe_op_q[(0 >= NUM_INP_REGS ? NUM_INP_REGS : NUM_INP_REGS - NUM_INP_REGS) * fpnew_pkg_OP_BITS+:fpnew_pkg_OP_BITS] == fpnew_pkg_CLASSIFY;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * ((1 + EXP_BITS) + MAN_BITS)) + ((NUM_OUT_REGS * ((1 + EXP_BITS) + MAN_BITS)) - 1) : ((NUM_OUT_REGS + 1) * ((1 + EXP_BITS) + MAN_BITS)) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * ((1 + EXP_BITS) + MAN_BITS) : 0)] out_pipe_result_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * 5) + ((NUM_OUT_REGS * 5) - 1) : ((NUM_OUT_REGS + 1) * 5) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * 5 : 0)] out_pipe_status_q;
+ wire [0:NUM_OUT_REGS] out_pipe_extension_bit_q;
+ wire [(0 >= NUM_OUT_REGS ? ((1 - NUM_OUT_REGS) * 10) + ((NUM_OUT_REGS * 10) - 1) : ((NUM_OUT_REGS + 1) * 10) - 1):(0 >= NUM_OUT_REGS ? NUM_OUT_REGS * 10 : 0)] out_pipe_class_mask_q;
+ wire [0:NUM_OUT_REGS] out_pipe_is_class_q;
+ wire [0:NUM_OUT_REGS] out_pipe_tag_q;
+ wire [0:NUM_OUT_REGS] out_pipe_aux_q;
+ wire [0:NUM_OUT_REGS] out_pipe_valid_q;
+ wire [0:NUM_OUT_REGS] out_pipe_ready;
+ assign out_pipe_result_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * ((1 + EXP_BITS) + MAN_BITS)+:(1 + EXP_BITS) + MAN_BITS] = result_d;
+ assign out_pipe_status_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * 5+:5] = status_d;
+ assign out_pipe_extension_bit_q[0] = extension_bit_d;
+ assign out_pipe_class_mask_q[(0 >= NUM_OUT_REGS ? 0 : NUM_OUT_REGS) * 10+:10] = class_mask_d;
+ assign out_pipe_is_class_q[0] = is_class_d;
+ assign out_pipe_tag_q[0] = inp_pipe_tag_q[NUM_INP_REGS];
+ assign out_pipe_aux_q[0] = inp_pipe_aux_q[NUM_INP_REGS];
+ assign out_pipe_valid_q[0] = inp_pipe_valid_q[NUM_INP_REGS];
+ assign inp_pipe_ready[NUM_INP_REGS] = out_pipe_ready[0];
+ generate
+ for (i = 0; i < NUM_OUT_REGS; i = i + 1) begin : gen_output_pipeline
+ wire reg_ena;
+ assign out_pipe_ready[i] = out_pipe_ready[i + 1] | ~out_pipe_valid_q[i + 1];
+ assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
+ end
+ endgenerate
+ assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
+ assign result_o = out_pipe_result_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * ((1 + EXP_BITS) + MAN_BITS)+:(1 + EXP_BITS) + MAN_BITS];
+ assign status_o = out_pipe_status_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * 5+:5];
+ assign extension_bit_o = out_pipe_extension_bit_q[NUM_OUT_REGS];
+ assign class_mask_o = out_pipe_class_mask_q[(0 >= NUM_OUT_REGS ? NUM_OUT_REGS : NUM_OUT_REGS - NUM_OUT_REGS) * 10+:10];
+ assign is_class_o = out_pipe_is_class_q[NUM_OUT_REGS];
+ assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
+ assign aux_o = out_pipe_aux_q[NUM_OUT_REGS];
+ assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
+ assign busy_o = |{inp_pipe_valid_q, out_pipe_valid_q};
+endmodule
+module fpnew_opgroup_block_BE2AB (
+ clk_i,
+ rst_ni,
+ operands_i,
+ is_boxed_i,
+ rnd_mode_i,
+ op_i,
+ op_mod_i,
+ src_fmt_i,
+ dst_fmt_i,
+ int_fmt_i,
+ vectorial_op_i,
+ tag_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ extension_bit_o,
+ tag_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ localparam [1:0] fpnew_pkg_ADDMUL = 0;
+ parameter [1:0] OpGroup = fpnew_pkg_ADDMUL;
+ parameter [31:0] Width = 32;
+ parameter [0:0] EnableVectors = 1'b1;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ parameter [0:0] FpFmtMask = 1'sb1;
+ localparam [31:0] fpnew_pkg_NUM_INT_FORMATS = 1;
+ parameter [0:0] IntFmtMask = 1'sb1;
+ parameter [31:0] FmtPipeRegs = 32'd0;
+ localparam [1:0] fpnew_pkg_PARALLEL = 1;
+ parameter [1:0] FmtUnitTypes = {fpnew_pkg_PARALLEL};
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ parameter [1:0] PipeConfig = fpnew_pkg_BEFORE;
+ localparam [31:0] NUM_FORMATS = fpnew_pkg_NUM_FP_FORMATS;
+ localparam [1:0] fpnew_pkg_CONV = 3;
+ localparam [1:0] fpnew_pkg_DIVSQRT = 1;
+ localparam [1:0] fpnew_pkg_NONCOMP = 2;
+ function automatic [31:0] fpnew_pkg_num_operands;
+ input reg [1:0] grp;
+ case (grp)
+ fpnew_pkg_ADDMUL: fpnew_pkg_num_operands = 3;
+ fpnew_pkg_DIVSQRT: fpnew_pkg_num_operands = 2;
+ fpnew_pkg_NONCOMP: fpnew_pkg_num_operands = 2;
+ fpnew_pkg_CONV: fpnew_pkg_num_operands = 3;
+ default: fpnew_pkg_num_operands = 0;
+ endcase
+ endfunction
+ localparam [31:0] NUM_OPERANDS = fpnew_pkg_num_operands(OpGroup);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(NUM_OPERANDS * Width) - 1:0] operands_i;
+ input wire [(NUM_FORMATS * NUM_OPERANDS) - 1:0] is_boxed_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire op_mod_i;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] src_fmt_i;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_i;
+ localparam [31:0] fpnew_pkg_INT_FORMAT_BITS = 0;
+ input wire [fpnew_pkg_INT_FORMAT_BITS - 1:0] int_fmt_i;
+ input wire vectorial_op_i;
+ input wire tag_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [Width - 1:0] result_o;
+ output wire [4:0] status_o;
+ output wire extension_bit_o;
+ output wire tag_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ wire [0:0] fmt_in_ready;
+ wire [0:0] fmt_out_valid;
+ wire [0:0] fmt_out_ready;
+ wire [0:0] fmt_busy;
+ wire [((Width + 6) >= 0 ? Width + 6 : (1 - (Width + 6)) + (Width + 5)):((Width + 6) >= 0 ? 0 : Width + 6)] fmt_outputs;
+ assign in_ready_o = in_valid_i & fmt_in_ready[dst_fmt_i];
+ localparam [0:0] fpnew_pkg_DONT_CARE = 1'b1;
+ localparam [1:0] fpnew_pkg_MERGED = 2;
+ function automatic fpnew_pkg_any_enabled_multi;
+ input reg [1:0] types;
+ input reg [0:0] cfg;
+ reg [0:1] _sv2v_jump;
+ begin
+ _sv2v_jump = 2'b00;
+ begin : sv2v_autoblock_113
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (_sv2v_jump < 2'b10) begin
+ _sv2v_jump = 2'b00;
+ if (cfg[i] && (types[i * 2+:2] == fpnew_pkg_MERGED)) begin
+ fpnew_pkg_any_enabled_multi = 1'b1;
+ _sv2v_jump = 2'b11;
+ end
+ end
+ end
+ if (_sv2v_jump != 2'b11)
+ _sv2v_jump = 2'b00;
+ if (_sv2v_jump == 2'b00) begin
+ fpnew_pkg_any_enabled_multi = 1'b0;
+ _sv2v_jump = 2'b11;
+ end
+ end
+ endfunction
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_F6DD6;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_F6DD6 = inp;
+ endfunction
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] fpnew_pkg_get_first_enabled_multi;
+ input reg [1:0] types;
+ input reg [0:0] cfg;
+ reg [0:1] _sv2v_jump;
+ begin
+ _sv2v_jump = 2'b00;
+ begin : sv2v_autoblock_114
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (_sv2v_jump < 2'b10) begin
+ _sv2v_jump = 2'b00;
+ if (cfg[i] && (types[i * 2+:2] == fpnew_pkg_MERGED)) begin
+ fpnew_pkg_get_first_enabled_multi = sv2v_cast_F6DD6(i);
+ _sv2v_jump = 2'b11;
+ end
+ end
+ end
+ if (_sv2v_jump != 2'b11)
+ _sv2v_jump = 2'b00;
+ if (_sv2v_jump == 2'b00) begin
+ fpnew_pkg_get_first_enabled_multi = sv2v_cast_F6DD6(0);
+ _sv2v_jump = 2'b11;
+ end
+ end
+ endfunction
+ function automatic fpnew_pkg_is_first_enabled_multi;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ input reg [1:0] types;
+ input reg [0:0] cfg;
+ reg [0:1] _sv2v_jump;
+ begin
+ _sv2v_jump = 2'b00;
+ begin : sv2v_autoblock_115
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (_sv2v_jump < 2'b10) begin
+ _sv2v_jump = 2'b00;
+ if (cfg[i] && (types[i * 2+:2] == fpnew_pkg_MERGED)) begin
+ fpnew_pkg_is_first_enabled_multi = sv2v_cast_F6DD6(i) == fmt;
+ _sv2v_jump = 2'b11;
+ end
+ end
+ end
+ if (_sv2v_jump != 2'b11)
+ _sv2v_jump = 2'b00;
+ if (_sv2v_jump == 2'b00) begin
+ fpnew_pkg_is_first_enabled_multi = 1'b0;
+ _sv2v_jump = 2'b11;
+ end
+ end
+ endfunction
+ localparam [1:0] fpnew_pkg_DISABLED = 0;
+ generate
+ genvar fmt;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : gen_parallel_slices
+ localparam [0:0] ANY_MERGED = fpnew_pkg_any_enabled_multi(FmtUnitTypes, FpFmtMask);
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_F6DD6;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_F6DD6 = inp;
+ endfunction
+ localparam [0:0] IS_FIRST_MERGED = fpnew_pkg_is_first_enabled_multi(sv2v_cast_F6DD6(fmt), FmtUnitTypes, FpFmtMask);
+ if (FpFmtMask[fmt] && (FmtUnitTypes[fmt * 2+:2] == fpnew_pkg_PARALLEL)) begin : active_format
+ wire in_valid;
+ assign in_valid = in_valid_i & (dst_fmt_i == fmt);
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_F6DD6;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_F6DD6 = inp;
+ endfunction
+ fpnew_opgroup_fmt_slice_30528 #(
+ .OpGroup(OpGroup),
+ .FpFormat(sv2v_cast_F6DD6(fmt)),
+ .Width(Width),
+ .EnableVectors(EnableVectors),
+ .NumPipeRegs(FmtPipeRegs[fmt * 32+:32]),
+ .PipeConfig(PipeConfig)
+ ) i_fmt_slice(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .operands_i(operands_i),
+ .is_boxed_i(is_boxed_i[fmt * NUM_OPERANDS+:NUM_OPERANDS]),
+ .rnd_mode_i(rnd_mode_i),
+ .op_i(op_i),
+ .op_mod_i(op_mod_i),
+ .vectorial_op_i(vectorial_op_i),
+ .tag_i(tag_i),
+ .in_valid_i(in_valid),
+ .in_ready_o(fmt_in_ready[fmt]),
+ .flush_i(flush_i),
+ .result_o(fmt_outputs[((Width + 6) >= 0 ? (fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? Width + 6 : (Width + 6) - (Width + 6)) : (((fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? Width + 6 : (Width + 6) - (Width + 6))) + ((Width + 6) >= 7 ? Width : 8 - (Width + 6))) - 1)-:((Width + 6) >= 7 ? Width : 8 - (Width + 6))]),
+ .status_o(fmt_outputs[((Width + 6) >= 0 ? (fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 6 : Width) : ((fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 6 : Width)) + 4)-:5]),
+ .extension_bit_o(fmt_outputs[(fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 1 : Width + 5)]),
+ .tag_o(fmt_outputs[(fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 0 : Width + 6)]),
+ .out_valid_o(fmt_out_valid[fmt]),
+ .out_ready_i(fmt_out_ready[fmt]),
+ .busy_o(fmt_busy[fmt])
+ );
+ end
+ else if ((FpFmtMask[fmt] && ANY_MERGED) && !IS_FIRST_MERGED) begin : merged_unused
+ localparam FMT = fpnew_pkg_get_first_enabled_multi(FmtUnitTypes, FpFmtMask);
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ assign fmt_in_ready[fmt] = fmt_in_ready[sv2v_cast_32_signed(FMT)];
+ assign fmt_out_valid[fmt] = 1'b0;
+ assign fmt_busy[fmt] = 1'b0;
+ assign fmt_outputs[((Width + 6) >= 0 ? (fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? Width + 6 : (Width + 6) - (Width + 6)) : (((fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? Width + 6 : (Width + 6) - (Width + 6))) + ((Width + 6) >= 7 ? Width : 8 - (Width + 6))) - 1)-:((Width + 6) >= 7 ? Width : 8 - (Width + 6))] = {Width {fpnew_pkg_DONT_CARE}};
+ assign fmt_outputs[((Width + 6) >= 0 ? (fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 6 : Width) : ((fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 6 : Width)) + 4)-:5] = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ assign fmt_outputs[(fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 1 : Width + 5)] = fpnew_pkg_DONT_CARE;
+ assign fmt_outputs[(fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 0 : Width + 6)] = fpnew_pkg_DONT_CARE;
+ end
+ else if (!FpFmtMask[fmt] || (FmtUnitTypes[fmt * 2+:2] == fpnew_pkg_DISABLED)) begin : disable_fmt
+ assign fmt_in_ready[fmt] = 1'b0;
+ assign fmt_out_valid[fmt] = 1'b0;
+ assign fmt_busy[fmt] = 1'b0;
+ assign fmt_outputs[((Width + 6) >= 0 ? (fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? Width + 6 : (Width + 6) - (Width + 6)) : (((fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? Width + 6 : (Width + 6) - (Width + 6))) + ((Width + 6) >= 7 ? Width : 8 - (Width + 6))) - 1)-:((Width + 6) >= 7 ? Width : 8 - (Width + 6))] = {Width {fpnew_pkg_DONT_CARE}};
+ assign fmt_outputs[((Width + 6) >= 0 ? (fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 6 : Width) : ((fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 6 : Width)) + 4)-:5] = {fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE, fpnew_pkg_DONT_CARE};
+ assign fmt_outputs[(fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 1 : Width + 5)] = fpnew_pkg_DONT_CARE;
+ assign fmt_outputs[(fmt * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 0 : Width + 6)] = fpnew_pkg_DONT_CARE;
+ end
+ end
+ endgenerate
+ function automatic signed [31:0] fpnew_pkg_maximum;
+ input reg signed [31:0] a;
+ input reg signed [31:0] b;
+ fpnew_pkg_maximum = (a > b ? a : b);
+ endfunction
+ function automatic [31:0] fpnew_pkg_get_num_regs_multi;
+ input reg [31:0] regs;
+ input reg [1:0] types;
+ input reg [0:0] cfg;
+ reg [31:0] res;
+ begin
+ res = 0;
+ begin : sv2v_autoblock_116
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (cfg[i] && (types[i * 2+:2] == fpnew_pkg_MERGED))
+ res = fpnew_pkg_maximum(res, regs[i * 32+:32]);
+ end
+ fpnew_pkg_get_num_regs_multi = res;
+ end
+ endfunction
+ generate
+ if (fpnew_pkg_any_enabled_multi(FmtUnitTypes, FpFmtMask)) begin : gen_merged_slice
+ localparam FMT = fpnew_pkg_get_first_enabled_multi(FmtUnitTypes, FpFmtMask);
+ localparam REG = fpnew_pkg_get_num_regs_multi(FmtPipeRegs, FmtUnitTypes, FpFmtMask);
+ wire in_valid;
+ assign in_valid = in_valid_i & (FmtUnitTypes[dst_fmt_i * 2+:2] == fpnew_pkg_MERGED);
+ fpnew_opgroup_multifmt_slice_7C482 #(
+ .OpGroup(OpGroup),
+ .Width(Width),
+ .FpFmtConfig(FpFmtMask),
+ .IntFmtConfig(IntFmtMask),
+ .EnableVectors(EnableVectors),
+ .NumPipeRegs(REG),
+ .PipeConfig(PipeConfig)
+ ) i_multifmt_slice(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .operands_i(operands_i),
+ .is_boxed_i(is_boxed_i),
+ .rnd_mode_i(rnd_mode_i),
+ .op_i(op_i),
+ .op_mod_i(op_mod_i),
+ .src_fmt_i(src_fmt_i),
+ .dst_fmt_i(dst_fmt_i),
+ .int_fmt_i(int_fmt_i),
+ .vectorial_op_i(vectorial_op_i),
+ .tag_i(tag_i),
+ .in_valid_i(in_valid),
+ .in_ready_o(fmt_in_ready[FMT]),
+ .flush_i(flush_i),
+ .result_o(fmt_outputs[((Width + 6) >= 0 ? (FMT * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? Width + 6 : (Width + 6) - (Width + 6)) : (((FMT * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? Width + 6 : (Width + 6) - (Width + 6))) + ((Width + 6) >= 7 ? Width : 8 - (Width + 6))) - 1)-:((Width + 6) >= 7 ? Width : 8 - (Width + 6))]),
+ .status_o(fmt_outputs[((Width + 6) >= 0 ? (FMT * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 6 : Width) : ((FMT * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 6 : Width)) + 4)-:5]),
+ .extension_bit_o(fmt_outputs[(FMT * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 1 : Width + 5)]),
+ .tag_o(fmt_outputs[(FMT * ((Width + 6) >= 0 ? Width + 7 : 1 - (Width + 6))) + ((Width + 6) >= 0 ? 0 : Width + 6)]),
+ .out_valid_o(fmt_out_valid[FMT]),
+ .out_ready_i(fmt_out_ready[FMT]),
+ .busy_o(fmt_busy[FMT])
+ );
+ end
+ endgenerate
+ wire [Width + 6:0] arbiter_output;
+ rr_arb_tree_252F1_F315E #(
+ .DataType_Width(Width),
+ .NumIn(NUM_FORMATS),
+ .AxiVldRdy(1'b1)
+ ) i_arbiter(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .flush_i(flush_i),
+ .rr_i({32'd1 {1'sb0}}),
+ .req_i(fmt_out_valid),
+ .gnt_o(fmt_out_ready),
+ .data_i(fmt_outputs),
+ .gnt_i(out_ready_i),
+ .req_o(out_valid_o),
+ .data_o(arbiter_output),
+ .idx_o()
+ );
+ assign result_o = arbiter_output[Width + 6-:((Width + 6) >= 7 ? Width : 8 - (Width + 6))];
+ assign status_o = arbiter_output[6-:5];
+ assign extension_bit_o = arbiter_output[1];
+ assign tag_o = arbiter_output[0];
+ assign busy_o = |fmt_busy;
+endmodule
+module fpnew_opgroup_fmt_slice_30528 (
+ clk_i,
+ rst_ni,
+ operands_i,
+ is_boxed_i,
+ rnd_mode_i,
+ op_i,
+ op_mod_i,
+ vectorial_op_i,
+ tag_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ extension_bit_o,
+ tag_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ localparam [1:0] fpnew_pkg_ADDMUL = 0;
+ parameter [1:0] OpGroup = fpnew_pkg_ADDMUL;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_CA66C;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_CA66C = inp;
+ endfunction
+ parameter [fpnew_pkg_FP_FORMAT_BITS - 1:0] FpFormat = sv2v_cast_CA66C(0);
+ parameter [31:0] Width = 32;
+ parameter [0:0] EnableVectors = 1'b1;
+ parameter [31:0] NumPipeRegs = 0;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ parameter [1:0] PipeConfig = fpnew_pkg_BEFORE;
+ localparam [1:0] fpnew_pkg_CONV = 3;
+ localparam [1:0] fpnew_pkg_DIVSQRT = 1;
+ localparam [1:0] fpnew_pkg_NONCOMP = 2;
+ function automatic [31:0] fpnew_pkg_num_operands;
+ input reg [1:0] grp;
+ case (grp)
+ fpnew_pkg_ADDMUL: fpnew_pkg_num_operands = 3;
+ fpnew_pkg_DIVSQRT: fpnew_pkg_num_operands = 2;
+ fpnew_pkg_NONCOMP: fpnew_pkg_num_operands = 2;
+ fpnew_pkg_CONV: fpnew_pkg_num_operands = 3;
+ default: fpnew_pkg_num_operands = 0;
+ endcase
+ endfunction
+ localparam [31:0] NUM_OPERANDS = fpnew_pkg_num_operands(OpGroup);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(NUM_OPERANDS * Width) - 1:0] operands_i;
+ input wire [NUM_OPERANDS - 1:0] is_boxed_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire op_mod_i;
+ input wire vectorial_op_i;
+ input wire tag_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [Width - 1:0] result_o;
+ output reg [4:0] status_o;
+ output wire extension_bit_o;
+ output wire tag_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(FpFormat);
+ function automatic [31:0] fpnew_pkg_num_lanes;
+ input reg [31:0] width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ input reg vec;
+ fpnew_pkg_num_lanes = (vec ? width / fpnew_pkg_fp_width(fmt) : 1);
+ endfunction
+ localparam [31:0] NUM_LANES = fpnew_pkg_num_lanes(Width, FpFormat, EnableVectors);
+ wire [NUM_LANES - 1:0] lane_in_ready;
+ wire [NUM_LANES - 1:0] lane_out_valid;
+ wire vectorial_op;
+ wire [(NUM_LANES * FP_WIDTH) - 1:0] slice_result;
+ wire [Width - 1:0] slice_regular_result;
+ wire [Width - 1:0] slice_class_result;
+ wire [Width - 1:0] slice_vec_class_result;
+ wire [(NUM_LANES * 5) - 1:0] lane_status;
+ wire [NUM_LANES - 1:0] lane_ext_bit;
+ wire [(NUM_LANES * 10) - 1:0] lane_class_mask;
+ wire [NUM_LANES - 1:0] lane_tags;
+ wire [NUM_LANES - 1:0] lane_vectorial;
+ wire [NUM_LANES - 1:0] lane_busy;
+ wire [NUM_LANES - 1:0] lane_is_class;
+ wire result_is_vector;
+ wire result_is_class;
+ assign in_ready_o = lane_in_ready[0];
+ assign vectorial_op = vectorial_op_i & EnableVectors;
+ localparam [9:0] fpnew_pkg_NEGINF = 10'b0000000001;
+ localparam [9:0] fpnew_pkg_NEGNORM = 10'b0000000010;
+ localparam [9:0] fpnew_pkg_NEGSUBNORM = 10'b0000000100;
+ localparam [9:0] fpnew_pkg_NEGZERO = 10'b0000001000;
+ localparam [9:0] fpnew_pkg_POSINF = 10'b0010000000;
+ localparam [9:0] fpnew_pkg_POSNORM = 10'b0001000000;
+ localparam [9:0] fpnew_pkg_POSSUBNORM = 10'b0000100000;
+ localparam [9:0] fpnew_pkg_POSZERO = 10'b0000010000;
+ localparam [9:0] fpnew_pkg_QNAN = 10'b1000000000;
+ localparam [9:0] fpnew_pkg_SNAN = 10'b0100000000;
+ generate
+ genvar lane;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ for (lane = 0; lane < sv2v_cast_32_signed(NUM_LANES); lane = lane + 1) begin : gen_num_lanes
+ wire [FP_WIDTH - 1:0] local_result;
+ wire local_sign;
+ if ((lane == 0) || EnableVectors) begin : active_lane
+ wire in_valid;
+ wire out_valid;
+ wire out_ready;
+ reg [(NUM_OPERANDS * FP_WIDTH) - 1:0] local_operands;
+ wire [FP_WIDTH - 1:0] op_result;
+ wire [4:0] op_status;
+ assign in_valid = in_valid_i & ((lane == 0) | vectorial_op);
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ always @(*) begin : prepare_input
+ begin : sv2v_autoblock_117
+ reg signed [31:0] i;
+ for (i = 0; i < sv2v_cast_32_signed(NUM_OPERANDS); i = i + 1)
+ local_operands[i * FP_WIDTH+:FP_WIDTH] = operands_i[(i * Width) + (((($unsigned(lane) + 1) * FP_WIDTH) - 1) >= ($unsigned(lane) * FP_WIDTH) ? (($unsigned(lane) + 1) * FP_WIDTH) - 1 : (((($unsigned(lane) + 1) * FP_WIDTH) - 1) + (((($unsigned(lane) + 1) * FP_WIDTH) - 1) >= ($unsigned(lane) * FP_WIDTH) ? (((($unsigned(lane) + 1) * FP_WIDTH) - 1) - ($unsigned(lane) * FP_WIDTH)) + 1 : (($unsigned(lane) * FP_WIDTH) - ((($unsigned(lane) + 1) * FP_WIDTH) - 1)) + 1)) - 1)-:(((($unsigned(lane) + 1) * FP_WIDTH) - 1) >= ($unsigned(lane) * FP_WIDTH) ? (((($unsigned(lane) + 1) * FP_WIDTH) - 1) - ($unsigned(lane) * FP_WIDTH)) + 1 : (($unsigned(lane) * FP_WIDTH) - ((($unsigned(lane) + 1) * FP_WIDTH) - 1)) + 1)];
+ end
+ end
+ if (OpGroup == fpnew_pkg_ADDMUL) begin : lane_instance
+ fpnew_fma_B2D03 #(
+ .FpFormat(FpFormat),
+ .NumPipeRegs(NumPipeRegs),
+ .PipeConfig(PipeConfig)
+ ) i_fma(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .operands_i(local_operands),
+ .is_boxed_i(is_boxed_i[NUM_OPERANDS - 1:0]),
+ .rnd_mode_i(rnd_mode_i),
+ .op_i(op_i),
+ .op_mod_i(op_mod_i),
+ .tag_i(tag_i),
+ .aux_i(vectorial_op),
+ .in_valid_i(in_valid),
+ .in_ready_o(lane_in_ready[lane]),
+ .flush_i(flush_i),
+ .result_o(op_result),
+ .status_o(op_status),
+ .extension_bit_o(lane_ext_bit[lane]),
+ .tag_o(lane_tags[lane]),
+ .aux_o(lane_vectorial[lane]),
+ .out_valid_o(out_valid),
+ .out_ready_i(out_ready),
+ .busy_o(lane_busy[lane])
+ );
+ assign lane_is_class[lane] = 1'b0;
+ assign lane_class_mask[lane * 10+:10] = fpnew_pkg_NEGINF;
+ end
+ else if (OpGroup == fpnew_pkg_DIVSQRT) ;
+ else if (OpGroup == fpnew_pkg_NONCOMP) begin : lane_instance
+ fpnew_noncomp_6DFAC #(
+ .FpFormat(FpFormat),
+ .NumPipeRegs(NumPipeRegs),
+ .PipeConfig(PipeConfig)
+ ) i_noncomp(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .operands_i(local_operands),
+ .is_boxed_i(is_boxed_i[NUM_OPERANDS - 1:0]),
+ .rnd_mode_i(rnd_mode_i),
+ .op_i(op_i),
+ .op_mod_i(op_mod_i),
+ .tag_i(tag_i),
+ .aux_i(vectorial_op),
+ .in_valid_i(in_valid),
+ .in_ready_o(lane_in_ready[lane]),
+ .flush_i(flush_i),
+ .result_o(op_result),
+ .status_o(op_status),
+ .extension_bit_o(lane_ext_bit[lane]),
+ .class_mask_o(lane_class_mask[lane * 10+:10]),
+ .is_class_o(lane_is_class[lane]),
+ .tag_o(lane_tags[lane]),
+ .aux_o(lane_vectorial[lane]),
+ .out_valid_o(out_valid),
+ .out_ready_i(out_ready),
+ .busy_o(lane_busy[lane])
+ );
+ end
+ assign out_ready = out_ready_i & ((lane == 0) | result_is_vector);
+ assign lane_out_valid[lane] = out_valid & ((lane == 0) | result_is_vector);
+ assign local_result = (lane_out_valid[lane] ? op_result : {FP_WIDTH {lane_ext_bit[0]}});
+ assign lane_status[lane * 5+:5] = (lane_out_valid[lane] ? op_status : {5 {1'sb0}});
+ end
+ else begin
+ assign lane_out_valid[lane] = 1'b0;
+ assign lane_in_ready[lane] = 1'b0;
+ assign local_result = {FP_WIDTH {lane_ext_bit[0]}};
+ assign lane_status[lane * 5+:5] = {5 {1'sb0}};
+ assign lane_busy[lane] = 1'b0;
+ assign lane_is_class[lane] = 1'b0;
+ end
+ assign slice_result[(($unsigned(lane) + 1) * FP_WIDTH) - 1:$unsigned(lane) * FP_WIDTH] = local_result;
+ if (((lane + 1) * 8) <= Width) begin : vectorial_class
+ assign local_sign = (((lane_class_mask[lane * 10+:10] == fpnew_pkg_NEGINF) || (lane_class_mask[lane * 10+:10] == fpnew_pkg_NEGNORM)) || (lane_class_mask[lane * 10+:10] == fpnew_pkg_NEGSUBNORM)) || (lane_class_mask[lane * 10+:10] == fpnew_pkg_NEGZERO);
+ assign slice_vec_class_result[((lane + 1) * 8) - 1:lane * 8] = {local_sign, ~local_sign, lane_class_mask[lane * 10+:10] == fpnew_pkg_QNAN, lane_class_mask[lane * 10+:10] == fpnew_pkg_SNAN, (lane_class_mask[lane * 10+:10] == fpnew_pkg_POSZERO) || (lane_class_mask[lane * 10+:10] == fpnew_pkg_NEGZERO), (lane_class_mask[lane * 10+:10] == fpnew_pkg_POSSUBNORM) || (lane_class_mask[lane * 10+:10] == fpnew_pkg_NEGSUBNORM), (lane_class_mask[lane * 10+:10] == fpnew_pkg_POSNORM) || (lane_class_mask[lane * 10+:10] == fpnew_pkg_NEGNORM), (lane_class_mask[lane * 10+:10] == fpnew_pkg_POSINF) || (lane_class_mask[lane * 10+:10] == fpnew_pkg_NEGINF)};
+ end
+ end
+ endgenerate
+ assign result_is_vector = lane_vectorial[0];
+ assign result_is_class = lane_is_class[0];
+ assign slice_regular_result = $signed({extension_bit_o, slice_result});
+ localparam [31:0] CLASS_VEC_BITS = ((NUM_LANES * 8) > Width ? 8 * (Width / 8) : NUM_LANES * 8);
+ generate
+ if (CLASS_VEC_BITS < Width) begin : pad_vectorial_class
+ assign slice_vec_class_result[Width - 1:CLASS_VEC_BITS] = {((Width - 1) >= CLASS_VEC_BITS ? ((Width - 1) - CLASS_VEC_BITS) + 1 : (CLASS_VEC_BITS - (Width - 1)) + 1) {1'sb0}};
+ end
+ endgenerate
+ assign slice_class_result = (result_is_vector ? slice_vec_class_result : lane_class_mask[0+:10]);
+ assign result_o = (result_is_class ? slice_class_result : slice_regular_result);
+ assign extension_bit_o = lane_ext_bit[0];
+ assign tag_o = lane_tags[0];
+ assign busy_o = |lane_busy;
+ assign out_valid_o = lane_out_valid[0];
+ always @(*) begin : output_processing
+ reg [4:0] temp_status;
+ temp_status = {5 {1'sb0}};
+ begin : sv2v_autoblock_118
+ reg signed [31:0] i;
+ for (i = 0; i < sv2v_cast_32_signed(NUM_LANES); i = i + 1)
+ temp_status = temp_status | lane_status[i * 5+:5];
+ end
+ status_o = temp_status;
+ end
+endmodule
+module fpnew_opgroup_multifmt_slice_7C482 (
+ clk_i,
+ rst_ni,
+ operands_i,
+ is_boxed_i,
+ rnd_mode_i,
+ op_i,
+ op_mod_i,
+ src_fmt_i,
+ dst_fmt_i,
+ int_fmt_i,
+ vectorial_op_i,
+ tag_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ extension_bit_o,
+ tag_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ localparam [1:0] fpnew_pkg_CONV = 3;
+ parameter [1:0] OpGroup = fpnew_pkg_CONV;
+ parameter [31:0] Width = 64;
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ parameter [0:0] FpFmtConfig = 1'sb1;
+ localparam [31:0] fpnew_pkg_NUM_INT_FORMATS = 1;
+ parameter [0:0] IntFmtConfig = 1'sb1;
+ parameter [0:0] EnableVectors = 1'b1;
+ parameter [31:0] NumPipeRegs = 0;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ parameter [1:0] PipeConfig = fpnew_pkg_BEFORE;
+ localparam [1:0] fpnew_pkg_ADDMUL = 0;
+ localparam [1:0] fpnew_pkg_DIVSQRT = 1;
+ localparam [1:0] fpnew_pkg_NONCOMP = 2;
+ function automatic [31:0] fpnew_pkg_num_operands;
+ input reg [1:0] grp;
+ case (grp)
+ fpnew_pkg_ADDMUL: fpnew_pkg_num_operands = 3;
+ fpnew_pkg_DIVSQRT: fpnew_pkg_num_operands = 2;
+ fpnew_pkg_NONCOMP: fpnew_pkg_num_operands = 2;
+ fpnew_pkg_CONV: fpnew_pkg_num_operands = 3;
+ default: fpnew_pkg_num_operands = 0;
+ endcase
+ endfunction
+ localparam [31:0] NUM_OPERANDS = fpnew_pkg_num_operands(OpGroup);
+ localparam [31:0] NUM_FORMATS = fpnew_pkg_NUM_FP_FORMATS;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(NUM_OPERANDS * Width) - 1:0] operands_i;
+ input wire [(NUM_FORMATS * NUM_OPERANDS) - 1:0] is_boxed_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire op_mod_i;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] src_fmt_i;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_i;
+ localparam [31:0] fpnew_pkg_INT_FORMAT_BITS = 0;
+ input wire [fpnew_pkg_INT_FORMAT_BITS - 1:0] int_fmt_i;
+ input wire vectorial_op_i;
+ input wire tag_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [Width - 1:0] result_o;
+ output reg [4:0] status_o;
+ output wire extension_bit_o;
+ output wire tag_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ function automatic signed [31:0] fpnew_pkg_maximum;
+ input reg signed [31:0] a;
+ input reg signed [31:0] b;
+ fpnew_pkg_maximum = (a > b ? a : b);
+ endfunction
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_38622;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_38622 = inp;
+ endfunction
+ function automatic [31:0] fpnew_pkg_max_fp_width;
+ input reg [0:0] cfg;
+ reg [31:0] res;
+ begin
+ res = 0;
+ begin : sv2v_autoblock_119
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (cfg[i])
+ res = $unsigned(fpnew_pkg_maximum(res, fpnew_pkg_fp_width(sv2v_cast_38622(i))));
+ end
+ fpnew_pkg_max_fp_width = res;
+ end
+ endfunction
+ localparam [31:0] MAX_FP_WIDTH = fpnew_pkg_max_fp_width(FpFmtConfig);
+ localparam [fpnew_pkg_INT_FORMAT_BITS - 1:0] fpnew_pkg_INT32 = 0;
+ function automatic [31:0] fpnew_pkg_int_width;
+ input reg [fpnew_pkg_INT_FORMAT_BITS - 1:0] ifmt;
+ case (ifmt)
+ fpnew_pkg_INT32: fpnew_pkg_int_width = 32;
+ endcase
+ endfunction
+ function automatic [fpnew_pkg_INT_FORMAT_BITS - 1:0] sv2v_cast_E880F;
+ input reg [fpnew_pkg_INT_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_E880F = inp;
+ endfunction
+ function automatic [31:0] fpnew_pkg_max_int_width;
+ input reg [0:0] cfg;
+ reg [31:0] res;
+ begin
+ res = 0;
+ begin : sv2v_autoblock_120
+ reg signed [31:0] ifmt;
+ for (ifmt = 0; ifmt < fpnew_pkg_NUM_INT_FORMATS; ifmt = ifmt + 1)
+ if (cfg[ifmt])
+ res = fpnew_pkg_maximum(res, fpnew_pkg_int_width(sv2v_cast_E880F(ifmt)));
+ end
+ fpnew_pkg_max_int_width = res;
+ end
+ endfunction
+ localparam [31:0] MAX_INT_WIDTH = fpnew_pkg_max_int_width(IntFmtConfig);
+ function automatic signed [31:0] fpnew_pkg_minimum;
+ input reg signed [31:0] a;
+ input reg signed [31:0] b;
+ fpnew_pkg_minimum = (a < b ? a : b);
+ endfunction
+ function automatic [31:0] fpnew_pkg_min_fp_width;
+ input reg [0:0] cfg;
+ reg [31:0] res;
+ begin
+ res = fpnew_pkg_max_fp_width(cfg);
+ begin : sv2v_autoblock_121
+ reg [31:0] i;
+ for (i = 0; i < fpnew_pkg_NUM_FP_FORMATS; i = i + 1)
+ if (cfg[i])
+ res = $unsigned(fpnew_pkg_minimum(res, fpnew_pkg_fp_width(sv2v_cast_38622(i))));
+ end
+ fpnew_pkg_min_fp_width = res;
+ end
+ endfunction
+ function automatic [31:0] fpnew_pkg_max_num_lanes;
+ input reg [31:0] width;
+ input reg [0:0] cfg;
+ input reg vec;
+ fpnew_pkg_max_num_lanes = (vec ? width / fpnew_pkg_min_fp_width(cfg) : 1);
+ endfunction
+ localparam [31:0] NUM_LANES = fpnew_pkg_max_num_lanes(Width, FpFmtConfig, 1'b1);
+ localparam [31:0] NUM_INT_FORMATS = fpnew_pkg_NUM_INT_FORMATS;
+ localparam [31:0] FMT_BITS = fpnew_pkg_maximum(0, 0);
+ localparam [31:0] AUX_BITS = FMT_BITS + 2;
+ wire [NUM_LANES - 1:0] lane_in_ready;
+ wire [NUM_LANES - 1:0] lane_out_valid;
+ wire vectorial_op;
+ wire [FMT_BITS - 1:0] dst_fmt;
+ wire [AUX_BITS - 1:0] aux_data;
+ wire dst_fmt_is_int;
+ wire dst_is_cpk;
+ wire [1:0] dst_vec_op;
+ wire [2:0] target_aux_d;
+ wire [2:0] target_aux_q;
+ wire is_up_cast;
+ wire is_down_cast;
+ wire [(NUM_FORMATS * Width) - 1:0] fmt_slice_result;
+ wire [(NUM_INT_FORMATS * Width) - 1:0] ifmt_slice_result;
+ wire [Width - 1:0] conv_slice_result;
+ wire [Width - 1:0] conv_target_d;
+ wire [Width - 1:0] conv_target_q;
+ wire [(NUM_LANES * 5) - 1:0] lane_status;
+ wire [NUM_LANES - 1:0] lane_ext_bit;
+ wire [NUM_LANES - 1:0] lane_tags;
+ wire [(NUM_LANES * AUX_BITS) - 1:0] lane_aux;
+ wire [NUM_LANES - 1:0] lane_busy;
+ wire result_is_vector;
+ wire [FMT_BITS - 1:0] result_fmt;
+ wire result_fmt_is_int;
+ wire result_is_cpk;
+ wire [1:0] result_vec_op;
+ assign in_ready_o = lane_in_ready[0];
+ assign vectorial_op = vectorial_op_i & EnableVectors;
+ localparam [3:0] fpnew_pkg_F2I = 11;
+ assign dst_fmt_is_int = (OpGroup == fpnew_pkg_CONV) & (op_i == fpnew_pkg_F2I);
+ localparam [3:0] fpnew_pkg_CPKAB = 13;
+ localparam [3:0] fpnew_pkg_CPKCD = 14;
+ assign dst_is_cpk = (OpGroup == fpnew_pkg_CONV) & ((op_i == fpnew_pkg_CPKAB) || (op_i == fpnew_pkg_CPKCD));
+ assign dst_vec_op = (OpGroup == fpnew_pkg_CONV) & {op_i == fpnew_pkg_CPKCD, op_mod_i};
+ assign is_up_cast = fpnew_pkg_fp_width(dst_fmt_i) > fpnew_pkg_fp_width(src_fmt_i);
+ assign is_down_cast = fpnew_pkg_fp_width(dst_fmt_i) < fpnew_pkg_fp_width(src_fmt_i);
+ assign dst_fmt = (dst_fmt_is_int ? int_fmt_i : dst_fmt_i);
+ assign aux_data = {dst_fmt_is_int, vectorial_op, dst_fmt};
+ assign target_aux_d = {dst_vec_op, dst_is_cpk};
+ generate
+ if (OpGroup == fpnew_pkg_CONV) begin : conv_target
+ assign conv_target_d = (dst_is_cpk ? operands_i[2 * Width+:Width] : operands_i[Width+:Width]);
+ end
+ endgenerate
+ reg [0:0] is_boxed_1op;
+ reg [1:0] is_boxed_2op;
+ always @(*) begin : boxed_2op
+ begin : sv2v_autoblock_122
+ reg signed [31:0] fmt;
+ for (fmt = 0; fmt < NUM_FORMATS; fmt = fmt + 1)
+ begin
+ is_boxed_1op[fmt] = is_boxed_i[fmt * NUM_OPERANDS];
+ is_boxed_2op[fmt * 2+:2] = is_boxed_i[(fmt * NUM_OPERANDS) + 1-:2];
+ end
+ end
+ end
+ localparam [0:0] fpnew_pkg_CPK_FORMATS = 5'b11000;
+ function automatic [0:0] fpnew_pkg_get_conv_lane_formats;
+ input reg [31:0] width;
+ input reg [0:0] cfg;
+ input reg [31:0] lane_no;
+ reg [0:0] res;
+ reg [31:0] fmt;
+ begin
+ for (fmt = 0; fmt < fpnew_pkg_NUM_FP_FORMATS; fmt = fmt + 1)
+ res[fmt] = cfg[fmt] && (((width / fpnew_pkg_fp_width(sv2v_cast_38622(fmt))) > lane_no) || (fpnew_pkg_CPK_FORMATS[fmt] && (lane_no < 2)));
+ fpnew_pkg_get_conv_lane_formats = res;
+ end
+ endfunction
+ function automatic [0:0] fpnew_pkg_get_conv_lane_int_formats;
+ input reg [31:0] width;
+ input reg [0:0] cfg;
+ input reg [0:0] icfg;
+ input reg [31:0] lane_no;
+ reg [0:0] res;
+ reg [0:0] lanefmts;
+ begin
+ res = 1'b0;
+ lanefmts = fpnew_pkg_get_conv_lane_formats(width, cfg, lane_no);
+ begin : sv2v_autoblock_123
+ reg [31:0] ifmt;
+ for (ifmt = 0; ifmt < fpnew_pkg_NUM_INT_FORMATS; ifmt = ifmt + 1)
+ begin : sv2v_autoblock_124
+ reg [31:0] fmt;
+ for (fmt = 0; fmt < fpnew_pkg_NUM_FP_FORMATS; fmt = fmt + 1)
+ res[ifmt] = res[ifmt] | ((icfg[ifmt] && lanefmts[fmt]) && (fpnew_pkg_fp_width(sv2v_cast_38622(fmt)) == fpnew_pkg_int_width(sv2v_cast_E880F(ifmt))));
+ end
+ end
+ fpnew_pkg_get_conv_lane_int_formats = res;
+ end
+ endfunction
+ function automatic [0:0] fpnew_pkg_get_lane_formats;
+ input reg [31:0] width;
+ input reg [0:0] cfg;
+ input reg [31:0] lane_no;
+ reg [0:0] res;
+ reg [31:0] fmt;
+ begin
+ for (fmt = 0; fmt < fpnew_pkg_NUM_FP_FORMATS; fmt = fmt + 1)
+ res[fmt] = cfg[fmt] & ((width / fpnew_pkg_fp_width(sv2v_cast_38622(fmt))) > lane_no);
+ fpnew_pkg_get_lane_formats = res;
+ end
+ endfunction
+ function automatic [0:0] fpnew_pkg_get_lane_int_formats;
+ input reg [31:0] width;
+ input reg [0:0] cfg;
+ input reg [0:0] icfg;
+ input reg [31:0] lane_no;
+ reg [0:0] res;
+ reg [0:0] lanefmts;
+ begin
+ res = 1'b0;
+ lanefmts = fpnew_pkg_get_lane_formats(width, cfg, lane_no);
+ begin : sv2v_autoblock_125
+ reg [31:0] ifmt;
+ for (ifmt = 0; ifmt < fpnew_pkg_NUM_INT_FORMATS; ifmt = ifmt + 1)
+ begin : sv2v_autoblock_126
+ reg [31:0] fmt;
+ for (fmt = 0; fmt < fpnew_pkg_NUM_FP_FORMATS; fmt = fmt + 1)
+ if (fpnew_pkg_fp_width(sv2v_cast_38622(fmt)) == fpnew_pkg_int_width(sv2v_cast_E880F(ifmt)))
+ res[ifmt] = res[ifmt] | (icfg[ifmt] && lanefmts[fmt]);
+ end
+ end
+ fpnew_pkg_get_lane_int_formats = res;
+ end
+ endfunction
+ localparam [3:0] fpnew_pkg_F2F = 10;
+ localparam [3:0] fpnew_pkg_I2F = 12;
+ generate
+ genvar lane;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ for (lane = 0; lane < sv2v_cast_32_signed(NUM_LANES); lane = lane + 1) begin : gen_num_lanes
+ localparam [31:0] LANE = $unsigned(lane);
+ localparam [0:0] ACTIVE_FORMATS = fpnew_pkg_get_lane_formats(Width, FpFmtConfig, LANE);
+ localparam [0:0] ACTIVE_INT_FORMATS = fpnew_pkg_get_lane_int_formats(Width, FpFmtConfig, IntFmtConfig, LANE);
+ localparam [31:0] MAX_WIDTH = fpnew_pkg_max_fp_width(ACTIVE_FORMATS);
+ localparam [0:0] CONV_FORMATS = fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, LANE);
+ localparam [0:0] CONV_INT_FORMATS = fpnew_pkg_get_conv_lane_int_formats(Width, FpFmtConfig, IntFmtConfig, LANE);
+ localparam [31:0] CONV_WIDTH = fpnew_pkg_max_fp_width(CONV_FORMATS);
+ localparam [0:0] LANE_FORMATS = (OpGroup == fpnew_pkg_CONV ? CONV_FORMATS : ACTIVE_FORMATS);
+ localparam [31:0] LANE_WIDTH = (OpGroup == fpnew_pkg_CONV ? CONV_WIDTH : MAX_WIDTH);
+ wire [LANE_WIDTH - 1:0] local_result;
+ if ((lane == 0) || EnableVectors) begin : active_lane
+ wire in_valid;
+ wire out_valid;
+ wire out_ready;
+ reg [(NUM_OPERANDS * LANE_WIDTH) - 1:0] local_operands;
+ wire [LANE_WIDTH - 1:0] op_result;
+ wire [4:0] op_status;
+ assign in_valid = in_valid_i & ((lane == 0) | vectorial_op);
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ function automatic [0:0] sv2v_cast_1;
+ input reg [0:0] inp;
+ sv2v_cast_1 = inp;
+ endfunction
+ always @(*) begin : prepare_input
+ begin : sv2v_autoblock_127
+ reg [31:0] i;
+ for (i = 0; i < NUM_OPERANDS; i = i + 1)
+ local_operands[i * sv2v_cast_32((OpGroup == fpnew_pkg_CONV ? sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) : sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane))))))))+:sv2v_cast_32((OpGroup == fpnew_pkg_CONV ? sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) : sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane))))))))] = operands_i[i * Width+:Width] >> (LANE * fpnew_pkg_fp_width(src_fmt_i));
+ end
+ if (OpGroup == fpnew_pkg_CONV)
+ if (op_i == fpnew_pkg_I2F)
+ local_operands[0+:sv2v_cast_32((OpGroup == fpnew_pkg_CONV ? sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) : sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane))))))))] = operands_i[0+:Width] >> (LANE * fpnew_pkg_int_width(int_fmt_i));
+ else if (op_i == fpnew_pkg_F2F) begin
+ if ((vectorial_op && op_mod_i) && is_up_cast)
+ local_operands[0+:sv2v_cast_32((OpGroup == fpnew_pkg_CONV ? sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) : sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane))))))))] = operands_i[0+:Width] >> ((LANE * fpnew_pkg_fp_width(src_fmt_i)) + (MAX_FP_WIDTH / 2));
+ end
+ else if (dst_is_cpk)
+ if (lane == 1)
+ local_operands[0+:sv2v_cast_32((OpGroup == fpnew_pkg_CONV ? sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) : sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane))))))))] = operands_i[Width + (LANE_WIDTH - 1)-:LANE_WIDTH];
+ end
+ if (OpGroup == fpnew_pkg_ADDMUL) begin : lane_instance
+ fpnew_fma_multi_E4D0A_BE123 #(
+ .AuxType_AUX_BITS(AUX_BITS),
+ .FpFmtConfig(LANE_FORMATS),
+ .NumPipeRegs(NumPipeRegs),
+ .PipeConfig(PipeConfig)
+ ) i_fpnew_fma_multi(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .operands_i(local_operands),
+ .is_boxed_i(is_boxed_i),
+ .rnd_mode_i(rnd_mode_i),
+ .op_i(op_i),
+ .op_mod_i(op_mod_i),
+ .src_fmt_i(src_fmt_i),
+ .dst_fmt_i(dst_fmt_i),
+ .tag_i(tag_i),
+ .aux_i(aux_data),
+ .in_valid_i(in_valid),
+ .in_ready_o(lane_in_ready[lane]),
+ .flush_i(flush_i),
+ .result_o(op_result),
+ .status_o(op_status),
+ .extension_bit_o(lane_ext_bit[lane]),
+ .tag_o(lane_tags[lane]),
+ .aux_o(lane_aux[lane * AUX_BITS+:AUX_BITS]),
+ .out_valid_o(out_valid),
+ .out_ready_i(out_ready),
+ .busy_o(lane_busy[lane])
+ );
+ end
+ else if (OpGroup == fpnew_pkg_DIVSQRT) begin : lane_instance
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ function automatic [0:0] sv2v_cast_1;
+ input reg [0:0] inp;
+ sv2v_cast_1 = inp;
+ endfunction
+ fpnew_divsqrt_multi_28154_735ED #(
+ .AuxType_AUX_BITS(AUX_BITS),
+ .FpFmtConfig(LANE_FORMATS),
+ .NumPipeRegs(NumPipeRegs),
+ .PipeConfig(PipeConfig)
+ ) i_fpnew_divsqrt_multi(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .operands_i(local_operands[0+:sv2v_cast_32((OpGroup == fpnew_pkg_CONV ? sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) : sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))))) * 2]),
+ .is_boxed_i(is_boxed_2op),
+ .rnd_mode_i(rnd_mode_i),
+ .op_i(op_i),
+ .dst_fmt_i(dst_fmt_i),
+ .tag_i(tag_i),
+ .aux_i(aux_data),
+ .in_valid_i(in_valid),
+ .in_ready_o(lane_in_ready[lane]),
+ .flush_i(flush_i),
+ .result_o(op_result),
+ .status_o(op_status),
+ .extension_bit_o(lane_ext_bit[lane]),
+ .tag_o(lane_tags[lane]),
+ .aux_o(lane_aux[lane * AUX_BITS+:AUX_BITS]),
+ .out_valid_o(out_valid),
+ .out_ready_i(out_ready),
+ .busy_o(lane_busy[lane])
+ );
+ end
+ else if (OpGroup == fpnew_pkg_NONCOMP) ;
+ else if (OpGroup == fpnew_pkg_CONV) begin : lane_instance
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ function automatic [0:0] sv2v_cast_1;
+ input reg [0:0] inp;
+ sv2v_cast_1 = inp;
+ endfunction
+ fpnew_cast_multi_8A35C_87530 #(
+ .AuxType_AUX_BITS(AUX_BITS),
+ .FpFmtConfig(LANE_FORMATS),
+ .IntFmtConfig(CONV_INT_FORMATS),
+ .NumPipeRegs(NumPipeRegs),
+ .PipeConfig(PipeConfig)
+ ) i_fpnew_cast_multi(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .operands_i(local_operands[0+:sv2v_cast_32((OpGroup == fpnew_pkg_CONV ? sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) : sv2v_cast_32(fpnew_pkg_max_fp_width(sv2v_cast_1(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane))))))))]),
+ .is_boxed_i(is_boxed_1op),
+ .rnd_mode_i(rnd_mode_i),
+ .op_i(op_i),
+ .op_mod_i(op_mod_i),
+ .src_fmt_i(src_fmt_i),
+ .dst_fmt_i(dst_fmt_i),
+ .int_fmt_i(int_fmt_i),
+ .tag_i(tag_i),
+ .aux_i(aux_data),
+ .in_valid_i(in_valid),
+ .in_ready_o(lane_in_ready[lane]),
+ .flush_i(flush_i),
+ .result_o(op_result),
+ .status_o(op_status),
+ .extension_bit_o(lane_ext_bit[lane]),
+ .tag_o(lane_tags[lane]),
+ .aux_o(lane_aux[lane * AUX_BITS+:AUX_BITS]),
+ .out_valid_o(out_valid),
+ .out_ready_i(out_ready),
+ .busy_o(lane_busy[lane])
+ );
+ end
+ assign out_ready = out_ready_i & ((lane == 0) | result_is_vector);
+ assign lane_out_valid[lane] = out_valid & ((lane == 0) | result_is_vector);
+ function automatic [0:0] sv2v_cast_18C91;
+ input reg [0:0] inp;
+ sv2v_cast_18C91 = inp;
+ endfunction
+ assign local_result = (lane_out_valid[lane] ? op_result : {(OpGroup == fpnew_pkg_CONV ? fpnew_pkg_max_fp_width(sv2v_cast_18C91(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane))))) : fpnew_pkg_max_fp_width(sv2v_cast_18C91(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) {lane_ext_bit[0]}});
+ assign lane_status[lane * 5+:5] = (lane_out_valid[lane] ? op_status : {5 {1'sb0}});
+ end
+ else begin : inactive_lane
+ assign lane_out_valid[lane] = 1'b0;
+ assign lane_in_ready[lane] = 1'b0;
+ function automatic [0:0] sv2v_cast_18C91;
+ input reg [0:0] inp;
+ sv2v_cast_18C91 = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ assign local_result = {(OpGroup == fpnew_pkg_CONV ? fpnew_pkg_max_fp_width(sv2v_cast_18C91(fpnew_pkg_get_conv_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane))))) : fpnew_pkg_max_fp_width(sv2v_cast_18C91(fpnew_pkg_get_lane_formats(Width, FpFmtConfig, sv2v_cast_32($unsigned(lane)))))) {lane_ext_bit[0]}};
+ assign lane_status[lane * 5+:5] = {5 {1'sb0}};
+ assign lane_busy[lane] = 1'b0;
+ end
+ genvar fmt;
+ for (fmt = 0; fmt < NUM_FORMATS; fmt = fmt + 1) begin : pack_fp_result
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_38622;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_38622 = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_38622(fmt));
+ if (ACTIVE_FORMATS[fmt]) begin
+ assign fmt_slice_result[(fmt * Width) + ((((LANE + 1) * FP_WIDTH) - 1) >= (LANE * FP_WIDTH) ? ((LANE + 1) * FP_WIDTH) - 1 : ((((LANE + 1) * FP_WIDTH) - 1) + ((((LANE + 1) * FP_WIDTH) - 1) >= (LANE * FP_WIDTH) ? ((((LANE + 1) * FP_WIDTH) - 1) - (LANE * FP_WIDTH)) + 1 : ((LANE * FP_WIDTH) - (((LANE + 1) * FP_WIDTH) - 1)) + 1)) - 1)-:((((LANE + 1) * FP_WIDTH) - 1) >= (LANE * FP_WIDTH) ? ((((LANE + 1) * FP_WIDTH) - 1) - (LANE * FP_WIDTH)) + 1 : ((LANE * FP_WIDTH) - (((LANE + 1) * FP_WIDTH) - 1)) + 1)] = local_result[FP_WIDTH - 1:0];
+ end
+ else if (((LANE + 1) * FP_WIDTH) <= Width) begin
+ assign fmt_slice_result[(fmt * Width) + ((((LANE + 1) * FP_WIDTH) - 1) >= (LANE * FP_WIDTH) ? ((LANE + 1) * FP_WIDTH) - 1 : ((((LANE + 1) * FP_WIDTH) - 1) + ((((LANE + 1) * FP_WIDTH) - 1) >= (LANE * FP_WIDTH) ? ((((LANE + 1) * FP_WIDTH) - 1) - (LANE * FP_WIDTH)) + 1 : ((LANE * FP_WIDTH) - (((LANE + 1) * FP_WIDTH) - 1)) + 1)) - 1)-:((((LANE + 1) * FP_WIDTH) - 1) >= (LANE * FP_WIDTH) ? ((((LANE + 1) * FP_WIDTH) - 1) - (LANE * FP_WIDTH)) + 1 : ((LANE * FP_WIDTH) - (((LANE + 1) * FP_WIDTH) - 1)) + 1)] = {((((LANE + 1) * FP_WIDTH) - 1) >= (LANE * FP_WIDTH) ? ((((LANE + 1) * FP_WIDTH) - 1) - (LANE * FP_WIDTH)) + 1 : ((LANE * FP_WIDTH) - (((LANE + 1) * FP_WIDTH) - 1)) + 1) {lane_ext_bit[LANE]}};
+ end
+ else if ((LANE * FP_WIDTH) < Width) assign fmt_slice_result[(fmt * Width) + ((Width - 1) >= (LANE * FP_WIDTH) ? Width - 1 : ((Width - 1) + ((Width - 1) >= (LANE * FP_WIDTH) ? ((Width - 1) - (LANE * FP_WIDTH)) + 1 : ((LANE * FP_WIDTH) - (Width - 1)) + 1)) - 1)-:((Width - 1) >= (LANE * FP_WIDTH) ? ((Width - 1) - (LANE * FP_WIDTH)) + 1 : ((LANE * FP_WIDTH) - (Width - 1)) + 1)] = {((Width - 1) >= (LANE * FP_WIDTH) ? ((Width - 1) - (LANE * FP_WIDTH)) + 1 : ((LANE * FP_WIDTH) - (Width - 1)) + 1) {lane_ext_bit[LANE]}};
+ end
+ if (OpGroup == fpnew_pkg_CONV) begin : int_results_enabled
+ genvar ifmt;
+ for (ifmt = 0; ifmt < NUM_INT_FORMATS; ifmt = ifmt + 1) begin : pack_int_result
+ function automatic [fpnew_pkg_INT_FORMAT_BITS - 1:0] sv2v_cast_E880F;
+ input reg [fpnew_pkg_INT_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_E880F = inp;
+ endfunction
+ localparam [31:0] INT_WIDTH = fpnew_pkg_int_width(sv2v_cast_E880F(ifmt));
+ if (ACTIVE_INT_FORMATS[ifmt]) begin
+ assign ifmt_slice_result[(ifmt * Width) + ((((LANE + 1) * INT_WIDTH) - 1) >= (LANE * INT_WIDTH) ? ((LANE + 1) * INT_WIDTH) - 1 : ((((LANE + 1) * INT_WIDTH) - 1) + ((((LANE + 1) * INT_WIDTH) - 1) >= (LANE * INT_WIDTH) ? ((((LANE + 1) * INT_WIDTH) - 1) - (LANE * INT_WIDTH)) + 1 : ((LANE * INT_WIDTH) - (((LANE + 1) * INT_WIDTH) - 1)) + 1)) - 1)-:((((LANE + 1) * INT_WIDTH) - 1) >= (LANE * INT_WIDTH) ? ((((LANE + 1) * INT_WIDTH) - 1) - (LANE * INT_WIDTH)) + 1 : ((LANE * INT_WIDTH) - (((LANE + 1) * INT_WIDTH) - 1)) + 1)] = local_result[INT_WIDTH - 1:0];
+ end
+ else if (((LANE + 1) * INT_WIDTH) <= Width) begin
+ assign ifmt_slice_result[(ifmt * Width) + ((((LANE + 1) * INT_WIDTH) - 1) >= (LANE * INT_WIDTH) ? ((LANE + 1) * INT_WIDTH) - 1 : ((((LANE + 1) * INT_WIDTH) - 1) + ((((LANE + 1) * INT_WIDTH) - 1) >= (LANE * INT_WIDTH) ? ((((LANE + 1) * INT_WIDTH) - 1) - (LANE * INT_WIDTH)) + 1 : ((LANE * INT_WIDTH) - (((LANE + 1) * INT_WIDTH) - 1)) + 1)) - 1)-:((((LANE + 1) * INT_WIDTH) - 1) >= (LANE * INT_WIDTH) ? ((((LANE + 1) * INT_WIDTH) - 1) - (LANE * INT_WIDTH)) + 1 : ((LANE * INT_WIDTH) - (((LANE + 1) * INT_WIDTH) - 1)) + 1)] = {((((LANE + 1) * INT_WIDTH) - 1) >= (LANE * INT_WIDTH) ? ((((LANE + 1) * INT_WIDTH) - 1) - (LANE * INT_WIDTH)) + 1 : ((LANE * INT_WIDTH) - (((LANE + 1) * INT_WIDTH) - 1)) + 1) {1'sb0}};
+ end
+ else if ((LANE * INT_WIDTH) < Width) assign ifmt_slice_result[(ifmt * Width) + ((Width - 1) >= (LANE * INT_WIDTH) ? Width - 1 : ((Width - 1) + ((Width - 1) >= (LANE * INT_WIDTH) ? ((Width - 1) - (LANE * INT_WIDTH)) + 1 : ((LANE * INT_WIDTH) - (Width - 1)) + 1)) - 1)-:((Width - 1) >= (LANE * INT_WIDTH) ? ((Width - 1) - (LANE * INT_WIDTH)) + 1 : ((LANE * INT_WIDTH) - (Width - 1)) + 1)] = {((Width - 1) >= (LANE * INT_WIDTH) ? ((Width - 1) - (LANE * INT_WIDTH)) + 1 : ((LANE * INT_WIDTH) - (Width - 1)) + 1) {1'sb0}};
+ end
+ end
+ end
+ endgenerate
+ generate
+ genvar fmt;
+ for (fmt = 0; fmt < NUM_FORMATS; fmt = fmt + 1) begin : extend_fp_result
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_38622;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_38622 = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_38622(fmt));
+ if ((NUM_LANES * FP_WIDTH) < Width) assign fmt_slice_result[(fmt * Width) + ((Width - 1) >= (NUM_LANES * FP_WIDTH) ? Width - 1 : ((Width - 1) + ((Width - 1) >= (NUM_LANES * FP_WIDTH) ? ((Width - 1) - (NUM_LANES * FP_WIDTH)) + 1 : ((NUM_LANES * FP_WIDTH) - (Width - 1)) + 1)) - 1)-:((Width - 1) >= (NUM_LANES * FP_WIDTH) ? ((Width - 1) - (NUM_LANES * FP_WIDTH)) + 1 : ((NUM_LANES * FP_WIDTH) - (Width - 1)) + 1)] = {((Width - 1) >= (NUM_LANES * FP_WIDTH) ? ((Width - 1) - (NUM_LANES * FP_WIDTH)) + 1 : ((NUM_LANES * FP_WIDTH) - (Width - 1)) + 1) {lane_ext_bit[0]}};
+ end
+ endgenerate
+ generate
+ genvar ifmt;
+ for (ifmt = 0; ifmt < NUM_INT_FORMATS; ifmt = ifmt + 1) begin : int_results_disabled
+ if (OpGroup != fpnew_pkg_CONV) begin : mute_int_result
+ assign ifmt_slice_result[ifmt * Width+:Width] = {Width {1'sb0}};
+ end
+ end
+ endgenerate
+ generate
+ if (OpGroup == fpnew_pkg_CONV) begin : target_regs
+ wire [(0 >= NumPipeRegs ? ((1 - NumPipeRegs) * Width) + ((NumPipeRegs * Width) - 1) : ((NumPipeRegs + 1) * Width) - 1):(0 >= NumPipeRegs ? NumPipeRegs * Width : 0)] byp_pipe_target_q;
+ wire [(0 >= NumPipeRegs ? ((1 - NumPipeRegs) * 3) + ((NumPipeRegs * 3) - 1) : ((NumPipeRegs + 1) * 3) - 1):(0 >= NumPipeRegs ? NumPipeRegs * 3 : 0)] byp_pipe_aux_q;
+ wire [0:NumPipeRegs] byp_pipe_valid_q;
+ wire [0:NumPipeRegs] byp_pipe_ready;
+ assign byp_pipe_target_q[(0 >= NumPipeRegs ? 0 : NumPipeRegs) * Width+:Width] = conv_target_d;
+ assign byp_pipe_aux_q[(0 >= NumPipeRegs ? 0 : NumPipeRegs) * 3+:3] = target_aux_d;
+ assign byp_pipe_valid_q[0] = in_valid_i & vectorial_op;
+ genvar i;
+ for (i = 0; i < NumPipeRegs; i = i + 1) begin : gen_bypass_pipeline
+ wire reg_ena;
+ assign byp_pipe_ready[i] = byp_pipe_ready[i + 1] | ~byp_pipe_valid_q[i + 1];
+ assign reg_ena = byp_pipe_ready[i] & byp_pipe_valid_q[i];
+ end
+ assign byp_pipe_ready[NumPipeRegs] = out_ready_i & result_is_vector;
+ assign conv_target_q = byp_pipe_target_q[(0 >= NumPipeRegs ? NumPipeRegs : NumPipeRegs - NumPipeRegs) * Width+:Width];
+ assign {result_vec_op, result_is_cpk} = byp_pipe_aux_q[(0 >= NumPipeRegs ? NumPipeRegs : NumPipeRegs - NumPipeRegs) * 3+:3];
+ end
+ else begin : no_conv
+ assign {result_vec_op, result_is_cpk} = {3 {1'sb0}};
+ end
+ endgenerate
+ assign {result_fmt_is_int, result_is_vector, result_fmt} = lane_aux[0+:AUX_BITS];
+ assign result_o = (result_fmt_is_int ? ifmt_slice_result[result_fmt * Width+:Width] : fmt_slice_result[result_fmt * Width+:Width]);
+ assign extension_bit_o = lane_ext_bit[0];
+ assign tag_o = lane_tags[0];
+ assign busy_o = |lane_busy;
+ assign out_valid_o = lane_out_valid[0];
+ always @(*) begin : output_processing
+ reg [4:0] temp_status;
+ temp_status = {5 {1'sb0}};
+ begin : sv2v_autoblock_128
+ reg signed [31:0] i;
+ for (i = 0; i < sv2v_cast_32_signed(NUM_LANES); i = i + 1)
+ temp_status = temp_status | lane_status[i * 5+:5];
+ end
+ status_o = temp_status;
+ end
+endmodule
+module fpnew_rounding (
+ abs_value_i,
+ sign_i,
+ round_sticky_bits_i,
+ rnd_mode_i,
+ effective_subtraction_i,
+ abs_rounded_o,
+ sign_o,
+ exact_zero_o
+);
+ parameter [31:0] AbsWidth = 2;
+ input wire [AbsWidth - 1:0] abs_value_i;
+ input wire sign_i;
+ input wire [1:0] round_sticky_bits_i;
+ input wire [2:0] rnd_mode_i;
+ input wire effective_subtraction_i;
+ output wire [AbsWidth - 1:0] abs_rounded_o;
+ output wire sign_o;
+ output wire exact_zero_o;
+ reg round_up;
+ localparam [0:0] fpnew_pkg_DONT_CARE = 1'b1;
+ localparam [2:0] fpnew_pkg_RDN = 3'b010;
+ localparam [2:0] fpnew_pkg_RMM = 3'b100;
+ localparam [2:0] fpnew_pkg_RNE = 3'b000;
+ localparam [2:0] fpnew_pkg_RTZ = 3'b001;
+ localparam [2:0] fpnew_pkg_RUP = 3'b011;
+ always @(*) begin : rounding_decision
+ case (rnd_mode_i)
+ fpnew_pkg_RNE:
+ case (round_sticky_bits_i)
+ 2'b00, 2'b01: round_up = 1'b0;
+ 2'b10: round_up = abs_value_i[0];
+ 2'b11: round_up = 1'b1;
+ endcase
+ fpnew_pkg_RTZ: round_up = 1'b0;
+ fpnew_pkg_RDN: round_up = (|round_sticky_bits_i ? sign_i : 1'b0);
+ fpnew_pkg_RUP: round_up = (|round_sticky_bits_i ? ~sign_i : 1'b0);
+ fpnew_pkg_RMM: round_up = round_sticky_bits_i[1];
+ default: round_up = fpnew_pkg_DONT_CARE;
+ endcase
+ end
+ assign abs_rounded_o = abs_value_i + round_up;
+ assign exact_zero_o = (abs_value_i == {AbsWidth {1'sb0}}) && (round_sticky_bits_i == {2 {1'sb0}});
+ assign sign_o = (exact_zero_o && effective_subtraction_i ? rnd_mode_i == fpnew_pkg_RDN : sign_i);
+endmodule
+module fpnew_top_F1920 (
+ clk_i,
+ rst_ni,
+ operands_i,
+ rnd_mode_i,
+ op_i,
+ op_mod_i,
+ src_fmt_i,
+ dst_fmt_i,
+ int_fmt_i,
+ vectorial_op_i,
+ tag_i,
+ in_valid_i,
+ in_ready_o,
+ flush_i,
+ result_o,
+ status_o,
+ tag_o,
+ out_valid_o,
+ out_ready_i,
+ busy_o
+);
+ localparam [31:0] fpnew_pkg_NUM_FP_FORMATS = 1;
+ localparam [31:0] fpnew_pkg_NUM_INT_FORMATS = 1;
+ function automatic [0:0] sv2v_cast_1;
+ input reg [0:0] inp;
+ sv2v_cast_1 = inp;
+ endfunction
+ localparam [35:0] fpnew_pkg_RV64D_Xsflt = {34'b0000000000000000000000000100000011, sv2v_cast_1(5'b11111), sv2v_cast_1(4'b1111)};
+ parameter [35:0] Features = fpnew_pkg_RV64D_Xsflt;
+ localparam [31:0] fpnew_pkg_NUM_OPGROUPS = 4;
+ localparam [1:0] fpnew_pkg_BEFORE = 0;
+ localparam [1:0] fpnew_pkg_MERGED = 2;
+ localparam [1:0] fpnew_pkg_PARALLEL = 1;
+ function automatic [31:0] sv2v_cast_33F2F;
+ input reg [31:0] inp;
+ sv2v_cast_33F2F = inp;
+ endfunction
+ function automatic [127:0] sv2v_cast_128;
+ input reg [127:0] inp;
+ sv2v_cast_128 = inp;
+ endfunction
+ function automatic [7:0] sv2v_cast_8;
+ input reg [7:0] inp;
+ sv2v_cast_8 = inp;
+ endfunction
+ localparam [137:0] fpnew_pkg_DEFAULT_NOREGS = {sv2v_cast_128({fpnew_pkg_NUM_OPGROUPS {sv2v_cast_33F2F(0)}}), sv2v_cast_8({{fpnew_pkg_PARALLEL}, {fpnew_pkg_MERGED}, {fpnew_pkg_PARALLEL}, {fpnew_pkg_MERGED}}), fpnew_pkg_BEFORE};
+ parameter [137:0] Implementation = fpnew_pkg_DEFAULT_NOREGS;
+ localparam [31:0] WIDTH = Features[35-:32];
+ localparam [31:0] NUM_OPERANDS = 3;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [(NUM_OPERANDS * WIDTH) - 1:0] operands_i;
+ input wire [2:0] rnd_mode_i;
+ localparam [31:0] fpnew_pkg_OP_BITS = 4;
+ input wire [3:0] op_i;
+ input wire op_mod_i;
+ localparam [31:0] fpnew_pkg_FP_FORMAT_BITS = 0;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] src_fmt_i;
+ input wire [fpnew_pkg_FP_FORMAT_BITS - 1:0] dst_fmt_i;
+ localparam [31:0] fpnew_pkg_INT_FORMAT_BITS = 0;
+ input wire [fpnew_pkg_INT_FORMAT_BITS - 1:0] int_fmt_i;
+ input wire vectorial_op_i;
+ input wire tag_i;
+ input wire in_valid_i;
+ output wire in_ready_o;
+ input wire flush_i;
+ output wire [WIDTH - 1:0] result_o;
+ output wire [4:0] status_o;
+ output wire tag_o;
+ output wire out_valid_o;
+ input wire out_ready_i;
+ output wire busy_o;
+ localparam [31:0] NUM_OPGROUPS = fpnew_pkg_NUM_OPGROUPS;
+ localparam [31:0] NUM_FORMATS = fpnew_pkg_NUM_FP_FORMATS;
+ wire [3:0] opgrp_in_ready;
+ wire [3:0] opgrp_out_valid;
+ wire [3:0] opgrp_out_ready;
+ wire [3:0] opgrp_ext;
+ wire [3:0] opgrp_busy;
+ wire [((WIDTH + 5) >= 0 ? (4 * (WIDTH + 6)) - 1 : (4 * (1 - (WIDTH + 5))) + (WIDTH + 4)):((WIDTH + 5) >= 0 ? 0 : WIDTH + 5)] opgrp_outputs;
+ wire [2:0] is_boxed;
+ localparam [3:0] fpnew_pkg_ADD = 2;
+ localparam [1:0] fpnew_pkg_ADDMUL = 0;
+ localparam [3:0] fpnew_pkg_CLASSIFY = 9;
+ localparam [3:0] fpnew_pkg_CMP = 8;
+ localparam [1:0] fpnew_pkg_CONV = 3;
+ localparam [3:0] fpnew_pkg_CPKAB = 13;
+ localparam [3:0] fpnew_pkg_CPKCD = 14;
+ localparam [3:0] fpnew_pkg_DIV = 4;
+ localparam [1:0] fpnew_pkg_DIVSQRT = 1;
+ localparam [3:0] fpnew_pkg_F2F = 10;
+ localparam [3:0] fpnew_pkg_F2I = 11;
+ localparam [3:0] fpnew_pkg_FMADD = 0;
+ localparam [3:0] fpnew_pkg_FNMSUB = 1;
+ localparam [3:0] fpnew_pkg_I2F = 12;
+ localparam [3:0] fpnew_pkg_MINMAX = 7;
+ localparam [3:0] fpnew_pkg_MUL = 3;
+ localparam [1:0] fpnew_pkg_NONCOMP = 2;
+ localparam [3:0] fpnew_pkg_SGNJ = 6;
+ localparam [3:0] fpnew_pkg_SQRT = 5;
+ function automatic [1:0] fpnew_pkg_get_opgroup;
+ input reg [3:0] op;
+ case (op)
+ fpnew_pkg_FMADD, fpnew_pkg_FNMSUB, fpnew_pkg_ADD, fpnew_pkg_MUL: fpnew_pkg_get_opgroup = fpnew_pkg_ADDMUL;
+ fpnew_pkg_DIV, fpnew_pkg_SQRT: fpnew_pkg_get_opgroup = fpnew_pkg_DIVSQRT;
+ fpnew_pkg_SGNJ, fpnew_pkg_MINMAX, fpnew_pkg_CMP, fpnew_pkg_CLASSIFY: fpnew_pkg_get_opgroup = fpnew_pkg_NONCOMP;
+ fpnew_pkg_F2F, fpnew_pkg_F2I, fpnew_pkg_I2F, fpnew_pkg_CPKAB, fpnew_pkg_CPKCD: fpnew_pkg_get_opgroup = fpnew_pkg_CONV;
+ default: fpnew_pkg_get_opgroup = fpnew_pkg_NONCOMP;
+ endcase
+ endfunction
+ assign in_ready_o = in_valid_i & opgrp_in_ready[fpnew_pkg_get_opgroup(op_i)];
+ localparam [63:0] fpnew_pkg_FP_ENCODINGS = 64'h0000000800000017;
+ function automatic [31:0] fpnew_pkg_fp_width;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] fmt;
+ fpnew_pkg_fp_width = (fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 63-:32] + fpnew_pkg_FP_ENCODINGS[(fmt * 64) + 31-:32]) + 1;
+ endfunction
+ generate
+ genvar fmt;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ for (fmt = 0; fmt < sv2v_cast_32_signed(NUM_FORMATS); fmt = fmt + 1) begin : gen_nanbox_check
+ function automatic [fpnew_pkg_FP_FORMAT_BITS - 1:0] sv2v_cast_B5DD5;
+ input reg [fpnew_pkg_FP_FORMAT_BITS - 1:0] inp;
+ sv2v_cast_B5DD5 = inp;
+ endfunction
+ localparam [31:0] FP_WIDTH = fpnew_pkg_fp_width(sv2v_cast_B5DD5(fmt));
+ if (Features[2] && (FP_WIDTH < WIDTH)) begin : check
+ genvar op;
+ function automatic signed [31:0] sv2v_cast_32_signed;
+ input reg signed [31:0] inp;
+ sv2v_cast_32_signed = inp;
+ endfunction
+ for (op = 0; op < sv2v_cast_32_signed(NUM_OPERANDS); op = op + 1) begin : operands
+ assign is_boxed[(fmt * NUM_OPERANDS) + op] = (!vectorial_op_i ? operands_i[(op * WIDTH) + ((WIDTH - 1) >= FP_WIDTH ? WIDTH - 1 : ((WIDTH - 1) + ((WIDTH - 1) >= FP_WIDTH ? ((WIDTH - 1) - FP_WIDTH) + 1 : (FP_WIDTH - (WIDTH - 1)) + 1)) - 1)-:((WIDTH - 1) >= FP_WIDTH ? ((WIDTH - 1) - FP_WIDTH) + 1 : (FP_WIDTH - (WIDTH - 1)) + 1)] == {((WIDTH - 1) >= FP_WIDTH ? ((WIDTH - 1) - FP_WIDTH) + 1 : (FP_WIDTH - (WIDTH - 1)) + 1) {1'sb1}} : 1'b1);
+ end
+ end
+ else begin : no_check
+ assign is_boxed[fmt * NUM_OPERANDS+:NUM_OPERANDS] = {3 {1'sb1}};
+ end
+ end
+ endgenerate
+ function automatic [31:0] fpnew_pkg_num_operands;
+ input reg [1:0] grp;
+ case (grp)
+ fpnew_pkg_ADDMUL: fpnew_pkg_num_operands = 3;
+ fpnew_pkg_DIVSQRT: fpnew_pkg_num_operands = 2;
+ fpnew_pkg_NONCOMP: fpnew_pkg_num_operands = 2;
+ fpnew_pkg_CONV: fpnew_pkg_num_operands = 3;
+ default: fpnew_pkg_num_operands = 0;
+ endcase
+ endfunction
+ generate
+ genvar opgrp;
+ for (opgrp = 0; opgrp < sv2v_cast_32_signed(NUM_OPGROUPS); opgrp = opgrp + 1) begin : gen_operation_groups
+ function automatic [1:0] sv2v_cast_2;
+ input reg [1:0] inp;
+ sv2v_cast_2 = inp;
+ endfunction
+ localparam [31:0] NUM_OPS = fpnew_pkg_num_operands(sv2v_cast_2(opgrp));
+ wire in_valid;
+ reg [(NUM_FORMATS * NUM_OPS) - 1:0] input_boxed;
+ assign in_valid = in_valid_i & (fpnew_pkg_get_opgroup(op_i) == sv2v_cast_2(opgrp));
+ function automatic [31:0] sv2v_cast_32;
+ input reg [31:0] inp;
+ sv2v_cast_32 = inp;
+ endfunction
+ always @(*) begin : slice_inputs
+ begin : sv2v_autoblock_129
+ reg [31:0] fmt;
+ for (fmt = 0; fmt < NUM_FORMATS; fmt = fmt + 1)
+ input_boxed[fmt * sv2v_cast_32(fpnew_pkg_num_operands(sv2v_cast_2(opgrp)))+:sv2v_cast_32(fpnew_pkg_num_operands(sv2v_cast_2(opgrp)))] = is_boxed[(fmt * 3) + (NUM_OPS - 1)-:NUM_OPS];
+ end
+ end
+ fpnew_opgroup_block_BE2AB #(
+ .OpGroup(sv2v_cast_2(opgrp)),
+ .Width(WIDTH),
+ .EnableVectors(Features[3]),
+ .FpFmtMask(Features[1-:1]),
+ .IntFmtMask(Features[0-:1]),
+ .FmtPipeRegs(Implementation[10 + (32 * (3 - opgrp))+:32]),
+ .FmtUnitTypes(Implementation[2 + (2 * (3 - opgrp))+:2]),
+ .PipeConfig(Implementation[1-:2])
+ ) i_opgroup_block(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .operands_i(operands_i[WIDTH * ((NUM_OPS - 1) - (NUM_OPS - 1))+:WIDTH * NUM_OPS]),
+ .is_boxed_i(input_boxed),
+ .rnd_mode_i(rnd_mode_i),
+ .op_i(op_i),
+ .op_mod_i(op_mod_i),
+ .src_fmt_i(src_fmt_i),
+ .dst_fmt_i(dst_fmt_i),
+ .int_fmt_i(int_fmt_i),
+ .vectorial_op_i(vectorial_op_i),
+ .tag_i(tag_i),
+ .in_valid_i(in_valid),
+ .in_ready_o(opgrp_in_ready[opgrp]),
+ .flush_i(flush_i),
+ .result_o(opgrp_outputs[((WIDTH + 5) >= 0 ? (opgrp * ((WIDTH + 5) >= 0 ? WIDTH + 6 : 1 - (WIDTH + 5))) + ((WIDTH + 5) >= 0 ? WIDTH + 5 : (WIDTH + 5) - (WIDTH + 5)) : (((opgrp * ((WIDTH + 5) >= 0 ? WIDTH + 6 : 1 - (WIDTH + 5))) + ((WIDTH + 5) >= 0 ? WIDTH + 5 : (WIDTH + 5) - (WIDTH + 5))) + ((WIDTH + 5) >= 6 ? WIDTH : 7 - (WIDTH + 5))) - 1)-:((WIDTH + 5) >= 6 ? WIDTH : 7 - (WIDTH + 5))]),
+ .status_o(opgrp_outputs[((WIDTH + 5) >= 0 ? (opgrp * ((WIDTH + 5) >= 0 ? WIDTH + 6 : 1 - (WIDTH + 5))) + ((WIDTH + 5) >= 0 ? 5 : WIDTH) : ((opgrp * ((WIDTH + 5) >= 0 ? WIDTH + 6 : 1 - (WIDTH + 5))) + ((WIDTH + 5) >= 0 ? 5 : WIDTH)) + 4)-:5]),
+ .extension_bit_o(opgrp_ext[opgrp]),
+ .tag_o(opgrp_outputs[(opgrp * ((WIDTH + 5) >= 0 ? WIDTH + 6 : 1 - (WIDTH + 5))) + ((WIDTH + 5) >= 0 ? 0 : WIDTH + 5)]),
+ .out_valid_o(opgrp_out_valid[opgrp]),
+ .out_ready_i(opgrp_out_ready[opgrp]),
+ .busy_o(opgrp_busy[opgrp])
+ );
+ end
+ endgenerate
+ wire [WIDTH + 5:0] arbiter_output;
+ rr_arb_tree_CBEBF_6E668 #(
+ .DataType_WIDTH(WIDTH),
+ .NumIn(NUM_OPGROUPS),
+ .AxiVldRdy(1'b1)
+ ) i_arbiter(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .flush_i(flush_i),
+ .rr_i({$unsigned(2) {1'sb0}}),
+ .req_i(opgrp_out_valid),
+ .gnt_o(opgrp_out_ready),
+ .data_i(opgrp_outputs),
+ .gnt_i(out_ready_i),
+ .req_o(out_valid_o),
+ .data_o(arbiter_output),
+ .idx_o()
+ );
+ assign result_o = arbiter_output[WIDTH + 5-:((WIDTH + 5) >= 6 ? WIDTH : 7 - (WIDTH + 5))];
+ assign status_o = arbiter_output[5-:5];
+ assign tag_o = arbiter_output[0];
+ assign busy_o = |opgrp_busy;
+endmodule
+module gpio_reg_top (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ reg2hw,
+ hw2reg,
+ devmode_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire [458:0] reg2hw;
+ input wire [257:0] hw2reg;
+ input devmode_i;
+ localparam signed [31:0] AW = 6;
+ localparam signed [31:0] DW = 32;
+ localparam signed [31:0] DBW = 4;
+ wire reg_we;
+ wire reg_re;
+ wire [5:0] reg_addr;
+ wire [31:0] reg_wdata;
+ wire [3:0] reg_be;
+ wire [31:0] reg_rdata;
+ wire reg_error;
+ wire addrmiss;
+ reg wr_err;
+ reg [31:0] reg_rdata_next;
+ wire [85:0] tl_reg_h2d;
+ wire [51:0] tl_reg_d2h;
+ assign tl_reg_h2d = tl_i;
+ assign tl_o = tl_reg_d2h;
+ tlul_adapter_reg #(
+ .RegAw(AW),
+ .RegDw(DW)
+ ) u_reg_if(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_reg_h2d),
+ .tl_o(tl_reg_d2h),
+ .we_o(reg_we),
+ .re_o(reg_re),
+ .addr_o(reg_addr),
+ .wdata_o(reg_wdata),
+ .be_o(reg_be),
+ .rdata_i(reg_rdata),
+ .error_i(reg_error)
+ );
+ assign reg_rdata = reg_rdata_next;
+ assign reg_error = (devmode_i & addrmiss) | wr_err;
+ wire [31:0] intr_state_qs;
+ wire [31:0] intr_state_wd;
+ wire intr_state_we;
+ wire [31:0] intr_enable_qs;
+ wire [31:0] intr_enable_wd;
+ wire intr_enable_we;
+ wire [31:0] intr_test_wd;
+ wire intr_test_we;
+ wire [31:0] data_in_qs;
+ wire [31:0] direct_out_qs;
+ wire [31:0] direct_out_wd;
+ wire direct_out_we;
+ wire direct_out_re;
+ wire [15:0] masked_out_lower_data_qs;
+ wire [15:0] masked_out_lower_data_wd;
+ wire masked_out_lower_data_we;
+ wire masked_out_lower_data_re;
+ wire [15:0] masked_out_lower_mask_wd;
+ wire masked_out_lower_mask_we;
+ wire [15:0] masked_out_upper_data_qs;
+ wire [15:0] masked_out_upper_data_wd;
+ wire masked_out_upper_data_we;
+ wire masked_out_upper_data_re;
+ wire [15:0] masked_out_upper_mask_wd;
+ wire masked_out_upper_mask_we;
+ wire [31:0] direct_oe_qs;
+ wire [31:0] direct_oe_wd;
+ wire direct_oe_we;
+ wire direct_oe_re;
+ wire [15:0] masked_oe_lower_data_qs;
+ wire [15:0] masked_oe_lower_data_wd;
+ wire masked_oe_lower_data_we;
+ wire masked_oe_lower_data_re;
+ wire [15:0] masked_oe_lower_mask_qs;
+ wire [15:0] masked_oe_lower_mask_wd;
+ wire masked_oe_lower_mask_we;
+ wire masked_oe_lower_mask_re;
+ wire [15:0] masked_oe_upper_data_qs;
+ wire [15:0] masked_oe_upper_data_wd;
+ wire masked_oe_upper_data_we;
+ wire masked_oe_upper_data_re;
+ wire [15:0] masked_oe_upper_mask_qs;
+ wire [15:0] masked_oe_upper_mask_wd;
+ wire masked_oe_upper_mask_we;
+ wire masked_oe_upper_mask_re;
+ wire [31:0] intr_ctrl_en_rising_qs;
+ wire [31:0] intr_ctrl_en_rising_wd;
+ wire intr_ctrl_en_rising_we;
+ wire [31:0] intr_ctrl_en_falling_qs;
+ wire [31:0] intr_ctrl_en_falling_wd;
+ wire intr_ctrl_en_falling_we;
+ wire [31:0] intr_ctrl_en_lvlhigh_qs;
+ wire [31:0] intr_ctrl_en_lvlhigh_wd;
+ wire intr_ctrl_en_lvlhigh_we;
+ wire [31:0] intr_ctrl_en_lvllow_qs;
+ wire [31:0] intr_ctrl_en_lvllow_wd;
+ wire intr_ctrl_en_lvllow_we;
+ wire [31:0] ctrl_en_input_filter_qs;
+ wire [31:0] ctrl_en_input_filter_wd;
+ wire ctrl_en_input_filter_we;
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("W1C"),
+ .RESVAL(32'h00000000)
+ ) u_intr_state(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(intr_state_we),
+ .wd(intr_state_wd),
+ .de(hw2reg[225]),
+ .d(hw2reg[257-:32]),
+ .qe(),
+ .q(reg2hw[458-:32]),
+ .qs(intr_state_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'h00000000)
+ ) u_intr_enable(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(intr_enable_we),
+ .wd(intr_enable_wd),
+ .de(1'b0),
+ .d({32 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[426-:32]),
+ .qs(intr_enable_qs)
+ );
+ prim_subreg_ext #(.DW(32)) u_intr_test(
+ .re(1'b0),
+ .we(intr_test_we),
+ .wd(intr_test_wd),
+ .d({32 {1'sb0}}),
+ .qre(),
+ .qe(reg2hw[362]),
+ .q(reg2hw[394-:32]),
+ .qs()
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RO"),
+ .RESVAL(32'h00000000)
+ ) u_data_in(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd({32 {1'sb0}}),
+ .de(hw2reg[192]),
+ .d(hw2reg[224-:32]),
+ .qe(),
+ .q(),
+ .qs(data_in_qs)
+ );
+ prim_subreg_ext #(.DW(32)) u_direct_out(
+ .re(direct_out_re),
+ .we(direct_out_we),
+ .wd(direct_out_wd),
+ .d(hw2reg[191-:32]),
+ .qre(),
+ .qe(reg2hw[329]),
+ .q(reg2hw[361-:32]),
+ .qs(direct_out_qs)
+ );
+ prim_subreg_ext #(.DW(16)) u_masked_out_lower_data(
+ .re(masked_out_lower_data_re),
+ .we(masked_out_lower_data_we),
+ .wd(masked_out_lower_data_wd),
+ .d(hw2reg[159-:16]),
+ .qre(),
+ .qe(reg2hw[312]),
+ .q(reg2hw[328-:16]),
+ .qs(masked_out_lower_data_qs)
+ );
+ prim_subreg_ext #(.DW(16)) u_masked_out_lower_mask(
+ .re(1'b0),
+ .we(masked_out_lower_mask_we),
+ .wd(masked_out_lower_mask_wd),
+ .d(hw2reg[143-:16]),
+ .qre(),
+ .qe(reg2hw[295]),
+ .q(reg2hw[311-:16]),
+ .qs()
+ );
+ prim_subreg_ext #(.DW(16)) u_masked_out_upper_data(
+ .re(masked_out_upper_data_re),
+ .we(masked_out_upper_data_we),
+ .wd(masked_out_upper_data_wd),
+ .d(hw2reg[127-:16]),
+ .qre(),
+ .qe(reg2hw[278]),
+ .q(reg2hw[294-:16]),
+ .qs(masked_out_upper_data_qs)
+ );
+ prim_subreg_ext #(.DW(16)) u_masked_out_upper_mask(
+ .re(1'b0),
+ .we(masked_out_upper_mask_we),
+ .wd(masked_out_upper_mask_wd),
+ .d(hw2reg[111-:16]),
+ .qre(),
+ .qe(reg2hw[261]),
+ .q(reg2hw[277-:16]),
+ .qs()
+ );
+ prim_subreg_ext #(.DW(32)) u_direct_oe(
+ .re(direct_oe_re),
+ .we(direct_oe_we),
+ .wd(direct_oe_wd),
+ .d(hw2reg[95-:32]),
+ .qre(),
+ .qe(reg2hw[228]),
+ .q(reg2hw[260-:32]),
+ .qs(direct_oe_qs)
+ );
+ prim_subreg_ext #(.DW(16)) u_masked_oe_lower_data(
+ .re(masked_oe_lower_data_re),
+ .we(masked_oe_lower_data_we),
+ .wd(masked_oe_lower_data_wd),
+ .d(hw2reg[63-:16]),
+ .qre(),
+ .qe(reg2hw[211]),
+ .q(reg2hw[227-:16]),
+ .qs(masked_oe_lower_data_qs)
+ );
+ prim_subreg_ext #(.DW(16)) u_masked_oe_lower_mask(
+ .re(masked_oe_lower_mask_re),
+ .we(masked_oe_lower_mask_we),
+ .wd(masked_oe_lower_mask_wd),
+ .d(hw2reg[47-:16]),
+ .qre(),
+ .qe(reg2hw[194]),
+ .q(reg2hw[210-:16]),
+ .qs(masked_oe_lower_mask_qs)
+ );
+ prim_subreg_ext #(.DW(16)) u_masked_oe_upper_data(
+ .re(masked_oe_upper_data_re),
+ .we(masked_oe_upper_data_we),
+ .wd(masked_oe_upper_data_wd),
+ .d(hw2reg[31-:16]),
+ .qre(),
+ .qe(reg2hw[177]),
+ .q(reg2hw[193-:16]),
+ .qs(masked_oe_upper_data_qs)
+ );
+ prim_subreg_ext #(.DW(16)) u_masked_oe_upper_mask(
+ .re(masked_oe_upper_mask_re),
+ .we(masked_oe_upper_mask_we),
+ .wd(masked_oe_upper_mask_wd),
+ .d(hw2reg[15-:16]),
+ .qre(),
+ .qe(reg2hw[160]),
+ .q(reg2hw[176-:16]),
+ .qs(masked_oe_upper_mask_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'h00000000)
+ ) u_intr_ctrl_en_rising(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(intr_ctrl_en_rising_we),
+ .wd(intr_ctrl_en_rising_wd),
+ .de(1'b0),
+ .d({32 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[159-:32]),
+ .qs(intr_ctrl_en_rising_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'h00000000)
+ ) u_intr_ctrl_en_falling(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(intr_ctrl_en_falling_we),
+ .wd(intr_ctrl_en_falling_wd),
+ .de(1'b0),
+ .d({32 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[127-:32]),
+ .qs(intr_ctrl_en_falling_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'h00000000)
+ ) u_intr_ctrl_en_lvlhigh(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(intr_ctrl_en_lvlhigh_we),
+ .wd(intr_ctrl_en_lvlhigh_wd),
+ .de(1'b0),
+ .d({32 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[95-:32]),
+ .qs(intr_ctrl_en_lvlhigh_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'h00000000)
+ ) u_intr_ctrl_en_lvllow(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(intr_ctrl_en_lvllow_we),
+ .wd(intr_ctrl_en_lvllow_wd),
+ .de(1'b0),
+ .d({32 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[63-:32]),
+ .qs(intr_ctrl_en_lvllow_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'h00000000)
+ ) u_ctrl_en_input_filter(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ctrl_en_input_filter_we),
+ .wd(ctrl_en_input_filter_wd),
+ .de(1'b0),
+ .d({32 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[31-:32]),
+ .qs(ctrl_en_input_filter_qs)
+ );
+ reg [14:0] addr_hit;
+ localparam signed [31:0] gpio_reg_pkg_BlockAw = 6;
+ localparam [5:0] gpio_reg_pkg_GPIO_CTRL_EN_INPUT_FILTER_OFFSET = 6'h38;
+ localparam [5:0] gpio_reg_pkg_GPIO_DATA_IN_OFFSET = 6'h0c;
+ localparam [5:0] gpio_reg_pkg_GPIO_DIRECT_OE_OFFSET = 6'h1c;
+ localparam [5:0] gpio_reg_pkg_GPIO_DIRECT_OUT_OFFSET = 6'h10;
+ localparam [5:0] gpio_reg_pkg_GPIO_INTR_CTRL_EN_FALLING_OFFSET = 6'h2c;
+ localparam [5:0] gpio_reg_pkg_GPIO_INTR_CTRL_EN_LVLHIGH_OFFSET = 6'h30;
+ localparam [5:0] gpio_reg_pkg_GPIO_INTR_CTRL_EN_LVLLOW_OFFSET = 6'h34;
+ localparam [5:0] gpio_reg_pkg_GPIO_INTR_CTRL_EN_RISING_OFFSET = 6'h28;
+ localparam [5:0] gpio_reg_pkg_GPIO_INTR_ENABLE_OFFSET = 6'h04;
+ localparam [5:0] gpio_reg_pkg_GPIO_INTR_STATE_OFFSET = 6'h00;
+ localparam [5:0] gpio_reg_pkg_GPIO_INTR_TEST_OFFSET = 6'h08;
+ localparam [5:0] gpio_reg_pkg_GPIO_MASKED_OE_LOWER_OFFSET = 6'h20;
+ localparam [5:0] gpio_reg_pkg_GPIO_MASKED_OE_UPPER_OFFSET = 6'h24;
+ localparam [5:0] gpio_reg_pkg_GPIO_MASKED_OUT_LOWER_OFFSET = 6'h14;
+ localparam [5:0] gpio_reg_pkg_GPIO_MASKED_OUT_UPPER_OFFSET = 6'h18;
+ always @(*) begin
+ addr_hit = {15 {1'sb0}};
+ addr_hit[0] = reg_addr == gpio_reg_pkg_GPIO_INTR_STATE_OFFSET;
+ addr_hit[1] = reg_addr == gpio_reg_pkg_GPIO_INTR_ENABLE_OFFSET;
+ addr_hit[2] = reg_addr == gpio_reg_pkg_GPIO_INTR_TEST_OFFSET;
+ addr_hit[3] = reg_addr == gpio_reg_pkg_GPIO_DATA_IN_OFFSET;
+ addr_hit[4] = reg_addr == gpio_reg_pkg_GPIO_DIRECT_OUT_OFFSET;
+ addr_hit[5] = reg_addr == gpio_reg_pkg_GPIO_MASKED_OUT_LOWER_OFFSET;
+ addr_hit[6] = reg_addr == gpio_reg_pkg_GPIO_MASKED_OUT_UPPER_OFFSET;
+ addr_hit[7] = reg_addr == gpio_reg_pkg_GPIO_DIRECT_OE_OFFSET;
+ addr_hit[8] = reg_addr == gpio_reg_pkg_GPIO_MASKED_OE_LOWER_OFFSET;
+ addr_hit[9] = reg_addr == gpio_reg_pkg_GPIO_MASKED_OE_UPPER_OFFSET;
+ addr_hit[10] = reg_addr == gpio_reg_pkg_GPIO_INTR_CTRL_EN_RISING_OFFSET;
+ addr_hit[11] = reg_addr == gpio_reg_pkg_GPIO_INTR_CTRL_EN_FALLING_OFFSET;
+ addr_hit[12] = reg_addr == gpio_reg_pkg_GPIO_INTR_CTRL_EN_LVLHIGH_OFFSET;
+ addr_hit[13] = reg_addr == gpio_reg_pkg_GPIO_INTR_CTRL_EN_LVLLOW_OFFSET;
+ addr_hit[14] = reg_addr == gpio_reg_pkg_GPIO_CTRL_EN_INPUT_FILTER_OFFSET;
+ end
+ assign addrmiss = (reg_re || reg_we ? ~|addr_hit : 1'b0);
+ localparam [59:0] gpio_reg_pkg_GPIO_PERMIT = 60'b111111111111111111111111111111111111111111111111111111111111;
+ always @(*) begin
+ wr_err = 1'b0;
+ if ((addr_hit[0] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[56+:4] != (gpio_reg_pkg_GPIO_PERMIT[56+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[1] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[52+:4] != (gpio_reg_pkg_GPIO_PERMIT[52+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[2] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[48+:4] != (gpio_reg_pkg_GPIO_PERMIT[48+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[3] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[44+:4] != (gpio_reg_pkg_GPIO_PERMIT[44+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[4] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[40+:4] != (gpio_reg_pkg_GPIO_PERMIT[40+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[5] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[36+:4] != (gpio_reg_pkg_GPIO_PERMIT[36+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[6] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[32+:4] != (gpio_reg_pkg_GPIO_PERMIT[32+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[7] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[28+:4] != (gpio_reg_pkg_GPIO_PERMIT[28+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[8] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[24+:4] != (gpio_reg_pkg_GPIO_PERMIT[24+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[9] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[20+:4] != (gpio_reg_pkg_GPIO_PERMIT[20+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[10] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[16+:4] != (gpio_reg_pkg_GPIO_PERMIT[16+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[11] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[12+:4] != (gpio_reg_pkg_GPIO_PERMIT[12+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[12] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[8+:4] != (gpio_reg_pkg_GPIO_PERMIT[8+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[13] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[4+:4] != (gpio_reg_pkg_GPIO_PERMIT[4+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[14] && reg_we) && (gpio_reg_pkg_GPIO_PERMIT[0+:4] != (gpio_reg_pkg_GPIO_PERMIT[0+:4] & reg_be)))
+ wr_err = 1'b1;
+ end
+ assign intr_state_we = (addr_hit[0] & reg_we) & ~wr_err;
+ assign intr_state_wd = reg_wdata[31:0];
+ assign intr_enable_we = (addr_hit[1] & reg_we) & ~wr_err;
+ assign intr_enable_wd = reg_wdata[31:0];
+ assign intr_test_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign intr_test_wd = reg_wdata[31:0];
+ assign direct_out_we = (addr_hit[4] & reg_we) & ~wr_err;
+ assign direct_out_wd = reg_wdata[31:0];
+ assign direct_out_re = addr_hit[4] && reg_re;
+ assign masked_out_lower_data_we = (addr_hit[5] & reg_we) & ~wr_err;
+ assign masked_out_lower_data_wd = reg_wdata[15:0];
+ assign masked_out_lower_data_re = addr_hit[5] && reg_re;
+ assign masked_out_lower_mask_we = (addr_hit[5] & reg_we) & ~wr_err;
+ assign masked_out_lower_mask_wd = reg_wdata[31:16];
+ assign masked_out_upper_data_we = (addr_hit[6] & reg_we) & ~wr_err;
+ assign masked_out_upper_data_wd = reg_wdata[15:0];
+ assign masked_out_upper_data_re = addr_hit[6] && reg_re;
+ assign masked_out_upper_mask_we = (addr_hit[6] & reg_we) & ~wr_err;
+ assign masked_out_upper_mask_wd = reg_wdata[31:16];
+ assign direct_oe_we = (addr_hit[7] & reg_we) & ~wr_err;
+ assign direct_oe_wd = reg_wdata[31:0];
+ assign direct_oe_re = addr_hit[7] && reg_re;
+ assign masked_oe_lower_data_we = (addr_hit[8] & reg_we) & ~wr_err;
+ assign masked_oe_lower_data_wd = reg_wdata[15:0];
+ assign masked_oe_lower_data_re = addr_hit[8] && reg_re;
+ assign masked_oe_lower_mask_we = (addr_hit[8] & reg_we) & ~wr_err;
+ assign masked_oe_lower_mask_wd = reg_wdata[31:16];
+ assign masked_oe_lower_mask_re = addr_hit[8] && reg_re;
+ assign masked_oe_upper_data_we = (addr_hit[9] & reg_we) & ~wr_err;
+ assign masked_oe_upper_data_wd = reg_wdata[15:0];
+ assign masked_oe_upper_data_re = addr_hit[9] && reg_re;
+ assign masked_oe_upper_mask_we = (addr_hit[9] & reg_we) & ~wr_err;
+ assign masked_oe_upper_mask_wd = reg_wdata[31:16];
+ assign masked_oe_upper_mask_re = addr_hit[9] && reg_re;
+ assign intr_ctrl_en_rising_we = (addr_hit[10] & reg_we) & ~wr_err;
+ assign intr_ctrl_en_rising_wd = reg_wdata[31:0];
+ assign intr_ctrl_en_falling_we = (addr_hit[11] & reg_we) & ~wr_err;
+ assign intr_ctrl_en_falling_wd = reg_wdata[31:0];
+ assign intr_ctrl_en_lvlhigh_we = (addr_hit[12] & reg_we) & ~wr_err;
+ assign intr_ctrl_en_lvlhigh_wd = reg_wdata[31:0];
+ assign intr_ctrl_en_lvllow_we = (addr_hit[13] & reg_we) & ~wr_err;
+ assign intr_ctrl_en_lvllow_wd = reg_wdata[31:0];
+ assign ctrl_en_input_filter_we = (addr_hit[14] & reg_we) & ~wr_err;
+ assign ctrl_en_input_filter_wd = reg_wdata[31:0];
+ always @(*) begin
+ reg_rdata_next = {32 {1'sb0}};
+ case (1'b1)
+ addr_hit[0]: reg_rdata_next[31:0] = intr_state_qs;
+ addr_hit[1]: reg_rdata_next[31:0] = intr_enable_qs;
+ addr_hit[2]: reg_rdata_next[31:0] = {32 {1'sb0}};
+ addr_hit[3]: reg_rdata_next[31:0] = data_in_qs;
+ addr_hit[4]: reg_rdata_next[31:0] = direct_out_qs;
+ addr_hit[5]: begin
+ reg_rdata_next[15:0] = masked_out_lower_data_qs;
+ reg_rdata_next[31:16] = {16 {1'sb0}};
+ end
+ addr_hit[6]: begin
+ reg_rdata_next[15:0] = masked_out_upper_data_qs;
+ reg_rdata_next[31:16] = {16 {1'sb0}};
+ end
+ addr_hit[7]: reg_rdata_next[31:0] = direct_oe_qs;
+ addr_hit[8]: begin
+ reg_rdata_next[15:0] = masked_oe_lower_data_qs;
+ reg_rdata_next[31:16] = masked_oe_lower_mask_qs;
+ end
+ addr_hit[9]: begin
+ reg_rdata_next[15:0] = masked_oe_upper_data_qs;
+ reg_rdata_next[31:16] = masked_oe_upper_mask_qs;
+ end
+ addr_hit[10]: reg_rdata_next[31:0] = intr_ctrl_en_rising_qs;
+ addr_hit[11]: reg_rdata_next[31:0] = intr_ctrl_en_falling_qs;
+ addr_hit[12]: reg_rdata_next[31:0] = intr_ctrl_en_lvlhigh_qs;
+ addr_hit[13]: reg_rdata_next[31:0] = intr_ctrl_en_lvllow_qs;
+ addr_hit[14]: reg_rdata_next[31:0] = ctrl_en_input_filter_qs;
+ default: reg_rdata_next = {32 {1'sb1}};
+ endcase
+ end
+endmodule
+module gpio (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ cio_gpio_i,
+ cio_gpio_o,
+ cio_gpio_en_o,
+ intr_gpio_o
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ input wire [31:0] cio_gpio_i;
+ output wire [31:0] cio_gpio_o;
+ output wire [31:0] cio_gpio_en_o;
+ output wire [31:0] intr_gpio_o;
+ wire [458:0] reg2hw;
+ wire [257:0] hw2reg;
+ reg [31:0] cio_gpio_q;
+ reg [31:0] cio_gpio_en_q;
+ wire [31:0] data_in_d;
+ generate
+ genvar i;
+ for (i = 0; i < 32; i = i + 1) begin : gen_filter
+ prim_filter_ctr #(.Cycles(16)) filter(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .enable_i(reg2hw[i]),
+ .filter_i(cio_gpio_i[i]),
+ .filter_o(data_in_d[i])
+ );
+ end
+ endgenerate
+ assign hw2reg[192] = 1'b1;
+ assign hw2reg[224-:32] = data_in_d;
+ assign cio_gpio_o = cio_gpio_q;
+ assign cio_gpio_en_o = cio_gpio_en_q;
+ assign hw2reg[191-:32] = cio_gpio_q;
+ assign hw2reg[127-:16] = cio_gpio_q[31:16];
+ assign hw2reg[111-:16] = 16'h0000;
+ assign hw2reg[159-:16] = cio_gpio_q[15:0];
+ assign hw2reg[143-:16] = 16'h0000;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ cio_gpio_q <= {32 {1'sb0}};
+ else if (reg2hw[329])
+ cio_gpio_q <= reg2hw[361-:32];
+ else if (reg2hw[278])
+ cio_gpio_q[31:16] <= (reg2hw[277-:16] & reg2hw[294-:16]) | (~reg2hw[277-:16] & cio_gpio_q[31:16]);
+ else if (reg2hw[312])
+ cio_gpio_q[15:0] <= (reg2hw[311-:16] & reg2hw[328-:16]) | (~reg2hw[311-:16] & cio_gpio_q[15:0]);
+ assign hw2reg[95-:32] = cio_gpio_en_q;
+ assign hw2reg[31-:16] = cio_gpio_en_q[31:16];
+ assign hw2reg[15-:16] = 16'h0000;
+ assign hw2reg[63-:16] = cio_gpio_en_q[15:0];
+ assign hw2reg[47-:16] = 16'h0000;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ cio_gpio_en_q <= {32 {1'sb0}};
+ else if (reg2hw[228])
+ cio_gpio_en_q <= reg2hw[260-:32];
+ else if (reg2hw[177])
+ cio_gpio_en_q[31:16] <= (reg2hw[176-:16] & reg2hw[193-:16]) | (~reg2hw[176-:16] & cio_gpio_en_q[31:16]);
+ else if (reg2hw[211])
+ cio_gpio_en_q[15:0] <= (reg2hw[210-:16] & reg2hw[227-:16]) | (~reg2hw[210-:16] & cio_gpio_en_q[15:0]);
+ reg [31:0] data_in_q;
+ always @(posedge clk_i) data_in_q <= data_in_d;
+ wire [31:0] event_intr_rise;
+ wire [31:0] event_intr_fall;
+ wire [31:0] event_intr_actlow;
+ wire [31:0] event_intr_acthigh;
+ wire [31:0] event_intr_combined;
+ prim_intr_hw #(.Width(32)) intr_hw(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .event_intr_i(event_intr_combined),
+ .reg2hw_intr_enable_q_i(reg2hw[426-:32]),
+ .reg2hw_intr_test_q_i(reg2hw[394-:32]),
+ .reg2hw_intr_test_qe_i(reg2hw[362]),
+ .reg2hw_intr_state_q_i(reg2hw[458-:32]),
+ .hw2reg_intr_state_de_o(hw2reg[225]),
+ .hw2reg_intr_state_d_o(hw2reg[257-:32]),
+ .intr_o(intr_gpio_o)
+ );
+ assign event_intr_rise = (~data_in_q & data_in_d) & reg2hw[159-:32];
+ assign event_intr_fall = (data_in_q & ~data_in_d) & reg2hw[127-:32];
+ assign event_intr_acthigh = data_in_d & reg2hw[95-:32];
+ assign event_intr_actlow = ~data_in_d & reg2hw[63-:32];
+ assign event_intr_combined = ((event_intr_rise | event_intr_fall) | event_intr_actlow) | event_intr_acthigh;
+ gpio_reg_top u_reg(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_i),
+ .tl_o(tl_o),
+ .reg2hw(reg2hw),
+ .hw2reg(hw2reg),
+ .devmode_i(1'b1)
+ );
+endmodule
+module iccm_controller (
+ clk_i,
+ rst_ni,
+ prog_i,
+ rx_dv_i,
+ rx_byte_i,
+ we_o,
+ addr_o,
+ wdata_o,
+ reset_o
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire prog_i;
+ input wire rx_dv_i;
+ input wire [7:0] rx_byte_i;
+ output wire we_o;
+ output wire [11:0] addr_o;
+ output wire [31:0] wdata_o;
+ output wire reset_o;
+ reg [1:0] ctrl_fsm_cs;
+ reg [1:0] ctrl_fsm_ns;
+ wire [7:0] rx_byte_d;
+ reg [7:0] rx_byte_q0;
+ reg [7:0] rx_byte_q1;
+ reg [7:0] rx_byte_q2;
+ reg [7:0] rx_byte_q3;
+ reg we_q;
+ reg we_d;
+ reg [11:0] addr_q;
+ reg [11:0] addr_d;
+ reg reset_q;
+ reg reset_d;
+ reg [1:0] byte_count;
+ localparam [1:0] DONE = 3;
+ localparam [1:0] LOAD = 1;
+ localparam [1:0] PROG = 2;
+ localparam [1:0] RESET = 0;
+ always @(*) begin
+ we_d = we_q;
+ addr_d = addr_q;
+ reset_d = reset_q;
+ ctrl_fsm_ns = ctrl_fsm_cs;
+ case (ctrl_fsm_cs)
+ RESET: begin
+ we_d = 1'b0;
+ reset_d = 1'b0;
+ if (rx_dv_i)
+ ctrl_fsm_ns = LOAD;
+ else
+ ctrl_fsm_ns = RESET;
+ end
+ LOAD:
+ if (((byte_count == 2'b11) && (rx_byte_q2 != 8'h0f)) && (rx_byte_d != 8'hff)) begin
+ we_d = 1'b1;
+ ctrl_fsm_ns = PROG;
+ end
+ else
+ ctrl_fsm_ns = DONE;
+ PROG: begin
+ we_d = 1'b0;
+ ctrl_fsm_ns = DONE;
+ end
+ DONE:
+ if ((wdata_o == 32'h00000fff) || !rst_ni) begin
+ ctrl_fsm_ns = DONE;
+ reset_d = 1'b1;
+ end
+ else if (rx_dv_i)
+ ctrl_fsm_ns = LOAD;
+ else
+ ctrl_fsm_ns = DONE;
+ endcase
+ end
+ assign rx_byte_d = rx_byte_i;
+ assign we_o = we_q;
+ assign addr_o = addr_q;
+ assign wdata_o = {rx_byte_q0, rx_byte_q1, rx_byte_q2, rx_byte_q3};
+ assign reset_o = reset_q;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ we_q <= 1'b0;
+ addr_q <= 12'b000000000000;
+ rx_byte_q0 <= 8'b00000000;
+ rx_byte_q1 <= 8'b00000000;
+ rx_byte_q2 <= 8'b00000000;
+ rx_byte_q3 <= 8'b00000000;
+ reset_q <= 1'b1;
+ byte_count <= 2'b00;
+ ctrl_fsm_cs <= DONE;
+ end
+ else if (prog_i) begin
+ we_q <= 1'b0;
+ addr_q <= 12'b000000000000;
+ rx_byte_q0 <= 8'b00000000;
+ rx_byte_q1 <= 8'b00000000;
+ rx_byte_q2 <= 8'b00000000;
+ rx_byte_q3 <= 8'b00000000;
+ reset_q <= 1'b0;
+ byte_count <= 2'b00;
+ ctrl_fsm_cs <= RESET;
+ end
+ else begin
+ we_q <= we_d;
+ if (ctrl_fsm_cs == LOAD) begin
+ if (byte_count == 2'b00) begin
+ rx_byte_q0 <= rx_byte_d;
+ byte_count <= 2'b01;
+ end
+ else if (byte_count == 2'b01) begin
+ rx_byte_q1 <= rx_byte_d;
+ byte_count <= 2'b10;
+ end
+ else if (byte_count == 2'b10) begin
+ rx_byte_q2 <= rx_byte_d;
+ byte_count <= 2'b11;
+ end
+ else begin
+ rx_byte_q3 <= rx_byte_d;
+ byte_count <= 2'b00;
+ end
+ addr_q <= addr_d;
+ end
+ if (ctrl_fsm_cs == PROG)
+ addr_q <= addr_d + 1'b1;
+ reset_q <= reset_d;
+ ctrl_fsm_cs <= ctrl_fsm_ns;
+ end
+endmodule
+module instr_mem_top (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ iccm_ctrl_addr,
+ iccm_ctrl_wdata,
+ iccm_ctrl_we,
+ prog_rst_ni,
+ csb,
+ addr_o,
+ wdata_o,
+ wmask_o,
+ we_o,
+ rdata_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ input [11:0] iccm_ctrl_addr;
+ input [31:0] iccm_ctrl_wdata;
+ input wire iccm_ctrl_we;
+ input wire prog_rst_ni;
+ output wire csb;
+ output wire [11:0] addr_o;
+ output wire [31:0] wdata_o;
+ output wire [3:0] wmask_o;
+ output wire we_o;
+ input wire [31:0] rdata_i;
+ reg rvalid;
+ wire tl_we;
+ wire [31:0] tl_wmask;
+ wire [31:0] tl_wdata;
+ wire [11:0] tl_addr;
+ wire tl_req;
+ wire [3:0] mask_sel;
+ assign mask_sel[0] = (tl_wmask[7:0] != 8'b00000000 ? 1'b1 : 1'b0);
+ assign mask_sel[1] = (tl_wmask[15:8] != 8'b00000000 ? 1'b1 : 1'b0);
+ assign mask_sel[2] = (tl_wmask[23:16] != 8'b00000000 ? 1'b1 : 1'b0);
+ assign mask_sel[3] = (tl_wmask[31:24] != 8'b00000000 ? 1'b1 : 1'b0);
+ assign csb = ~(prog_rst_ni ? tl_req : iccm_ctrl_we);
+ assign addr_o = (prog_rst_ni ? tl_addr : iccm_ctrl_addr);
+ assign wdata_o = (prog_rst_ni ? tl_wdata : iccm_ctrl_wdata);
+ assign we_o = ~(prog_rst_ni ? tl_we : iccm_ctrl_we);
+ assign wmask_o = (prog_rst_ni ? mask_sel : 4'b1111);
+ tlul_sram_adapter #(
+ .SramAw(12),
+ .SramDw(32),
+ .Outstanding(2),
+ .ByteAccess(1),
+ .ErrOnWrite(0),
+ .ErrOnRead(0)
+ ) inst_mem(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_i),
+ .tl_o(tl_o),
+ .req_o(tl_req),
+ .gnt_i(1'b1),
+ .we_o(tl_we),
+ .addr_o(tl_addr),
+ .wdata_o(tl_wdata),
+ .wmask_o(tl_wmask),
+ .rdata_i((rst_ni ? rdata_i : {32 {1'sb0}})),
+ .rvalid_i(rvalid),
+ .rerror_i(2'b00)
+ );
+ always @(posedge clk_i)
+ if (!rst_ni)
+ rvalid <= 1'b0;
+ else if (iccm_ctrl_we | tl_we)
+ rvalid <= 1'b0;
+ else
+ rvalid <= tl_req;
+endmodule
+module iteration_div_sqrt_mvp (
+ A_DI,
+ B_DI,
+ Div_enable_SI,
+ Div_start_dly_SI,
+ Sqrt_enable_SI,
+ D_DI,
+ D_DO,
+ Sum_DO,
+ Carry_out_DO
+);
+ parameter WIDTH = 25;
+ input wire [WIDTH - 1:0] A_DI;
+ input wire [WIDTH - 1:0] B_DI;
+ input wire Div_enable_SI;
+ input wire Div_start_dly_SI;
+ input wire Sqrt_enable_SI;
+ input wire [1:0] D_DI;
+ output wire [1:0] D_DO;
+ output wire [WIDTH - 1:0] Sum_DO;
+ output wire Carry_out_DO;
+ wire D_carry_D;
+ wire Sqrt_cin_D;
+ wire Cin_D;
+ assign D_DO[0] = ~D_DI[0];
+ assign D_DO[1] = ~(D_DI[1] ^ D_DI[0]);
+ assign D_carry_D = D_DI[1] | D_DI[0];
+ assign Sqrt_cin_D = Sqrt_enable_SI && D_carry_D;
+ assign Cin_D = (Div_enable_SI ? 1'b0 : Sqrt_cin_D);
+ assign {Carry_out_DO, Sum_DO} = (A_DI + B_DI) + Cin_D;
+endmodule
+module lzc (
+ in_i,
+ cnt_o,
+ empty_o
+);
+ parameter [31:0] WIDTH = 2;
+ parameter [0:0] MODE = 1'b0;
+ function automatic [31:0] cf_math_pkg_idx_width;
+ input reg [31:0] num_idx;
+ cf_math_pkg_idx_width = (num_idx > 32'd1 ? $unsigned($clog2(num_idx)) : 32'd1);
+ endfunction
+ parameter [31:0] CNT_WIDTH = cf_math_pkg_idx_width(WIDTH);
+ input wire [WIDTH - 1:0] in_i;
+ output wire [CNT_WIDTH - 1:0] cnt_o;
+ output wire empty_o;
+ generate
+ if (WIDTH == 1) begin : gen_degenerate_lzc
+ assign cnt_o[0] = !in_i[0];
+ assign empty_o = !in_i[0];
+ end
+ else begin : gen_lzc
+ localparam [31:0] NumLevels = $clog2(WIDTH);
+ wire [(WIDTH * NumLevels) - 1:0] index_lut;
+ wire [(2 ** NumLevels) - 1:0] sel_nodes;
+ wire [((2 ** NumLevels) * NumLevels) - 1:0] index_nodes;
+ reg [WIDTH - 1:0] in_tmp;
+ always @(*) begin : flip_vector
+ begin : sv2v_autoblock_130
+ reg [31:0] i;
+ for (i = 0; i < WIDTH; i = i + 1)
+ in_tmp[i] = (MODE ? in_i[(WIDTH - 1) - i] : in_i[i]);
+ end
+ end
+ genvar j;
+ for (j = 0; $unsigned(j) < WIDTH; j = j + 1) begin : g_index_lut
+ function automatic [NumLevels - 1:0] sv2v_cast_4C5E6;
+ input reg [NumLevels - 1:0] inp;
+ sv2v_cast_4C5E6 = inp;
+ endfunction
+ assign index_lut[j * NumLevels+:NumLevels] = sv2v_cast_4C5E6($unsigned(j));
+ end
+ genvar level;
+ for (level = 0; $unsigned(level) < NumLevels; level = level + 1) begin : g_levels
+ if ($unsigned(level) == (NumLevels - 1)) begin : g_last_level
+ genvar k;
+ for (k = 0; k < (2 ** level); k = k + 1) begin : g_level
+ if (($unsigned(k) * 2) < (WIDTH - 1)) begin : g_reduce
+ assign sel_nodes[((2 ** level) - 1) + k] = in_tmp[k * 2] | in_tmp[(k * 2) + 1];
+ assign index_nodes[(((2 ** level) - 1) + k) * NumLevels+:NumLevels] = (in_tmp[k * 2] == 1'b1 ? index_lut[(k * 2) * NumLevels+:NumLevels] : index_lut[((k * 2) + 1) * NumLevels+:NumLevels]);
+ end
+ if (($unsigned(k) * 2) == (WIDTH - 1)) begin : g_base
+ assign sel_nodes[((2 ** level) - 1) + k] = in_tmp[k * 2];
+ assign index_nodes[(((2 ** level) - 1) + k) * NumLevels+:NumLevels] = index_lut[(k * 2) * NumLevels+:NumLevels];
+ end
+ if (($unsigned(k) * 2) > (WIDTH - 1)) begin : g_out_of_range
+ assign sel_nodes[((2 ** level) - 1) + k] = 1'b0;
+ assign index_nodes[(((2 ** level) - 1) + k) * NumLevels+:NumLevels] = {NumLevels {1'sb0}};
+ end
+ end
+ end
+ else begin : g_not_last_level
+ genvar l;
+ for (l = 0; l < (2 ** level); l = l + 1) begin : g_level
+ assign sel_nodes[((2 ** level) - 1) + l] = sel_nodes[((2 ** (level + 1)) - 1) + (l * 2)] | sel_nodes[(((2 ** (level + 1)) - 1) + (l * 2)) + 1];
+ assign index_nodes[(((2 ** level) - 1) + l) * NumLevels+:NumLevels] = (sel_nodes[((2 ** (level + 1)) - 1) + (l * 2)] == 1'b1 ? index_nodes[(((2 ** (level + 1)) - 1) + (l * 2)) * NumLevels+:NumLevels] : index_nodes[((((2 ** (level + 1)) - 1) + (l * 2)) + 1) * NumLevels+:NumLevels]);
+ end
+ end
+ end
+ assign cnt_o = (NumLevels > $unsigned(0) ? index_nodes[0+:NumLevels] : {$clog2(WIDTH) {1'b0}});
+ assign empty_o = (NumLevels > $unsigned(0) ? ~sel_nodes[0] : ~(|in_i));
+ end
+ endgenerate
+endmodule
+module norm_div_sqrt_mvp (
+ Mant_in_DI,
+ Exp_in_DI,
+ Sign_in_DI,
+ Div_enable_SI,
+ Sqrt_enable_SI,
+ Inf_a_SI,
+ Inf_b_SI,
+ Zero_a_SI,
+ Zero_b_SI,
+ NaN_a_SI,
+ NaN_b_SI,
+ SNaN_SI,
+ RM_SI,
+ Full_precision_SI,
+ FP32_SI,
+ FP64_SI,
+ FP16_SI,
+ FP16ALT_SI,
+ Result_DO,
+ Fflags_SO
+);
+ localparam defs_div_sqrt_mvp_C_MANT_FP64 = 52;
+ input wire [56:0] Mant_in_DI;
+ localparam defs_div_sqrt_mvp_C_EXP_FP64 = 11;
+ input wire signed [12:0] Exp_in_DI;
+ input wire Sign_in_DI;
+ input wire Div_enable_SI;
+ input wire Sqrt_enable_SI;
+ input wire Inf_a_SI;
+ input wire Inf_b_SI;
+ input wire Zero_a_SI;
+ input wire Zero_b_SI;
+ input wire NaN_a_SI;
+ input wire NaN_b_SI;
+ input wire SNaN_SI;
+ localparam defs_div_sqrt_mvp_C_RM = 3;
+ input wire [2:0] RM_SI;
+ input wire Full_precision_SI;
+ input wire FP32_SI;
+ input wire FP64_SI;
+ input wire FP16_SI;
+ input wire FP16ALT_SI;
+ output reg [63:0] Result_DO;
+ output wire [4:0] Fflags_SO;
+ reg Sign_res_D;
+ reg NV_OP_S;
+ reg Exp_OF_S;
+ reg Exp_UF_S;
+ reg Div_Zero_S;
+ wire In_Exact_S;
+ reg [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_res_norm_D;
+ reg [10:0] Exp_res_norm_D;
+ wire [12:0] Exp_Max_RS_FP64_D;
+ localparam defs_div_sqrt_mvp_C_EXP_FP32 = 8;
+ wire [9:0] Exp_Max_RS_FP32_D;
+ localparam defs_div_sqrt_mvp_C_EXP_FP16 = 5;
+ wire [6:0] Exp_Max_RS_FP16_D;
+ localparam defs_div_sqrt_mvp_C_EXP_FP16ALT = 8;
+ wire [9:0] Exp_Max_RS_FP16ALT_D;
+ assign Exp_Max_RS_FP64_D = (Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP64:0] + defs_div_sqrt_mvp_C_MANT_FP64) + 1;
+ localparam defs_div_sqrt_mvp_C_MANT_FP32 = 23;
+ assign Exp_Max_RS_FP32_D = (Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP32:0] + defs_div_sqrt_mvp_C_MANT_FP32) + 1;
+ localparam defs_div_sqrt_mvp_C_MANT_FP16 = 10;
+ assign Exp_Max_RS_FP16_D = (Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP16:0] + defs_div_sqrt_mvp_C_MANT_FP16) + 1;
+ localparam defs_div_sqrt_mvp_C_MANT_FP16ALT = 7;
+ assign Exp_Max_RS_FP16ALT_D = (Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP16ALT:0] + defs_div_sqrt_mvp_C_MANT_FP16ALT) + 1;
+ wire [12:0] Num_RS_D;
+ assign Num_RS_D = ~Exp_in_DI + 2;
+ wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_RS_D;
+ wire [56:0] Mant_forsticky_D;
+ assign {Mant_RS_D, Mant_forsticky_D} = {Mant_in_DI, {53 {1'b0}}} >> Num_RS_D;
+ wire [12:0] Exp_subOne_D;
+ assign Exp_subOne_D = Exp_in_DI - 1;
+ reg [1:0] Mant_lower_D;
+ reg Mant_sticky_bit_D;
+ reg [56:0] Mant_forround_D;
+ localparam defs_div_sqrt_mvp_C_EXP_ONE_FP64 = 13'h0001;
+ localparam defs_div_sqrt_mvp_C_MANT_NAN_FP64 = 52'h8000000000000;
+ always @(*)
+ if (NaN_a_SI) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {1'b0, defs_div_sqrt_mvp_C_MANT_NAN_FP64};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = 1'b0;
+ NV_OP_S = SNaN_SI;
+ end
+ else if (NaN_b_SI) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {1'b0, defs_div_sqrt_mvp_C_MANT_NAN_FP64};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = 1'b0;
+ NV_OP_S = SNaN_SI;
+ end
+ else if (Inf_a_SI) begin
+ if (Div_enable_SI && Inf_b_SI) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {1'b0, defs_div_sqrt_mvp_C_MANT_NAN_FP64};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = 1'b0;
+ NV_OP_S = 1'b1;
+ end
+ else if (Sqrt_enable_SI && Sign_in_DI) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {1'b0, defs_div_sqrt_mvp_C_MANT_NAN_FP64};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = 1'b0;
+ NV_OP_S = 1'b1;
+ end
+ else begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b1;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {53 {1'sb0}};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ end
+ else if (Div_enable_SI && Inf_b_SI) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b1;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {53 {1'sb0}};
+ Exp_res_norm_D = {11 {1'sb0}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else if (Zero_a_SI) begin
+ if (Div_enable_SI && Zero_b_SI) begin
+ Div_Zero_S = 1'b1;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {1'b0, defs_div_sqrt_mvp_C_MANT_NAN_FP64};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = 1'b0;
+ NV_OP_S = 1'b1;
+ end
+ else begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {53 {1'sb0}};
+ Exp_res_norm_D = {11 {1'sb0}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ end
+ else if (Div_enable_SI && Zero_b_SI) begin
+ Div_Zero_S = 1'b1;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {53 {1'sb0}};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else if (Sign_in_DI && Sqrt_enable_SI) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {1'b0, defs_div_sqrt_mvp_C_MANT_NAN_FP64};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = 1'b0;
+ NV_OP_S = 1'b1;
+ end
+ else if (Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP64:0] == {12 {1'sb0}}) begin
+ if (Mant_in_DI != {57 {1'sb0}}) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b1;
+ Mant_res_norm_D = {1'b0, Mant_in_DI[56:5]};
+ Exp_res_norm_D = {11 {1'sb0}};
+ Mant_forround_D = {Mant_in_DI[4:0], {defs_div_sqrt_mvp_C_MANT_FP64 {1'b0}}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {53 {1'sb0}};
+ Exp_res_norm_D = {11 {1'sb0}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ end
+ else if ((Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP64:0] == defs_div_sqrt_mvp_C_EXP_ONE_FP64) && ~Mant_in_DI[56]) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b1;
+ Mant_res_norm_D = Mant_in_DI[56:4];
+ Exp_res_norm_D = {11 {1'sb0}};
+ Mant_forround_D = {Mant_in_DI[3:0], {53 {1'b0}}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else if (Exp_in_DI[12]) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b1;
+ Mant_res_norm_D = {Mant_RS_D[defs_div_sqrt_mvp_C_MANT_FP64:0]};
+ Exp_res_norm_D = {11 {1'sb0}};
+ Mant_forround_D = {Mant_forsticky_D[56:0]};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else if ((((Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP32] && FP32_SI) | (Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP64] && FP64_SI)) | (Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP16] && FP16_SI)) | (Exp_in_DI[defs_div_sqrt_mvp_C_EXP_FP16ALT] && FP16ALT_SI)) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b1;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {53 {1'sb0}};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else if (((((Exp_in_DI[7:0] == {8 {1'sb1}}) && FP32_SI) | ((Exp_in_DI[10:0] == {11 {1'sb1}}) && FP64_SI)) | ((Exp_in_DI[4:0] == {5 {1'sb1}}) && FP16_SI)) | ((Exp_in_DI[7:0] == {8 {1'sb1}}) && FP16ALT_SI)) begin
+ if (~Mant_in_DI[56]) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = Mant_in_DI[55:3];
+ Exp_res_norm_D = Exp_subOne_D;
+ Mant_forround_D = {Mant_in_DI[2:0], {54 {1'b0}}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else if (Mant_in_DI != {57 {1'sb0}}) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b1;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {53 {1'sb0}};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b1;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = {53 {1'sb0}};
+ Exp_res_norm_D = {11 {1'sb1}};
+ Mant_forround_D = {57 {1'sb0}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ end
+ else if (Mant_in_DI[56]) begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = Mant_in_DI[56:4];
+ Exp_res_norm_D = Exp_in_DI[10:0];
+ Mant_forround_D = {Mant_in_DI[3:0], {53 {1'b0}}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ else begin
+ Div_Zero_S = 1'b0;
+ Exp_OF_S = 1'b0;
+ Exp_UF_S = 1'b0;
+ Mant_res_norm_D = Mant_in_DI[55:3];
+ Exp_res_norm_D = Exp_subOne_D;
+ Mant_forround_D = {Mant_in_DI[2:0], {54 {1'b0}}};
+ Sign_res_D = Sign_in_DI;
+ NV_OP_S = 1'b0;
+ end
+ reg [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_upper_D;
+ wire [53:0] Mant_upperRounded_D;
+ reg Mant_roundUp_S;
+ wire Mant_rounded_S;
+ always @(*)
+ if (FP32_SI) begin
+ Mant_upper_D = {Mant_res_norm_D[defs_div_sqrt_mvp_C_MANT_FP64:29], {29 {1'b0}}};
+ Mant_lower_D = Mant_res_norm_D[28:27];
+ Mant_sticky_bit_D = |Mant_res_norm_D[26:0];
+ end
+ else if (FP64_SI) begin
+ Mant_upper_D = Mant_res_norm_D[defs_div_sqrt_mvp_C_MANT_FP64:0];
+ Mant_lower_D = Mant_forround_D[56:55];
+ Mant_sticky_bit_D = |Mant_forround_D[55:0];
+ end
+ else if (FP16_SI) begin
+ Mant_upper_D = {Mant_res_norm_D[defs_div_sqrt_mvp_C_MANT_FP64:42], {42 {1'b0}}};
+ Mant_lower_D = Mant_res_norm_D[41:40];
+ Mant_sticky_bit_D = |Mant_res_norm_D[39:30];
+ end
+ else begin
+ Mant_upper_D = {Mant_res_norm_D[defs_div_sqrt_mvp_C_MANT_FP64:45], {45 {1'b0}}};
+ Mant_lower_D = Mant_res_norm_D[44:43];
+ Mant_sticky_bit_D = |Mant_res_norm_D[42:30];
+ end
+ assign Mant_rounded_S = |Mant_lower_D | Mant_sticky_bit_D;
+ localparam defs_div_sqrt_mvp_C_RM_MINUSINF = 3'h3;
+ localparam defs_div_sqrt_mvp_C_RM_NEAREST = 3'h0;
+ localparam defs_div_sqrt_mvp_C_RM_PLUSINF = 3'h2;
+ localparam defs_div_sqrt_mvp_C_RM_TRUNC = 3'h1;
+ always @(*) begin
+ Mant_roundUp_S = 1'b0;
+ case (RM_SI)
+ defs_div_sqrt_mvp_C_RM_NEAREST: Mant_roundUp_S = Mant_lower_D[1] && ((Mant_lower_D[0] | Mant_sticky_bit_D) | ((((FP32_SI && Mant_upper_D[29]) | (FP64_SI && Mant_upper_D[0])) | (FP16_SI && Mant_upper_D[42])) | (FP16ALT_SI && Mant_upper_D[45])));
+ defs_div_sqrt_mvp_C_RM_TRUNC: Mant_roundUp_S = 0;
+ defs_div_sqrt_mvp_C_RM_PLUSINF: Mant_roundUp_S = Mant_rounded_S & ~Sign_in_DI;
+ defs_div_sqrt_mvp_C_RM_MINUSINF: Mant_roundUp_S = Mant_rounded_S & Sign_in_DI;
+ default: Mant_roundUp_S = 0;
+ endcase
+ end
+ wire Mant_renorm_S;
+ wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_roundUp_Vector_S;
+ assign Mant_roundUp_Vector_S = {7'h00, FP16ALT_SI && Mant_roundUp_S, 2'h0, FP16_SI && Mant_roundUp_S, 12'h000, FP32_SI && Mant_roundUp_S, 28'h0000000, FP64_SI && Mant_roundUp_S};
+ assign Mant_upperRounded_D = Mant_upper_D + Mant_roundUp_Vector_S;
+ assign Mant_renorm_S = Mant_upperRounded_D[53];
+ wire [51:0] Mant_res_round_D;
+ wire [10:0] Exp_res_round_D;
+ assign Mant_res_round_D = (Mant_renorm_S ? Mant_upperRounded_D[defs_div_sqrt_mvp_C_MANT_FP64:1] : Mant_upperRounded_D[51:0]);
+ assign Exp_res_round_D = Exp_res_norm_D + Mant_renorm_S;
+ wire [51:0] Mant_before_format_ctl_D;
+ wire [10:0] Exp_before_format_ctl_D;
+ assign Mant_before_format_ctl_D = (Full_precision_SI ? Mant_res_round_D : Mant_res_norm_D);
+ assign Exp_before_format_ctl_D = (Full_precision_SI ? Exp_res_round_D : Exp_res_norm_D);
+ always @(*)
+ if (FP32_SI)
+ Result_DO = {32'hffffffff, Sign_res_D, Exp_before_format_ctl_D[7:0], Mant_before_format_ctl_D[51:29]};
+ else if (FP64_SI)
+ Result_DO = {Sign_res_D, Exp_before_format_ctl_D[10:0], Mant_before_format_ctl_D[51:0]};
+ else if (FP16_SI)
+ Result_DO = {48'hffffffffffff, Sign_res_D, Exp_before_format_ctl_D[4:0], Mant_before_format_ctl_D[51:42]};
+ else
+ Result_DO = {48'hffffffffffff, Sign_res_D, Exp_before_format_ctl_D[7:0], Mant_before_format_ctl_D[51:45]};
+ assign In_Exact_S = ~Full_precision_SI | Mant_rounded_S;
+ assign Fflags_SO = {NV_OP_S, Div_Zero_S, Exp_OF_S, Exp_UF_S, In_Exact_S};
+endmodule
+module nrbd_nrsc_mvp (
+ Clk_CI,
+ Rst_RBI,
+ Div_start_SI,
+ Sqrt_start_SI,
+ Start_SI,
+ Kill_SI,
+ Special_case_SBI,
+ Special_case_dly_SBI,
+ Precision_ctl_SI,
+ Format_sel_SI,
+ Mant_a_DI,
+ Mant_b_DI,
+ Exp_a_DI,
+ Exp_b_DI,
+ Div_enable_SO,
+ Sqrt_enable_SO,
+ Full_precision_SO,
+ FP32_SO,
+ FP64_SO,
+ FP16_SO,
+ FP16ALT_SO,
+ Ready_SO,
+ Done_SO,
+ Mant_z_DO,
+ Exp_z_DO
+);
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Div_start_SI;
+ input wire Sqrt_start_SI;
+ input wire Start_SI;
+ input wire Kill_SI;
+ input wire Special_case_SBI;
+ input wire Special_case_dly_SBI;
+ localparam defs_div_sqrt_mvp_C_PC = 6;
+ input wire [5:0] Precision_ctl_SI;
+ input wire [1:0] Format_sel_SI;
+ localparam defs_div_sqrt_mvp_C_MANT_FP64 = 52;
+ input wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_a_DI;
+ input wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_b_DI;
+ localparam defs_div_sqrt_mvp_C_EXP_FP64 = 11;
+ input wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_a_DI;
+ input wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_b_DI;
+ output wire Div_enable_SO;
+ output wire Sqrt_enable_SO;
+ output wire Full_precision_SO;
+ output wire FP32_SO;
+ output wire FP64_SO;
+ output wire FP16_SO;
+ output wire FP16ALT_SO;
+ output wire Ready_SO;
+ output wire Done_SO;
+ output wire [56:0] Mant_z_DO;
+ output wire [12:0] Exp_z_DO;
+ wire Div_start_dly_S;
+ wire Sqrt_start_dly_S;
+ control_mvp control_U0(
+ .Clk_CI(Clk_CI),
+ .Rst_RBI(Rst_RBI),
+ .Div_start_SI(Div_start_SI),
+ .Sqrt_start_SI(Sqrt_start_SI),
+ .Start_SI(Start_SI),
+ .Kill_SI(Kill_SI),
+ .Special_case_SBI(Special_case_SBI),
+ .Special_case_dly_SBI(Special_case_dly_SBI),
+ .Precision_ctl_SI(Precision_ctl_SI),
+ .Format_sel_SI(Format_sel_SI),
+ .Numerator_DI(Mant_a_DI),
+ .Exp_num_DI(Exp_a_DI),
+ .Denominator_DI(Mant_b_DI),
+ .Exp_den_DI(Exp_b_DI),
+ .Div_start_dly_SO(Div_start_dly_S),
+ .Sqrt_start_dly_SO(Sqrt_start_dly_S),
+ .Div_enable_SO(Div_enable_SO),
+ .Sqrt_enable_SO(Sqrt_enable_SO),
+ .Full_precision_SO(Full_precision_SO),
+ .FP32_SO(FP32_SO),
+ .FP64_SO(FP64_SO),
+ .FP16_SO(FP16_SO),
+ .FP16ALT_SO(FP16ALT_SO),
+ .Ready_SO(Ready_SO),
+ .Done_SO(Done_SO),
+ .Mant_result_prenorm_DO(Mant_z_DO),
+ .Exp_result_prenorm_DO(Exp_z_DO)
+ );
+endmodule
+module preprocess_mvp (
+ Clk_CI,
+ Rst_RBI,
+ Div_start_SI,
+ Sqrt_start_SI,
+ Ready_SI,
+ Operand_a_DI,
+ Operand_b_DI,
+ RM_SI,
+ Format_sel_SI,
+ Start_SO,
+ Exp_a_DO_norm,
+ Exp_b_DO_norm,
+ Mant_a_DO_norm,
+ Mant_b_DO_norm,
+ RM_dly_SO,
+ Sign_z_DO,
+ Inf_a_SO,
+ Inf_b_SO,
+ Zero_a_SO,
+ Zero_b_SO,
+ NaN_a_SO,
+ NaN_b_SO,
+ SNaN_SO,
+ Special_case_SBO,
+ Special_case_dly_SBO
+);
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Div_start_SI;
+ input wire Sqrt_start_SI;
+ input wire Ready_SI;
+ localparam defs_div_sqrt_mvp_C_OP_FP64 = 64;
+ input wire [63:0] Operand_a_DI;
+ input wire [63:0] Operand_b_DI;
+ localparam defs_div_sqrt_mvp_C_RM = 3;
+ input wire [2:0] RM_SI;
+ localparam defs_div_sqrt_mvp_C_FS = 2;
+ input wire [1:0] Format_sel_SI;
+ output wire Start_SO;
+ localparam defs_div_sqrt_mvp_C_EXP_FP64 = 11;
+ output wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_a_DO_norm;
+ output wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_b_DO_norm;
+ localparam defs_div_sqrt_mvp_C_MANT_FP64 = 52;
+ output wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_a_DO_norm;
+ output wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_b_DO_norm;
+ output wire [2:0] RM_dly_SO;
+ output wire Sign_z_DO;
+ output wire Inf_a_SO;
+ output wire Inf_b_SO;
+ output wire Zero_a_SO;
+ output wire Zero_b_SO;
+ output wire NaN_a_SO;
+ output wire NaN_b_SO;
+ output wire SNaN_SO;
+ output wire Special_case_SBO;
+ output reg Special_case_dly_SBO;
+ wire Hb_a_D;
+ wire Hb_b_D;
+ reg [10:0] Exp_a_D;
+ reg [10:0] Exp_b_D;
+ reg [51:0] Mant_a_NonH_D;
+ reg [51:0] Mant_b_NonH_D;
+ wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_a_D;
+ wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_b_D;
+ reg Sign_a_D;
+ reg Sign_b_D;
+ wire Start_S;
+ localparam defs_div_sqrt_mvp_C_MANT_FP16 = 10;
+ localparam defs_div_sqrt_mvp_C_MANT_FP16ALT = 7;
+ localparam defs_div_sqrt_mvp_C_MANT_FP32 = 23;
+ localparam defs_div_sqrt_mvp_C_OP_FP16 = 16;
+ localparam defs_div_sqrt_mvp_C_OP_FP16ALT = 16;
+ localparam defs_div_sqrt_mvp_C_OP_FP32 = 32;
+ always @(*)
+ case (Format_sel_SI)
+ 2'b00: begin
+ Sign_a_D = Operand_a_DI[31];
+ Sign_b_D = Operand_b_DI[31];
+ Exp_a_D = {3'h0, Operand_a_DI[30:defs_div_sqrt_mvp_C_MANT_FP32]};
+ Exp_b_D = {3'h0, Operand_b_DI[30:defs_div_sqrt_mvp_C_MANT_FP32]};
+ Mant_a_NonH_D = {Operand_a_DI[22:0], 29'h00000000};
+ Mant_b_NonH_D = {Operand_b_DI[22:0], 29'h00000000};
+ end
+ 2'b01: begin
+ Sign_a_D = Operand_a_DI[63];
+ Sign_b_D = Operand_b_DI[63];
+ Exp_a_D = Operand_a_DI[62:defs_div_sqrt_mvp_C_MANT_FP64];
+ Exp_b_D = Operand_b_DI[62:defs_div_sqrt_mvp_C_MANT_FP64];
+ Mant_a_NonH_D = Operand_a_DI[51:0];
+ Mant_b_NonH_D = Operand_b_DI[51:0];
+ end
+ 2'b10: begin
+ Sign_a_D = Operand_a_DI[15];
+ Sign_b_D = Operand_b_DI[15];
+ Exp_a_D = {6'h00, Operand_a_DI[14:defs_div_sqrt_mvp_C_MANT_FP16]};
+ Exp_b_D = {6'h00, Operand_b_DI[14:defs_div_sqrt_mvp_C_MANT_FP16]};
+ Mant_a_NonH_D = {Operand_a_DI[9:0], 42'h00000000000};
+ Mant_b_NonH_D = {Operand_b_DI[9:0], 42'h00000000000};
+ end
+ 2'b11: begin
+ Sign_a_D = Operand_a_DI[15];
+ Sign_b_D = Operand_b_DI[15];
+ Exp_a_D = {3'h0, Operand_a_DI[14:defs_div_sqrt_mvp_C_MANT_FP16ALT]};
+ Exp_b_D = {3'h0, Operand_b_DI[14:defs_div_sqrt_mvp_C_MANT_FP16ALT]};
+ Mant_a_NonH_D = {Operand_a_DI[6:0], 45'h000000000000};
+ Mant_b_NonH_D = {Operand_b_DI[6:0], 45'h000000000000};
+ end
+ endcase
+ assign Mant_a_D = {Hb_a_D, Mant_a_NonH_D};
+ assign Mant_b_D = {Hb_b_D, Mant_b_NonH_D};
+ assign Hb_a_D = |Exp_a_D;
+ assign Hb_b_D = |Exp_b_D;
+ assign Start_S = Div_start_SI | Sqrt_start_SI;
+ reg Mant_a_prenorm_zero_S;
+ reg Mant_b_prenorm_zero_S;
+ wire Exp_a_prenorm_zero_S;
+ wire Exp_b_prenorm_zero_S;
+ assign Exp_a_prenorm_zero_S = ~Hb_a_D;
+ assign Exp_b_prenorm_zero_S = ~Hb_b_D;
+ reg Exp_a_prenorm_Inf_NaN_S;
+ reg Exp_b_prenorm_Inf_NaN_S;
+ wire Mant_a_prenorm_QNaN_S;
+ wire Mant_a_prenorm_SNaN_S;
+ wire Mant_b_prenorm_QNaN_S;
+ wire Mant_b_prenorm_SNaN_S;
+ assign Mant_a_prenorm_QNaN_S = Mant_a_NonH_D[51] && ~(|Mant_a_NonH_D[50:0]);
+ assign Mant_a_prenorm_SNaN_S = ~Mant_a_NonH_D[51] && |Mant_a_NonH_D[50:0];
+ assign Mant_b_prenorm_QNaN_S = Mant_b_NonH_D[51] && ~(|Mant_b_NonH_D[50:0]);
+ assign Mant_b_prenorm_SNaN_S = ~Mant_b_NonH_D[51] && |Mant_b_NonH_D[50:0];
+ localparam defs_div_sqrt_mvp_C_EXP_INF_FP16 = 5'h1f;
+ localparam defs_div_sqrt_mvp_C_EXP_INF_FP16ALT = 8'hff;
+ localparam defs_div_sqrt_mvp_C_EXP_INF_FP32 = 8'hff;
+ localparam defs_div_sqrt_mvp_C_EXP_INF_FP64 = 11'h7ff;
+ localparam defs_div_sqrt_mvp_C_MANT_ZERO_FP16 = 10'h000;
+ localparam defs_div_sqrt_mvp_C_MANT_ZERO_FP16ALT = 7'h00;
+ localparam defs_div_sqrt_mvp_C_MANT_ZERO_FP32 = 23'h000000;
+ localparam defs_div_sqrt_mvp_C_MANT_ZERO_FP64 = 52'h0000000000000;
+ always @(*)
+ case (Format_sel_SI)
+ 2'b00: begin
+ Mant_a_prenorm_zero_S = Operand_a_DI[22:0] == defs_div_sqrt_mvp_C_MANT_ZERO_FP32;
+ Mant_b_prenorm_zero_S = Operand_b_DI[22:0] == defs_div_sqrt_mvp_C_MANT_ZERO_FP32;
+ Exp_a_prenorm_Inf_NaN_S = Operand_a_DI[30:defs_div_sqrt_mvp_C_MANT_FP32] == defs_div_sqrt_mvp_C_EXP_INF_FP32;
+ Exp_b_prenorm_Inf_NaN_S = Operand_b_DI[30:defs_div_sqrt_mvp_C_MANT_FP32] == defs_div_sqrt_mvp_C_EXP_INF_FP32;
+ end
+ 2'b01: begin
+ Mant_a_prenorm_zero_S = Operand_a_DI[51:0] == defs_div_sqrt_mvp_C_MANT_ZERO_FP64;
+ Mant_b_prenorm_zero_S = Operand_b_DI[51:0] == defs_div_sqrt_mvp_C_MANT_ZERO_FP64;
+ Exp_a_prenorm_Inf_NaN_S = Operand_a_DI[62:defs_div_sqrt_mvp_C_MANT_FP64] == defs_div_sqrt_mvp_C_EXP_INF_FP64;
+ Exp_b_prenorm_Inf_NaN_S = Operand_b_DI[62:defs_div_sqrt_mvp_C_MANT_FP64] == defs_div_sqrt_mvp_C_EXP_INF_FP64;
+ end
+ 2'b10: begin
+ Mant_a_prenorm_zero_S = Operand_a_DI[9:0] == defs_div_sqrt_mvp_C_MANT_ZERO_FP16;
+ Mant_b_prenorm_zero_S = Operand_b_DI[9:0] == defs_div_sqrt_mvp_C_MANT_ZERO_FP16;
+ Exp_a_prenorm_Inf_NaN_S = Operand_a_DI[14:defs_div_sqrt_mvp_C_MANT_FP16] == defs_div_sqrt_mvp_C_EXP_INF_FP16;
+ Exp_b_prenorm_Inf_NaN_S = Operand_b_DI[14:defs_div_sqrt_mvp_C_MANT_FP16] == defs_div_sqrt_mvp_C_EXP_INF_FP16;
+ end
+ 2'b11: begin
+ Mant_a_prenorm_zero_S = Operand_a_DI[6:0] == defs_div_sqrt_mvp_C_MANT_ZERO_FP16ALT;
+ Mant_b_prenorm_zero_S = Operand_b_DI[6:0] == defs_div_sqrt_mvp_C_MANT_ZERO_FP16ALT;
+ Exp_a_prenorm_Inf_NaN_S = Operand_a_DI[14:defs_div_sqrt_mvp_C_MANT_FP16ALT] == defs_div_sqrt_mvp_C_EXP_INF_FP16ALT;
+ Exp_b_prenorm_Inf_NaN_S = Operand_b_DI[14:defs_div_sqrt_mvp_C_MANT_FP16ALT] == defs_div_sqrt_mvp_C_EXP_INF_FP16ALT;
+ end
+ endcase
+ wire Zero_a_SN;
+ reg Zero_a_SP;
+ wire Zero_b_SN;
+ reg Zero_b_SP;
+ wire Inf_a_SN;
+ reg Inf_a_SP;
+ wire Inf_b_SN;
+ reg Inf_b_SP;
+ wire NaN_a_SN;
+ reg NaN_a_SP;
+ wire NaN_b_SN;
+ reg NaN_b_SP;
+ wire SNaN_SN;
+ reg SNaN_SP;
+ assign Zero_a_SN = (Start_S && Ready_SI ? Exp_a_prenorm_zero_S && Mant_a_prenorm_zero_S : Zero_a_SP);
+ assign Zero_b_SN = (Start_S && Ready_SI ? Exp_b_prenorm_zero_S && Mant_b_prenorm_zero_S : Zero_b_SP);
+ assign Inf_a_SN = (Start_S && Ready_SI ? Exp_a_prenorm_Inf_NaN_S && Mant_a_prenorm_zero_S : Inf_a_SP);
+ assign Inf_b_SN = (Start_S && Ready_SI ? Exp_b_prenorm_Inf_NaN_S && Mant_b_prenorm_zero_S : Inf_b_SP);
+ assign NaN_a_SN = (Start_S && Ready_SI ? Exp_a_prenorm_Inf_NaN_S && ~Mant_a_prenorm_zero_S : NaN_a_SP);
+ assign NaN_b_SN = (Start_S && Ready_SI ? Exp_b_prenorm_Inf_NaN_S && ~Mant_b_prenorm_zero_S : NaN_b_SP);
+ assign SNaN_SN = (Start_S && Ready_SI ? (Mant_a_prenorm_SNaN_S && NaN_a_SN) | (Mant_b_prenorm_SNaN_S && NaN_b_SN) : SNaN_SP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI) begin
+ Zero_a_SP <= 1'b0;
+ Zero_b_SP <= 1'b0;
+ Inf_a_SP <= 1'b0;
+ Inf_b_SP <= 1'b0;
+ NaN_a_SP <= 1'b0;
+ NaN_b_SP <= 1'b0;
+ SNaN_SP <= 1'b0;
+ end
+ else begin
+ Inf_a_SP <= Inf_a_SN;
+ Inf_b_SP <= Inf_b_SN;
+ Zero_a_SP <= Zero_a_SN;
+ Zero_b_SP <= Zero_b_SN;
+ NaN_a_SP <= NaN_a_SN;
+ NaN_b_SP <= NaN_b_SN;
+ SNaN_SP <= SNaN_SN;
+ end
+ assign Special_case_SBO = ~{(Div_start_SI ? ((((Zero_a_SN | Zero_b_SN) | Inf_a_SN) | Inf_b_SN) | NaN_a_SN) | NaN_b_SN : ((Zero_a_SN | Inf_a_SN) | NaN_a_SN) | Sign_a_D)} && (Start_S && Ready_SI);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Special_case_dly_SBO <= 1'b0;
+ else if (Start_S && Ready_SI)
+ Special_case_dly_SBO <= Special_case_SBO;
+ else if (Special_case_dly_SBO)
+ Special_case_dly_SBO <= 1'b1;
+ else
+ Special_case_dly_SBO <= 1'b0;
+ reg Sign_z_DN;
+ reg Sign_z_DP;
+ always @(*)
+ if (Div_start_SI && Ready_SI)
+ Sign_z_DN = Sign_a_D ^ Sign_b_D;
+ else if (Sqrt_start_SI && Ready_SI)
+ Sign_z_DN = Sign_a_D;
+ else
+ Sign_z_DN = Sign_z_DP;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Sign_z_DP <= 1'b0;
+ else
+ Sign_z_DP <= Sign_z_DN;
+ reg [2:0] RM_DN;
+ reg [2:0] RM_DP;
+ always @(*)
+ if (Start_S && Ready_SI)
+ RM_DN = RM_SI;
+ else
+ RM_DN = RM_DP;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ RM_DP <= {3 {1'sb0}};
+ else
+ RM_DP <= RM_DN;
+ assign RM_dly_SO = RM_DP;
+ wire [5:0] Mant_leadingOne_a;
+ wire [5:0] Mant_leadingOne_b;
+ wire Mant_zero_S_a;
+ wire Mant_zero_S_b;
+ lzc #(
+ .WIDTH(53),
+ .MODE(1)
+ ) LOD_Ua(
+ .in_i(Mant_a_D),
+ .cnt_o(Mant_leadingOne_a),
+ .empty_o(Mant_zero_S_a)
+ );
+ wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_a_norm_DN;
+ reg [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_a_norm_DP;
+ assign Mant_a_norm_DN = (Start_S && Ready_SI ? Mant_a_D << Mant_leadingOne_a : Mant_a_norm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Mant_a_norm_DP <= {53 {1'sb0}};
+ else
+ Mant_a_norm_DP <= Mant_a_norm_DN;
+ wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_a_norm_DN;
+ reg [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_a_norm_DP;
+ assign Exp_a_norm_DN = (Start_S && Ready_SI ? (Exp_a_D - Mant_leadingOne_a) + |Mant_leadingOne_a : Exp_a_norm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Exp_a_norm_DP <= {12 {1'sb0}};
+ else
+ Exp_a_norm_DP <= Exp_a_norm_DN;
+ lzc #(
+ .WIDTH(53),
+ .MODE(1)
+ ) LOD_Ub(
+ .in_i(Mant_b_D),
+ .cnt_o(Mant_leadingOne_b),
+ .empty_o(Mant_zero_S_b)
+ );
+ wire [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_b_norm_DN;
+ reg [defs_div_sqrt_mvp_C_MANT_FP64:0] Mant_b_norm_DP;
+ assign Mant_b_norm_DN = (Start_S && Ready_SI ? Mant_b_D << Mant_leadingOne_b : Mant_b_norm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Mant_b_norm_DP <= {53 {1'sb0}};
+ else
+ Mant_b_norm_DP <= Mant_b_norm_DN;
+ wire [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_b_norm_DN;
+ reg [defs_div_sqrt_mvp_C_EXP_FP64:0] Exp_b_norm_DP;
+ assign Exp_b_norm_DN = (Start_S && Ready_SI ? (Exp_b_D - Mant_leadingOne_b) + |Mant_leadingOne_b : Exp_b_norm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Exp_b_norm_DP <= {12 {1'sb0}};
+ else
+ Exp_b_norm_DP <= Exp_b_norm_DN;
+ assign Start_SO = Start_S;
+ assign Exp_a_DO_norm = Exp_a_norm_DP;
+ assign Exp_b_DO_norm = Exp_b_norm_DP;
+ assign Mant_a_DO_norm = Mant_a_norm_DP;
+ assign Mant_b_DO_norm = Mant_b_norm_DP;
+ assign Sign_z_DO = Sign_z_DP;
+ assign Inf_a_SO = Inf_a_SP;
+ assign Inf_b_SO = Inf_b_SP;
+ assign Zero_a_SO = Zero_a_SP;
+ assign Zero_b_SO = Zero_b_SP;
+ assign NaN_a_SO = NaN_a_SP;
+ assign NaN_b_SO = NaN_b_SP;
+ assign SNaN_SO = SNaN_SP;
+endmodule
+module prim_arbiter_ppc (
+ clk_i,
+ rst_ni,
+ req_i,
+ data_i,
+ gnt_o,
+ idx_o,
+ valid_o,
+ data_o,
+ ready_i
+);
+ parameter [31:0] N = 8;
+ parameter [31:0] DW = 32;
+ parameter [0:0] EnDataPort = 1;
+ parameter [0:0] EnReqStabA = 1;
+ localparam signed [31:0] IdxW = $clog2(N);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [N - 1:0] req_i;
+ input wire [(0 >= (N - 1) ? ((2 - N) * DW) + (((N - 1) * DW) - 1) : (N * DW) - 1):(0 >= (N - 1) ? (N - 1) * DW : 0)] data_i;
+ output wire [N - 1:0] gnt_o;
+ output reg [IdxW - 1:0] idx_o;
+ output wire valid_o;
+ output reg [DW - 1:0] data_o;
+ input wire ready_i;
+ generate
+ if (N == 1) begin : gen_degenerate_case
+ assign valid_o = req_i[0];
+ wire [DW:1] sv2v_tmp_10CA1;
+ assign sv2v_tmp_10CA1 = data_i[(0 >= (N - 1) ? 0 : N - 1) * DW+:DW];
+ always @(*) data_o = sv2v_tmp_10CA1;
+ assign gnt_o[0] = valid_o & ready_i;
+ wire [IdxW:1] sv2v_tmp_3D566;
+ assign sv2v_tmp_3D566 = {IdxW {1'sb0}};
+ always @(*) idx_o = sv2v_tmp_3D566;
+ end
+ else begin : gen_normal_case
+ wire [N - 1:0] masked_req;
+ reg [N - 1:0] ppc_out;
+ wire [N - 1:0] arb_req;
+ reg [N - 1:0] mask;
+ wire [N - 1:0] mask_next;
+ wire [N - 1:0] winner;
+ assign masked_req = mask & req_i;
+ assign arb_req = (|masked_req ? masked_req : req_i);
+ always @(*) begin
+ ppc_out[0] = arb_req[0];
+ begin : sv2v_autoblock_131
+ reg signed [31:0] i;
+ for (i = 1; i < N; i = i + 1)
+ ppc_out[i] = ppc_out[i - 1] | arb_req[i];
+ end
+ end
+ assign winner = ppc_out ^ {ppc_out[N - 2:0], 1'b0};
+ assign gnt_o = (ready_i ? winner : {N {1'sb0}});
+ assign valid_o = |req_i;
+ assign mask_next = {ppc_out[N - 2:0], 1'b0};
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ mask <= {N {1'sb0}};
+ else if (valid_o && ready_i)
+ mask <= mask_next;
+ else if (valid_o && !ready_i)
+ mask <= ppc_out;
+ if (EnDataPort == 1) begin : gen_datapath
+ always @(*) begin
+ data_o = {DW {1'sb0}};
+ begin : sv2v_autoblock_132
+ reg signed [31:0] i;
+ for (i = 0; i < N; i = i + 1)
+ if (winner[i])
+ data_o = data_i[(0 >= (N - 1) ? i : (N - 1) - i) * DW+:DW];
+ end
+ end
+ end
+ else begin : gen_nodatapath
+ wire [DW:1] sv2v_tmp_546E1;
+ assign sv2v_tmp_546E1 = {DW {1'sb1}};
+ always @(*) data_o = sv2v_tmp_546E1;
+ end
+ always @(*) begin
+ idx_o = {IdxW {1'sb0}};
+ begin : sv2v_autoblock_133
+ reg [31:0] i;
+ for (i = 0; i < N; i = i + 1)
+ if (winner[i])
+ idx_o = i[IdxW - 1:0];
+ end
+ end
+ end
+ endgenerate
+endmodule
+module prim_clock_gating (
+ clk_i,
+ en_i,
+ test_en_i,
+ clk_o
+);
+ input wire clk_i;
+ input wire en_i;
+ input wire test_en_i;
+ output wire clk_o;
+ sky130_fd_sc_hd__dlclkp_1 CG(
+ .CLK(clk_i),
+ .GCLK(clk_o),
+ .GATE(en_i | test_en_i)
+ );
+endmodule
+module prim_filter_ctr (
+ clk_i,
+ rst_ni,
+ enable_i,
+ filter_i,
+ filter_o
+);
+ parameter [31:0] Cycles = 4;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire enable_i;
+ input wire filter_i;
+ output wire filter_o;
+ localparam [31:0] CTR_WIDTH = $clog2(Cycles);
+ function automatic [CTR_WIDTH - 1:0] sv2v_cast_FC6F8;
+ input reg [CTR_WIDTH - 1:0] inp;
+ sv2v_cast_FC6F8 = inp;
+ endfunction
+ localparam [CTR_WIDTH - 1:0] CYCLESM1 = sv2v_cast_FC6F8(Cycles - 1);
+ reg [CTR_WIDTH - 1:0] diff_ctr_q;
+ wire [CTR_WIDTH - 1:0] diff_ctr_d;
+ reg filter_q;
+ reg stored_value_q;
+ wire update_stored_value;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ filter_q <= 1'b0;
+ else
+ filter_q <= filter_i;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ stored_value_q <= 1'b0;
+ else if (update_stored_value)
+ stored_value_q <= filter_i;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ diff_ctr_q <= {CTR_WIDTH {1'b0}};
+ else
+ diff_ctr_q <= diff_ctr_d;
+ assign diff_ctr_d = (filter_i != filter_q ? {CTR_WIDTH {1'sb0}} : (diff_ctr_q == CYCLESM1 ? CYCLESM1 : diff_ctr_q + 1'b1));
+ assign update_stored_value = diff_ctr_d == CYCLESM1;
+ assign filter_o = (enable_i ? stored_value_q : filter_i);
+endmodule
+module prim_generic_clock_inv (
+ clk_i,
+ scanmode_i,
+ clk_no
+);
+ parameter [0:0] HasScanMode = 1'b1;
+ input wire clk_i;
+ input wire scanmode_i;
+ output wire clk_no;
+ generate
+ if (HasScanMode) begin : gen_scan
+ prim_generic_clock_mux2 i_dft_tck_mux(
+ .clk0_i(~clk_i),
+ .clk1_i(clk_i),
+ .sel_i(scanmode_i),
+ .clk_o(clk_no)
+ );
+ end
+ else begin : gen_noscan
+ wire unused_scanmode;
+ assign unused_scanmode = scanmode_i;
+ assign clk_no = ~clk_i;
+ end
+ endgenerate
+endmodule
+module prim_generic_clock_mux2 (
+ clk0_i,
+ clk1_i,
+ sel_i,
+ clk_o
+);
+ parameter [0:0] NoFpgaBufG = 1'b0;
+ input wire clk0_i;
+ input wire clk1_i;
+ input wire sel_i;
+ output wire clk_o;
+ assign clk_o = (sel_i ? clk1_i : clk0_i);
+endmodule
+module prim_generic_flop_2sync (
+ clk_i,
+ rst_ni,
+ d_i,
+ q_o
+);
+ parameter signed [31:0] Width = 16;
+ localparam signed [31:0] WidthSubOne = Width - 1;
+ parameter [WidthSubOne:0] ResetValue = 1'sb0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [Width - 1:0] d_i;
+ output wire [Width - 1:0] q_o;
+ wire [Width - 1:0] intq;
+ prim_generic_flop #(
+ .Width(Width),
+ .ResetValue(ResetValue)
+ ) u_sync_1(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .d_i(d_i),
+ .q_o(intq)
+ );
+ prim_generic_flop #(
+ .Width(Width),
+ .ResetValue(ResetValue)
+ ) u_sync_2(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .d_i(intq),
+ .q_o(q_o)
+ );
+endmodule
+module prim_generic_flop (
+ clk_i,
+ rst_ni,
+ d_i,
+ q_o
+);
+ parameter signed [31:0] Width = 1;
+ localparam signed [31:0] WidthSubOne = Width - 1;
+ parameter [WidthSubOne:0] ResetValue = 0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [Width - 1:0] d_i;
+ output reg [Width - 1:0] q_o;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ q_o <= ResetValue;
+ else
+ q_o <= d_i;
+endmodule
+module prim_intr_hw (
+ clk_i,
+ rst_ni,
+ event_intr_i,
+ reg2hw_intr_enable_q_i,
+ reg2hw_intr_test_q_i,
+ reg2hw_intr_test_qe_i,
+ reg2hw_intr_state_q_i,
+ hw2reg_intr_state_de_o,
+ hw2reg_intr_state_d_o,
+ intr_o
+);
+ parameter [31:0] Width = 1;
+ parameter [0:0] FlopOutput = 1;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [Width - 1:0] event_intr_i;
+ input wire [Width - 1:0] reg2hw_intr_enable_q_i;
+ input wire [Width - 1:0] reg2hw_intr_test_q_i;
+ input wire reg2hw_intr_test_qe_i;
+ input wire [Width - 1:0] reg2hw_intr_state_q_i;
+ output wire hw2reg_intr_state_de_o;
+ output wire [Width - 1:0] hw2reg_intr_state_d_o;
+ output reg [Width - 1:0] intr_o;
+ wire [Width - 1:0] new_event;
+ assign new_event = ({Width {reg2hw_intr_test_qe_i}} & reg2hw_intr_test_q_i) | event_intr_i;
+ assign hw2reg_intr_state_de_o = |new_event;
+ assign hw2reg_intr_state_d_o = new_event | reg2hw_intr_state_q_i;
+ generate
+ if (FlopOutput == 1) begin : gen_flop_intr_output
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ intr_o <= 1'b0;
+ else
+ intr_o <= reg2hw_intr_state_q_i & reg2hw_intr_enable_q_i;
+ end
+ else begin : gen_intr_passthrough_output
+ wire unused_clk;
+ wire unused_rst_n;
+ assign unused_clk = clk_i;
+ assign unused_rst_n = rst_ni;
+ wire [Width:1] sv2v_tmp_BA45F;
+ assign sv2v_tmp_BA45F = reg2hw_intr_state_q_i & reg2hw_intr_enable_q_i;
+ always @(*) intr_o = sv2v_tmp_BA45F;
+ end
+ endgenerate
+endmodule
+module prim_subreg_arb (
+ we,
+ wd,
+ de,
+ d,
+ q,
+ wr_en,
+ wr_data
+);
+ parameter signed [31:0] DW = 32;
+ parameter SWACCESS = "RW";
+ input wire we;
+ input wire [DW - 1:0] wd;
+ input wire de;
+ input wire [DW - 1:0] d;
+ input wire [DW - 1:0] q;
+ output wire wr_en;
+ output wire [DW - 1:0] wr_data;
+ generate
+ if ((SWACCESS == "RW") || (SWACCESS == "WO")) begin : gen_w
+ assign wr_en = we | de;
+ assign wr_data = (we == 1'b1 ? wd : d);
+ wire [DW - 1:0] unused_q;
+ assign unused_q = q;
+ end
+ else if (SWACCESS == "RO") begin : gen_ro
+ assign wr_en = de;
+ assign wr_data = d;
+ wire unused_we;
+ wire [DW - 1:0] unused_wd;
+ wire [DW - 1:0] unused_q;
+ assign unused_we = we;
+ assign unused_wd = wd;
+ assign unused_q = q;
+ end
+ else if (SWACCESS == "W1S") begin : gen_w1s
+ assign wr_en = we | de;
+ assign wr_data = (de ? d : q) | (we ? wd : {DW {1'sb0}});
+ end
+ else if (SWACCESS == "W1C") begin : gen_w1c
+ assign wr_en = we | de;
+ assign wr_data = (de ? d : q) & (we ? ~wd : {DW {1'sb1}});
+ end
+ else if (SWACCESS == "W0C") begin : gen_w0c
+ assign wr_en = we | de;
+ assign wr_data = (de ? d : q) & (we ? wd : {DW {1'sb1}});
+ end
+ else if (SWACCESS == "RC") begin : gen_rc
+ assign wr_en = we | de;
+ assign wr_data = (de ? d : q) & (we ? {DW {1'sb0}} : {DW {1'sb1}});
+ wire [DW - 1:0] unused_wd;
+ assign unused_wd = wd;
+ end
+ else begin : gen_hw
+ assign wr_en = de;
+ assign wr_data = d;
+ wire unused_we;
+ wire [DW - 1:0] unused_wd;
+ wire [DW - 1:0] unused_q;
+ assign unused_we = we;
+ assign unused_wd = wd;
+ assign unused_q = q;
+ end
+ endgenerate
+endmodule
+module prim_subreg_ext (
+ re,
+ we,
+ wd,
+ d,
+ qe,
+ qre,
+ q,
+ qs
+);
+ parameter [31:0] DW = 32;
+ input wire re;
+ input wire we;
+ input wire [DW - 1:0] wd;
+ input wire [DW - 1:0] d;
+ output wire qe;
+ output wire qre;
+ output wire [DW - 1:0] q;
+ output wire [DW - 1:0] qs;
+ assign qs = d;
+ assign q = wd;
+ assign qe = we;
+ assign qre = re;
+endmodule
+module prim_subreg (
+ clk_i,
+ rst_ni,
+ we,
+ wd,
+ de,
+ d,
+ qe,
+ q,
+ qs
+);
+ parameter signed [31:0] DW = 32;
+ parameter SWACCESS = "RW";
+ parameter [DW - 1:0] RESVAL = 1'sb0;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire we;
+ input wire [DW - 1:0] wd;
+ input wire de;
+ input wire [DW - 1:0] d;
+ output reg qe;
+ output reg [DW - 1:0] q;
+ output wire [DW - 1:0] qs;
+ wire wr_en;
+ wire [DW - 1:0] wr_data;
+ prim_subreg_arb #(
+ .DW(DW),
+ .SWACCESS(SWACCESS)
+ ) wr_en_data_arb(
+ .we(we),
+ .wd(wd),
+ .de(de),
+ .d(d),
+ .q(q),
+ .wr_en(wr_en),
+ .wr_data(wr_data)
+ );
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ qe <= 1'b0;
+ else
+ qe <= we;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ q <= RESVAL;
+ else if (wr_en)
+ q <= wr_data;
+ assign qs = q;
+endmodule
+module pwm_top (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ pwm_o,
+ pwm_o_2,
+ pwm1_oe,
+ pwm2_oe
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire pwm_o;
+ output wire pwm_o_2;
+ output wire pwm1_oe;
+ output wire pwm2_oe;
+ localparam signed [31:0] AW = 8;
+ localparam signed [31:0] DW = 32;
+ localparam signed [31:0] DBW = 4;
+ wire re;
+ wire we;
+ wire [7:0] addr;
+ wire [31:0] wdata;
+ wire [3:0] be;
+ wire [31:0] rdata;
+ wire err;
+ pwm pwm_core(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .re_i(re),
+ .we_i(we),
+ .addr_i(addr),
+ .wdata_i(wdata),
+ .be_i(be),
+ .rdata_o(rdata),
+ .o_pwm(pwm_o),
+ .o_pwm_2(pwm_o_2),
+ .oe_pwm1(pwm1_oe),
+ .oe_pwm2(pwm2_oe)
+ );
+ tlul_adapter_reg #(
+ .RegAw(AW),
+ .RegDw(DW)
+ ) u_reg_if(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_i),
+ .tl_o(tl_o),
+ .we_o(we),
+ .re_o(re),
+ .addr_o(addr),
+ .wdata_o(wdata),
+ .be_o(be),
+ .rdata_i(rdata),
+ .error_i(1'b0)
+ );
+endmodule
+module pwm (
+ clk_i,
+ rst_ni,
+ re_i,
+ we_i,
+ addr_i,
+ wdata_i,
+ be_i,
+ rdata_o,
+ o_pwm,
+ o_pwm_2,
+ oe_pwm1,
+ oe_pwm2
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire re_i;
+ input wire we_i;
+ input wire [7:0] addr_i;
+ input wire [31:0] wdata_i;
+ input wire [3:0] be_i;
+ output wire [31:0] rdata_o;
+ output wire o_pwm;
+ output wire o_pwm_2;
+ output reg oe_pwm1;
+ output reg oe_pwm2;
+ parameter adr_ctrl_1 = 0;
+ parameter adr_divisor_1 = 4;
+ parameter adr_period_1 = 8;
+ parameter adr_DC_1 = 12;
+ parameter adr_ctrl_2 = 16;
+ parameter adr_divisor_2 = 20;
+ parameter adr_period_2 = 24;
+ parameter adr_DC_2 = 28;
+ reg [7:0] ctrl;
+ reg [15:0] period;
+ reg [15:0] DC_1;
+ reg [15:0] divisor;
+ reg [7:0] ctrl_2;
+ reg [15:0] period_2;
+ reg [15:0] DC_2;
+ reg [15:0] divisor_2;
+ wire write;
+ assign write = we_i & ~re_i;
+ always @(posedge clk_i)
+ if (~rst_ni) begin
+ ctrl[4:2] <= 3'b000;
+ ctrl[0] <= 1'b0;
+ ctrl[1] <= 1'b0;
+ ctrl[7:5] <= 3'b000;
+ DC_1 <= 16'b0000000000000000;
+ period <= 16'b0000000000000000;
+ divisor <= 16'b0000000000000000;
+ ctrl_2[4:2] <= 3'b000;
+ ctrl_2[0] <= 1'b0;
+ ctrl_2[7:5] <= 3'b000;
+ ctrl_2[1] <= 1'b0;
+ DC_2 <= 16'b0000000000000000;
+ period_2 <= 16'b0000000000000000;
+ divisor_2 <= 16'b0000000000000000;
+ end
+ else if (write)
+ case (addr_i)
+ adr_ctrl_1: begin
+ ctrl[0] <= wdata_i[0];
+ ctrl[1] <= 1'b1;
+ ctrl[4:2] <= wdata_i[4:2];
+ ctrl[7:5] <= wdata_i[7:5];
+ end
+ adr_ctrl_2: begin
+ ctrl_2[0] <= wdata_i[0];
+ ctrl_2[1] <= 1'b1;
+ ctrl_2[4:2] <= wdata_i[4:2];
+ ctrl_2[7:5] <= wdata_i[7:5];
+ end
+ adr_divisor_1: divisor <= wdata_i[15:0];
+ adr_period_1: period <= wdata_i[15:0];
+ adr_DC_1: DC_1 <= wdata_i[15:0];
+ adr_divisor_2: divisor_2 <= wdata_i[15:0];
+ adr_period_2: period_2 <= wdata_i[15:0];
+ adr_DC_2: DC_2 <= wdata_i[15:0];
+ endcase
+ wire pwm_1;
+ assign pwm_1 = ctrl[1];
+ wire pwm_2;
+ assign pwm_2 = ctrl_2[1];
+ reg clock_p1;
+ reg clock_p2;
+ reg [15:0] counter_p1;
+ reg [15:0] counter_p2;
+ reg [15:0] period_counter1;
+ reg [15:0] period_counter2;
+ reg pts;
+ reg pts_2;
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni) begin
+ clock_p1 <= 1'b0;
+ clock_p2 <= 1'b0;
+ counter_p1 <= 16'b0000000000000000;
+ counter_p2 <= 16'b0000000000000000;
+ end
+ else begin
+ if (pwm_1) begin
+ counter_p1 <= counter_p1 + 16'b0000000000000001;
+ if (counter_p1 == (divisor - 1)) begin
+ counter_p1 <= 16'b0000000000000000;
+ clock_p1 <= ~clock_p1;
+ end
+ end
+ if (pwm_2) begin
+ counter_p2 <= counter_p2 + 16'b0000000000000001;
+ if (counter_p2 == (divisor_2 - 1)) begin
+ counter_p2 <= 16'b0000000000000000;
+ clock_p2 <= ~clock_p2;
+ end
+ end
+ end
+ always @(posedge clock_p1)
+ if (~rst_ni) begin
+ pts <= 1'b0;
+ period_counter1 <= 16'b0000000000000000;
+ end
+ else if (ctrl[2]) begin
+ if (pwm_1) begin
+ oe_pwm1 <= 1'b1;
+ if (period_counter1 >= period)
+ period_counter1 <= 16'b0000000000000000;
+ else
+ period_counter1 <= period_counter1 + 16'b0000000000000001;
+ if (period_counter1 < DC_1)
+ pts <= 1'b1;
+ else
+ pts <= 1'b0;
+ end
+ end
+ else begin
+ pts <= 1'b0;
+ period_counter1 <= 16'b0000000000000000;
+ oe_pwm1 <= 1'b0;
+ end
+ always @(posedge clock_p2)
+ if (~rst_ni) begin
+ pts_2 <= 1'b0;
+ period_counter2 <= 16'b0000000000000000;
+ end
+ else if (ctrl_2[2]) begin
+ if (pwm_2) begin
+ oe_pwm2 <= 1'b1;
+ if (period_counter2 >= period_2)
+ period_counter2 <= 16'b0000000000000000;
+ else
+ period_counter2 <= period_counter2 + 16'b0000000000000001;
+ if (period_counter2 < DC_2)
+ pts_2 <= 1'b1;
+ else
+ pts_2 <= 1'b0;
+ end
+ end
+ else begin
+ pts_2 <= 1'b0;
+ period_counter2 <= 16'b0000000000000000;
+ oe_pwm2 <= 1'b0;
+ end
+ assign o_pwm = (ctrl[4] ? pts : 1'b0);
+ assign o_pwm_2 = (ctrl_2[4] ? pts_2 : 1'b0);
+ assign rdata_o = (addr_i == adr_ctrl_1 ? {8'h00, ctrl} : (addr_i == adr_divisor_1 ? divisor : (addr_i == adr_period_1 ? period : (addr_i == adr_DC_1 ? DC_1 : (addr_i == adr_DC_2 ? DC_2 : (addr_i == adr_period_2 ? period_2 : (addr_i == adr_divisor_2 ? divisor_2 : (addr_i == adr_ctrl_2 ? {8'h00, ctrl_2} : 32'b00000000000000000000000000000000))))))));
+endmodule
+module rr_arb_tree_252F1_F315E (
+ clk_i,
+ rst_ni,
+ flush_i,
+ rr_i,
+ req_i,
+ gnt_o,
+ data_i,
+ req_o,
+ gnt_i,
+ data_o,
+ idx_o
+);
+ parameter [31:0] DataType_Width = 0;
+ parameter [31:0] NumIn = 64;
+ parameter [31:0] DataWidth = 32;
+ parameter [0:0] ExtPrio = 1'b0;
+ parameter [0:0] AxiVldRdy = 1'b0;
+ parameter [0:0] LockIn = 1'b0;
+ parameter [0:0] FairArb = 1'b1;
+ parameter [31:0] IdxWidth = (NumIn > 32'd1 ? $unsigned($clog2(NumIn)) : 32'd1);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire flush_i;
+ input wire [IdxWidth - 1:0] rr_i;
+ input wire [NumIn - 1:0] req_i;
+ output wire [NumIn - 1:0] gnt_o;
+ input wire [((DataType_Width + 6) >= 0 ? (NumIn * (DataType_Width + 7)) - 1 : (NumIn * (1 - (DataType_Width + 6))) + (DataType_Width + 5)):((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6)] data_i;
+ output wire req_o;
+ input wire gnt_i;
+ output wire [DataType_Width + 6:0] data_o;
+ output wire [IdxWidth - 1:0] idx_o;
+ generate
+ if (NumIn == $unsigned(1)) begin : gen_pass_through
+ assign req_o = req_i[0];
+ assign gnt_o[0] = gnt_i;
+ assign data_o = data_i[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6)+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))];
+ assign idx_o = {IdxWidth {1'sb0}};
+ end
+ else begin : gen_arbiter
+ localparam [31:0] NumLevels = $unsigned($clog2(NumIn));
+ wire [(((2 ** NumLevels) - 2) >= 0 ? (((2 ** NumLevels) - 1) * IdxWidth) - 1 : ((3 - (2 ** NumLevels)) * IdxWidth) + ((((2 ** NumLevels) - 2) * IdxWidth) - 1)):(((2 ** NumLevels) - 2) >= 0 ? 0 : ((2 ** NumLevels) - 2) * IdxWidth)] index_nodes;
+ wire [(((2 ** NumLevels) - 2) >= 0 ? ((DataType_Width + 6) >= 0 ? (((2 ** NumLevels) - 1) * (DataType_Width + 7)) - 1 : (((2 ** NumLevels) - 1) * (1 - (DataType_Width + 6))) + (DataType_Width + 5)) : ((DataType_Width + 6) >= 0 ? ((3 - (2 ** NumLevels)) * (DataType_Width + 7)) + ((((2 ** NumLevels) - 2) * (DataType_Width + 7)) - 1) : ((3 - (2 ** NumLevels)) * (1 - (DataType_Width + 6))) + (((DataType_Width + 6) + (((2 ** NumLevels) - 2) * (1 - (DataType_Width + 6)))) - 1))):(((2 ** NumLevels) - 2) >= 0 ? ((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) : ((DataType_Width + 6) >= 0 ? ((2 ** NumLevels) - 2) * (DataType_Width + 7) : (DataType_Width + 6) + (((2 ** NumLevels) - 2) * (1 - (DataType_Width + 6)))))] data_nodes;
+ wire [(2 ** NumLevels) - 2:0] gnt_nodes;
+ wire [(2 ** NumLevels) - 2:0] req_nodes;
+ reg [IdxWidth - 1:0] rr_q;
+ wire [NumIn - 1:0] req_d;
+ assign req_o = req_nodes[0];
+ assign data_o = data_nodes[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((((2 ** NumLevels) - 2) >= 0 ? 0 : (2 ** NumLevels) - 2) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))];
+ assign idx_o = index_nodes[(((2 ** NumLevels) - 2) >= 0 ? 0 : (2 ** NumLevels) - 2) * IdxWidth+:IdxWidth];
+ if (ExtPrio) begin : gen_ext_rr
+ wire [IdxWidth:1] sv2v_tmp_48DE0;
+ assign sv2v_tmp_48DE0 = rr_i;
+ always @(*) rr_q = sv2v_tmp_48DE0;
+ assign req_d = req_i;
+ end
+ else begin : gen_int_rr
+ wire [IdxWidth - 1:0] rr_d;
+ if (LockIn) begin : gen_lock
+ wire lock_d;
+ reg lock_q;
+ reg [NumIn - 1:0] req_q;
+ assign lock_d = req_o & ~gnt_i;
+ assign req_d = (lock_q ? req_q : req_i);
+ always @(posedge clk_i or negedge rst_ni) begin : p_lock_reg
+ if (!rst_ni)
+ lock_q <= 1'b0;
+ else if (flush_i)
+ lock_q <= 1'b0;
+ else
+ lock_q <= lock_d;
+ end
+ always @(posedge clk_i or negedge rst_ni) begin : p_req_regs
+ if (!rst_ni)
+ req_q <= {NumIn {1'sb0}};
+ else if (flush_i)
+ req_q <= {NumIn {1'sb0}};
+ else
+ req_q <= req_d;
+ end
+ end
+ else begin : gen_no_lock
+ assign req_d = req_i;
+ end
+ if (FairArb) begin : gen_fair_arb
+ wire [NumIn - 1:0] upper_mask;
+ wire [NumIn - 1:0] lower_mask;
+ wire [IdxWidth - 1:0] upper_idx;
+ wire [IdxWidth - 1:0] lower_idx;
+ wire [IdxWidth - 1:0] next_idx;
+ wire upper_empty;
+ wire lower_empty;
+ genvar i;
+ for (i = 0; i < NumIn; i = i + 1) begin : gen_mask
+ assign upper_mask[i] = (i > rr_q ? req_d[i] : 1'b0);
+ assign lower_mask[i] = (i <= rr_q ? req_d[i] : 1'b0);
+ end
+ lzc #(
+ .WIDTH(NumIn),
+ .MODE(1'b0)
+ ) i_lzc_upper(
+ .in_i(upper_mask),
+ .cnt_o(upper_idx),
+ .empty_o(upper_empty)
+ );
+ lzc #(
+ .WIDTH(NumIn),
+ .MODE(1'b0)
+ ) i_lzc_lower(
+ .in_i(lower_mask),
+ .cnt_o(lower_idx),
+ .empty_o()
+ );
+ assign next_idx = (upper_empty ? lower_idx : upper_idx);
+ assign rr_d = (gnt_i && req_o ? next_idx : rr_q);
+ end
+ else begin : gen_unfair_arb
+ function automatic [IdxWidth - 1:0] sv2v_cast_40B81;
+ input reg [IdxWidth - 1:0] inp;
+ sv2v_cast_40B81 = inp;
+ endfunction
+ assign rr_d = (gnt_i && req_o ? (rr_q == sv2v_cast_40B81(NumIn - 1) ? {IdxWidth {1'sb0}} : rr_q + 1'b1) : rr_q);
+ end
+ always @(posedge clk_i or negedge rst_ni) begin : p_rr_regs
+ if (!rst_ni)
+ rr_q <= {IdxWidth {1'sb0}};
+ else if (flush_i)
+ rr_q <= {IdxWidth {1'sb0}};
+ else
+ rr_q <= rr_d;
+ end
+ end
+ assign gnt_nodes[0] = gnt_i;
+ genvar level;
+ for (level = 0; $unsigned(level) < NumLevels; level = level + 1) begin : gen_levels
+ genvar l;
+ for (l = 0; l < (2 ** level); l = l + 1) begin : gen_level
+ wire sel;
+ localparam [31:0] Idx0 = ((2 ** level) - 1) + l;
+ localparam [31:0] Idx1 = ((2 ** (level + 1)) - 1) + (l * 2);
+ if ($unsigned(level) == (NumLevels - 1)) begin : gen_first_level
+ if (($unsigned(l) * 2) < (NumIn - 1)) begin : gen_reduce
+ assign req_nodes[Idx0] = req_d[l * 2] | req_d[(l * 2) + 1];
+ assign sel = ~req_d[l * 2] | (req_d[(l * 2) + 1] & rr_q[(NumLevels - 1) - level]);
+ function automatic [IdxWidth - 1:0] sv2v_cast_40B81;
+ input reg [IdxWidth - 1:0] inp;
+ sv2v_cast_40B81 = inp;
+ endfunction
+ assign index_nodes[(((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * IdxWidth+:IdxWidth] = sv2v_cast_40B81(sel);
+ assign data_nodes[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))] = (sel ? data_i[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + (((l * 2) + 1) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))] : data_i[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((l * 2) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))]);
+ assign gnt_o[l * 2] = (gnt_nodes[Idx0] & (AxiVldRdy | req_d[l * 2])) & ~sel;
+ assign gnt_o[(l * 2) + 1] = (gnt_nodes[Idx0] & (AxiVldRdy | req_d[(l * 2) + 1])) & sel;
+ end
+ if (($unsigned(l) * 2) == (NumIn - 1)) begin : gen_first
+ assign req_nodes[Idx0] = req_d[l * 2];
+ assign index_nodes[(((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * IdxWidth+:IdxWidth] = {IdxWidth {1'sb0}};
+ assign data_nodes[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))] = data_i[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((l * 2) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))];
+ assign gnt_o[l * 2] = gnt_nodes[Idx0] & (AxiVldRdy | req_d[l * 2]);
+ end
+ if (($unsigned(l) * 2) > (NumIn - 1)) begin : gen_out_of_range
+ assign req_nodes[Idx0] = 1'b0;
+ function automatic [IdxWidth - 1:0] sv2v_cast_40B81;
+ input reg [IdxWidth - 1:0] inp;
+ sv2v_cast_40B81 = inp;
+ endfunction
+ assign index_nodes[(((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * IdxWidth+:IdxWidth] = sv2v_cast_40B81(1'sb0);
+ function automatic [((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)) - 1:0] sv2v_cast_69F84;
+ input reg [((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)) - 1:0] inp;
+ sv2v_cast_69F84 = inp;
+ endfunction
+ assign data_nodes[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))] = sv2v_cast_69F84(1'sb0);
+ end
+ end
+ else begin : gen_other_levels
+ assign req_nodes[Idx0] = req_nodes[Idx1] | req_nodes[Idx1 + 1];
+ assign sel = ~req_nodes[Idx1] | (req_nodes[Idx1 + 1] & rr_q[(NumLevels - 1) - level]);
+ function automatic [IdxWidth - 1:0] sv2v_cast_40B81;
+ input reg [IdxWidth - 1:0] inp;
+ sv2v_cast_40B81 = inp;
+ endfunction
+ assign index_nodes[(((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * IdxWidth+:IdxWidth] = (sel ? sv2v_cast_40B81({1'b1, index_nodes[((((2 ** NumLevels) - 2) >= 0 ? Idx1 + 1 : ((2 ** NumLevels) - 2) - (Idx1 + 1)) * IdxWidth) + (((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 2 : (((NumLevels - $unsigned(level)) - 2) + (((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 1 : 3 - (NumLevels - $unsigned(level)))) - 1)-:(((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 1 : 3 - (NumLevels - $unsigned(level)))]}) : sv2v_cast_40B81({1'b0, index_nodes[((((2 ** NumLevels) - 2) >= 0 ? Idx1 : ((2 ** NumLevels) - 2) - Idx1) * IdxWidth) + (((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 2 : (((NumLevels - $unsigned(level)) - 2) + (((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 1 : 3 - (NumLevels - $unsigned(level)))) - 1)-:(((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 1 : 3 - (NumLevels - $unsigned(level)))]}));
+ assign data_nodes[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))] = (sel ? data_nodes[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((((2 ** NumLevels) - 2) >= 0 ? Idx1 + 1 : ((2 ** NumLevels) - 2) - (Idx1 + 1)) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))] : data_nodes[((DataType_Width + 6) >= 0 ? 0 : DataType_Width + 6) + ((((2 ** NumLevels) - 2) >= 0 ? Idx1 : ((2 ** NumLevels) - 2) - Idx1) * ((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6)))+:((DataType_Width + 6) >= 0 ? DataType_Width + 7 : 1 - (DataType_Width + 6))]);
+ assign gnt_nodes[Idx1] = gnt_nodes[Idx0] & ~sel;
+ assign gnt_nodes[Idx1 + 1] = gnt_nodes[Idx0] & sel;
+ end
+ end
+ end
+ end
+ endgenerate
+endmodule
+module rr_arb_tree_CBEBF_6E668 (
+ clk_i,
+ rst_ni,
+ flush_i,
+ rr_i,
+ req_i,
+ gnt_o,
+ data_i,
+ req_o,
+ gnt_i,
+ data_o,
+ idx_o
+);
+ parameter [31:0] DataType_WIDTH = 0;
+ parameter [31:0] NumIn = 64;
+ parameter [31:0] DataWidth = 32;
+ parameter [0:0] ExtPrio = 1'b0;
+ parameter [0:0] AxiVldRdy = 1'b0;
+ parameter [0:0] LockIn = 1'b0;
+ parameter [0:0] FairArb = 1'b1;
+ parameter [31:0] IdxWidth = (NumIn > 32'd1 ? $unsigned($clog2(NumIn)) : 32'd1);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire flush_i;
+ input wire [IdxWidth - 1:0] rr_i;
+ input wire [NumIn - 1:0] req_i;
+ output wire [NumIn - 1:0] gnt_o;
+ input wire [((DataType_WIDTH + 5) >= 0 ? (NumIn * (DataType_WIDTH + 6)) - 1 : (NumIn * (1 - (DataType_WIDTH + 5))) + (DataType_WIDTH + 4)):((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5)] data_i;
+ output wire req_o;
+ input wire gnt_i;
+ output wire [DataType_WIDTH + 5:0] data_o;
+ output wire [IdxWidth - 1:0] idx_o;
+ generate
+ if (NumIn == $unsigned(1)) begin : gen_pass_through
+ assign req_o = req_i[0];
+ assign gnt_o[0] = gnt_i;
+ assign data_o = data_i[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5)+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))];
+ assign idx_o = {IdxWidth {1'sb0}};
+ end
+ else begin : gen_arbiter
+ localparam [31:0] NumLevels = $unsigned($clog2(NumIn));
+ wire [(((2 ** NumLevels) - 2) >= 0 ? (((2 ** NumLevels) - 1) * IdxWidth) - 1 : ((3 - (2 ** NumLevels)) * IdxWidth) + ((((2 ** NumLevels) - 2) * IdxWidth) - 1)):(((2 ** NumLevels) - 2) >= 0 ? 0 : ((2 ** NumLevels) - 2) * IdxWidth)] index_nodes;
+ wire [(((2 ** NumLevels) - 2) >= 0 ? ((DataType_WIDTH + 5) >= 0 ? (((2 ** NumLevels) - 1) * (DataType_WIDTH + 6)) - 1 : (((2 ** NumLevels) - 1) * (1 - (DataType_WIDTH + 5))) + (DataType_WIDTH + 4)) : ((DataType_WIDTH + 5) >= 0 ? ((3 - (2 ** NumLevels)) * (DataType_WIDTH + 6)) + ((((2 ** NumLevels) - 2) * (DataType_WIDTH + 6)) - 1) : ((3 - (2 ** NumLevels)) * (1 - (DataType_WIDTH + 5))) + (((DataType_WIDTH + 5) + (((2 ** NumLevels) - 2) * (1 - (DataType_WIDTH + 5)))) - 1))):(((2 ** NumLevels) - 2) >= 0 ? ((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) : ((DataType_WIDTH + 5) >= 0 ? ((2 ** NumLevels) - 2) * (DataType_WIDTH + 6) : (DataType_WIDTH + 5) + (((2 ** NumLevels) - 2) * (1 - (DataType_WIDTH + 5)))))] data_nodes;
+ wire [(2 ** NumLevels) - 2:0] gnt_nodes;
+ wire [(2 ** NumLevels) - 2:0] req_nodes;
+ reg [IdxWidth - 1:0] rr_q;
+ wire [NumIn - 1:0] req_d;
+ assign req_o = req_nodes[0];
+ assign data_o = data_nodes[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((((2 ** NumLevels) - 2) >= 0 ? 0 : (2 ** NumLevels) - 2) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))];
+ assign idx_o = index_nodes[(((2 ** NumLevels) - 2) >= 0 ? 0 : (2 ** NumLevels) - 2) * IdxWidth+:IdxWidth];
+ if (ExtPrio) begin : gen_ext_rr
+ wire [IdxWidth:1] sv2v_tmp_48DE0;
+ assign sv2v_tmp_48DE0 = rr_i;
+ always @(*) rr_q = sv2v_tmp_48DE0;
+ assign req_d = req_i;
+ end
+ else begin : gen_int_rr
+ wire [IdxWidth - 1:0] rr_d;
+ if (LockIn) begin : gen_lock
+ wire lock_d;
+ reg lock_q;
+ reg [NumIn - 1:0] req_q;
+ assign lock_d = req_o & ~gnt_i;
+ assign req_d = (lock_q ? req_q : req_i);
+ always @(posedge clk_i or negedge rst_ni) begin : p_lock_reg
+ if (!rst_ni)
+ lock_q <= 1'b0;
+ else if (flush_i)
+ lock_q <= 1'b0;
+ else
+ lock_q <= lock_d;
+ end
+ always @(posedge clk_i or negedge rst_ni) begin : p_req_regs
+ if (!rst_ni)
+ req_q <= {NumIn {1'sb0}};
+ else if (flush_i)
+ req_q <= {NumIn {1'sb0}};
+ else
+ req_q <= req_d;
+ end
+ end
+ else begin : gen_no_lock
+ assign req_d = req_i;
+ end
+ if (FairArb) begin : gen_fair_arb
+ wire [NumIn - 1:0] upper_mask;
+ wire [NumIn - 1:0] lower_mask;
+ wire [IdxWidth - 1:0] upper_idx;
+ wire [IdxWidth - 1:0] lower_idx;
+ wire [IdxWidth - 1:0] next_idx;
+ wire upper_empty;
+ wire lower_empty;
+ genvar i;
+ for (i = 0; i < NumIn; i = i + 1) begin : gen_mask
+ assign upper_mask[i] = (i > rr_q ? req_d[i] : 1'b0);
+ assign lower_mask[i] = (i <= rr_q ? req_d[i] : 1'b0);
+ end
+ lzc #(
+ .WIDTH(NumIn),
+ .MODE(1'b0)
+ ) i_lzc_upper(
+ .in_i(upper_mask),
+ .cnt_o(upper_idx),
+ .empty_o(upper_empty)
+ );
+ lzc #(
+ .WIDTH(NumIn),
+ .MODE(1'b0)
+ ) i_lzc_lower(
+ .in_i(lower_mask),
+ .cnt_o(lower_idx),
+ .empty_o()
+ );
+ assign next_idx = (upper_empty ? lower_idx : upper_idx);
+ assign rr_d = (gnt_i && req_o ? next_idx : rr_q);
+ end
+ else begin : gen_unfair_arb
+ function automatic [IdxWidth - 1:0] sv2v_cast_15989;
+ input reg [IdxWidth - 1:0] inp;
+ sv2v_cast_15989 = inp;
+ endfunction
+ assign rr_d = (gnt_i && req_o ? (rr_q == sv2v_cast_15989(NumIn - 1) ? {IdxWidth {1'sb0}} : rr_q + 1'b1) : rr_q);
+ end
+ always @(posedge clk_i or negedge rst_ni) begin : p_rr_regs
+ if (!rst_ni)
+ rr_q <= {IdxWidth {1'sb0}};
+ else if (flush_i)
+ rr_q <= {IdxWidth {1'sb0}};
+ else
+ rr_q <= rr_d;
+ end
+ end
+ assign gnt_nodes[0] = gnt_i;
+ genvar level;
+ for (level = 0; $unsigned(level) < NumLevels; level = level + 1) begin : gen_levels
+ genvar l;
+ for (l = 0; l < (2 ** level); l = l + 1) begin : gen_level
+ wire sel;
+ localparam [31:0] Idx0 = ((2 ** level) - 1) + l;
+ localparam [31:0] Idx1 = ((2 ** (level + 1)) - 1) + (l * 2);
+ if ($unsigned(level) == (NumLevels - 1)) begin : gen_first_level
+ if (($unsigned(l) * 2) < (NumIn - 1)) begin : gen_reduce
+ assign req_nodes[Idx0] = req_d[l * 2] | req_d[(l * 2) + 1];
+ assign sel = ~req_d[l * 2] | (req_d[(l * 2) + 1] & rr_q[(NumLevels - 1) - level]);
+ function automatic [IdxWidth - 1:0] sv2v_cast_15989;
+ input reg [IdxWidth - 1:0] inp;
+ sv2v_cast_15989 = inp;
+ endfunction
+ assign index_nodes[(((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * IdxWidth+:IdxWidth] = sv2v_cast_15989(sel);
+ assign data_nodes[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))] = (sel ? data_i[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + (((l * 2) + 1) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))] : data_i[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((l * 2) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))]);
+ assign gnt_o[l * 2] = (gnt_nodes[Idx0] & (AxiVldRdy | req_d[l * 2])) & ~sel;
+ assign gnt_o[(l * 2) + 1] = (gnt_nodes[Idx0] & (AxiVldRdy | req_d[(l * 2) + 1])) & sel;
+ end
+ if (($unsigned(l) * 2) == (NumIn - 1)) begin : gen_first
+ assign req_nodes[Idx0] = req_d[l * 2];
+ assign index_nodes[(((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * IdxWidth+:IdxWidth] = {IdxWidth {1'sb0}};
+ assign data_nodes[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))] = data_i[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((l * 2) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))];
+ assign gnt_o[l * 2] = gnt_nodes[Idx0] & (AxiVldRdy | req_d[l * 2]);
+ end
+ if (($unsigned(l) * 2) > (NumIn - 1)) begin : gen_out_of_range
+ assign req_nodes[Idx0] = 1'b0;
+ function automatic [IdxWidth - 1:0] sv2v_cast_15989;
+ input reg [IdxWidth - 1:0] inp;
+ sv2v_cast_15989 = inp;
+ endfunction
+ assign index_nodes[(((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * IdxWidth+:IdxWidth] = sv2v_cast_15989(1'sb0);
+ function automatic [((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)) - 1:0] sv2v_cast_FF7FF;
+ input reg [((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)) - 1:0] inp;
+ sv2v_cast_FF7FF = inp;
+ endfunction
+ assign data_nodes[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))] = sv2v_cast_FF7FF(1'sb0);
+ end
+ end
+ else begin : gen_other_levels
+ assign req_nodes[Idx0] = req_nodes[Idx1] | req_nodes[Idx1 + 1];
+ assign sel = ~req_nodes[Idx1] | (req_nodes[Idx1 + 1] & rr_q[(NumLevels - 1) - level]);
+ function automatic [IdxWidth - 1:0] sv2v_cast_15989;
+ input reg [IdxWidth - 1:0] inp;
+ sv2v_cast_15989 = inp;
+ endfunction
+ assign index_nodes[(((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * IdxWidth+:IdxWidth] = (sel ? sv2v_cast_15989({1'b1, index_nodes[((((2 ** NumLevels) - 2) >= 0 ? Idx1 + 1 : ((2 ** NumLevels) - 2) - (Idx1 + 1)) * IdxWidth) + (((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 2 : (((NumLevels - $unsigned(level)) - 2) + (((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 1 : 3 - (NumLevels - $unsigned(level)))) - 1)-:(((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 1 : 3 - (NumLevels - $unsigned(level)))]}) : sv2v_cast_15989({1'b0, index_nodes[((((2 ** NumLevels) - 2) >= 0 ? Idx1 : ((2 ** NumLevels) - 2) - Idx1) * IdxWidth) + (((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 2 : (((NumLevels - $unsigned(level)) - 2) + (((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 1 : 3 - (NumLevels - $unsigned(level)))) - 1)-:(((NumLevels - $unsigned(level)) - 2) >= 0 ? (NumLevels - $unsigned(level)) - 1 : 3 - (NumLevels - $unsigned(level)))]}));
+ assign data_nodes[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((((2 ** NumLevels) - 2) >= 0 ? Idx0 : ((2 ** NumLevels) - 2) - Idx0) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))] = (sel ? data_nodes[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((((2 ** NumLevels) - 2) >= 0 ? Idx1 + 1 : ((2 ** NumLevels) - 2) - (Idx1 + 1)) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))] : data_nodes[((DataType_WIDTH + 5) >= 0 ? 0 : DataType_WIDTH + 5) + ((((2 ** NumLevels) - 2) >= 0 ? Idx1 : ((2 ** NumLevels) - 2) - Idx1) * ((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5)))+:((DataType_WIDTH + 5) >= 0 ? DataType_WIDTH + 6 : 1 - (DataType_WIDTH + 5))]);
+ assign gnt_nodes[Idx1] = gnt_nodes[Idx0] & ~sel;
+ assign gnt_nodes[Idx1 + 1] = gnt_nodes[Idx0] & sel;
+ end
+ end
+ end
+ end
+ endgenerate
+endmodule
+module rstmgr (
+ clk_i,
+ rst_ni,
+ prog_rst_ni,
+ ndmreset,
+ sys_rst_ni
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire prog_rst_ni;
+ input wire ndmreset;
+ output reg sys_rst_ni;
+ always @(*)
+ if (!rst_ni)
+ sys_rst_ni = 1'b0;
+ else if (!prog_rst_ni)
+ sys_rst_ni = 1'b0;
+ else if (ndmreset)
+ sys_rst_ni = 1'b0;
+ else
+ sys_rst_ni = prog_rst_ni;
+endmodule
+module rv_dm (
+ clk_i,
+ rst_ni,
+ testmode_i,
+ ndmreset_o,
+ dmactive_o,
+ debug_req_o,
+ unavailable_i,
+ tl_d_i,
+ tl_d_o,
+ tl_h_o,
+ tl_h_i,
+ jtag_req_i,
+ jtag_rsp_o
+);
+ parameter signed [31:0] NrHarts = 1;
+ parameter [31:0] IdcodeValue = 32'h00000001;
+ parameter [0:0] DirectDmiTap = 1'b1;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire testmode_i;
+ output wire ndmreset_o;
+ output wire dmactive_o;
+ output wire [NrHarts - 1:0] debug_req_o;
+ input wire [NrHarts - 1:0] unavailable_i;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_d_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_d_o;
+ output wire [85:0] tl_h_o;
+ input wire [51:0] tl_h_i;
+ input wire [3:0] jtag_req_i;
+ output wire [1:0] jtag_rsp_o;
+ localparam signed [31:0] BusWidth = 32;
+ localparam [NrHarts - 1:0] SelectableHarts = {NrHarts {1'b1}};
+ wire [(NrHarts * 32) - 1:0] hartinfo;
+ wire [NrHarts - 1:0] halted;
+ wire [NrHarts - 1:0] resumeack;
+ wire [NrHarts - 1:0] haltreq;
+ wire [NrHarts - 1:0] resumereq;
+ wire clear_resumeack;
+ wire cmd_valid;
+ wire [31:0] cmd;
+ wire cmderror_valid;
+ wire [2:0] cmderror;
+ wire cmdbusy;
+ localparam [4:0] dm_ProgBufSize = 5'h08;
+ wire [(dm_ProgBufSize * 32) - 1:0] progbuf;
+ localparam [3:0] dm_DataCount = 4'h2;
+ wire [(dm_DataCount * 32) - 1:0] data_csrs_mem;
+ wire [(dm_DataCount * 32) - 1:0] data_mem_csrs;
+ wire data_valid;
+ wire [19:0] hartsel;
+ wire [31:0] sbaddress_csrs_sba;
+ wire [31:0] sbaddress_sba_csrs;
+ wire sbaddress_write_valid;
+ wire sbreadonaddr;
+ wire sbautoincrement;
+ wire [2:0] sbaccess;
+ wire sbreadondata;
+ wire [31:0] sbdata_write;
+ wire sbdata_read_valid;
+ wire sbdata_write_valid;
+ wire [31:0] sbdata_read;
+ wire sbdata_valid;
+ wire sbbusy;
+ wire sberror_valid;
+ wire [2:0] sberror;
+ wire [40:0] dmi_req;
+ wire [33:0] dmi_rsp;
+ wire dmi_req_valid;
+ wire dmi_req_ready;
+ wire dmi_rsp_valid;
+ wire dmi_rsp_ready;
+ wire dmi_rst_n;
+ localparam [11:0] dm_DataAddr = 12'h380;
+ localparam [31:0] DebugHartInfo = {16'b0000000000100001, dm_DataCount, dm_DataAddr};
+ generate
+ genvar i;
+ for (i = 0; i < NrHarts; i = i + 1) begin : gen_dm_hart_ctrl
+ assign hartinfo[i * 32+:32] = DebugHartInfo;
+ end
+ endgenerate
+ dm_csrs #(
+ .NrHarts(NrHarts),
+ .BusWidth(BusWidth),
+ .SelectableHarts(SelectableHarts)
+ ) i_dm_csrs(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .testmode_i(testmode_i),
+ .dmi_rst_ni(dmi_rst_n),
+ .dmi_req_valid_i(dmi_req_valid),
+ .dmi_req_ready_o(dmi_req_ready),
+ .dmi_req_i(dmi_req),
+ .dmi_resp_valid_o(dmi_rsp_valid),
+ .dmi_resp_ready_i(dmi_rsp_ready),
+ .dmi_resp_o(dmi_rsp),
+ .ndmreset_o(ndmreset_o),
+ .dmactive_o(dmactive_o),
+ .hartsel_o(hartsel),
+ .hartinfo_i(hartinfo),
+ .halted_i(halted),
+ .unavailable_i(unavailable_i),
+ .resumeack_i(resumeack),
+ .haltreq_o(haltreq),
+ .resumereq_o(resumereq),
+ .clear_resumeack_o(clear_resumeack),
+ .cmd_valid_o(cmd_valid),
+ .cmd_o(cmd),
+ .cmderror_valid_i(cmderror_valid),
+ .cmderror_i(cmderror),
+ .cmdbusy_i(cmdbusy),
+ .progbuf_o(progbuf),
+ .data_i(data_mem_csrs),
+ .data_valid_i(data_valid),
+ .data_o(data_csrs_mem),
+ .sbaddress_o(sbaddress_csrs_sba),
+ .sbaddress_i(sbaddress_sba_csrs),
+ .sbaddress_write_valid_o(sbaddress_write_valid),
+ .sbreadonaddr_o(sbreadonaddr),
+ .sbautoincrement_o(sbautoincrement),
+ .sbaccess_o(sbaccess),
+ .sbreadondata_o(sbreadondata),
+ .sbdata_o(sbdata_write),
+ .sbdata_read_valid_o(sbdata_read_valid),
+ .sbdata_write_valid_o(sbdata_write_valid),
+ .sbdata_i(sbdata_read),
+ .sbdata_valid_i(sbdata_valid),
+ .sbbusy_i(sbbusy),
+ .sberror_valid_i(sberror_valid),
+ .sberror_i(sberror)
+ );
+ wire host_req;
+ wire [31:0] host_add;
+ wire host_we;
+ wire [31:0] host_wdata;
+ wire [3:0] host_be;
+ wire host_gnt;
+ wire host_r_valid;
+ wire [31:0] host_r_rdata;
+ wire host_r_err;
+ dm_sba #(.BusWidth(BusWidth)) i_dm_sba(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .master_req_o(host_req),
+ .master_add_o(host_add),
+ .master_we_o(host_we),
+ .master_wdata_o(host_wdata),
+ .master_be_o(host_be),
+ .master_gnt_i(host_gnt),
+ .master_r_valid_i(host_r_valid),
+ .master_r_rdata_i(host_r_rdata),
+ .dmactive_i(dmactive_o),
+ .sbaddress_i(sbaddress_csrs_sba),
+ .sbaddress_o(sbaddress_sba_csrs),
+ .sbaddress_write_valid_i(sbaddress_write_valid),
+ .sbreadonaddr_i(sbreadonaddr),
+ .sbautoincrement_i(sbautoincrement),
+ .sbaccess_i(sbaccess),
+ .sbreadondata_i(sbreadondata),
+ .sbdata_i(sbdata_write),
+ .sbdata_read_valid_i(sbdata_read_valid),
+ .sbdata_write_valid_i(sbdata_write_valid),
+ .sbdata_o(sbdata_read),
+ .sbdata_valid_o(sbdata_valid),
+ .sbbusy_o(sbbusy),
+ .sberror_valid_o(sberror_valid),
+ .sberror_o(sberror)
+ );
+ tlul_host_adapter #(.MAX_REQS(1)) tl_adapter_host_sba(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .req_i(host_req),
+ .gnt_o(host_gnt),
+ .addr_i(host_add),
+ .we_i(host_we),
+ .wdata_i(host_wdata),
+ .be_i(host_be),
+ .valid_o(host_r_valid),
+ .rdata_o(host_r_rdata),
+ .err_o(host_r_err),
+ .tl_h_c_a(tl_h_o),
+ .tl_h_c_d(tl_h_i)
+ );
+ localparam [31:0] AddressWidthWords = 30;
+ wire req;
+ wire we;
+ wire [3:0] be;
+ wire [31:0] wdata;
+ wire [31:0] rdata;
+ reg rvalid;
+ wire [31:0] addr_b;
+ wire [29:0] addr_w;
+ assign be = {4 {1'b1}};
+ assign addr_b = {addr_w, {2 {1'b0}}};
+ dm_mem #(
+ .NrHarts(NrHarts),
+ .BusWidth(BusWidth),
+ .SelectableHarts(SelectableHarts),
+ .DmBaseAddress(1)
+ ) i_dm_mem(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .debug_req_o(debug_req_o),
+ .hartsel_i(hartsel),
+ .haltreq_i(haltreq),
+ .resumereq_i(resumereq),
+ .clear_resumeack_i(clear_resumeack),
+ .halted_o(halted),
+ .resuming_o(resumeack),
+ .cmd_valid_i(cmd_valid),
+ .cmd_i(cmd),
+ .cmderror_valid_o(cmderror_valid),
+ .cmderror_o(cmderror),
+ .cmdbusy_o(cmdbusy),
+ .progbuf_i(progbuf),
+ .data_i(data_csrs_mem),
+ .data_o(data_mem_csrs),
+ .data_valid_o(data_valid),
+ .req_i(req),
+ .we_i(we),
+ .addr_i(addr_b),
+ .wdata_i(wdata),
+ .be_i(be),
+ .rdata_o(rdata)
+ );
+ dmi_jtag #(.IdcodeValue(IdcodeValue)) dap(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .testmode_i(testmode_i),
+ .dmi_rst_no(dmi_rst_n),
+ .dmi_req_o(dmi_req),
+ .dmi_req_valid_o(dmi_req_valid),
+ .dmi_req_ready_i(dmi_req_ready),
+ .dmi_resp_i(dmi_rsp),
+ .dmi_resp_ready_o(dmi_rsp_ready),
+ .dmi_resp_valid_i(dmi_rsp_valid),
+ .tck_i(jtag_req_i[3]),
+ .tms_i(jtag_req_i[2]),
+ .trst_ni(jtag_req_i[1]),
+ .td_i(jtag_req_i[0]),
+ .td_o(jtag_rsp_o[1]),
+ .tdo_oe_o(jtag_rsp_o[0])
+ );
+ tlul_sram_adapter #(
+ .SramAw(AddressWidthWords),
+ .SramDw(BusWidth),
+ .Outstanding(1),
+ .ByteAccess(0)
+ ) tl_adapter_device_mem(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .req_o(req),
+ .gnt_i(1'b1),
+ .we_o(we),
+ .addr_o(addr_w),
+ .wdata_o(wdata),
+ .wmask_o(),
+ .rdata_i(rdata),
+ .rvalid_i(rvalid),
+ .rerror_i(2'b00),
+ .tl_o(tl_d_o),
+ .tl_i(tl_d_i)
+ );
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ rvalid <= 1'b0;
+ else
+ rvalid <= req & ~we;
+endmodule
+module rv_plic_gateway (
+ clk_i,
+ rst_ni,
+ src_i,
+ le_i,
+ claim_i,
+ complete_i,
+ ip_o
+);
+ parameter signed [31:0] N_SOURCE = 32;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [N_SOURCE - 1:0] src_i;
+ input wire [N_SOURCE - 1:0] le_i;
+ input wire [N_SOURCE - 1:0] claim_i;
+ input wire [N_SOURCE - 1:0] complete_i;
+ output reg [N_SOURCE - 1:0] ip_o;
+ reg [N_SOURCE - 1:0] ia;
+ reg [N_SOURCE - 1:0] set;
+ reg [N_SOURCE - 1:0] src_q;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ src_q <= {N_SOURCE {1'sb0}};
+ else
+ src_q <= src_i;
+ always @(*) begin : sv2v_autoblock_134
+ reg signed [31:0] i;
+ for (i = 0; i < N_SOURCE; i = i + 1)
+ set[i] = (le_i[i] ? src_i[i] & ~src_q[i] : src_i[i]);
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ ip_o <= {N_SOURCE {1'sb0}};
+ else
+ ip_o <= (ip_o | ((set & ~ia) & ~ip_o)) & ~(ip_o & claim_i);
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ ia <= {N_SOURCE {1'sb0}};
+ else
+ ia <= (ia | (set & ~ia)) & ~((ia & complete_i) & ~ip_o);
+endmodule
+module rv_plic_reg_top (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ reg2hw,
+ hw2reg,
+ devmode_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire [154:0] reg2hw;
+ input wire [77:0] hw2reg;
+ input devmode_i;
+ localparam signed [31:0] AW = 10;
+ localparam signed [31:0] DW = 32;
+ localparam signed [31:0] DBW = 4;
+ wire reg_we;
+ wire reg_re;
+ wire [9:0] reg_addr;
+ wire [31:0] reg_wdata;
+ wire [3:0] reg_be;
+ wire [31:0] reg_rdata;
+ wire reg_error;
+ wire addrmiss;
+ reg wr_err;
+ reg [31:0] reg_rdata_next;
+ wire [85:0] tl_reg_h2d;
+ wire [51:0] tl_reg_d2h;
+ assign tl_reg_h2d = tl_i;
+ assign tl_o = tl_reg_d2h;
+ tlul_adapter_reg #(
+ .RegAw(AW),
+ .RegDw(DW)
+ ) u_reg_if(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_reg_h2d),
+ .tl_o(tl_reg_d2h),
+ .we_o(reg_we),
+ .re_o(reg_re),
+ .addr_o(reg_addr),
+ .wdata_o(reg_wdata),
+ .be_o(reg_be),
+ .rdata_i(reg_rdata),
+ .error_i(reg_error)
+ );
+ assign reg_rdata = reg_rdata_next;
+ assign reg_error = (devmode_i & addrmiss) | wr_err;
+ wire ip_0_p_0_qs;
+ wire ip_0_p_1_qs;
+ wire ip_0_p_2_qs;
+ wire ip_0_p_3_qs;
+ wire ip_0_p_4_qs;
+ wire ip_0_p_5_qs;
+ wire ip_0_p_6_qs;
+ wire ip_0_p_7_qs;
+ wire ip_0_p_8_qs;
+ wire ip_0_p_9_qs;
+ wire ip_0_p_10_qs;
+ wire ip_0_p_11_qs;
+ wire ip_0_p_12_qs;
+ wire ip_0_p_13_qs;
+ wire ip_0_p_14_qs;
+ wire ip_0_p_15_qs;
+ wire ip_0_p_16_qs;
+ wire ip_0_p_17_qs;
+ wire ip_0_p_18_qs;
+ wire ip_0_p_19_qs;
+ wire ip_0_p_20_qs;
+ wire ip_0_p_21_qs;
+ wire ip_0_p_22_qs;
+ wire ip_0_p_23_qs;
+ wire ip_0_p_24_qs;
+ wire ip_0_p_25_qs;
+ wire ip_0_p_26_qs;
+ wire ip_0_p_27_qs;
+ wire ip_0_p_28_qs;
+ wire ip_0_p_29_qs;
+ wire ip_0_p_30_qs;
+ wire ip_0_p_31_qs;
+ wire ip_1_p_32_qs;
+ wire ip_1_p_33_qs;
+ wire ip_1_p_34_qs;
+ wire ip_1_p_35_qs;
+ wire ip_1_p_36_qs;
+ wire ip_1_p_37_qs;
+ wire ip_1_p_38_qs;
+ wire ip_1_p_39_qs;
+ wire ip_1_p_40_qs;
+ wire ip_1_p_41_qs;
+ wire ip_1_p_42_qs;
+ wire ip_1_p_43_qs;
+ wire le_0_le_0_qs;
+ wire le_0_le_0_wd;
+ wire le_0_le_0_we;
+ wire le_0_le_1_qs;
+ wire le_0_le_1_wd;
+ wire le_0_le_1_we;
+ wire le_0_le_2_qs;
+ wire le_0_le_2_wd;
+ wire le_0_le_2_we;
+ wire le_0_le_3_qs;
+ wire le_0_le_3_wd;
+ wire le_0_le_3_we;
+ wire le_0_le_4_qs;
+ wire le_0_le_4_wd;
+ wire le_0_le_4_we;
+ wire le_0_le_5_qs;
+ wire le_0_le_5_wd;
+ wire le_0_le_5_we;
+ wire le_0_le_6_qs;
+ wire le_0_le_6_wd;
+ wire le_0_le_6_we;
+ wire le_0_le_7_qs;
+ wire le_0_le_7_wd;
+ wire le_0_le_7_we;
+ wire le_0_le_8_qs;
+ wire le_0_le_8_wd;
+ wire le_0_le_8_we;
+ wire le_0_le_9_qs;
+ wire le_0_le_9_wd;
+ wire le_0_le_9_we;
+ wire le_0_le_10_qs;
+ wire le_0_le_10_wd;
+ wire le_0_le_10_we;
+ wire le_0_le_11_qs;
+ wire le_0_le_11_wd;
+ wire le_0_le_11_we;
+ wire le_0_le_12_qs;
+ wire le_0_le_12_wd;
+ wire le_0_le_12_we;
+ wire le_0_le_13_qs;
+ wire le_0_le_13_wd;
+ wire le_0_le_13_we;
+ wire le_0_le_14_qs;
+ wire le_0_le_14_wd;
+ wire le_0_le_14_we;
+ wire le_0_le_15_qs;
+ wire le_0_le_15_wd;
+ wire le_0_le_15_we;
+ wire le_0_le_16_qs;
+ wire le_0_le_16_wd;
+ wire le_0_le_16_we;
+ wire le_0_le_17_qs;
+ wire le_0_le_17_wd;
+ wire le_0_le_17_we;
+ wire le_0_le_18_qs;
+ wire le_0_le_18_wd;
+ wire le_0_le_18_we;
+ wire le_0_le_19_qs;
+ wire le_0_le_19_wd;
+ wire le_0_le_19_we;
+ wire le_0_le_20_qs;
+ wire le_0_le_20_wd;
+ wire le_0_le_20_we;
+ wire le_0_le_21_qs;
+ wire le_0_le_21_wd;
+ wire le_0_le_21_we;
+ wire le_0_le_22_qs;
+ wire le_0_le_22_wd;
+ wire le_0_le_22_we;
+ wire le_0_le_23_qs;
+ wire le_0_le_23_wd;
+ wire le_0_le_23_we;
+ wire le_0_le_24_qs;
+ wire le_0_le_24_wd;
+ wire le_0_le_24_we;
+ wire le_0_le_25_qs;
+ wire le_0_le_25_wd;
+ wire le_0_le_25_we;
+ wire le_0_le_26_qs;
+ wire le_0_le_26_wd;
+ wire le_0_le_26_we;
+ wire le_0_le_27_qs;
+ wire le_0_le_27_wd;
+ wire le_0_le_27_we;
+ wire le_0_le_28_qs;
+ wire le_0_le_28_wd;
+ wire le_0_le_28_we;
+ wire le_0_le_29_qs;
+ wire le_0_le_29_wd;
+ wire le_0_le_29_we;
+ wire le_0_le_30_qs;
+ wire le_0_le_30_wd;
+ wire le_0_le_30_we;
+ wire le_0_le_31_qs;
+ wire le_0_le_31_wd;
+ wire le_0_le_31_we;
+ wire le_1_le_32_qs;
+ wire le_1_le_32_wd;
+ wire le_1_le_32_we;
+ wire le_1_le_33_qs;
+ wire le_1_le_33_wd;
+ wire le_1_le_33_we;
+ wire le_1_le_34_qs;
+ wire le_1_le_34_wd;
+ wire le_1_le_34_we;
+ wire le_1_le_35_qs;
+ wire le_1_le_35_wd;
+ wire le_1_le_35_we;
+ wire [1:0] prio0_qs;
+ wire [1:0] prio0_wd;
+ wire prio0_we;
+ wire [1:0] prio1_qs;
+ wire [1:0] prio1_wd;
+ wire prio1_we;
+ wire [1:0] prio2_qs;
+ wire [1:0] prio2_wd;
+ wire prio2_we;
+ wire [1:0] prio3_qs;
+ wire [1:0] prio3_wd;
+ wire prio3_we;
+ wire [1:0] prio4_qs;
+ wire [1:0] prio4_wd;
+ wire prio4_we;
+ wire [1:0] prio5_qs;
+ wire [1:0] prio5_wd;
+ wire prio5_we;
+ wire [1:0] prio6_qs;
+ wire [1:0] prio6_wd;
+ wire prio6_we;
+ wire [1:0] prio7_qs;
+ wire [1:0] prio7_wd;
+ wire prio7_we;
+ wire [1:0] prio8_qs;
+ wire [1:0] prio8_wd;
+ wire prio8_we;
+ wire [1:0] prio9_qs;
+ wire [1:0] prio9_wd;
+ wire prio9_we;
+ wire [1:0] prio10_qs;
+ wire [1:0] prio10_wd;
+ wire prio10_we;
+ wire [1:0] prio11_qs;
+ wire [1:0] prio11_wd;
+ wire prio11_we;
+ wire [1:0] prio12_qs;
+ wire [1:0] prio12_wd;
+ wire prio12_we;
+ wire [1:0] prio13_qs;
+ wire [1:0] prio13_wd;
+ wire prio13_we;
+ wire [1:0] prio14_qs;
+ wire [1:0] prio14_wd;
+ wire prio14_we;
+ wire [1:0] prio15_qs;
+ wire [1:0] prio15_wd;
+ wire prio15_we;
+ wire [1:0] prio16_qs;
+ wire [1:0] prio16_wd;
+ wire prio16_we;
+ wire [1:0] prio17_qs;
+ wire [1:0] prio17_wd;
+ wire prio17_we;
+ wire [1:0] prio18_qs;
+ wire [1:0] prio18_wd;
+ wire prio18_we;
+ wire [1:0] prio19_qs;
+ wire [1:0] prio19_wd;
+ wire prio19_we;
+ wire [1:0] prio20_qs;
+ wire [1:0] prio20_wd;
+ wire prio20_we;
+ wire [1:0] prio21_qs;
+ wire [1:0] prio21_wd;
+ wire prio21_we;
+ wire [1:0] prio22_qs;
+ wire [1:0] prio22_wd;
+ wire prio22_we;
+ wire [1:0] prio23_qs;
+ wire [1:0] prio23_wd;
+ wire prio23_we;
+ wire [1:0] prio24_qs;
+ wire [1:0] prio24_wd;
+ wire prio24_we;
+ wire [1:0] prio25_qs;
+ wire [1:0] prio25_wd;
+ wire prio25_we;
+ wire [1:0] prio26_qs;
+ wire [1:0] prio26_wd;
+ wire prio26_we;
+ wire [1:0] prio27_qs;
+ wire [1:0] prio27_wd;
+ wire prio27_we;
+ wire [1:0] prio28_qs;
+ wire [1:0] prio28_wd;
+ wire prio28_we;
+ wire [1:0] prio29_qs;
+ wire [1:0] prio29_wd;
+ wire prio29_we;
+ wire [1:0] prio30_qs;
+ wire [1:0] prio30_wd;
+ wire prio30_we;
+ wire [1:0] prio31_qs;
+ wire [1:0] prio31_wd;
+ wire prio31_we;
+ wire [1:0] prio32_qs;
+ wire [1:0] prio32_wd;
+ wire prio32_we;
+ wire [1:0] prio33_qs;
+ wire [1:0] prio33_wd;
+ wire prio33_we;
+ wire [1:0] prio34_qs;
+ wire [1:0] prio34_wd;
+ wire prio34_we;
+ wire [1:0] prio35_qs;
+ wire [1:0] prio35_wd;
+ wire prio35_we;
+ wire ie0_0_e_0_qs;
+ wire ie0_0_e_0_wd;
+ wire ie0_0_e_0_we;
+ wire ie0_0_e_1_qs;
+ wire ie0_0_e_1_wd;
+ wire ie0_0_e_1_we;
+ wire ie0_0_e_2_qs;
+ wire ie0_0_e_2_wd;
+ wire ie0_0_e_2_we;
+ wire ie0_0_e_3_qs;
+ wire ie0_0_e_3_wd;
+ wire ie0_0_e_3_we;
+ wire ie0_0_e_4_qs;
+ wire ie0_0_e_4_wd;
+ wire ie0_0_e_4_we;
+ wire ie0_0_e_5_qs;
+ wire ie0_0_e_5_wd;
+ wire ie0_0_e_5_we;
+ wire ie0_0_e_6_qs;
+ wire ie0_0_e_6_wd;
+ wire ie0_0_e_6_we;
+ wire ie0_0_e_7_qs;
+ wire ie0_0_e_7_wd;
+ wire ie0_0_e_7_we;
+ wire ie0_0_e_8_qs;
+ wire ie0_0_e_8_wd;
+ wire ie0_0_e_8_we;
+ wire ie0_0_e_9_qs;
+ wire ie0_0_e_9_wd;
+ wire ie0_0_e_9_we;
+ wire ie0_0_e_10_qs;
+ wire ie0_0_e_10_wd;
+ wire ie0_0_e_10_we;
+ wire ie0_0_e_11_qs;
+ wire ie0_0_e_11_wd;
+ wire ie0_0_e_11_we;
+ wire ie0_0_e_12_qs;
+ wire ie0_0_e_12_wd;
+ wire ie0_0_e_12_we;
+ wire ie0_0_e_13_qs;
+ wire ie0_0_e_13_wd;
+ wire ie0_0_e_13_we;
+ wire ie0_0_e_14_qs;
+ wire ie0_0_e_14_wd;
+ wire ie0_0_e_14_we;
+ wire ie0_0_e_15_qs;
+ wire ie0_0_e_15_wd;
+ wire ie0_0_e_15_we;
+ wire ie0_0_e_16_qs;
+ wire ie0_0_e_16_wd;
+ wire ie0_0_e_16_we;
+ wire ie0_0_e_17_qs;
+ wire ie0_0_e_17_wd;
+ wire ie0_0_e_17_we;
+ wire ie0_0_e_18_qs;
+ wire ie0_0_e_18_wd;
+ wire ie0_0_e_18_we;
+ wire ie0_0_e_19_qs;
+ wire ie0_0_e_19_wd;
+ wire ie0_0_e_19_we;
+ wire ie0_0_e_20_qs;
+ wire ie0_0_e_20_wd;
+ wire ie0_0_e_20_we;
+ wire ie0_0_e_21_qs;
+ wire ie0_0_e_21_wd;
+ wire ie0_0_e_21_we;
+ wire ie0_0_e_22_qs;
+ wire ie0_0_e_22_wd;
+ wire ie0_0_e_22_we;
+ wire ie0_0_e_23_qs;
+ wire ie0_0_e_23_wd;
+ wire ie0_0_e_23_we;
+ wire ie0_0_e_24_qs;
+ wire ie0_0_e_24_wd;
+ wire ie0_0_e_24_we;
+ wire ie0_0_e_25_qs;
+ wire ie0_0_e_25_wd;
+ wire ie0_0_e_25_we;
+ wire ie0_0_e_26_qs;
+ wire ie0_0_e_26_wd;
+ wire ie0_0_e_26_we;
+ wire ie0_0_e_27_qs;
+ wire ie0_0_e_27_wd;
+ wire ie0_0_e_27_we;
+ wire ie0_0_e_28_qs;
+ wire ie0_0_e_28_wd;
+ wire ie0_0_e_28_we;
+ wire ie0_0_e_29_qs;
+ wire ie0_0_e_29_wd;
+ wire ie0_0_e_29_we;
+ wire ie0_0_e_30_qs;
+ wire ie0_0_e_30_wd;
+ wire ie0_0_e_30_we;
+ wire ie0_0_e_31_qs;
+ wire ie0_0_e_31_wd;
+ wire ie0_0_e_31_we;
+ wire ie0_1_e_32_qs;
+ wire ie0_1_e_32_wd;
+ wire ie0_1_e_32_we;
+ wire ie0_1_e_33_qs;
+ wire ie0_1_e_33_wd;
+ wire ie0_1_e_33_we;
+ wire ie0_1_e_34_qs;
+ wire ie0_1_e_34_wd;
+ wire ie0_1_e_34_we;
+ wire ie0_1_e_35_qs;
+ wire ie0_1_e_35_wd;
+ wire ie0_1_e_35_we;
+ wire [1:0] threshold0_qs;
+ wire [1:0] threshold0_wd;
+ wire threshold0_we;
+ wire [5:0] cc0_qs;
+ wire [5:0] cc0_wd;
+ wire cc0_we;
+ wire cc0_re;
+ wire msip0_qs;
+ wire msip0_wd;
+ wire msip0_we;
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[6]),
+ .d(hw2reg[7]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_0_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_1(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[8]),
+ .d(hw2reg[9]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_1_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_2(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[10]),
+ .d(hw2reg[11]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_2_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_3(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[12]),
+ .d(hw2reg[13]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_3_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_4(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[14]),
+ .d(hw2reg[15]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_4_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_5(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[16]),
+ .d(hw2reg[17]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_5_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_6(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[18]),
+ .d(hw2reg[19]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_6_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_7(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[20]),
+ .d(hw2reg[21]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_7_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_8(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[22]),
+ .d(hw2reg[23]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_8_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_9(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[24]),
+ .d(hw2reg[25]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_9_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_10(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[26]),
+ .d(hw2reg[27]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_10_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_11(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[28]),
+ .d(hw2reg[29]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_11_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_12(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[30]),
+ .d(hw2reg[31]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_12_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_13(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[32]),
+ .d(hw2reg[33]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_13_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_14(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[34]),
+ .d(hw2reg[35]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_14_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_15(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[36]),
+ .d(hw2reg[37]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_15_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_16(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[38]),
+ .d(hw2reg[39]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_16_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_17(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[40]),
+ .d(hw2reg[41]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_17_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_18(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[42]),
+ .d(hw2reg[43]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_18_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_19(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[44]),
+ .d(hw2reg[45]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_19_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_20(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[46]),
+ .d(hw2reg[47]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_20_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_21(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[48]),
+ .d(hw2reg[49]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_21_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_22(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[50]),
+ .d(hw2reg[51]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_22_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_23(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[52]),
+ .d(hw2reg[53]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_23_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_24(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[54]),
+ .d(hw2reg[55]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_24_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_25(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[56]),
+ .d(hw2reg[57]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_25_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_26(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[58]),
+ .d(hw2reg[59]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_26_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_27(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[60]),
+ .d(hw2reg[61]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_27_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_28(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[62]),
+ .d(hw2reg[63]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_28_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_29(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[64]),
+ .d(hw2reg[65]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_29_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_30(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[66]),
+ .d(hw2reg[67]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_30_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_0_p_31(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[68]),
+ .d(hw2reg[69]),
+ .qe(),
+ .q(),
+ .qs(ip_0_p_31_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_1_p_32(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[70]),
+ .d(hw2reg[71]),
+ .qe(),
+ .q(),
+ .qs(ip_1_p_32_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_1_p_33(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[72]),
+ .d(hw2reg[73]),
+ .qe(),
+ .q(),
+ .qs(ip_1_p_33_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_1_p_34(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[74]),
+ .d(hw2reg[75]),
+ .qe(),
+ .q(),
+ .qs(ip_1_p_34_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RO"),
+ .RESVAL(1'h0)
+ ) u_ip_1_p_35(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(1'b0),
+ .wd(1'b0),
+ .de(hw2reg[76]),
+ .d(hw2reg[77]),
+ .qe(),
+ .q(),
+ .qs(ip_1_p_35_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_0_we),
+ .wd(le_0_le_0_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[119]),
+ .qs(le_0_le_0_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_1(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_1_we),
+ .wd(le_0_le_1_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[120]),
+ .qs(le_0_le_1_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_2(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_2_we),
+ .wd(le_0_le_2_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[121]),
+ .qs(le_0_le_2_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_3(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_3_we),
+ .wd(le_0_le_3_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[122]),
+ .qs(le_0_le_3_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_4(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_4_we),
+ .wd(le_0_le_4_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[123]),
+ .qs(le_0_le_4_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_5(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_5_we),
+ .wd(le_0_le_5_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[124]),
+ .qs(le_0_le_5_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_6(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_6_we),
+ .wd(le_0_le_6_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[125]),
+ .qs(le_0_le_6_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_7(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_7_we),
+ .wd(le_0_le_7_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[126]),
+ .qs(le_0_le_7_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_8(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_8_we),
+ .wd(le_0_le_8_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[127]),
+ .qs(le_0_le_8_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_9(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_9_we),
+ .wd(le_0_le_9_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[128]),
+ .qs(le_0_le_9_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_10(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_10_we),
+ .wd(le_0_le_10_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[129]),
+ .qs(le_0_le_10_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_11(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_11_we),
+ .wd(le_0_le_11_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[130]),
+ .qs(le_0_le_11_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_12(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_12_we),
+ .wd(le_0_le_12_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[131]),
+ .qs(le_0_le_12_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_13(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_13_we),
+ .wd(le_0_le_13_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[132]),
+ .qs(le_0_le_13_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_14(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_14_we),
+ .wd(le_0_le_14_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[133]),
+ .qs(le_0_le_14_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_15(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_15_we),
+ .wd(le_0_le_15_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[134]),
+ .qs(le_0_le_15_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_16(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_16_we),
+ .wd(le_0_le_16_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[135]),
+ .qs(le_0_le_16_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_17(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_17_we),
+ .wd(le_0_le_17_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[136]),
+ .qs(le_0_le_17_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_18(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_18_we),
+ .wd(le_0_le_18_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[137]),
+ .qs(le_0_le_18_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_19(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_19_we),
+ .wd(le_0_le_19_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[138]),
+ .qs(le_0_le_19_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_20(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_20_we),
+ .wd(le_0_le_20_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[139]),
+ .qs(le_0_le_20_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_21(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_21_we),
+ .wd(le_0_le_21_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[140]),
+ .qs(le_0_le_21_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_22(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_22_we),
+ .wd(le_0_le_22_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[141]),
+ .qs(le_0_le_22_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_23(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_23_we),
+ .wd(le_0_le_23_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[142]),
+ .qs(le_0_le_23_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_24(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_24_we),
+ .wd(le_0_le_24_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[143]),
+ .qs(le_0_le_24_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_25(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_25_we),
+ .wd(le_0_le_25_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[144]),
+ .qs(le_0_le_25_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_26(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_26_we),
+ .wd(le_0_le_26_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[145]),
+ .qs(le_0_le_26_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_27(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_27_we),
+ .wd(le_0_le_27_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[146]),
+ .qs(le_0_le_27_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_28(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_28_we),
+ .wd(le_0_le_28_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[147]),
+ .qs(le_0_le_28_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_29(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_29_we),
+ .wd(le_0_le_29_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[148]),
+ .qs(le_0_le_29_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_30(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_30_we),
+ .wd(le_0_le_30_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[149]),
+ .qs(le_0_le_30_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_0_le_31(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_0_le_31_we),
+ .wd(le_0_le_31_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[150]),
+ .qs(le_0_le_31_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_1_le_32(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_1_le_32_we),
+ .wd(le_1_le_32_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[151]),
+ .qs(le_1_le_32_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_1_le_33(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_1_le_33_we),
+ .wd(le_1_le_33_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[152]),
+ .qs(le_1_le_33_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_1_le_34(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_1_le_34_we),
+ .wd(le_1_le_34_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[153]),
+ .qs(le_1_le_34_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_le_1_le_35(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(le_1_le_35_we),
+ .wd(le_1_le_35_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[154]),
+ .qs(le_1_le_35_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio0_we),
+ .wd(prio0_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[118-:2]),
+ .qs(prio0_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio1(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio1_we),
+ .wd(prio1_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[116-:2]),
+ .qs(prio1_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio2(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio2_we),
+ .wd(prio2_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[114-:2]),
+ .qs(prio2_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio3(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio3_we),
+ .wd(prio3_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[112-:2]),
+ .qs(prio3_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio4(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio4_we),
+ .wd(prio4_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[110-:2]),
+ .qs(prio4_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio5(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio5_we),
+ .wd(prio5_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[108-:2]),
+ .qs(prio5_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio6(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio6_we),
+ .wd(prio6_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[106-:2]),
+ .qs(prio6_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio7(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio7_we),
+ .wd(prio7_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[104-:2]),
+ .qs(prio7_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio8(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio8_we),
+ .wd(prio8_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[102-:2]),
+ .qs(prio8_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio9(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio9_we),
+ .wd(prio9_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[100-:2]),
+ .qs(prio9_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio10(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio10_we),
+ .wd(prio10_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[98-:2]),
+ .qs(prio10_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio11(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio11_we),
+ .wd(prio11_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[96-:2]),
+ .qs(prio11_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio12(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio12_we),
+ .wd(prio12_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[94-:2]),
+ .qs(prio12_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio13(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio13_we),
+ .wd(prio13_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[92-:2]),
+ .qs(prio13_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio14(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio14_we),
+ .wd(prio14_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[90-:2]),
+ .qs(prio14_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio15(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio15_we),
+ .wd(prio15_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[88-:2]),
+ .qs(prio15_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio16(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio16_we),
+ .wd(prio16_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[86-:2]),
+ .qs(prio16_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio17(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio17_we),
+ .wd(prio17_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[84-:2]),
+ .qs(prio17_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio18(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio18_we),
+ .wd(prio18_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[82-:2]),
+ .qs(prio18_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio19(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio19_we),
+ .wd(prio19_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[80-:2]),
+ .qs(prio19_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio20(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio20_we),
+ .wd(prio20_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[78-:2]),
+ .qs(prio20_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio21(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio21_we),
+ .wd(prio21_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[76-:2]),
+ .qs(prio21_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio22(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio22_we),
+ .wd(prio22_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[74-:2]),
+ .qs(prio22_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio23(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio23_we),
+ .wd(prio23_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[72-:2]),
+ .qs(prio23_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio24(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio24_we),
+ .wd(prio24_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[70-:2]),
+ .qs(prio24_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio25(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio25_we),
+ .wd(prio25_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[68-:2]),
+ .qs(prio25_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio26(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio26_we),
+ .wd(prio26_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[66-:2]),
+ .qs(prio26_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio27(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio27_we),
+ .wd(prio27_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[64-:2]),
+ .qs(prio27_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio28(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio28_we),
+ .wd(prio28_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[62-:2]),
+ .qs(prio28_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio29(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio29_we),
+ .wd(prio29_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[60-:2]),
+ .qs(prio29_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio30(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio30_we),
+ .wd(prio30_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[58-:2]),
+ .qs(prio30_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio31(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio31_we),
+ .wd(prio31_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[56-:2]),
+ .qs(prio31_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio32(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio32_we),
+ .wd(prio32_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[54-:2]),
+ .qs(prio32_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio33(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio33_we),
+ .wd(prio33_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[52-:2]),
+ .qs(prio33_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio34(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio34_we),
+ .wd(prio34_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[50-:2]),
+ .qs(prio34_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_prio35(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(prio35_we),
+ .wd(prio35_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[48-:2]),
+ .qs(prio35_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_0_we),
+ .wd(ie0_0_e_0_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[11]),
+ .qs(ie0_0_e_0_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_1(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_1_we),
+ .wd(ie0_0_e_1_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[12]),
+ .qs(ie0_0_e_1_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_2(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_2_we),
+ .wd(ie0_0_e_2_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[13]),
+ .qs(ie0_0_e_2_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_3(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_3_we),
+ .wd(ie0_0_e_3_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[14]),
+ .qs(ie0_0_e_3_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_4(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_4_we),
+ .wd(ie0_0_e_4_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[15]),
+ .qs(ie0_0_e_4_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_5(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_5_we),
+ .wd(ie0_0_e_5_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[16]),
+ .qs(ie0_0_e_5_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_6(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_6_we),
+ .wd(ie0_0_e_6_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[17]),
+ .qs(ie0_0_e_6_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_7(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_7_we),
+ .wd(ie0_0_e_7_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[18]),
+ .qs(ie0_0_e_7_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_8(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_8_we),
+ .wd(ie0_0_e_8_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[19]),
+ .qs(ie0_0_e_8_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_9(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_9_we),
+ .wd(ie0_0_e_9_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[20]),
+ .qs(ie0_0_e_9_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_10(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_10_we),
+ .wd(ie0_0_e_10_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[21]),
+ .qs(ie0_0_e_10_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_11(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_11_we),
+ .wd(ie0_0_e_11_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[22]),
+ .qs(ie0_0_e_11_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_12(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_12_we),
+ .wd(ie0_0_e_12_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[23]),
+ .qs(ie0_0_e_12_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_13(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_13_we),
+ .wd(ie0_0_e_13_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[24]),
+ .qs(ie0_0_e_13_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_14(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_14_we),
+ .wd(ie0_0_e_14_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[25]),
+ .qs(ie0_0_e_14_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_15(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_15_we),
+ .wd(ie0_0_e_15_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[26]),
+ .qs(ie0_0_e_15_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_16(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_16_we),
+ .wd(ie0_0_e_16_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[27]),
+ .qs(ie0_0_e_16_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_17(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_17_we),
+ .wd(ie0_0_e_17_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[28]),
+ .qs(ie0_0_e_17_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_18(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_18_we),
+ .wd(ie0_0_e_18_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[29]),
+ .qs(ie0_0_e_18_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_19(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_19_we),
+ .wd(ie0_0_e_19_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[30]),
+ .qs(ie0_0_e_19_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_20(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_20_we),
+ .wd(ie0_0_e_20_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[31]),
+ .qs(ie0_0_e_20_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_21(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_21_we),
+ .wd(ie0_0_e_21_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[32]),
+ .qs(ie0_0_e_21_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_22(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_22_we),
+ .wd(ie0_0_e_22_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[33]),
+ .qs(ie0_0_e_22_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_23(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_23_we),
+ .wd(ie0_0_e_23_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[34]),
+ .qs(ie0_0_e_23_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_24(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_24_we),
+ .wd(ie0_0_e_24_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[35]),
+ .qs(ie0_0_e_24_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_25(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_25_we),
+ .wd(ie0_0_e_25_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[36]),
+ .qs(ie0_0_e_25_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_26(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_26_we),
+ .wd(ie0_0_e_26_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[37]),
+ .qs(ie0_0_e_26_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_27(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_27_we),
+ .wd(ie0_0_e_27_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[38]),
+ .qs(ie0_0_e_27_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_28(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_28_we),
+ .wd(ie0_0_e_28_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[39]),
+ .qs(ie0_0_e_28_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_29(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_29_we),
+ .wd(ie0_0_e_29_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[40]),
+ .qs(ie0_0_e_29_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_30(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_30_we),
+ .wd(ie0_0_e_30_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[41]),
+ .qs(ie0_0_e_30_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_0_e_31(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_0_e_31_we),
+ .wd(ie0_0_e_31_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[42]),
+ .qs(ie0_0_e_31_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_1_e_32(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_1_e_32_we),
+ .wd(ie0_1_e_32_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[43]),
+ .qs(ie0_1_e_32_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_1_e_33(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_1_e_33_we),
+ .wd(ie0_1_e_33_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[44]),
+ .qs(ie0_1_e_33_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_1_e_34(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_1_e_34_we),
+ .wd(ie0_1_e_34_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[45]),
+ .qs(ie0_1_e_34_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ie0_1_e_35(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ie0_1_e_35_we),
+ .wd(ie0_1_e_35_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[46]),
+ .qs(ie0_1_e_35_qs)
+ );
+ prim_subreg #(
+ .DW(2),
+ .SWACCESS("RW"),
+ .RESVAL(2'h0)
+ ) u_threshold0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(threshold0_we),
+ .wd(threshold0_wd),
+ .de(1'b0),
+ .d({2 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[10-:2]),
+ .qs(threshold0_qs)
+ );
+ prim_subreg_ext #(.DW(6)) u_cc0(
+ .re(cc0_re),
+ .we(cc0_we),
+ .wd(cc0_wd),
+ .d(hw2reg[5-:6]),
+ .qre(reg2hw[1]),
+ .qe(reg2hw[2]),
+ .q(reg2hw[8-:6]),
+ .qs(cc0_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_msip0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(msip0_we),
+ .wd(msip0_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[-0]),
+ .qs(msip0_qs)
+ );
+ reg [44:0] addr_hit;
+ localparam signed [31:0] rv_plic_reg_pkg_BlockAw = 10;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_CC0_OFFSET = 10'h0ac;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_IE0_0_OFFSET = 10'h0a0;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_IE0_1_OFFSET = 10'h0a4;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_IP_0_OFFSET = 10'h000;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_IP_1_OFFSET = 10'h004;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_LE_0_OFFSET = 10'h008;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_LE_1_OFFSET = 10'h00c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_MSIP0_OFFSET = 10'h0b0;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO0_OFFSET = 10'h010;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO10_OFFSET = 10'h038;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO11_OFFSET = 10'h03c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO12_OFFSET = 10'h040;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO13_OFFSET = 10'h044;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO14_OFFSET = 10'h048;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO15_OFFSET = 10'h04c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO16_OFFSET = 10'h050;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO17_OFFSET = 10'h054;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO18_OFFSET = 10'h058;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO19_OFFSET = 10'h05c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO1_OFFSET = 10'h014;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO20_OFFSET = 10'h060;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO21_OFFSET = 10'h064;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO22_OFFSET = 10'h068;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO23_OFFSET = 10'h06c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO24_OFFSET = 10'h070;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO25_OFFSET = 10'h074;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO26_OFFSET = 10'h078;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO27_OFFSET = 10'h07c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO28_OFFSET = 10'h080;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO29_OFFSET = 10'h084;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO2_OFFSET = 10'h018;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO30_OFFSET = 10'h088;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO31_OFFSET = 10'h08c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO32_OFFSET = 10'h090;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO33_OFFSET = 10'h094;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO34_OFFSET = 10'h098;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO35_OFFSET = 10'h09c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO3_OFFSET = 10'h01c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO4_OFFSET = 10'h020;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO5_OFFSET = 10'h024;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO6_OFFSET = 10'h028;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO7_OFFSET = 10'h02c;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO8_OFFSET = 10'h030;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_PRIO9_OFFSET = 10'h034;
+ localparam [9:0] rv_plic_reg_pkg_RV_PLIC_THRESHOLD0_OFFSET = 10'h0a8;
+ always @(*) begin
+ addr_hit = {45 {1'sb0}};
+ addr_hit[0] = reg_addr == rv_plic_reg_pkg_RV_PLIC_IP_0_OFFSET;
+ addr_hit[1] = reg_addr == rv_plic_reg_pkg_RV_PLIC_IP_1_OFFSET;
+ addr_hit[2] = reg_addr == rv_plic_reg_pkg_RV_PLIC_LE_0_OFFSET;
+ addr_hit[3] = reg_addr == rv_plic_reg_pkg_RV_PLIC_LE_1_OFFSET;
+ addr_hit[4] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO0_OFFSET;
+ addr_hit[5] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO1_OFFSET;
+ addr_hit[6] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO2_OFFSET;
+ addr_hit[7] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO3_OFFSET;
+ addr_hit[8] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO4_OFFSET;
+ addr_hit[9] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO5_OFFSET;
+ addr_hit[10] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO6_OFFSET;
+ addr_hit[11] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO7_OFFSET;
+ addr_hit[12] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO8_OFFSET;
+ addr_hit[13] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO9_OFFSET;
+ addr_hit[14] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO10_OFFSET;
+ addr_hit[15] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO11_OFFSET;
+ addr_hit[16] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO12_OFFSET;
+ addr_hit[17] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO13_OFFSET;
+ addr_hit[18] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO14_OFFSET;
+ addr_hit[19] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO15_OFFSET;
+ addr_hit[20] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO16_OFFSET;
+ addr_hit[21] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO17_OFFSET;
+ addr_hit[22] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO18_OFFSET;
+ addr_hit[23] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO19_OFFSET;
+ addr_hit[24] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO20_OFFSET;
+ addr_hit[25] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO21_OFFSET;
+ addr_hit[26] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO22_OFFSET;
+ addr_hit[27] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO23_OFFSET;
+ addr_hit[28] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO24_OFFSET;
+ addr_hit[29] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO25_OFFSET;
+ addr_hit[30] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO26_OFFSET;
+ addr_hit[31] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO27_OFFSET;
+ addr_hit[32] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO28_OFFSET;
+ addr_hit[33] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO29_OFFSET;
+ addr_hit[34] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO30_OFFSET;
+ addr_hit[35] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO31_OFFSET;
+ addr_hit[36] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO32_OFFSET;
+ addr_hit[37] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO33_OFFSET;
+ addr_hit[38] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO34_OFFSET;
+ addr_hit[39] = reg_addr == rv_plic_reg_pkg_RV_PLIC_PRIO35_OFFSET;
+ addr_hit[40] = reg_addr == rv_plic_reg_pkg_RV_PLIC_IE0_0_OFFSET;
+ addr_hit[41] = reg_addr == rv_plic_reg_pkg_RV_PLIC_IE0_1_OFFSET;
+ addr_hit[42] = reg_addr == rv_plic_reg_pkg_RV_PLIC_THRESHOLD0_OFFSET;
+ addr_hit[43] = reg_addr == rv_plic_reg_pkg_RV_PLIC_CC0_OFFSET;
+ addr_hit[44] = reg_addr == rv_plic_reg_pkg_RV_PLIC_MSIP0_OFFSET;
+ end
+ assign addrmiss = (reg_re || reg_we ? ~|addr_hit : 1'b0);
+ localparam [179:0] rv_plic_reg_pkg_RV_PLIC_PERMIT = 180'b111111111111111100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000111111111000100010001;
+ always @(*) begin
+ wr_err = 1'b0;
+ if ((addr_hit[0] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[176+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[176+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[1] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[172+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[172+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[2] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[168+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[168+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[3] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[164+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[164+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[4] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[160+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[160+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[5] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[156+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[156+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[6] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[152+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[152+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[7] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[148+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[148+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[8] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[144+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[144+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[9] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[140+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[140+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[10] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[136+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[136+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[11] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[132+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[132+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[12] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[128+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[128+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[13] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[124+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[124+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[14] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[120+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[120+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[15] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[116+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[116+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[16] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[112+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[112+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[17] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[108+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[108+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[18] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[104+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[104+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[19] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[100+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[100+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[20] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[96+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[96+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[21] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[92+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[92+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[22] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[88+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[88+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[23] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[84+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[84+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[24] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[80+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[80+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[25] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[76+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[76+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[26] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[72+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[72+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[27] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[68+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[68+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[28] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[64+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[64+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[29] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[60+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[60+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[30] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[56+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[56+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[31] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[52+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[52+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[32] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[48+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[48+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[33] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[44+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[44+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[34] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[40+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[40+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[35] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[36+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[36+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[36] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[32+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[32+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[37] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[28+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[28+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[38] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[24+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[24+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[39] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[20+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[20+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[40] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[16+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[16+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[41] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[12+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[12+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[42] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[8+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[8+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[43] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[4+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[4+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[44] && reg_we) && (rv_plic_reg_pkg_RV_PLIC_PERMIT[0+:4] != (rv_plic_reg_pkg_RV_PLIC_PERMIT[0+:4] & reg_be)))
+ wr_err = 1'b1;
+ end
+ assign le_0_le_0_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_0_wd = reg_wdata[0];
+ assign le_0_le_1_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_1_wd = reg_wdata[1];
+ assign le_0_le_2_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_2_wd = reg_wdata[2];
+ assign le_0_le_3_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_3_wd = reg_wdata[3];
+ assign le_0_le_4_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_4_wd = reg_wdata[4];
+ assign le_0_le_5_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_5_wd = reg_wdata[5];
+ assign le_0_le_6_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_6_wd = reg_wdata[6];
+ assign le_0_le_7_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_7_wd = reg_wdata[7];
+ assign le_0_le_8_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_8_wd = reg_wdata[8];
+ assign le_0_le_9_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_9_wd = reg_wdata[9];
+ assign le_0_le_10_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_10_wd = reg_wdata[10];
+ assign le_0_le_11_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_11_wd = reg_wdata[11];
+ assign le_0_le_12_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_12_wd = reg_wdata[12];
+ assign le_0_le_13_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_13_wd = reg_wdata[13];
+ assign le_0_le_14_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_14_wd = reg_wdata[14];
+ assign le_0_le_15_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_15_wd = reg_wdata[15];
+ assign le_0_le_16_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_16_wd = reg_wdata[16];
+ assign le_0_le_17_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_17_wd = reg_wdata[17];
+ assign le_0_le_18_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_18_wd = reg_wdata[18];
+ assign le_0_le_19_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_19_wd = reg_wdata[19];
+ assign le_0_le_20_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_20_wd = reg_wdata[20];
+ assign le_0_le_21_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_21_wd = reg_wdata[21];
+ assign le_0_le_22_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_22_wd = reg_wdata[22];
+ assign le_0_le_23_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_23_wd = reg_wdata[23];
+ assign le_0_le_24_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_24_wd = reg_wdata[24];
+ assign le_0_le_25_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_25_wd = reg_wdata[25];
+ assign le_0_le_26_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_26_wd = reg_wdata[26];
+ assign le_0_le_27_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_27_wd = reg_wdata[27];
+ assign le_0_le_28_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_28_wd = reg_wdata[28];
+ assign le_0_le_29_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_29_wd = reg_wdata[29];
+ assign le_0_le_30_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_30_wd = reg_wdata[30];
+ assign le_0_le_31_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign le_0_le_31_wd = reg_wdata[31];
+ assign le_1_le_32_we = (addr_hit[3] & reg_we) & ~wr_err;
+ assign le_1_le_32_wd = reg_wdata[0];
+ assign le_1_le_33_we = (addr_hit[3] & reg_we) & ~wr_err;
+ assign le_1_le_33_wd = reg_wdata[1];
+ assign le_1_le_34_we = (addr_hit[3] & reg_we) & ~wr_err;
+ assign le_1_le_34_wd = reg_wdata[2];
+ assign le_1_le_35_we = (addr_hit[3] & reg_we) & ~wr_err;
+ assign le_1_le_35_wd = reg_wdata[3];
+ assign prio0_we = (addr_hit[4] & reg_we) & ~wr_err;
+ assign prio0_wd = reg_wdata[1:0];
+ assign prio1_we = (addr_hit[5] & reg_we) & ~wr_err;
+ assign prio1_wd = reg_wdata[1:0];
+ assign prio2_we = (addr_hit[6] & reg_we) & ~wr_err;
+ assign prio2_wd = reg_wdata[1:0];
+ assign prio3_we = (addr_hit[7] & reg_we) & ~wr_err;
+ assign prio3_wd = reg_wdata[1:0];
+ assign prio4_we = (addr_hit[8] & reg_we) & ~wr_err;
+ assign prio4_wd = reg_wdata[1:0];
+ assign prio5_we = (addr_hit[9] & reg_we) & ~wr_err;
+ assign prio5_wd = reg_wdata[1:0];
+ assign prio6_we = (addr_hit[10] & reg_we) & ~wr_err;
+ assign prio6_wd = reg_wdata[1:0];
+ assign prio7_we = (addr_hit[11] & reg_we) & ~wr_err;
+ assign prio7_wd = reg_wdata[1:0];
+ assign prio8_we = (addr_hit[12] & reg_we) & ~wr_err;
+ assign prio8_wd = reg_wdata[1:0];
+ assign prio9_we = (addr_hit[13] & reg_we) & ~wr_err;
+ assign prio9_wd = reg_wdata[1:0];
+ assign prio10_we = (addr_hit[14] & reg_we) & ~wr_err;
+ assign prio10_wd = reg_wdata[1:0];
+ assign prio11_we = (addr_hit[15] & reg_we) & ~wr_err;
+ assign prio11_wd = reg_wdata[1:0];
+ assign prio12_we = (addr_hit[16] & reg_we) & ~wr_err;
+ assign prio12_wd = reg_wdata[1:0];
+ assign prio13_we = (addr_hit[17] & reg_we) & ~wr_err;
+ assign prio13_wd = reg_wdata[1:0];
+ assign prio14_we = (addr_hit[18] & reg_we) & ~wr_err;
+ assign prio14_wd = reg_wdata[1:0];
+ assign prio15_we = (addr_hit[19] & reg_we) & ~wr_err;
+ assign prio15_wd = reg_wdata[1:0];
+ assign prio16_we = (addr_hit[20] & reg_we) & ~wr_err;
+ assign prio16_wd = reg_wdata[1:0];
+ assign prio17_we = (addr_hit[21] & reg_we) & ~wr_err;
+ assign prio17_wd = reg_wdata[1:0];
+ assign prio18_we = (addr_hit[22] & reg_we) & ~wr_err;
+ assign prio18_wd = reg_wdata[1:0];
+ assign prio19_we = (addr_hit[23] & reg_we) & ~wr_err;
+ assign prio19_wd = reg_wdata[1:0];
+ assign prio20_we = (addr_hit[24] & reg_we) & ~wr_err;
+ assign prio20_wd = reg_wdata[1:0];
+ assign prio21_we = (addr_hit[25] & reg_we) & ~wr_err;
+ assign prio21_wd = reg_wdata[1:0];
+ assign prio22_we = (addr_hit[26] & reg_we) & ~wr_err;
+ assign prio22_wd = reg_wdata[1:0];
+ assign prio23_we = (addr_hit[27] & reg_we) & ~wr_err;
+ assign prio23_wd = reg_wdata[1:0];
+ assign prio24_we = (addr_hit[28] & reg_we) & ~wr_err;
+ assign prio24_wd = reg_wdata[1:0];
+ assign prio25_we = (addr_hit[29] & reg_we) & ~wr_err;
+ assign prio25_wd = reg_wdata[1:0];
+ assign prio26_we = (addr_hit[30] & reg_we) & ~wr_err;
+ assign prio26_wd = reg_wdata[1:0];
+ assign prio27_we = (addr_hit[31] & reg_we) & ~wr_err;
+ assign prio27_wd = reg_wdata[1:0];
+ assign prio28_we = (addr_hit[32] & reg_we) & ~wr_err;
+ assign prio28_wd = reg_wdata[1:0];
+ assign prio29_we = (addr_hit[33] & reg_we) & ~wr_err;
+ assign prio29_wd = reg_wdata[1:0];
+ assign prio30_we = (addr_hit[34] & reg_we) & ~wr_err;
+ assign prio30_wd = reg_wdata[1:0];
+ assign prio31_we = (addr_hit[35] & reg_we) & ~wr_err;
+ assign prio31_wd = reg_wdata[1:0];
+ assign prio32_we = (addr_hit[36] & reg_we) & ~wr_err;
+ assign prio32_wd = reg_wdata[1:0];
+ assign prio33_we = (addr_hit[37] & reg_we) & ~wr_err;
+ assign prio33_wd = reg_wdata[1:0];
+ assign prio34_we = (addr_hit[38] & reg_we) & ~wr_err;
+ assign prio34_wd = reg_wdata[1:0];
+ assign prio35_we = (addr_hit[39] & reg_we) & ~wr_err;
+ assign prio35_wd = reg_wdata[1:0];
+ assign ie0_0_e_0_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_0_wd = reg_wdata[0];
+ assign ie0_0_e_1_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_1_wd = reg_wdata[1];
+ assign ie0_0_e_2_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_2_wd = reg_wdata[2];
+ assign ie0_0_e_3_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_3_wd = reg_wdata[3];
+ assign ie0_0_e_4_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_4_wd = reg_wdata[4];
+ assign ie0_0_e_5_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_5_wd = reg_wdata[5];
+ assign ie0_0_e_6_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_6_wd = reg_wdata[6];
+ assign ie0_0_e_7_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_7_wd = reg_wdata[7];
+ assign ie0_0_e_8_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_8_wd = reg_wdata[8];
+ assign ie0_0_e_9_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_9_wd = reg_wdata[9];
+ assign ie0_0_e_10_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_10_wd = reg_wdata[10];
+ assign ie0_0_e_11_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_11_wd = reg_wdata[11];
+ assign ie0_0_e_12_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_12_wd = reg_wdata[12];
+ assign ie0_0_e_13_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_13_wd = reg_wdata[13];
+ assign ie0_0_e_14_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_14_wd = reg_wdata[14];
+ assign ie0_0_e_15_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_15_wd = reg_wdata[15];
+ assign ie0_0_e_16_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_16_wd = reg_wdata[16];
+ assign ie0_0_e_17_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_17_wd = reg_wdata[17];
+ assign ie0_0_e_18_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_18_wd = reg_wdata[18];
+ assign ie0_0_e_19_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_19_wd = reg_wdata[19];
+ assign ie0_0_e_20_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_20_wd = reg_wdata[20];
+ assign ie0_0_e_21_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_21_wd = reg_wdata[21];
+ assign ie0_0_e_22_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_22_wd = reg_wdata[22];
+ assign ie0_0_e_23_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_23_wd = reg_wdata[23];
+ assign ie0_0_e_24_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_24_wd = reg_wdata[24];
+ assign ie0_0_e_25_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_25_wd = reg_wdata[25];
+ assign ie0_0_e_26_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_26_wd = reg_wdata[26];
+ assign ie0_0_e_27_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_27_wd = reg_wdata[27];
+ assign ie0_0_e_28_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_28_wd = reg_wdata[28];
+ assign ie0_0_e_29_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_29_wd = reg_wdata[29];
+ assign ie0_0_e_30_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_30_wd = reg_wdata[30];
+ assign ie0_0_e_31_we = (addr_hit[40] & reg_we) & ~wr_err;
+ assign ie0_0_e_31_wd = reg_wdata[31];
+ assign ie0_1_e_32_we = (addr_hit[41] & reg_we) & ~wr_err;
+ assign ie0_1_e_32_wd = reg_wdata[0];
+ assign ie0_1_e_33_we = (addr_hit[41] & reg_we) & ~wr_err;
+ assign ie0_1_e_33_wd = reg_wdata[1];
+ assign ie0_1_e_34_we = (addr_hit[41] & reg_we) & ~wr_err;
+ assign ie0_1_e_34_wd = reg_wdata[2];
+ assign ie0_1_e_35_we = (addr_hit[41] & reg_we) & ~wr_err;
+ assign ie0_1_e_35_wd = reg_wdata[3];
+ assign threshold0_we = (addr_hit[42] & reg_we) & ~wr_err;
+ assign threshold0_wd = reg_wdata[1:0];
+ assign cc0_we = (addr_hit[43] & reg_we) & ~wr_err;
+ assign cc0_wd = reg_wdata[7:0];
+ assign cc0_re = addr_hit[43] && reg_re;
+ assign msip0_we = (addr_hit[44] & reg_we) & ~wr_err;
+ assign msip0_wd = reg_wdata[0];
+ always @(*) begin
+ reg_rdata_next = {32 {1'sb0}};
+ case (1'b1)
+ addr_hit[0]: begin
+ reg_rdata_next[0] = ip_0_p_0_qs;
+ reg_rdata_next[1] = ip_0_p_1_qs;
+ reg_rdata_next[2] = ip_0_p_2_qs;
+ reg_rdata_next[3] = ip_0_p_3_qs;
+ reg_rdata_next[4] = ip_0_p_4_qs;
+ reg_rdata_next[5] = ip_0_p_5_qs;
+ reg_rdata_next[6] = ip_0_p_6_qs;
+ reg_rdata_next[7] = ip_0_p_7_qs;
+ reg_rdata_next[8] = ip_0_p_8_qs;
+ reg_rdata_next[9] = ip_0_p_9_qs;
+ reg_rdata_next[10] = ip_0_p_10_qs;
+ reg_rdata_next[11] = ip_0_p_11_qs;
+ reg_rdata_next[12] = ip_0_p_12_qs;
+ reg_rdata_next[13] = ip_0_p_13_qs;
+ reg_rdata_next[14] = ip_0_p_14_qs;
+ reg_rdata_next[15] = ip_0_p_15_qs;
+ reg_rdata_next[16] = ip_0_p_16_qs;
+ reg_rdata_next[17] = ip_0_p_17_qs;
+ reg_rdata_next[18] = ip_0_p_18_qs;
+ reg_rdata_next[19] = ip_0_p_19_qs;
+ reg_rdata_next[20] = ip_0_p_20_qs;
+ reg_rdata_next[21] = ip_0_p_21_qs;
+ reg_rdata_next[22] = ip_0_p_22_qs;
+ reg_rdata_next[23] = ip_0_p_23_qs;
+ reg_rdata_next[24] = ip_0_p_24_qs;
+ reg_rdata_next[25] = ip_0_p_25_qs;
+ reg_rdata_next[26] = ip_0_p_26_qs;
+ reg_rdata_next[27] = ip_0_p_27_qs;
+ reg_rdata_next[28] = ip_0_p_28_qs;
+ reg_rdata_next[29] = ip_0_p_29_qs;
+ reg_rdata_next[30] = ip_0_p_30_qs;
+ reg_rdata_next[31] = ip_0_p_31_qs;
+ end
+ addr_hit[1]: begin
+ reg_rdata_next[0] = ip_1_p_32_qs;
+ reg_rdata_next[1] = ip_1_p_33_qs;
+ reg_rdata_next[2] = ip_1_p_34_qs;
+ reg_rdata_next[3] = ip_1_p_35_qs;
+ end
+ addr_hit[2]: begin
+ reg_rdata_next[0] = le_0_le_0_qs;
+ reg_rdata_next[1] = le_0_le_1_qs;
+ reg_rdata_next[2] = le_0_le_2_qs;
+ reg_rdata_next[3] = le_0_le_3_qs;
+ reg_rdata_next[4] = le_0_le_4_qs;
+ reg_rdata_next[5] = le_0_le_5_qs;
+ reg_rdata_next[6] = le_0_le_6_qs;
+ reg_rdata_next[7] = le_0_le_7_qs;
+ reg_rdata_next[8] = le_0_le_8_qs;
+ reg_rdata_next[9] = le_0_le_9_qs;
+ reg_rdata_next[10] = le_0_le_10_qs;
+ reg_rdata_next[11] = le_0_le_11_qs;
+ reg_rdata_next[12] = le_0_le_12_qs;
+ reg_rdata_next[13] = le_0_le_13_qs;
+ reg_rdata_next[14] = le_0_le_14_qs;
+ reg_rdata_next[15] = le_0_le_15_qs;
+ reg_rdata_next[16] = le_0_le_16_qs;
+ reg_rdata_next[17] = le_0_le_17_qs;
+ reg_rdata_next[18] = le_0_le_18_qs;
+ reg_rdata_next[19] = le_0_le_19_qs;
+ reg_rdata_next[20] = le_0_le_20_qs;
+ reg_rdata_next[21] = le_0_le_21_qs;
+ reg_rdata_next[22] = le_0_le_22_qs;
+ reg_rdata_next[23] = le_0_le_23_qs;
+ reg_rdata_next[24] = le_0_le_24_qs;
+ reg_rdata_next[25] = le_0_le_25_qs;
+ reg_rdata_next[26] = le_0_le_26_qs;
+ reg_rdata_next[27] = le_0_le_27_qs;
+ reg_rdata_next[28] = le_0_le_28_qs;
+ reg_rdata_next[29] = le_0_le_29_qs;
+ reg_rdata_next[30] = le_0_le_30_qs;
+ reg_rdata_next[31] = le_0_le_31_qs;
+ end
+ addr_hit[3]: begin
+ reg_rdata_next[0] = le_1_le_32_qs;
+ reg_rdata_next[1] = le_1_le_33_qs;
+ reg_rdata_next[2] = le_1_le_34_qs;
+ reg_rdata_next[3] = le_1_le_35_qs;
+ end
+ addr_hit[4]: reg_rdata_next[1:0] = prio0_qs;
+ addr_hit[5]: reg_rdata_next[1:0] = prio1_qs;
+ addr_hit[6]: reg_rdata_next[1:0] = prio2_qs;
+ addr_hit[7]: reg_rdata_next[1:0] = prio3_qs;
+ addr_hit[8]: reg_rdata_next[1:0] = prio4_qs;
+ addr_hit[9]: reg_rdata_next[1:0] = prio5_qs;
+ addr_hit[10]: reg_rdata_next[1:0] = prio6_qs;
+ addr_hit[11]: reg_rdata_next[1:0] = prio7_qs;
+ addr_hit[12]: reg_rdata_next[1:0] = prio8_qs;
+ addr_hit[13]: reg_rdata_next[1:0] = prio9_qs;
+ addr_hit[14]: reg_rdata_next[1:0] = prio10_qs;
+ addr_hit[15]: reg_rdata_next[1:0] = prio11_qs;
+ addr_hit[16]: reg_rdata_next[1:0] = prio12_qs;
+ addr_hit[17]: reg_rdata_next[1:0] = prio13_qs;
+ addr_hit[18]: reg_rdata_next[1:0] = prio14_qs;
+ addr_hit[19]: reg_rdata_next[1:0] = prio15_qs;
+ addr_hit[20]: reg_rdata_next[1:0] = prio16_qs;
+ addr_hit[21]: reg_rdata_next[1:0] = prio17_qs;
+ addr_hit[22]: reg_rdata_next[1:0] = prio18_qs;
+ addr_hit[23]: reg_rdata_next[1:0] = prio19_qs;
+ addr_hit[24]: reg_rdata_next[1:0] = prio20_qs;
+ addr_hit[25]: reg_rdata_next[1:0] = prio21_qs;
+ addr_hit[26]: reg_rdata_next[1:0] = prio22_qs;
+ addr_hit[27]: reg_rdata_next[1:0] = prio23_qs;
+ addr_hit[28]: reg_rdata_next[1:0] = prio24_qs;
+ addr_hit[29]: reg_rdata_next[1:0] = prio25_qs;
+ addr_hit[30]: reg_rdata_next[1:0] = prio26_qs;
+ addr_hit[31]: reg_rdata_next[1:0] = prio27_qs;
+ addr_hit[32]: reg_rdata_next[1:0] = prio28_qs;
+ addr_hit[33]: reg_rdata_next[1:0] = prio29_qs;
+ addr_hit[34]: reg_rdata_next[1:0] = prio30_qs;
+ addr_hit[35]: reg_rdata_next[1:0] = prio31_qs;
+ addr_hit[36]: reg_rdata_next[1:0] = prio32_qs;
+ addr_hit[37]: reg_rdata_next[1:0] = prio33_qs;
+ addr_hit[38]: reg_rdata_next[1:0] = prio34_qs;
+ addr_hit[39]: reg_rdata_next[1:0] = prio35_qs;
+ addr_hit[40]: begin
+ reg_rdata_next[0] = ie0_0_e_0_qs;
+ reg_rdata_next[1] = ie0_0_e_1_qs;
+ reg_rdata_next[2] = ie0_0_e_2_qs;
+ reg_rdata_next[3] = ie0_0_e_3_qs;
+ reg_rdata_next[4] = ie0_0_e_4_qs;
+ reg_rdata_next[5] = ie0_0_e_5_qs;
+ reg_rdata_next[6] = ie0_0_e_6_qs;
+ reg_rdata_next[7] = ie0_0_e_7_qs;
+ reg_rdata_next[8] = ie0_0_e_8_qs;
+ reg_rdata_next[9] = ie0_0_e_9_qs;
+ reg_rdata_next[10] = ie0_0_e_10_qs;
+ reg_rdata_next[11] = ie0_0_e_11_qs;
+ reg_rdata_next[12] = ie0_0_e_12_qs;
+ reg_rdata_next[13] = ie0_0_e_13_qs;
+ reg_rdata_next[14] = ie0_0_e_14_qs;
+ reg_rdata_next[15] = ie0_0_e_15_qs;
+ reg_rdata_next[16] = ie0_0_e_16_qs;
+ reg_rdata_next[17] = ie0_0_e_17_qs;
+ reg_rdata_next[18] = ie0_0_e_18_qs;
+ reg_rdata_next[19] = ie0_0_e_19_qs;
+ reg_rdata_next[20] = ie0_0_e_20_qs;
+ reg_rdata_next[21] = ie0_0_e_21_qs;
+ reg_rdata_next[22] = ie0_0_e_22_qs;
+ reg_rdata_next[23] = ie0_0_e_23_qs;
+ reg_rdata_next[24] = ie0_0_e_24_qs;
+ reg_rdata_next[25] = ie0_0_e_25_qs;
+ reg_rdata_next[26] = ie0_0_e_26_qs;
+ reg_rdata_next[27] = ie0_0_e_27_qs;
+ reg_rdata_next[28] = ie0_0_e_28_qs;
+ reg_rdata_next[29] = ie0_0_e_29_qs;
+ reg_rdata_next[30] = ie0_0_e_30_qs;
+ reg_rdata_next[31] = ie0_0_e_31_qs;
+ end
+ addr_hit[41]: begin
+ reg_rdata_next[0] = ie0_1_e_32_qs;
+ reg_rdata_next[1] = ie0_1_e_33_qs;
+ reg_rdata_next[2] = ie0_1_e_34_qs;
+ reg_rdata_next[3] = ie0_1_e_35_qs;
+ end
+ addr_hit[42]: reg_rdata_next[1:0] = threshold0_qs;
+ addr_hit[43]: reg_rdata_next[7:0] = cc0_qs;
+ addr_hit[44]: reg_rdata_next[0] = msip0_qs;
+ default: reg_rdata_next = {32 {1'sb1}};
+ endcase
+ end
+endmodule
+module rv_plic (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ intr_src_i,
+ irq_o,
+ msip_o
+);
+ localparam signed [31:0] rv_plic_reg_pkg_NumSrc = 36;
+ localparam signed [31:0] SRCW = 6;
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ input wire [35:0] intr_src_i;
+ localparam signed [31:0] rv_plic_reg_pkg_NumTarget = 1;
+ output wire [0:0] irq_o;
+ output wire [0:0] msip_o;
+ wire [154:0] reg2hw;
+ wire [77:0] hw2reg;
+ localparam signed [31:0] MAX_PRIO = 3;
+ localparam signed [31:0] PRIOW = 2;
+ wire [6:0] irq_id_o;
+ wire [35:0] le;
+ wire [35:0] ip;
+ wire [35:0] ie [0:0];
+ wire [0:0] claim_re;
+ wire [5:0] claim_id [0:0];
+ reg [35:0] claim;
+ wire [0:0] complete_we;
+ wire [5:0] complete_id [0:0];
+ reg [35:0] complete;
+ wire [6:0] cc_id;
+ wire [71:0] prio;
+ wire [1:0] threshold [0:0];
+ assign cc_id = irq_id_o;
+ always @(*) begin
+ claim = {36 {1'sb0}};
+ begin : sv2v_autoblock_135
+ reg signed [31:0] i;
+ for (i = 0; i < rv_plic_reg_pkg_NumTarget; i = i + 1)
+ if (claim_re[i])
+ claim[claim_id[i]] = 1'b1;
+ end
+ end
+ always @(*) begin
+ complete = {36 {1'sb0}};
+ begin : sv2v_autoblock_136
+ reg signed [31:0] i;
+ for (i = 0; i < rv_plic_reg_pkg_NumTarget; i = i + 1)
+ if (complete_we[i])
+ complete[complete_id[i]] = 1'b1;
+ end
+ end
+ assign prio[70+:PRIOW] = reg2hw[118-:2];
+ assign prio[68+:PRIOW] = reg2hw[116-:2];
+ assign prio[66+:PRIOW] = reg2hw[114-:2];
+ assign prio[64+:PRIOW] = reg2hw[112-:2];
+ assign prio[62+:PRIOW] = reg2hw[110-:2];
+ assign prio[60+:PRIOW] = reg2hw[108-:2];
+ assign prio[58+:PRIOW] = reg2hw[106-:2];
+ assign prio[56+:PRIOW] = reg2hw[104-:2];
+ assign prio[54+:PRIOW] = reg2hw[102-:2];
+ assign prio[52+:PRIOW] = reg2hw[100-:2];
+ assign prio[50+:PRIOW] = reg2hw[98-:2];
+ assign prio[48+:PRIOW] = reg2hw[96-:2];
+ assign prio[46+:PRIOW] = reg2hw[94-:2];
+ assign prio[44+:PRIOW] = reg2hw[92-:2];
+ assign prio[42+:PRIOW] = reg2hw[90-:2];
+ assign prio[40+:PRIOW] = reg2hw[88-:2];
+ assign prio[38+:PRIOW] = reg2hw[86-:2];
+ assign prio[36+:PRIOW] = reg2hw[84-:2];
+ assign prio[34+:PRIOW] = reg2hw[82-:2];
+ assign prio[32+:PRIOW] = reg2hw[80-:2];
+ assign prio[30+:PRIOW] = reg2hw[78-:2];
+ assign prio[28+:PRIOW] = reg2hw[76-:2];
+ assign prio[26+:PRIOW] = reg2hw[74-:2];
+ assign prio[24+:PRIOW] = reg2hw[72-:2];
+ assign prio[22+:PRIOW] = reg2hw[70-:2];
+ assign prio[20+:PRIOW] = reg2hw[68-:2];
+ assign prio[18+:PRIOW] = reg2hw[66-:2];
+ assign prio[16+:PRIOW] = reg2hw[64-:2];
+ assign prio[14+:PRIOW] = reg2hw[62-:2];
+ assign prio[12+:PRIOW] = reg2hw[60-:2];
+ assign prio[10+:PRIOW] = reg2hw[58-:2];
+ assign prio[8+:PRIOW] = reg2hw[56-:2];
+ assign prio[6+:PRIOW] = reg2hw[54-:2];
+ assign prio[4+:PRIOW] = reg2hw[52-:2];
+ assign prio[2+:PRIOW] = reg2hw[50-:2];
+ assign prio[0+:PRIOW] = reg2hw[48-:2];
+ generate
+ genvar s;
+ for (s = 0; s < 36; s = s + 1) begin : gen_ie0
+ assign ie[0][s] = reg2hw[11 + s];
+ end
+ endgenerate
+ assign threshold[0] = reg2hw[10-:2];
+ assign claim_re[0] = reg2hw[1];
+ assign claim_id[0] = irq_id_o[0+:7];
+ assign complete_we[0] = reg2hw[2];
+ assign complete_id[0] = reg2hw[8-:6];
+ assign hw2reg[5-:6] = cc_id[0+:7];
+ assign msip_o[0] = reg2hw[-0];
+ generate
+ for (s = 0; s < 36; s = s + 1) begin : gen_ip
+ assign hw2reg[6 + (s * 2)] = 1'b1;
+ assign hw2reg[6 + ((s * 2) + 1)] = ip[s];
+ end
+ endgenerate
+ generate
+ for (s = 0; s < 36; s = s + 1) begin : gen_le
+ assign le[s] = reg2hw[119 + s];
+ end
+ endgenerate
+ rv_plic_gateway #(.N_SOURCE(rv_plic_reg_pkg_NumSrc)) u_gateway(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .src_i(intr_src_i),
+ .le_i(le),
+ .claim_i(claim),
+ .complete_i(complete),
+ .ip_o(ip)
+ );
+ generate
+ genvar i;
+ for (i = 0; i < rv_plic_reg_pkg_NumTarget; i = i + 1) begin : gen_target
+ rv_plic_target #(
+ .N_SOURCE(rv_plic_reg_pkg_NumSrc),
+ .MAX_PRIO(MAX_PRIO)
+ ) u_target(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .ip_i(ip),
+ .ie_i(ie[i]),
+ .prio_i(prio),
+ .threshold_i(threshold[i]),
+ .irq_o(irq_o[i]),
+ .irq_id_o(irq_id_o[i * 7+:7])
+ );
+ end
+ endgenerate
+ rv_plic_reg_top u_reg(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_i),
+ .tl_o(tl_o),
+ .reg2hw(reg2hw),
+ .hw2reg(hw2reg),
+ .devmode_i(1'b1)
+ );
+endmodule
+module rv_plic_target (
+ clk_i,
+ rst_ni,
+ ip_i,
+ ie_i,
+ prio_i,
+ threshold_i,
+ irq_o,
+ irq_id_o
+);
+ parameter signed [31:0] N_SOURCE = 32;
+ parameter signed [31:0] MAX_PRIO = 7;
+ localparam signed [31:0] SrcWidth = $clog2(N_SOURCE + 1);
+ localparam signed [31:0] PrioWidth = $clog2(MAX_PRIO + 1);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [N_SOURCE - 1:0] ip_i;
+ input wire [N_SOURCE - 1:0] ie_i;
+ input wire [(0 >= (N_SOURCE - 1) ? ((2 - N_SOURCE) * PrioWidth) + (((N_SOURCE - 1) * PrioWidth) - 1) : (N_SOURCE * PrioWidth) - 1):(0 >= (N_SOURCE - 1) ? (N_SOURCE - 1) * PrioWidth : 0)] prio_i;
+ input wire [PrioWidth - 1:0] threshold_i;
+ output wire irq_o;
+ output wire [SrcWidth - 1:0] irq_id_o;
+ localparam signed [31:0] NumLevels = $clog2(N_SOURCE);
+ wire [(2 ** (NumLevels + 1)) - 2:0] is_tree;
+ wire [(((2 ** (NumLevels + 1)) - 2) >= 0 ? (((2 ** (NumLevels + 1)) - 1) * SrcWidth) - 1 : ((3 - (2 ** (NumLevels + 1))) * SrcWidth) + ((((2 ** (NumLevels + 1)) - 2) * SrcWidth) - 1)):(((2 ** (NumLevels + 1)) - 2) >= 0 ? 0 : ((2 ** (NumLevels + 1)) - 2) * SrcWidth)] id_tree;
+ wire [(((2 ** (NumLevels + 1)) - 2) >= 0 ? (((2 ** (NumLevels + 1)) - 1) * PrioWidth) - 1 : ((3 - (2 ** (NumLevels + 1))) * PrioWidth) + ((((2 ** (NumLevels + 1)) - 2) * PrioWidth) - 1)):(((2 ** (NumLevels + 1)) - 2) >= 0 ? 0 : ((2 ** (NumLevels + 1)) - 2) * PrioWidth)] max_tree;
+ generate
+ genvar level;
+ for (level = 0; level < (NumLevels + 1); level = level + 1) begin : gen_tree
+ localparam signed [31:0] Base0 = (2 ** level) - 1;
+ localparam signed [31:0] Base1 = (2 ** (level + 1)) - 1;
+ genvar offset;
+ for (offset = 0; offset < (2 ** level); offset = offset + 1) begin : gen_level
+ localparam signed [31:0] Pa = Base0 + offset;
+ localparam signed [31:0] C0 = Base1 + (2 * offset);
+ localparam signed [31:0] C1 = (Base1 + (2 * offset)) + 1;
+ if (level == NumLevels) begin : gen_leafs
+ if (offset < N_SOURCE) begin : gen_assign
+ assign is_tree[Pa] = ip_i[offset] & ie_i[offset];
+ assign id_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? Pa : ((2 ** (NumLevels + 1)) - 2) - Pa) * SrcWidth+:SrcWidth] = offset;
+ assign max_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? Pa : ((2 ** (NumLevels + 1)) - 2) - Pa) * PrioWidth+:PrioWidth] = prio_i[(0 >= (N_SOURCE - 1) ? offset : (N_SOURCE - 1) - offset) * PrioWidth+:PrioWidth];
+ end
+ else begin : gen_tie_off
+ assign is_tree[Pa] = 1'b0;
+ assign id_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? Pa : ((2 ** (NumLevels + 1)) - 2) - Pa) * SrcWidth+:SrcWidth] = {SrcWidth {1'sb0}};
+ assign max_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? Pa : ((2 ** (NumLevels + 1)) - 2) - Pa) * PrioWidth+:PrioWidth] = {PrioWidth {1'sb0}};
+ end
+ end
+ else begin : gen_nodes
+ wire sel;
+ assign sel = (~is_tree[C0] & is_tree[C1]) | ((is_tree[C0] & is_tree[C1]) & (max_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? C1 : ((2 ** (NumLevels + 1)) - 2) - C1) * PrioWidth+:PrioWidth] > max_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? C0 : ((2 ** (NumLevels + 1)) - 2) - C0) * PrioWidth+:PrioWidth]));
+ assign is_tree[Pa] = (sel & is_tree[C1]) | (~sel & is_tree[C0]);
+ assign id_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? Pa : ((2 ** (NumLevels + 1)) - 2) - Pa) * SrcWidth+:SrcWidth] = ({SrcWidth {sel}} & id_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? C1 : ((2 ** (NumLevels + 1)) - 2) - C1) * SrcWidth+:SrcWidth]) | ({SrcWidth {~sel}} & id_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? C0 : ((2 ** (NumLevels + 1)) - 2) - C0) * SrcWidth+:SrcWidth]);
+ assign max_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? Pa : ((2 ** (NumLevels + 1)) - 2) - Pa) * PrioWidth+:PrioWidth] = ({PrioWidth {sel}} & max_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? C1 : ((2 ** (NumLevels + 1)) - 2) - C1) * PrioWidth+:PrioWidth]) | ({PrioWidth {~sel}} & max_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? C0 : ((2 ** (NumLevels + 1)) - 2) - C0) * PrioWidth+:PrioWidth]);
+ end
+ end
+ end
+ endgenerate
+ wire irq_d;
+ reg irq_q;
+ wire [SrcWidth - 1:0] irq_id_d;
+ reg [SrcWidth - 1:0] irq_id_q;
+ assign irq_d = (max_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? 0 : (2 ** (NumLevels + 1)) - 2) * PrioWidth+:PrioWidth] > threshold_i ? is_tree[0] : 1'b0);
+ assign irq_id_d = (is_tree[0] ? id_tree[(((2 ** (NumLevels + 1)) - 2) >= 0 ? 0 : (2 ** (NumLevels + 1)) - 2) * SrcWidth+:SrcWidth] : {SrcWidth {1'sb0}});
+ always @(posedge clk_i or negedge rst_ni) begin : gen_regs
+ if (!rst_ni) begin
+ irq_q <= 1'b0;
+ irq_id_q <= {SrcWidth {1'sb0}};
+ end
+ else begin
+ irq_q <= irq_d;
+ irq_id_q <= irq_id_d;
+ end
+ end
+ assign irq_o = irq_q;
+ assign irq_id_o = irq_id_q;
+endmodule
+module rv_timer_reg_top (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ reg2hw,
+ hw2reg,
+ devmode_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire [154:0] reg2hw;
+ input wire [67:0] hw2reg;
+ input devmode_i;
+ localparam signed [31:0] AW = 9;
+ localparam signed [31:0] DW = 32;
+ localparam signed [31:0] DBW = 4;
+ wire reg_we;
+ wire reg_re;
+ wire [8:0] reg_addr;
+ wire [31:0] reg_wdata;
+ wire [3:0] reg_be;
+ wire [31:0] reg_rdata;
+ wire reg_error;
+ wire addrmiss;
+ reg wr_err;
+ reg [31:0] reg_rdata_next;
+ wire [85:0] tl_reg_h2d;
+ wire [51:0] tl_reg_d2h;
+ assign tl_reg_h2d = tl_i;
+ assign tl_o = tl_reg_d2h;
+ tlul_adapter_reg #(
+ .RegAw(AW),
+ .RegDw(DW)
+ ) u_reg_if(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_reg_h2d),
+ .tl_o(tl_reg_d2h),
+ .we_o(reg_we),
+ .re_o(reg_re),
+ .addr_o(reg_addr),
+ .wdata_o(reg_wdata),
+ .be_o(reg_be),
+ .rdata_i(reg_rdata),
+ .error_i(reg_error)
+ );
+ assign reg_rdata = reg_rdata_next;
+ assign reg_error = (devmode_i & addrmiss) | wr_err;
+ wire ctrl_qs;
+ wire ctrl_wd;
+ wire ctrl_we;
+ wire [11:0] cfg0_prescale_qs;
+ wire [11:0] cfg0_prescale_wd;
+ wire cfg0_prescale_we;
+ wire [7:0] cfg0_step_qs;
+ wire [7:0] cfg0_step_wd;
+ wire cfg0_step_we;
+ wire [31:0] timer_v_lower0_qs;
+ wire [31:0] timer_v_lower0_wd;
+ wire timer_v_lower0_we;
+ wire [31:0] timer_v_upper0_qs;
+ wire [31:0] timer_v_upper0_wd;
+ wire timer_v_upper0_we;
+ wire [31:0] compare_lower0_0_qs;
+ wire [31:0] compare_lower0_0_wd;
+ wire compare_lower0_0_we;
+ wire [31:0] compare_upper0_0_qs;
+ wire [31:0] compare_upper0_0_wd;
+ wire compare_upper0_0_we;
+ wire intr_enable0_qs;
+ wire intr_enable0_wd;
+ wire intr_enable0_we;
+ wire intr_state0_qs;
+ wire intr_state0_wd;
+ wire intr_state0_we;
+ wire intr_test0_wd;
+ wire intr_test0_we;
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_ctrl(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(ctrl_we),
+ .wd(ctrl_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[154]),
+ .qs(ctrl_qs)
+ );
+ prim_subreg #(
+ .DW(12),
+ .SWACCESS("RW"),
+ .RESVAL(12'h000)
+ ) u_cfg0_prescale(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(cfg0_prescale_we),
+ .wd(cfg0_prescale_wd),
+ .de(1'b0),
+ .d({12 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[153-:12]),
+ .qs(cfg0_prescale_qs)
+ );
+ prim_subreg #(
+ .DW(8),
+ .SWACCESS("RW"),
+ .RESVAL(8'h01)
+ ) u_cfg0_step(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(cfg0_step_we),
+ .wd(cfg0_step_wd),
+ .de(1'b0),
+ .d({8 {1'sb0}}),
+ .qe(),
+ .q(reg2hw[141-:8]),
+ .qs(cfg0_step_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'h00000000)
+ ) u_timer_v_lower0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(timer_v_lower0_we),
+ .wd(timer_v_lower0_wd),
+ .de(hw2reg[35]),
+ .d(hw2reg[67-:32]),
+ .qe(),
+ .q(reg2hw[133-:32]),
+ .qs(timer_v_lower0_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'h00000000)
+ ) u_timer_v_upper0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(timer_v_upper0_we),
+ .wd(timer_v_upper0_wd),
+ .de(hw2reg[2]),
+ .d(hw2reg[34-:32]),
+ .qe(),
+ .q(reg2hw[101-:32]),
+ .qs(timer_v_upper0_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'hffffffff)
+ ) u_compare_lower0_0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(compare_lower0_0_we),
+ .wd(compare_lower0_0_wd),
+ .de(1'b0),
+ .d({32 {1'sb0}}),
+ .qe(reg2hw[37]),
+ .q(reg2hw[69-:32]),
+ .qs(compare_lower0_0_qs)
+ );
+ prim_subreg #(
+ .DW(32),
+ .SWACCESS("RW"),
+ .RESVAL(32'hffffffff)
+ ) u_compare_upper0_0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(compare_upper0_0_we),
+ .wd(compare_upper0_0_wd),
+ .de(1'b0),
+ .d({32 {1'sb0}}),
+ .qe(reg2hw[4]),
+ .q(reg2hw[36-:32]),
+ .qs(compare_upper0_0_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("RW"),
+ .RESVAL(1'h0)
+ ) u_intr_enable0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(intr_enable0_we),
+ .wd(intr_enable0_wd),
+ .de(1'b0),
+ .d(1'b0),
+ .qe(),
+ .q(reg2hw[3]),
+ .qs(intr_enable0_qs)
+ );
+ prim_subreg #(
+ .DW(1),
+ .SWACCESS("W1C"),
+ .RESVAL(1'h0)
+ ) u_intr_state0(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .we(intr_state0_we),
+ .wd(intr_state0_wd),
+ .de(hw2reg[0]),
+ .d(hw2reg[1]),
+ .qe(),
+ .q(reg2hw[2]),
+ .qs(intr_state0_qs)
+ );
+ prim_subreg_ext #(.DW(1)) u_intr_test0(
+ .re(1'b0),
+ .we(intr_test0_we),
+ .wd(intr_test0_wd),
+ .d(1'b0),
+ .qre(),
+ .qe(reg2hw[0]),
+ .q(reg2hw[1]),
+ .qs()
+ );
+ reg [8:0] addr_hit;
+ localparam signed [31:0] rv_timer_reg_pkg_BlockAw = 9;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_CFG0_OFFSET = 9'h100;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_COMPARE_LOWER0_0_OFFSET = 9'h10c;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_COMPARE_UPPER0_0_OFFSET = 9'h110;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_CTRL_OFFSET = 9'h000;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_INTR_ENABLE0_OFFSET = 9'h114;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_INTR_STATE0_OFFSET = 9'h118;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_INTR_TEST0_OFFSET = 9'h11c;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_TIMER_V_LOWER0_OFFSET = 9'h104;
+ localparam [8:0] rv_timer_reg_pkg_RV_TIMER_TIMER_V_UPPER0_OFFSET = 9'h108;
+ always @(*) begin
+ addr_hit = {9 {1'sb0}};
+ addr_hit[0] = reg_addr == rv_timer_reg_pkg_RV_TIMER_CTRL_OFFSET;
+ addr_hit[1] = reg_addr == rv_timer_reg_pkg_RV_TIMER_CFG0_OFFSET;
+ addr_hit[2] = reg_addr == rv_timer_reg_pkg_RV_TIMER_TIMER_V_LOWER0_OFFSET;
+ addr_hit[3] = reg_addr == rv_timer_reg_pkg_RV_TIMER_TIMER_V_UPPER0_OFFSET;
+ addr_hit[4] = reg_addr == rv_timer_reg_pkg_RV_TIMER_COMPARE_LOWER0_0_OFFSET;
+ addr_hit[5] = reg_addr == rv_timer_reg_pkg_RV_TIMER_COMPARE_UPPER0_0_OFFSET;
+ addr_hit[6] = reg_addr == rv_timer_reg_pkg_RV_TIMER_INTR_ENABLE0_OFFSET;
+ addr_hit[7] = reg_addr == rv_timer_reg_pkg_RV_TIMER_INTR_STATE0_OFFSET;
+ addr_hit[8] = reg_addr == rv_timer_reg_pkg_RV_TIMER_INTR_TEST0_OFFSET;
+ end
+ assign addrmiss = (reg_re || reg_we ? ~|addr_hit : 1'b0);
+ localparam [35:0] rv_timer_reg_pkg_RV_TIMER_PERMIT = 36'b000101111111111111111111000100010001;
+ always @(*) begin
+ wr_err = 1'b0;
+ if ((addr_hit[0] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[32+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[32+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[1] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[28+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[28+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[2] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[24+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[24+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[3] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[20+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[20+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[4] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[16+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[16+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[5] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[12+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[12+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[6] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[8+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[8+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[7] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[4+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[4+:4] & reg_be)))
+ wr_err = 1'b1;
+ if ((addr_hit[8] && reg_we) && (rv_timer_reg_pkg_RV_TIMER_PERMIT[0+:4] != (rv_timer_reg_pkg_RV_TIMER_PERMIT[0+:4] & reg_be)))
+ wr_err = 1'b1;
+ end
+ assign ctrl_we = (addr_hit[0] & reg_we) & ~wr_err;
+ assign ctrl_wd = reg_wdata[0];
+ assign cfg0_prescale_we = (addr_hit[1] & reg_we) & ~wr_err;
+ assign cfg0_prescale_wd = reg_wdata[11:0];
+ assign cfg0_step_we = (addr_hit[1] & reg_we) & ~wr_err;
+ assign cfg0_step_wd = reg_wdata[23:16];
+ assign timer_v_lower0_we = (addr_hit[2] & reg_we) & ~wr_err;
+ assign timer_v_lower0_wd = reg_wdata[31:0];
+ assign timer_v_upper0_we = (addr_hit[3] & reg_we) & ~wr_err;
+ assign timer_v_upper0_wd = reg_wdata[31:0];
+ assign compare_lower0_0_we = (addr_hit[4] & reg_we) & ~wr_err;
+ assign compare_lower0_0_wd = reg_wdata[31:0];
+ assign compare_upper0_0_we = (addr_hit[5] & reg_we) & ~wr_err;
+ assign compare_upper0_0_wd = reg_wdata[31:0];
+ assign intr_enable0_we = (addr_hit[6] & reg_we) & ~wr_err;
+ assign intr_enable0_wd = reg_wdata[0];
+ assign intr_state0_we = (addr_hit[7] & reg_we) & ~wr_err;
+ assign intr_state0_wd = reg_wdata[0];
+ assign intr_test0_we = (addr_hit[8] & reg_we) & ~wr_err;
+ assign intr_test0_wd = reg_wdata[0];
+ always @(*) begin
+ reg_rdata_next = {32 {1'sb0}};
+ case (1'b1)
+ addr_hit[0]: reg_rdata_next[0] = ctrl_qs;
+ addr_hit[1]: begin
+ reg_rdata_next[11:0] = cfg0_prescale_qs;
+ reg_rdata_next[23:16] = cfg0_step_qs;
+ end
+ addr_hit[2]: reg_rdata_next[31:0] = timer_v_lower0_qs;
+ addr_hit[3]: reg_rdata_next[31:0] = timer_v_upper0_qs;
+ addr_hit[4]: reg_rdata_next[31:0] = compare_lower0_0_qs;
+ addr_hit[5]: reg_rdata_next[31:0] = compare_upper0_0_qs;
+ addr_hit[6]: reg_rdata_next[0] = intr_enable0_qs;
+ addr_hit[7]: reg_rdata_next[0] = intr_state0_qs;
+ addr_hit[8]: reg_rdata_next[0] = 1'b0;
+ default: reg_rdata_next = {32 {1'sb1}};
+ endcase
+ end
+endmodule
+module rv_timer (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ intr_timer_expired_0_0_o
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire intr_timer_expired_0_0_o;
+ localparam signed [31:0] N_HARTS = 1;
+ localparam signed [31:0] N_TIMERS = 1;
+ wire [154:0] reg2hw;
+ wire [67:0] hw2reg;
+ wire [0:0] active;
+ wire [11:0] prescaler;
+ wire [7:0] step;
+ wire [0:0] tick;
+ wire [63:0] mtime_d [0:0];
+ wire [63:0] mtime [0:0];
+ wire [63:0] mtimecmp;
+ wire mtimecmp_update [0:0][0:0];
+ wire [0:0] intr_timer_set;
+ wire [0:0] intr_timer_en;
+ wire [0:0] intr_timer_test_q;
+ wire [0:0] intr_timer_test_qe;
+ wire [0:0] intr_timer_state_q;
+ wire [0:0] intr_timer_state_de;
+ wire [0:0] intr_timer_state_d;
+ wire [0:0] intr_out;
+ assign active[0] = reg2hw[154];
+ assign prescaler = {reg2hw[153-:12]};
+ assign step = {reg2hw[141-:8]};
+ assign hw2reg[2] = tick[0];
+ assign hw2reg[35] = tick[0];
+ assign hw2reg[34-:32] = mtime_d[0][63:32];
+ assign hw2reg[67-:32] = mtime_d[0][31:0];
+ assign mtime[0] = {reg2hw[101-:32], reg2hw[133-:32]};
+ assign mtimecmp = {reg2hw[36-:32], reg2hw[69-:32]};
+ assign mtimecmp_update[0][0] = reg2hw[4] | reg2hw[37];
+ assign intr_timer_expired_0_0_o = intr_out[0];
+ assign intr_timer_en = reg2hw[3];
+ assign intr_timer_state_q = reg2hw[2];
+ assign intr_timer_test_q = reg2hw[1];
+ assign intr_timer_test_qe = reg2hw[0];
+ assign hw2reg[0] = intr_timer_state_de | mtimecmp_update[0][0];
+ assign hw2reg[1] = intr_timer_state_d & ~mtimecmp_update[0][0];
+ generate
+ genvar h;
+ for (h = 0; h < N_HARTS; h = h + 1) begin : gen_harts
+ prim_intr_hw #(.Width(N_TIMERS)) u_intr_hw(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .event_intr_i(intr_timer_set),
+ .reg2hw_intr_enable_q_i(intr_timer_en[h * N_TIMERS+:N_TIMERS]),
+ .reg2hw_intr_test_q_i(intr_timer_test_q[h * N_TIMERS+:N_TIMERS]),
+ .reg2hw_intr_test_qe_i(intr_timer_test_qe[h]),
+ .reg2hw_intr_state_q_i(intr_timer_state_q[h * N_TIMERS+:N_TIMERS]),
+ .hw2reg_intr_state_de_o(intr_timer_state_de),
+ .hw2reg_intr_state_d_o(intr_timer_state_d[h * N_TIMERS+:N_TIMERS]),
+ .intr_o(intr_out[h * N_TIMERS+:N_TIMERS])
+ );
+ timer_core #(.N(N_TIMERS)) u_core(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .active(active[h]),
+ .prescaler(prescaler[h * 12+:12]),
+ .step(step[h * 8+:8]),
+ .tick(tick[h]),
+ .mtime_d(mtime_d[h]),
+ .mtime(mtime[h]),
+ .mtimecmp(mtimecmp[64 * h+:64]),
+ .intr(intr_timer_set[h * N_TIMERS+:N_TIMERS])
+ );
+ end
+ endgenerate
+ rv_timer_reg_top u_reg(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_i),
+ .tl_o(tl_o),
+ .reg2hw(reg2hw),
+ .hw2reg(hw2reg),
+ .devmode_i(1'b1)
+ );
+endmodule
+/*
+module sky130_sram_4kbyte_1rw1r_32x1024_8 (
+ clk0,
+ csb0,
+ web0,
+ wmask0,
+ addr0,
+ din0,
+ dout0,
+ clk1,
+ csb1,
+ addr1,
+ dout1
+);
+ parameter NUM_WMASKS = 4;
+ parameter DATA_WIDTH = 32;
+ parameter ADDR_WIDTH = 10;
+ parameter RAM_DEPTH = 1 << ADDR_WIDTH;
+ parameter DELAY = 3;
+ parameter VERBOSE = 1;
+ parameter T_HOLD = 1;
+ input clk0;
+ input csb0;
+ input web0;
+ input [NUM_WMASKS - 1:0] wmask0;
+ input [ADDR_WIDTH - 1:0] addr0;
+ input [DATA_WIDTH - 1:0] din0;
+ output [DATA_WIDTH - 1:0] dout0;
+ input clk1;
+ input csb1;
+ input [ADDR_WIDTH - 1:0] addr1;
+ output [DATA_WIDTH - 1:0] dout1;
+ reg csb0_reg;
+ reg web0_reg;
+ reg [NUM_WMASKS - 1:0] wmask0_reg;
+ reg [ADDR_WIDTH - 1:0] addr0_reg;
+ reg [DATA_WIDTH - 1:0] din0_reg;
+ reg [DATA_WIDTH - 1:0] mem [0:RAM_DEPTH - 1];
+ always @(posedge clk0) begin
+ csb0_reg = csb0;
+ web0_reg = web0;
+ wmask0_reg = wmask0;
+ addr0_reg = addr0;
+ din0_reg = din0;
+ #(T_HOLD) dout0 = 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
+ if ((!csb0_reg && web0_reg) && VERBOSE)
+ $display($time, " Reading %m addr0=%b dout0=%b", addr0_reg, mem[addr0_reg]);
+ if ((!csb0_reg && !web0_reg) && VERBOSE)
+ $display($time, " Writing %m addr0=%b din0=%b wmask0=%b", addr0_reg, din0_reg, wmask0_reg);
+ end
+ reg csb1_reg;
+ reg [ADDR_WIDTH - 1:0] addr1_reg;
+ always @(posedge clk1) begin
+ csb1_reg = csb1;
+ addr1_reg = addr1;
+ if (((!csb0 && !web0) && !csb1) && (addr0 == addr1))
+ $display($time, " WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!", addr0, addr1);
+ #(T_HOLD) dout1 = 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
+ if (!csb1_reg && VERBOSE)
+ $display($time, " Reading %m addr1=%b dout1=%b", addr1_reg, mem[addr1_reg]);
+ end
+ always @(negedge clk0) begin : MEM_WRITE0
+ if (!csb0_reg && !web0_reg) begin
+ if (wmask0_reg[0])
+ mem[addr0_reg][7:0] = din0_reg[7:0];
+ if (wmask0_reg[1])
+ mem[addr0_reg][15:8] = din0_reg[15:8];
+ if (wmask0_reg[2])
+ mem[addr0_reg][23:16] = din0_reg[23:16];
+ if (wmask0_reg[3])
+ mem[addr0_reg][31:24] = din0_reg[31:24];
+ end
+ end
+ always @(negedge clk0) begin : MEM_READ0
+ if (!csb0_reg && web0_reg)
+ dout0 <= #(DELAY) mem[addr0_reg];
+ end
+ always @(negedge clk1) begin : MEM_READ1
+ if (!csb1_reg)
+ dout1 <= #(DELAY) mem[addr1_reg];
+ end
+endmodule*/
+module spi_clgen (
+ clk_i,
+ rst_ni,
+ enable,
+ go,
+ last_clk,
+ divider,
+ clk_out,
+ pos_edge,
+ neg_edge
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire enable;
+ input wire go;
+ input wire last_clk;
+ input wire [15:0] divider;
+ output reg clk_out;
+ output reg pos_edge;
+ output reg neg_edge;
+ reg [15:0] cnt;
+ wire cnt_zero;
+ wire cnt_one;
+ assign cnt_zero = cnt == {16 {1'b0}};
+ assign cnt_one = cnt == {{15 {1'b0}}, 1'b1};
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni)
+ cnt <= {16 {1'b1}};
+ else if (!enable || cnt_zero)
+ cnt <= divider;
+ else
+ cnt <= cnt - {{15 {1'b0}}, 1'b1};
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni)
+ clk_out <= 1'b0;
+ else
+ clk_out <= ((enable && cnt_zero) && (!last_clk || clk_out) ? ~clk_out : clk_out);
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni) begin
+ pos_edge <= 1'b0;
+ neg_edge <= 1'b0;
+ end
+ else begin
+ pos_edge <= (((enable && !clk_out) && cnt_one) || (!(|divider) && clk_out)) || ((!(|divider) && go) && !enable);
+ neg_edge <= ((enable && clk_out) && cnt_one) || ((!(|divider) && !clk_out) && enable);
+ end
+endmodule
+module spi_core (
+ clk_i,
+ rst_ni,
+ addr_i,
+ wdata_i,
+ rdata_o,
+ be_i,
+ we_i,
+ re_i,
+ error_o,
+ intr_rx_o,
+ intr_tx_o,
+ ss_o,
+ sclk_o,
+ sd_o,
+ sd_oe,
+ sd_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire [7:0] addr_i;
+ input wire [31:0] wdata_i;
+ output reg [31:0] rdata_o;
+ input wire [3:0] be_i;
+ input wire we_i;
+ input wire re_i;
+ output reg error_o;
+ output reg intr_rx_o;
+ output reg intr_tx_o;
+ output wire [3:0] ss_o;
+ output wire sclk_o;
+ output wire sd_o;
+ output reg sd_oe;
+ input wire sd_i;
+ reg [15:0] divider;
+ reg [15:0] ctrl;
+ reg [3:0] ss;
+ reg [31:0] wb_dat;
+ wire [31:0] rx;
+ wire rx_negedge;
+ wire tx_negedge;
+ wire [4:0] char_len;
+ wire go;
+ wire lsb;
+ wire ie;
+ wire ass;
+ wire spi_divider_sel;
+ wire spi_ctrl_sel;
+ wire spi_tx_sel;
+ wire spi_ss_sel;
+ wire tip;
+ wire pos_edge;
+ wire neg_edge;
+ wire last_bit;
+ wire tx_en;
+ wire rx_en;
+ assign spi_divider_sel = (we_i & ~re_i) & (addr_i[6:2] == 5);
+ assign spi_ctrl_sel = (we_i & ~re_i) & (addr_i[6:2] == 4);
+ assign spi_tx_sel = ((we_i & ~re_i) & (addr_i[6:2] == 0)) & tx_en;
+ assign spi_ss_sel = (we_i & ~re_i) & (addr_i[6:2] == 6);
+ always @(addr_i or rx or ctrl or divider or ss)
+ case (addr_i[6:2])
+ 8: wb_dat = rx[31:0];
+ 4: wb_dat = ctrl;
+ 5: wb_dat = divider;
+ 6: wb_dat = ss;
+ default: wb_dat = 32'b00000000000000000000000000000000;
+ endcase
+ always @(posedge clk_i)
+ if (~rst_ni)
+ rdata_o <= 32'b00000000000000000000000000000000;
+ else
+ rdata_o <= wb_dat;
+ wire [1:1] sv2v_tmp_46A40;
+ assign sv2v_tmp_46A40 = 1'b0;
+ always @(*) error_o = sv2v_tmp_46A40;
+ always @(posedge clk_i)
+ if (~rst_ni)
+ intr_tx_o <= 1'b0;
+ else if ((((ie && tip) && last_bit) && pos_edge) && tx_en)
+ intr_tx_o <= 1'b1;
+ else
+ intr_tx_o <= 1'b0;
+ always @(posedge clk_i)
+ if (~rst_ni)
+ intr_rx_o <= 1'b0;
+ else if ((((ie && tip) && last_bit) && pos_edge) && rx_en)
+ intr_rx_o <= 1'b1;
+ else
+ intr_rx_o <= 1'b0;
+ always @(posedge clk_i)
+ if (~rst_ni)
+ divider <= {16 {1'b0}};
+ else if ((spi_divider_sel && we_i) && !tip) begin
+ if (be_i[0])
+ divider[7:0] <= wdata_i[7:0];
+ if (be_i[1])
+ divider[15:8] <= wdata_i[15:8];
+ end
+ always @(posedge clk_i)
+ if (~rst_ni)
+ ctrl <= {16 {1'b0}};
+ else if ((spi_ctrl_sel && we_i) && !tip) begin
+ if (be_i[0])
+ ctrl[7:0] <= wdata_i[7:0] | {7'b0000000, ctrl[0]};
+ if (be_i[1])
+ ctrl[15:8] <= wdata_i[15:8];
+ end
+ else if ((tip && last_bit) && pos_edge)
+ ctrl[8] <= 1'b0;
+ assign rx_negedge = ctrl[9];
+ assign tx_negedge = ctrl[10];
+ assign go = ctrl[8];
+ assign char_len = ctrl[6:0];
+ assign lsb = ctrl[11];
+ assign ie = ctrl[12];
+ assign ass = ctrl[13];
+ assign rx_en = ctrl[15];
+ assign tx_en = ctrl[14];
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni)
+ sd_oe <= 1'b0;
+ else if (tx_en & !rx_en)
+ sd_oe <= 1'b1;
+ else
+ sd_oe <= 1'b0;
+ always @(posedge clk_i)
+ if (~rst_ni)
+ ss <= {4 {1'b0}};
+ else if ((spi_ss_sel && we_i) && !tip)
+ if (be_i[0])
+ ss <= wdata_i[3:0];
+ assign ss_o = ~((ss & {4 {tip & ass}}) | (ss & {4 {!ass}}));
+ spi_clgen clgen(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .go(go),
+ .enable(tip),
+ .last_clk(last_bit),
+ .divider(divider),
+ .clk_out(sclk_o),
+ .pos_edge(pos_edge),
+ .neg_edge(neg_edge)
+ );
+ spi_shift shift(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .len(char_len[4:0]),
+ .latch(spi_tx_sel & we_i),
+ .byte_sel(be_i),
+ .lsb(lsb),
+ .go(go),
+ .pos_edge(pos_edge),
+ .neg_edge(neg_edge),
+ .rx_negedge(rx_negedge),
+ .tx_negedge(tx_negedge),
+ .tip(tip),
+ .last(last_bit),
+ .p_in(wdata_i),
+ .p_out(rx),
+ .s_clk(sclk_o),
+ .s_in(sd_i),
+ .s_out(sd_o),
+ .rx_en(rx_en)
+ );
+endmodule
+module spi_shift (
+ clk_i,
+ rst_ni,
+ latch,
+ byte_sel,
+ len,
+ lsb,
+ go,
+ pos_edge,
+ neg_edge,
+ rx_negedge,
+ tx_negedge,
+ tip,
+ last,
+ p_in,
+ p_out,
+ s_clk,
+ s_in,
+ s_out,
+ rx_en
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire latch;
+ input wire [3:0] byte_sel;
+ input wire [4:0] len;
+ input wire lsb;
+ input wire go;
+ input wire pos_edge;
+ input wire neg_edge;
+ input wire rx_negedge;
+ input wire tx_negedge;
+ output reg tip;
+ output wire last;
+ input wire [31:0] p_in;
+ output wire [31:0] p_out;
+ input wire s_clk;
+ input wire s_in;
+ output reg s_out;
+ input wire rx_en;
+ reg [5:0] cnt;
+ reg [31:0] data;
+ reg [31:0] data_rx;
+ wire [5:0] tx_bit_pos;
+ wire [5:0] rx_bit_pos;
+ wire rx_clk_i;
+ wire tx_clk_i;
+ assign p_out = data_rx;
+ assign tx_bit_pos = (lsb ? {!(|len), len} - cnt : cnt - {{5 {1'b0}}, 1'b1});
+ assign rx_bit_pos = (lsb ? {!(|len), len} - (rx_negedge ? cnt + {{5 {1'b0}}, 1'b1} : cnt) : (rx_negedge ? cnt : cnt - {{5 {1'b0}}, 1'b1}));
+ assign last = !(|cnt);
+ assign rx_clk_i = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk);
+ assign tx_clk_i = (tx_negedge ? neg_edge : pos_edge) && !last;
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni)
+ cnt <= {6 {1'b0}};
+ else if (tip)
+ cnt <= (pos_edge ? cnt - {{5 {1'b0}}, 1'b1} : cnt);
+ else
+ cnt <= (!(|len) ? {1'b1, {5 {1'b0}}} : {1'b0, len});
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni)
+ tip <= 1'b0;
+ else if (go && ~tip)
+ tip <= 1'b1;
+ else if ((tip && last) && pos_edge)
+ tip <= 1'b0;
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni)
+ s_out <= 1'b0;
+ else
+ s_out <= (tx_clk_i || !tip ? data[tx_bit_pos[4:0]] : s_out);
+ always @(posedge clk_i)
+ if (~rst_ni)
+ data <= {32 {1'b0}};
+ else if (latch && !tip) begin
+ if (byte_sel[0])
+ data[7:0] <= p_in[7:0];
+ if (byte_sel[1])
+ data[15:8] <= p_in[15:8];
+ if (byte_sel[2])
+ data[23:16] <= p_in[23:16];
+ if (byte_sel[3])
+ data[31:24] <= p_in[31:24];
+ end
+ else if (rx_en && tip)
+ data_rx[rx_bit_pos[4:0]] <= (rx_clk_i ? s_in : data_rx[rx_bit_pos[4:0]]);
+endmodule
+module spi_top (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ intr_rx_o,
+ intr_tx_o,
+ ss_o,
+ sclk_o,
+ sd_o,
+ sd_oe,
+ sd_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire intr_rx_o;
+ output wire intr_tx_o;
+ output wire [3:0] ss_o;
+ output wire sclk_o;
+ output wire sd_o;
+ output wire sd_oe;
+ input wire sd_i;
+ localparam signed [31:0] AW = 8;
+ localparam signed [31:0] DW = 32;
+ wire re;
+ wire we;
+ wire [7:0] addr;
+ wire [31:0] wdata;
+ wire [3:0] be;
+ wire [31:0] rdata;
+ wire err;
+ spi_core spi_host(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .addr_i(addr),
+ .wdata_i(wdata),
+ .rdata_o(rdata),
+ .be_i(be),
+ .we_i(we),
+ .re_i(re),
+ .error_o(err),
+ .intr_rx_o(intr_rx_o),
+ .intr_tx_o(intr_tx_o),
+ .ss_o(ss_o),
+ .sclk_o(sclk_o),
+ .sd_o(sd_o),
+ .sd_oe(sd_oe),
+ .sd_i(sd_i)
+ );
+ tlul_adapter_reg #(
+ .RegAw(AW),
+ .RegDw(DW)
+ ) u_reg_if(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_i),
+ .tl_o(tl_o),
+ .we_o(we),
+ .re_o(re),
+ .addr_o(addr),
+ .wdata_o(wdata),
+ .be_o(be),
+ .rdata_i(rdata),
+ .error_i(err)
+ );
+endmodule
+module timer_core (
+ clk_i,
+ rst_ni,
+ active,
+ prescaler,
+ step,
+ tick,
+ mtime_d,
+ mtime,
+ mtimecmp,
+ intr
+);
+ parameter signed [31:0] N = 1;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire active;
+ input wire [11:0] prescaler;
+ input wire [7:0] step;
+ output wire tick;
+ output wire [63:0] mtime_d;
+ input wire [63:0] mtime;
+ input wire [(0 >= (N - 1) ? ((2 - N) * 64) + (((N - 1) * 64) - 1) : (N * 64) - 1):(0 >= (N - 1) ? (N - 1) * 64 : 0)] mtimecmp;
+ output wire [N - 1:0] intr;
+ reg [11:0] tick_count;
+ always @(posedge clk_i or negedge rst_ni) begin : generate_tick
+ if (!rst_ni)
+ tick_count <= 12'h000;
+ else if (!active)
+ tick_count <= 12'h000;
+ else if (tick_count == prescaler)
+ tick_count <= 12'h000;
+ else
+ tick_count <= tick_count + 1'b1;
+ end
+ assign tick = active & (tick_count >= prescaler);
+ function automatic [63:0] sv2v_cast_64;
+ input reg [63:0] inp;
+ sv2v_cast_64 = inp;
+ endfunction
+ assign mtime_d = mtime + sv2v_cast_64(step);
+ generate
+ genvar t;
+ for (t = 0; t < N; t = t + 1) begin : gen_intr
+ assign intr[t] = active & (mtime >= mtimecmp[(0 >= (N - 1) ? t : (N - 1) - t) * 64+:64]);
+ end
+ endgenerate
+endmodule
+module tlul_adapter_reg (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ re_o,
+ we_o,
+ addr_o,
+ wdata_o,
+ be_o,
+ rdata_i,
+ error_i
+);
+ parameter signed [31:0] RegAw = 8;
+ parameter signed [31:0] RegDw = 32;
+ localparam signed [31:0] RegBw = RegDw / 8;
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire re_o;
+ output wire we_o;
+ output wire [RegAw - 1:0] addr_o;
+ output wire [RegDw - 1:0] wdata_o;
+ output wire [RegBw - 1:0] be_o;
+ input wire [RegDw - 1:0] rdata_i;
+ input wire error_i;
+ localparam signed [31:0] IW = 8;
+ localparam signed [31:0] SZW = 2;
+ reg outstanding;
+ wire a_ack;
+ wire d_ack;
+ reg [RegDw - 1:0] rdata;
+ reg error;
+ wire err_internal;
+ reg addr_align_err;
+ wire tl_err;
+ reg [7:0] reqid;
+ reg [1:0] reqsz;
+ reg [2:0] rspop;
+ wire rd_req;
+ wire wr_req;
+ assign a_ack = tl_i[85] & tl_o[0];
+ assign d_ack = tl_o[51] & tl_i[0];
+ localparam [2:0] tlul_pkg_PutFullData = 3'h0;
+ localparam [2:0] tlul_pkg_PutPartialData = 3'h1;
+ assign wr_req = a_ack & ((tl_i[84-:3] == tlul_pkg_PutFullData) | (tl_i[84-:3] == tlul_pkg_PutPartialData));
+ localparam [2:0] tlul_pkg_Get = 3'h4;
+ assign rd_req = a_ack & (tl_i[84-:3] == tlul_pkg_Get);
+ assign we_o = wr_req & ~err_internal;
+ assign re_o = rd_req & ~err_internal;
+ assign addr_o = {tl_i[36 + RegAw:39], 2'b00};
+ assign wdata_o = tl_i[tlul_pkg_TL_DW-:tlul_pkg_TL_DW];
+ assign be_o = tl_i[36-:4];
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ outstanding <= 1'b0;
+ else if (a_ack)
+ outstanding <= 1'b1;
+ else if (d_ack)
+ outstanding <= 1'b0;
+ localparam [2:0] tlul_pkg_AccessAck = 3'h0;
+ localparam [2:0] tlul_pkg_AccessAckData = 3'h1;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ reqid <= {8 {1'sb0}};
+ reqsz <= {2 {1'sb0}};
+ rspop <= tlul_pkg_AccessAck;
+ end
+ else if (a_ack) begin
+ reqid <= tl_i[76-:8];
+ reqsz <= tl_i[78-:2];
+ rspop <= (rd_req ? tlul_pkg_AccessAckData : tlul_pkg_AccessAck);
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ rdata <= {RegDw {1'sb0}};
+ error <= 1'b0;
+ end
+ else if (a_ack) begin
+ rdata <= (err_internal ? {RegDw {1'sb1}} : rdata_i);
+ error <= error_i | err_internal;
+ end
+ function automatic [1:0] sv2v_cast_87F6B;
+ input reg [1:0] inp;
+ sv2v_cast_87F6B = inp;
+ endfunction
+ function automatic [7:0] sv2v_cast_89DD5;
+ input reg [7:0] inp;
+ sv2v_cast_89DD5 = inp;
+ endfunction
+ function automatic [0:0] sv2v_cast_4D96F;
+ input reg [0:0] inp;
+ sv2v_cast_4D96F = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_F21A2;
+ input reg [31:0] inp;
+ sv2v_cast_F21A2 = inp;
+ endfunction
+ assign tl_o = {outstanding, rspop, 3'b000, sv2v_cast_87F6B(reqsz), sv2v_cast_89DD5(reqid), sv2v_cast_4D96F(1'sb0), sv2v_cast_F21A2(rdata), error, ~outstanding};
+ assign err_internal = addr_align_err | tl_err;
+ always @(*)
+ if (wr_req)
+ addr_align_err = |tl_i[38:37];
+ else
+ addr_align_err = 1'b0;
+ tlul_err u_err(
+ .tl_i(tl_i),
+ .err_o(tl_err)
+ );
+endmodule
+module tlul_err_resp (
+ clk_i,
+ rst_ni,
+ tl_h_i,
+ tl_h_o
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_h_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_h_o;
+ reg [2:0] err_opcode;
+ reg [7:0] err_source;
+ reg [1:0] err_size;
+ reg err_req_pending;
+ reg err_rsp_pending;
+ localparam [2:0] tlul_pkg_Get = 3'h4;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ err_req_pending <= 1'b0;
+ err_source <= {tlul_pkg_TL_AIW {1'b0}};
+ err_opcode <= tlul_pkg_Get;
+ err_size <= {2 {1'sb0}};
+ end
+ else if (tl_h_i[85] && tl_h_o[0]) begin
+ err_req_pending <= 1'b1;
+ err_source <= tl_h_i[76-:8];
+ err_opcode <= tl_h_i[84-:3];
+ err_size <= tl_h_i[78-:2];
+ end
+ else if (!err_rsp_pending)
+ err_req_pending <= 1'b0;
+ assign tl_h_o[0] = ~err_rsp_pending & ~(err_req_pending & ~tl_h_i[0]);
+ assign tl_h_o[51] = err_req_pending | err_rsp_pending;
+ assign tl_h_o[33-:tlul_pkg_TL_DW] = {32 {1'sb1}};
+ assign tl_h_o[42-:8] = err_source;
+ assign tl_h_o[34-:1] = 1'b0;
+ assign tl_h_o[47-:3] = {3 {1'sb0}};
+ assign tl_h_o[44-:2] = err_size;
+ localparam [2:0] tlul_pkg_AccessAck = 3'h0;
+ localparam [2:0] tlul_pkg_AccessAckData = 3'h1;
+ assign tl_h_o[50-:3] = (err_opcode == tlul_pkg_Get ? tlul_pkg_AccessAckData : tlul_pkg_AccessAck);
+ assign tl_h_o[1] = 1'b1;
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni)
+ err_rsp_pending <= 1'b0;
+ else if ((err_req_pending || err_rsp_pending) && !tl_h_i[0])
+ err_rsp_pending <= 1'b1;
+ else
+ err_rsp_pending <= 1'b0;
+endmodule
+module tlul_err (
+ tl_i,
+ err_o
+);
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ output wire err_o;
+ localparam signed [31:0] IW = 8;
+ localparam signed [31:0] SZW = 2;
+ localparam signed [31:0] DW = 32;
+ localparam signed [31:0] MW = 4;
+ localparam signed [31:0] SubAW = 2;
+ wire opcode_allowed;
+ wire a_config_allowed;
+ wire op_full;
+ wire op_partial;
+ wire op_get;
+ localparam [2:0] tlul_pkg_PutFullData = 3'h0;
+ assign op_full = tl_i[84-:3] == tlul_pkg_PutFullData;
+ localparam [2:0] tlul_pkg_PutPartialData = 3'h1;
+ assign op_partial = tl_i[84-:3] == tlul_pkg_PutPartialData;
+ localparam [2:0] tlul_pkg_Get = 3'h4;
+ assign op_get = tl_i[84-:3] == tlul_pkg_Get;
+ assign err_o = ~(opcode_allowed & a_config_allowed);
+ assign opcode_allowed = ((tl_i[84-:3] == tlul_pkg_PutFullData) | (tl_i[84-:3] == tlul_pkg_PutPartialData)) | (tl_i[84-:3] == tlul_pkg_Get);
+ reg addr_sz_chk;
+ reg mask_chk;
+ reg fulldata_chk;
+ wire [3:0] mask;
+ assign mask = 1 << tl_i[38:37];
+ always @(*) begin
+ addr_sz_chk = 1'b0;
+ mask_chk = 1'b0;
+ fulldata_chk = 1'b0;
+ if (tl_i[85])
+ case (tl_i[78-:2])
+ 'h0: begin
+ addr_sz_chk = 1'b1;
+ mask_chk = ~|(tl_i[36-:4] & ~mask);
+ fulldata_chk = |(tl_i[36-:4] & mask);
+ end
+ 'h1: begin
+ addr_sz_chk = ~tl_i[37];
+ mask_chk = (tl_i[38] ? ~|(tl_i[36-:4] & 4'b0011) : ~|(tl_i[36-:4] & 4'b1100));
+ fulldata_chk = (tl_i[38] ? &tl_i[36:35] : &tl_i[34:33]);
+ end
+ 'h2: begin
+ addr_sz_chk = ~|tl_i[38:37];
+ mask_chk = 1'b1;
+ fulldata_chk = &tl_i[36:33];
+ end
+ default: begin
+ addr_sz_chk = 1'b0;
+ mask_chk = 1'b0;
+ fulldata_chk = 1'b0;
+ end
+ endcase
+ else begin
+ addr_sz_chk = 1'b0;
+ mask_chk = 1'b0;
+ fulldata_chk = 1'b0;
+ end
+ end
+ assign a_config_allowed = (addr_sz_chk & mask_chk) & ((op_get | op_partial) | fulldata_chk);
+endmodule
+module tlul_fifo_sync (
+ clk_i,
+ rst_ni,
+ tl_h_i,
+ tl_h_o,
+ tl_d_o,
+ tl_d_i,
+ spare_req_i,
+ spare_req_o,
+ spare_rsp_i,
+ spare_rsp_o
+);
+ parameter [0:0] ReqPass = 1'b1;
+ parameter [0:0] RspPass = 1'b1;
+ parameter [31:0] ReqDepth = 0;
+ parameter [31:0] RspDepth = 0;
+ parameter [31:0] SpareReqW = 1;
+ parameter [31:0] SpareRspW = 1;
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_h_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_h_o;
+ output wire [85:0] tl_d_o;
+ input wire [51:0] tl_d_i;
+ input [SpareReqW - 1:0] spare_req_i;
+ output [SpareReqW - 1:0] spare_req_o;
+ input [SpareRspW - 1:0] spare_rsp_i;
+ output [SpareRspW - 1:0] spare_rsp_o;
+ localparam [31:0] REQFIFO_WIDTH = 84 + SpareReqW;
+ fifo_sync #(
+ .Width(REQFIFO_WIDTH),
+ .Pass(ReqPass),
+ .Depth(ReqDepth)
+ ) reqfifo(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .clr_i(1'b0),
+ .wvalid_i(tl_h_i[85]),
+ .wready_o(tl_h_o[0]),
+ .wdata_i({tl_h_i[84-:3], tl_h_i[81-:3], tl_h_i[78-:2], tl_h_i[76-:8], tl_h_i[68-:32], tl_h_i[36-:4], tl_h_i[tlul_pkg_TL_DW-:tlul_pkg_TL_DW], spare_req_i}),
+ .depth_o(),
+ .rvalid_o(tl_d_o[85]),
+ .rready_i(tl_d_i[0]),
+ .rdata_o({tl_d_o[84-:3], tl_d_o[81-:3], tl_d_o[78-:2], tl_d_o[76-:8], tl_d_o[68-:32], tl_d_o[36-:4], tl_d_o[tlul_pkg_TL_DW-:tlul_pkg_TL_DW], spare_req_o})
+ );
+ localparam [31:0] RSPFIFO_WIDTH = 50 + SpareRspW;
+ localparam [2:0] tlul_pkg_AccessAckData = 3'h1;
+ fifo_sync #(
+ .Width(RSPFIFO_WIDTH),
+ .Pass(RspPass),
+ .Depth(RspDepth)
+ ) rspfifo(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .clr_i(1'b0),
+ .wvalid_i(tl_d_i[51]),
+ .wready_o(tl_d_o[0]),
+ .wdata_i({tl_d_i[50-:3], tl_d_i[47-:3], tl_d_i[44-:2], tl_d_i[42-:8], tl_d_i[34-:1], (tl_d_i[50-:3] == tlul_pkg_AccessAckData ? tl_d_i[33-:tlul_pkg_TL_DW] : {tlul_pkg_TL_DW {1'b0}}), tl_d_i[1], spare_rsp_i}),
+ .depth_o(),
+ .rvalid_o(tl_h_o[51]),
+ .rready_i(tl_h_i[0]),
+ .rdata_o({tl_h_o[50-:3], tl_h_o[47-:3], tl_h_o[44-:2], tl_h_o[42-:8], tl_h_o[34-:1], tl_h_o[33-:tlul_pkg_TL_DW], tl_h_o[1], spare_rsp_o})
+ );
+endmodule
+module tlul_host_adapter (
+ clk_i,
+ rst_ni,
+ req_i,
+ gnt_o,
+ addr_i,
+ we_i,
+ wdata_i,
+ be_i,
+ valid_o,
+ rdata_o,
+ err_o,
+ tl_h_c_a,
+ tl_h_c_d
+);
+ parameter [31:0] MAX_REQS = 1;
+ input wire clk_i;
+ input wire rst_ni;
+ input req_i;
+ output wire gnt_o;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ input wire [31:0] addr_i;
+ input wire we_i;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ input wire [31:0] wdata_i;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ input wire [3:0] be_i;
+ output wire valid_o;
+ output wire [31:0] rdata_o;
+ output wire err_o;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ output wire [85:0] tl_h_c_a;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ input wire [51:0] tl_h_c_d;
+ localparam signed [31:0] WordSize = 2;
+ wire [7:0] tl_source;
+ wire [3:0] tl_be;
+ function automatic [7:0] sv2v_cast_8;
+ input reg [7:0] inp;
+ sv2v_cast_8 = inp;
+ endfunction
+ generate
+ if (MAX_REQS == 1) begin
+ assign tl_source = {8 {1'sb0}};
+ end
+ else begin
+ localparam signed [31:0] ReqNumW = $clog2(MAX_REQS);
+ reg [ReqNumW - 1:0] source_d;
+ reg [ReqNumW - 1:0] source_q;
+ always @(posedge clk_i)
+ if (!rst_ni)
+ source_q <= {ReqNumW {1'sb0}};
+ else
+ source_q <= source_d;
+ always @(*) begin
+ source_d = source_q;
+ if (req_i && gnt_o)
+ if (source_q == (MAX_REQS - 1))
+ source_d = {ReqNumW {1'sb0}};
+ else
+ source_d = source_q + 1;
+ end
+ assign tl_source = sv2v_cast_8(source_q);
+ end
+ endgenerate
+ assign tl_be = (~we_i ? {tlul_pkg_TL_DBW {1'b1}} : be_i);
+ localparam [2:0] tlul_pkg_Get = 3'h4;
+ localparam [2:0] tlul_pkg_PutFullData = 3'h0;
+ localparam [2:0] tlul_pkg_PutPartialData = 3'h1;
+ function automatic signed [1:0] sv2v_cast_6CB2A_signed;
+ input reg signed [1:0] inp;
+ sv2v_cast_6CB2A_signed = inp;
+ endfunction
+ function automatic [1:0] sv2v_cast_C1DF5;
+ input reg [1:0] inp;
+ sv2v_cast_C1DF5 = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_FABF2;
+ input reg [31:0] inp;
+ sv2v_cast_FABF2 = inp;
+ endfunction
+ assign tl_h_c_a = {req_i, (~we_i ? tlul_pkg_Get : (&be_i ? tlul_pkg_PutFullData : tlul_pkg_PutPartialData)), 3'h0, sv2v_cast_C1DF5(sv2v_cast_6CB2A_signed(WordSize)), tl_source, sv2v_cast_FABF2({addr_i[31:WordSize], {WordSize {1'b0}}}), tl_be, wdata_i, 1'b1};
+ assign gnt_o = tl_h_c_d[0];
+ assign err_o = tl_h_c_d[1];
+ assign valid_o = tl_h_c_d[51];
+ wire [31:0] rddata;
+ assign rddata = tl_h_c_d[33-:tlul_pkg_TL_DW];
+ assign rdata_o = rddata;
+endmodule
+module tlul_socket_1n (
+ clk_i,
+ rst_ni,
+ tl_h_i,
+ tl_h_o,
+ tl_d_o,
+ tl_d_i,
+ dev_select_i
+);
+ parameter [31:0] N = 4;
+ parameter [0:0] HReqPass = 1'b1;
+ parameter [0:0] HRspPass = 1'b1;
+ parameter [N - 1:0] DReqPass = {N {1'b1}};
+ parameter [N - 1:0] DRspPass = {N {1'b1}};
+ parameter [3:0] HReqDepth = 4'h2;
+ parameter [3:0] HRspDepth = 4'h2;
+ parameter [(N * 4) - 1:0] DReqDepth = {N {4'h2}};
+ parameter [(N * 4) - 1:0] DRspDepth = {N {4'h2}};
+ localparam [31:0] NWD = $clog2(N + 1);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_h_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_h_o;
+ output wire [(0 >= (N - 1) ? ((2 - N) * 86) + (((N - 1) * 86) - 1) : (N * 86) - 1):(0 >= (N - 1) ? (N - 1) * 86 : 0)] tl_d_o;
+ input wire [(0 >= (N - 1) ? ((2 - N) * 52) + (((N - 1) * 52) - 1) : (N * 52) - 1):(0 >= (N - 1) ? (N - 1) * 52 : 0)] tl_d_i;
+ input wire [NWD - 1:0] dev_select_i;
+ wire [NWD - 1:0] dev_select_t;
+ wire [85:0] tl_t_o;
+ wire [51:0] tl_t_i;
+ tlul_fifo_sync #(
+ .ReqPass(HReqPass),
+ .RspPass(HRspPass),
+ .ReqDepth(HReqDepth),
+ .RspDepth(HRspDepth),
+ .SpareReqW(NWD)
+ ) fifo_h(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(tl_h_i),
+ .tl_h_o(tl_h_o),
+ .tl_d_o(tl_t_o),
+ .tl_d_i(tl_t_i),
+ .spare_req_i(dev_select_i),
+ .spare_req_o(dev_select_t),
+ .spare_rsp_i(1'b0),
+ .spare_rsp_o()
+ );
+ localparam signed [31:0] MaxOutstanding = 65536;
+ localparam signed [31:0] OutstandingW = 17;
+ reg [16:0] num_req_outstanding;
+ reg [NWD - 1:0] dev_select_outstanding;
+ wire hold_all_requests;
+ wire accept_t_req;
+ wire accept_t_rsp;
+ assign accept_t_req = tl_t_o[85] & tl_t_i[0];
+ assign accept_t_rsp = tl_t_i[51] & tl_t_o[0];
+ always @(posedge clk_i or negedge rst_ni)
+ if (!rst_ni) begin
+ num_req_outstanding <= {17 {1'sb0}};
+ dev_select_outstanding <= {NWD {1'sb0}};
+ end
+ else if (accept_t_req) begin
+ if (!accept_t_rsp)
+ num_req_outstanding <= num_req_outstanding + 1'b1;
+ dev_select_outstanding <= dev_select_t;
+ end
+ else if (accept_t_rsp)
+ num_req_outstanding <= num_req_outstanding - 1'b1;
+ assign hold_all_requests = (num_req_outstanding != {17 {1'sb0}}) & (dev_select_t != dev_select_outstanding);
+ wire [85:0] tl_u_o [0:N];
+ wire [51:0] tl_u_i [0:N];
+ generate
+ genvar i;
+ for (i = 0; i < N; i = i + 1) begin : gen_u_o
+ function automatic signed [NWD - 1:0] sv2v_cast_BB804_signed;
+ input reg signed [NWD - 1:0] inp;
+ sv2v_cast_BB804_signed = inp;
+ endfunction
+ assign tl_u_o[i][85] = (tl_t_o[85] & (dev_select_t == sv2v_cast_BB804_signed(i))) & ~hold_all_requests;
+ assign tl_u_o[i][84-:3] = tl_t_o[84-:3];
+ assign tl_u_o[i][81-:3] = tl_t_o[81-:3];
+ assign tl_u_o[i][78-:2] = tl_t_o[78-:2];
+ assign tl_u_o[i][76-:8] = tl_t_o[76-:8];
+ assign tl_u_o[i][68-:32] = tl_t_o[68-:32];
+ assign tl_u_o[i][36-:4] = tl_t_o[36-:4];
+ assign tl_u_o[i][tlul_pkg_TL_DW-:tlul_pkg_TL_DW] = tl_t_o[tlul_pkg_TL_DW-:tlul_pkg_TL_DW];
+ end
+ endgenerate
+ reg [51:0] tl_t_p;
+ reg hfifo_reqready;
+ function automatic signed [NWD - 1:0] sv2v_cast_BB804_signed;
+ input reg signed [NWD - 1:0] inp;
+ sv2v_cast_BB804_signed = inp;
+ endfunction
+ always @(*) begin
+ hfifo_reqready = tl_u_i[N][0];
+ begin : sv2v_autoblock_137
+ reg signed [31:0] idx;
+ for (idx = 0; idx < N; idx = idx + 1)
+ if (dev_select_t == sv2v_cast_BB804_signed(idx))
+ hfifo_reqready = tl_u_i[idx][0];
+ end
+ if (hold_all_requests)
+ hfifo_reqready = 1'b0;
+ end
+ assign tl_t_i[0] = tl_t_o[85] & hfifo_reqready;
+ always @(*) begin
+ tl_t_p = tl_u_i[N];
+ begin : sv2v_autoblock_138
+ reg signed [31:0] idx;
+ for (idx = 0; idx < N; idx = idx + 1)
+ if (dev_select_outstanding == sv2v_cast_BB804_signed(idx))
+ tl_t_p = tl_u_i[idx];
+ end
+ end
+ assign tl_t_i[51] = tl_t_p[51];
+ assign tl_t_i[50-:3] = tl_t_p[50-:3];
+ assign tl_t_i[47-:3] = tl_t_p[47-:3];
+ assign tl_t_i[44-:2] = tl_t_p[44-:2];
+ assign tl_t_i[42-:8] = tl_t_p[42-:8];
+ assign tl_t_i[34-:1] = tl_t_p[34-:1];
+ assign tl_t_i[33-:tlul_pkg_TL_DW] = tl_t_p[33-:tlul_pkg_TL_DW];
+ assign tl_t_i[1] = tl_t_p[1];
+ generate
+ for (i = 0; i < (N + 1); i = i + 1) begin : gen_u_o_d_ready
+ assign tl_u_o[i][0] = tl_t_o[0];
+ end
+ endgenerate
+ generate
+ for (i = 0; i < N; i = i + 1) begin : gen_dfifo
+ tlul_fifo_sync #(
+ .ReqPass(DReqPass[i]),
+ .RspPass(DRspPass[i]),
+ .ReqDepth(DReqDepth[i * 4+:4]),
+ .RspDepth(DRspDepth[i * 4+:4])
+ ) fifo_d(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(tl_u_o[i]),
+ .tl_h_o(tl_u_i[i]),
+ .tl_d_o(tl_d_o[(0 >= (N - 1) ? i : (N - 1) - i) * 86+:86]),
+ .tl_d_i(tl_d_i[(0 >= (N - 1) ? i : (N - 1) - i) * 52+:52]),
+ .spare_req_i(1'b0),
+ .spare_req_o(),
+ .spare_rsp_i(1'b0),
+ .spare_rsp_o()
+ );
+ end
+ endgenerate
+ function automatic [NWD - 1:0] sv2v_cast_BB804;
+ input reg [NWD - 1:0] inp;
+ sv2v_cast_BB804 = inp;
+ endfunction
+ assign tl_u_o[N][85] = (tl_t_o[85] & (dev_select_t == sv2v_cast_BB804(N))) & ~hold_all_requests;
+ assign tl_u_o[N][84-:3] = tl_t_o[84-:3];
+ assign tl_u_o[N][81-:3] = tl_t_o[81-:3];
+ assign tl_u_o[N][78-:2] = tl_t_o[78-:2];
+ assign tl_u_o[N][76-:8] = tl_t_o[76-:8];
+ assign tl_u_o[N][68-:32] = tl_t_o[68-:32];
+ assign tl_u_o[N][36-:4] = tl_t_o[36-:4];
+ assign tl_u_o[N][tlul_pkg_TL_DW-:tlul_pkg_TL_DW] = tl_t_o[tlul_pkg_TL_DW-:tlul_pkg_TL_DW];
+ tlul_err_resp err_resp(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(tl_u_o[N]),
+ .tl_h_o(tl_u_i[N])
+ );
+endmodule
+module tlul_socket_m1 (
+ clk_i,
+ rst_ni,
+ tl_h_i,
+ tl_h_o,
+ tl_d_o,
+ tl_d_i
+);
+ parameter [31:0] M = 4;
+ parameter [M - 1:0] HReqPass = {M {1'b1}};
+ parameter [M - 1:0] HRspPass = {M {1'b1}};
+ parameter [(M * 4) - 1:0] HReqDepth = {M {4'h2}};
+ parameter [(M * 4) - 1:0] HRspDepth = {M {4'h2}};
+ parameter [0:0] DReqPass = 1'b1;
+ parameter [0:0] DRspPass = 1'b1;
+ parameter [3:0] DReqDepth = 4'h2;
+ parameter [3:0] DRspDepth = 4'h2;
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [(0 >= (M - 1) ? ((2 - M) * 86) + (((M - 1) * 86) - 1) : (M * 86) - 1):(0 >= (M - 1) ? (M - 1) * 86 : 0)] tl_h_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [(0 >= (M - 1) ? ((2 - M) * 52) + (((M - 1) * 52) - 1) : (M * 52) - 1):(0 >= (M - 1) ? (M - 1) * 52 : 0)] tl_h_o;
+ output wire [85:0] tl_d_o;
+ input wire [51:0] tl_d_i;
+ localparam [31:0] IDW = tlul_pkg_TL_AIW;
+ localparam [31:0] STIDW = $clog2(M);
+ wire [(0 >= (M - 1) ? ((2 - M) * 86) + (((M - 1) * 86) - 1) : (M * 86) - 1):(0 >= (M - 1) ? (M - 1) * 86 : 0)] hreq_fifo_o;
+ wire [51:0] hrsp_fifo_i [0:M - 1];
+ wire [M - 1:0] hrequest;
+ wire [M - 1:0] hgrant;
+ wire [85:0] dreq_fifo_i;
+ wire [51:0] drsp_fifo_o;
+ wire arb_valid;
+ wire arb_ready;
+ wire [85:0] arb_data;
+ generate
+ genvar i;
+ for (i = 0; i < M; i = i + 1) begin : gen_host_fifo
+ wire [85:0] hreq_fifo_i;
+ wire [STIDW - 1:0] reqid_sub;
+ wire [7:0] shifted_id;
+ assign reqid_sub = i;
+ assign shifted_id = {tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 69+:IDW - STIDW], reqid_sub};
+ wire [7:IDW - STIDW] unused_tl_h_source;
+ assign unused_tl_h_source = tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 76-:STIDW];
+ function automatic [2:0] sv2v_cast_3;
+ input reg [2:0] inp;
+ sv2v_cast_3 = inp;
+ endfunction
+ function automatic [1:0] sv2v_cast_539D2;
+ input reg [1:0] inp;
+ sv2v_cast_539D2 = inp;
+ endfunction
+ function automatic [7:0] sv2v_cast_F6BCE;
+ input reg [7:0] inp;
+ sv2v_cast_F6BCE = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_C6CCE;
+ input reg [31:0] inp;
+ sv2v_cast_C6CCE = inp;
+ endfunction
+ function automatic [3:0] sv2v_cast_45434;
+ input reg [3:0] inp;
+ sv2v_cast_45434 = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_486C6;
+ input reg [31:0] inp;
+ sv2v_cast_486C6 = inp;
+ endfunction
+ assign hreq_fifo_i = {tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 85], sv2v_cast_3(tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 84-:3]), sv2v_cast_3(tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 81-:3]), sv2v_cast_539D2(tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 78-:2]), sv2v_cast_F6BCE(shifted_id), sv2v_cast_C6CCE(tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 68-:32]), sv2v_cast_45434(tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 36-:4]), sv2v_cast_486C6(tl_h_i[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + tlul_pkg_TL_DW-:tlul_pkg_TL_DW]), tl_h_i[(0 >= (M - 1) ? i : (M - 1) - i) * 86]};
+ tlul_fifo_sync #(
+ .ReqPass(HReqPass[i]),
+ .RspPass(HRspPass[i]),
+ .ReqDepth(HReqDepth[i * 4+:4]),
+ .RspDepth(HRspDepth[i * 4+:4]),
+ .SpareReqW(1)
+ ) u_hostfifo(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(hreq_fifo_i),
+ .tl_h_o(tl_h_o[(0 >= (M - 1) ? i : (M - 1) - i) * 52+:52]),
+ .tl_d_o(hreq_fifo_o[(0 >= (M - 1) ? i : (M - 1) - i) * 86+:86]),
+ .tl_d_i(hrsp_fifo_i[i]),
+ .spare_req_i(1'b0),
+ .spare_req_o(),
+ .spare_rsp_i(1'b0),
+ .spare_rsp_o()
+ );
+ end
+ endgenerate
+ tlul_fifo_sync #(
+ .ReqPass(DReqPass),
+ .RspPass(DRspPass),
+ .ReqDepth(DReqDepth),
+ .RspDepth(DRspDepth),
+ .SpareReqW(1)
+ ) u_devicefifo(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(dreq_fifo_i),
+ .tl_h_o(drsp_fifo_o),
+ .tl_d_o(tl_d_o),
+ .tl_d_i(tl_d_i),
+ .spare_req_i(1'b0),
+ .spare_req_o(),
+ .spare_rsp_i(1'b0),
+ .spare_rsp_o()
+ );
+ generate
+ for (i = 0; i < M; i = i + 1) begin : gen_arbreqgnt
+ assign hrequest[i] = hreq_fifo_o[((0 >= (M - 1) ? i : (M - 1) - i) * 86) + 85];
+ end
+ endgenerate
+ assign arb_ready = drsp_fifo_o[0];
+ localparam tlul_pkg_ArbiterImpl = "PPC";
+ generate
+ if (tlul_pkg_ArbiterImpl == "PPC") begin : gen_arb_ppc
+ prim_arbiter_ppc #(
+ .N(M),
+ .DW(86),
+ .EnReqStabA(0)
+ ) u_reqarb(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .req_i(hrequest),
+ .data_i(hreq_fifo_o),
+ .gnt_o(hgrant),
+ .idx_o(),
+ .valid_o(arb_valid),
+ .data_o(arb_data),
+ .ready_i(arb_ready)
+ );
+ end
+ else if (tlul_pkg_ArbiterImpl == "BINTREE") begin : gen_tree_arb
+ prim_arbiter_tree #(
+ .N(M),
+ .DW(86),
+ .EnReqStabA(0)
+ ) u_reqarb(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .req_i(hrequest),
+ .data_i(hreq_fifo_o),
+ .gnt_o(hgrant),
+ .idx_o(),
+ .valid_o(arb_valid),
+ .data_o(arb_data),
+ .ready_i(arb_ready)
+ );
+ end
+ endgenerate
+ wire [M - 1:0] hfifo_rspvalid;
+ wire [M - 1:0] dfifo_rspready;
+ wire [7:0] hfifo_rspid;
+ wire dfifo_rspready_merged;
+ assign dfifo_rspready_merged = |dfifo_rspready;
+ function automatic [2:0] sv2v_cast_3;
+ input reg [2:0] inp;
+ sv2v_cast_3 = inp;
+ endfunction
+ function automatic [1:0] sv2v_cast_539D2;
+ input reg [1:0] inp;
+ sv2v_cast_539D2 = inp;
+ endfunction
+ function automatic [7:0] sv2v_cast_F6BCE;
+ input reg [7:0] inp;
+ sv2v_cast_F6BCE = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_C6CCE;
+ input reg [31:0] inp;
+ sv2v_cast_C6CCE = inp;
+ endfunction
+ function automatic [3:0] sv2v_cast_45434;
+ input reg [3:0] inp;
+ sv2v_cast_45434 = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_486C6;
+ input reg [31:0] inp;
+ sv2v_cast_486C6 = inp;
+ endfunction
+ assign dreq_fifo_i = {arb_valid, sv2v_cast_3(arb_data[84-:3]), sv2v_cast_3(arb_data[81-:3]), sv2v_cast_539D2(arb_data[78-:2]), sv2v_cast_F6BCE(arb_data[76-:8]), sv2v_cast_C6CCE(arb_data[68-:32]), sv2v_cast_45434(arb_data[36-:4]), sv2v_cast_486C6(arb_data[tlul_pkg_TL_DW-:tlul_pkg_TL_DW]), dfifo_rspready_merged};
+ assign hfifo_rspid = {{STIDW {1'b0}}, drsp_fifo_o[42:35 + STIDW]};
+ generate
+ for (i = 0; i < M; i = i + 1) begin : gen_idrouting
+ assign hfifo_rspvalid[i] = drsp_fifo_o[51] & (drsp_fifo_o[35+:STIDW] == i);
+ assign dfifo_rspready[i] = (hreq_fifo_o[(0 >= (M - 1) ? i : (M - 1) - i) * 86] & (drsp_fifo_o[35+:STIDW] == i)) & drsp_fifo_o[51];
+ function automatic [2:0] sv2v_cast_3;
+ input reg [2:0] inp;
+ sv2v_cast_3 = inp;
+ endfunction
+ function automatic [1:0] sv2v_cast_539D2;
+ input reg [1:0] inp;
+ sv2v_cast_539D2 = inp;
+ endfunction
+ function automatic [7:0] sv2v_cast_F6BCE;
+ input reg [7:0] inp;
+ sv2v_cast_F6BCE = inp;
+ endfunction
+ function automatic [0:0] sv2v_cast_D8FDD;
+ input reg [0:0] inp;
+ sv2v_cast_D8FDD = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_486C6;
+ input reg [31:0] inp;
+ sv2v_cast_486C6 = inp;
+ endfunction
+ assign hrsp_fifo_i[i] = {hfifo_rspvalid[i], sv2v_cast_3(drsp_fifo_o[50-:3]), sv2v_cast_3(drsp_fifo_o[47-:3]), sv2v_cast_539D2(drsp_fifo_o[44-:2]), sv2v_cast_F6BCE(hfifo_rspid), sv2v_cast_D8FDD(drsp_fifo_o[34-:1]), sv2v_cast_486C6(drsp_fifo_o[33-:tlul_pkg_TL_DW]), drsp_fifo_o[1], hgrant[i]};
+ end
+ endgenerate
+endmodule
+module tlul_sram_adapter (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ req_o,
+ gnt_i,
+ we_o,
+ addr_o,
+ wdata_o,
+ wmask_o,
+ rdata_i,
+ rvalid_i,
+ rerror_i
+);
+ parameter signed [31:0] SramAw = 12;
+ parameter signed [31:0] SramDw = 32;
+ parameter signed [31:0] Outstanding = 1;
+ parameter [0:0] ByteAccess = 1;
+ parameter [0:0] ErrOnWrite = 0;
+ parameter [0:0] ErrOnRead = 0;
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire req_o;
+ input wire gnt_i;
+ output wire we_o;
+ output wire [SramAw - 1:0] addr_o;
+ output wire [SramDw - 1:0] wdata_o;
+ output wire [SramDw - 1:0] wmask_o;
+ input wire [SramDw - 1:0] rdata_i;
+ input wire rvalid_i;
+ input wire [1:0] rerror_i;
+ localparam signed [31:0] SramByte = SramDw / 8;
+ function automatic integer tlul_pkg_vbits;
+ input integer value;
+ tlul_pkg_vbits = (value == 1 ? 1 : $clog2(value));
+ endfunction
+ localparam signed [31:0] DataBitWidth = tlul_pkg_vbits(SramByte);
+ localparam signed [31:0] WidthMult = SramDw / tlul_pkg_TL_DW;
+ localparam signed [31:0] WoffsetWidth = (SramByte == tlul_pkg_TL_DBW ? 1 : DataBitWidth - tlul_pkg_vbits(tlul_pkg_TL_DBW));
+ localparam signed [31:0] SramReqFifoWidth = tlul_pkg_TL_DBW + WoffsetWidth;
+ localparam signed [31:0] ReqFifoWidth = 13;
+ localparam signed [31:0] RspFifoWidth = (SramDw >= 0 ? SramDw + 1 : 1 - SramDw);
+ wire reqfifo_wvalid;
+ wire reqfifo_wready;
+ wire reqfifo_rvalid;
+ wire reqfifo_rready;
+ wire [12:0] reqfifo_wdata;
+ wire [12:0] reqfifo_rdata;
+ wire sramreqfifo_wvalid;
+ wire sramreqfifo_wready;
+ wire sramreqfifo_rready;
+ wire [(tlul_pkg_TL_DBW + WoffsetWidth) - 1:0] sramreqfifo_wdata;
+ wire [(tlul_pkg_TL_DBW + WoffsetWidth) - 1:0] sramreqfifo_rdata;
+ wire rspfifo_wvalid;
+ wire rspfifo_wready;
+ wire rspfifo_rvalid;
+ wire rspfifo_rready;
+ wire [SramDw:0] rspfifo_wdata;
+ wire [SramDw:0] rspfifo_rdata;
+ wire error_internal;
+ wire wr_attr_error;
+ wire wr_vld_error;
+ wire rd_vld_error;
+ wire tlul_error;
+ wire a_ack;
+ wire d_ack;
+ wire sram_ack;
+ assign a_ack = tl_i[85] & tl_o[0];
+ assign d_ack = tl_o[51] & tl_i[0];
+ assign sram_ack = req_o & gnt_i;
+ reg d_valid;
+ reg d_error;
+ localparam [1:0] OpRead = 1;
+ always @(*) begin
+ d_valid = 1'b0;
+ if (reqfifo_rvalid) begin
+ if (reqfifo_rdata[10])
+ d_valid = 1'b1;
+ else if (reqfifo_rdata[12-:2] == OpRead)
+ d_valid = rspfifo_rvalid;
+ else
+ d_valid = 1'b1;
+ end
+ else
+ d_valid = 1'b0;
+ end
+ always @(*) begin
+ d_error = 1'b0;
+ if (reqfifo_rvalid) begin
+ if (reqfifo_rdata[12-:2] == OpRead)
+ d_error = rspfifo_rdata[0] | reqfifo_rdata[10];
+ else
+ d_error = reqfifo_rdata[10];
+ end
+ else
+ d_error = 1'b0;
+ end
+ localparam [2:0] tlul_pkg_AccessAck = 3'h0;
+ localparam [2:0] tlul_pkg_AccessAckData = 3'h1;
+ function automatic [1:0] sv2v_cast_373C7;
+ input reg [1:0] inp;
+ sv2v_cast_373C7 = inp;
+ endfunction
+ function automatic [7:0] sv2v_cast_E8620;
+ input reg [7:0] inp;
+ sv2v_cast_E8620 = inp;
+ endfunction
+ function automatic [0:0] sv2v_cast_AF840;
+ input reg [0:0] inp;
+ sv2v_cast_AF840 = inp;
+ endfunction
+ function automatic [31:0] sv2v_cast_D61D5;
+ input reg [31:0] inp;
+ sv2v_cast_D61D5 = inp;
+ endfunction
+ assign tl_o = {d_valid, (d_valid && (reqfifo_rdata[12-:2] != OpRead) ? tlul_pkg_AccessAck : tlul_pkg_AccessAckData), 3'b000, sv2v_cast_373C7((d_valid ? reqfifo_rdata[9-:2] : {2 {1'sb0}})), sv2v_cast_E8620((d_valid ? reqfifo_rdata[7-:8] : {8 {1'sb0}})), sv2v_cast_AF840(1'b0), sv2v_cast_D61D5(((d_valid && rspfifo_rvalid) && (reqfifo_rdata[12-:2] == OpRead) ? rspfifo_rdata[SramDw-:(SramDw >= 1 ? SramDw : 2 - SramDw)] : {(SramDw >= 1 ? SramDw : 2 - SramDw) {1'sb0}})), d_valid && d_error, ((gnt_i | error_internal) & reqfifo_wready) & sramreqfifo_wready};
+ assign req_o = (tl_i[85] & reqfifo_wready) & ~error_internal;
+ localparam [2:0] tlul_pkg_PutFullData = 3'h0;
+ localparam [2:0] tlul_pkg_PutPartialData = 3'h1;
+ function automatic [0:0] sv2v_cast_1;
+ input reg [0:0] inp;
+ sv2v_cast_1 = inp;
+ endfunction
+ assign we_o = tl_i[85] & sv2v_cast_1(|{tl_i[84-:3] == tlul_pkg_PutFullData, tl_i[84-:3] == tlul_pkg_PutPartialData});
+ assign addr_o = (tl_i[85] ? tl_i[37 + DataBitWidth+:SramAw] : {SramAw {1'sb0}});
+ wire [WoffsetWidth - 1:0] woffset;
+ generate
+ if (tlul_pkg_TL_DW != SramDw) begin : gen_wordwidthadapt
+ assign woffset = tl_i[36 + DataBitWidth:37 + tlul_pkg_vbits(tlul_pkg_TL_DBW)];
+ end
+ else begin : gen_no_wordwidthadapt
+ assign woffset = {WoffsetWidth {1'sb0}};
+ end
+ endgenerate
+ reg [(WidthMult * tlul_pkg_TL_DW) - 1:0] wmask_int;
+ reg [(WidthMult * tlul_pkg_TL_DW) - 1:0] wdata_int;
+ always @(*) begin
+ wmask_int = {WidthMult * tlul_pkg_TL_DW {1'sb0}};
+ wdata_int = {WidthMult * tlul_pkg_TL_DW {1'sb0}};
+ if (tl_i[85]) begin : sv2v_autoblock_139
+ reg signed [31:0] i;
+ for (i = 0; i < 4; i = i + 1)
+ begin
+ wmask_int[(woffset * 32) + (8 * i)+:8] = {8 {tl_i[33 + i]}};
+ wdata_int[(woffset * 32) + (8 * i)+:8] = (tl_i[33 + i] && we_o ? tl_i[tlul_pkg_TL_DW - (31 - (8 * i))+:8] : {8 {1'sb0}});
+ end
+ end
+ end
+ assign wmask_o = wmask_int;
+ assign wdata_o = wdata_int;
+ assign wr_attr_error = ((tl_i[84-:3] == tlul_pkg_PutFullData) || (tl_i[84-:3] == tlul_pkg_PutPartialData) ? (ByteAccess == 0 ? (tl_i[36-:4] != {4 {1'sb1}}) || (tl_i[78-:2] != 2'h2) : 1'b0) : 1'b0);
+ localparam [2:0] tlul_pkg_Get = 3'h4;
+ generate
+ if (ErrOnWrite == 1) begin : gen_no_writes
+ assign wr_vld_error = tl_i[84-:3] != tlul_pkg_Get;
+ end
+ else begin : gen_writes_allowed
+ assign wr_vld_error = 1'b0;
+ end
+ endgenerate
+ generate
+ if (ErrOnRead == 1) begin : gen_no_reads
+ assign rd_vld_error = tl_i[84-:3] == tlul_pkg_Get;
+ end
+ else begin : gen_reads_allowed
+ assign rd_vld_error = 1'b0;
+ end
+ endgenerate
+ tlul_err u_err(
+ .tl_i(tl_i),
+ .err_o(tlul_error)
+ );
+ assign error_internal = ((wr_attr_error | wr_vld_error) | rd_vld_error) | tlul_error;
+ assign reqfifo_wvalid = a_ack;
+ localparam [1:0] OpWrite = 0;
+ assign reqfifo_wdata = {(tl_i[84-:3] != tlul_pkg_Get ? OpWrite : OpRead), error_internal, sv2v_cast_373C7(tl_i[78-:2]), sv2v_cast_E8620(tl_i[76-:8])};
+ assign reqfifo_rready = d_ack;
+ function automatic [3:0] sv2v_cast_43A59;
+ input reg [3:0] inp;
+ sv2v_cast_43A59 = inp;
+ endfunction
+ assign sramreqfifo_wdata = {sv2v_cast_43A59(tl_i[36-:4]), woffset};
+ assign sramreqfifo_wvalid = sram_ack & ~we_o;
+ assign sramreqfifo_rready = rspfifo_wvalid;
+ assign rspfifo_wvalid = rvalid_i & reqfifo_rvalid;
+ wire [(WidthMult * tlul_pkg_TL_DW) - 1:0] rdata;
+ reg [(WidthMult * tlul_pkg_TL_DW) - 1:0] rmask;
+ wire [31:0] rdata_tlword;
+ always @(*) begin
+ rmask = {WidthMult * tlul_pkg_TL_DW {1'sb0}};
+ begin : sv2v_autoblock_140
+ reg signed [31:0] i;
+ for (i = 0; i < 4; i = i + 1)
+ rmask[(sramreqfifo_rdata[WoffsetWidth - 1-:WoffsetWidth] * 32) + (8 * i)+:8] = {8 {sramreqfifo_rdata[(tlul_pkg_TL_DBW + (WoffsetWidth - 1)) - (3 - i)]}};
+ end
+ end
+ assign rdata = rdata_i & rmask;
+ assign rdata_tlword = rdata[sramreqfifo_rdata[WoffsetWidth - 1-:WoffsetWidth] * tlul_pkg_TL_DW+:tlul_pkg_TL_DW];
+ function automatic [SramDw - 1:0] sv2v_cast_1F998;
+ input reg [SramDw - 1:0] inp;
+ sv2v_cast_1F998 = inp;
+ endfunction
+ assign rspfifo_wdata = {sv2v_cast_1F998(rdata_tlword), rerror_i[1]};
+ assign rspfifo_rready = ((reqfifo_rdata[12-:2] == OpRead) & ~reqfifo_rdata[10] ? reqfifo_rready : 1'b0);
+ wire unused_rerror;
+ assign unused_rerror = rerror_i[0];
+ fifo_sync #(
+ .Width(ReqFifoWidth),
+ .Pass(1'b0),
+ .Depth(Outstanding)
+ ) u_reqfifo(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .clr_i(1'b0),
+ .wvalid_i(reqfifo_wvalid),
+ .wready_o(reqfifo_wready),
+ .wdata_i(reqfifo_wdata),
+ .depth_o(),
+ .rvalid_o(reqfifo_rvalid),
+ .rready_i(reqfifo_rready),
+ .rdata_o(reqfifo_rdata)
+ );
+ fifo_sync #(
+ .Width(SramReqFifoWidth),
+ .Pass(1'b0),
+ .Depth(Outstanding)
+ ) u_sramreqfifo(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .clr_i(1'b0),
+ .wvalid_i(sramreqfifo_wvalid),
+ .wready_o(sramreqfifo_wready),
+ .wdata_i(sramreqfifo_wdata),
+ .depth_o(),
+ .rvalid_o(),
+ .rready_i(sramreqfifo_rready),
+ .rdata_o(sramreqfifo_rdata)
+ );
+ fifo_sync #(
+ .Width(RspFifoWidth),
+ .Pass(1'b1),
+ .Depth(Outstanding)
+ ) u_rspfifo(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .clr_i(1'b0),
+ .wvalid_i(rspfifo_wvalid),
+ .wready_o(rspfifo_wready),
+ .wdata_i(rspfifo_wdata),
+ .depth_o(),
+ .rvalid_o(rspfifo_rvalid),
+ .rready_i(rspfifo_rready),
+ .rdata_o(rspfifo_rdata)
+ );
+endmodule
+module tl_xbar_main (
+ clk_i,
+ rst_ni,
+ tl_brqif_i,
+ tl_brqif_o,
+ tl_brqlsu_i,
+ tl_brqlsu_o,
+ tl_dm_sba_i,
+ tl_dm_sba_o,
+ tl_iccm_o,
+ tl_iccm_i,
+ tl_debug_rom_o,
+ tl_debug_rom_i,
+ tl_dccm_o,
+ tl_dccm_i,
+ tl_timer0_o,
+ tl_timer0_i,
+ tl_uart_o,
+ tl_uart_i,
+ tl_spi_o,
+ tl_spi_i,
+ tl_pwm_o,
+ tl_pwm_i,
+ tl_gpio_o,
+ tl_gpio_i,
+ tl_plic_o,
+ tl_plic_i
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_brqif_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_brqif_o;
+ input wire [85:0] tl_brqlsu_i;
+ output wire [51:0] tl_brqlsu_o;
+ input wire [85:0] tl_dm_sba_i;
+ output wire [51:0] tl_dm_sba_o;
+ output wire [85:0] tl_iccm_o;
+ input wire [51:0] tl_iccm_i;
+ output wire [85:0] tl_debug_rom_o;
+ input wire [51:0] tl_debug_rom_i;
+ output wire [85:0] tl_dccm_o;
+ input wire [51:0] tl_dccm_i;
+ output wire [85:0] tl_timer0_o;
+ input wire [51:0] tl_timer0_i;
+ output wire [85:0] tl_uart_o;
+ input wire [51:0] tl_uart_i;
+ output wire [85:0] tl_spi_o;
+ input wire [51:0] tl_spi_i;
+ output wire [85:0] tl_pwm_o;
+ input wire [51:0] tl_pwm_i;
+ output wire [85:0] tl_gpio_o;
+ input wire [51:0] tl_gpio_i;
+ output wire [85:0] tl_plic_o;
+ input wire [51:0] tl_plic_i;
+ wire [85:0] brqifu_to_s1n;
+ wire [51:0] s1n_to_brqifu;
+ reg [1:0] device_sel_1;
+ wire [85:0] brqlsu_to_s1n;
+ wire [51:0] s1n_to_brqlsu;
+ reg [3:0] device_sel_2;
+ wire [85:0] dbg_to_s1n;
+ wire [51:0] s1n_to_dbg;
+ reg [3:0] device_sel_3;
+ wire [171:0] h1_dv_i;
+ wire [103:0] h1_dv_o;
+ wire [773:0] h2_dv_i;
+ wire [467:0] h2_dv_o;
+ wire [687:0] h3_dv_i;
+ wire [415:0] h3_dv_o;
+ wire [257:0] s1n_sm1_1;
+ wire [155:0] sm1_s1n_1;
+ wire [171:0] s1n_sm1_2;
+ wire [103:0] sm1_s1n_2;
+ wire [171:0] s1n_sm1_4;
+ wire [103:0] sm1_s1n_4;
+ wire [171:0] s1n_sm1_5;
+ wire [103:0] sm1_s1n_5;
+ wire [171:0] s1n_sm1_6;
+ wire [103:0] sm1_s1n_6;
+ wire [171:0] s1n_sm1_7;
+ wire [103:0] sm1_s1n_7;
+ wire [171:0] s1n_sm1_8;
+ wire [103:0] sm1_s1n_8;
+ wire [171:0] s1n_sm1_9;
+ wire [103:0] sm1_s1n_9;
+ wire [171:0] s1n_sm1_10;
+ wire [103:0] sm1_s1n_10;
+ assign h1_dv_o[52+:52] = sm1_s1n_1[104+:52];
+ assign h3_dv_o[312+:52] = sm1_s1n_1[52+:52];
+ assign h2_dv_o[0+:52] = sm1_s1n_1[0+:52];
+ assign s1n_sm1_1[172+:86] = h1_dv_i[86+:86];
+ assign s1n_sm1_1[86+:86] = h3_dv_i[516+:86];
+ assign s1n_sm1_1[0+:86] = h2_dv_i[0+:86];
+ assign h2_dv_o[416+:52] = sm1_s1n_2[52+:52];
+ assign h3_dv_o[364+:52] = sm1_s1n_2[0+:52];
+ assign s1n_sm1_2[86+:86] = h2_dv_i[688+:86];
+ assign s1n_sm1_2[0+:86] = h3_dv_i[602+:86];
+ assign h1_dv_o[0+:52] = sm1_s1n_4[52+:52];
+ assign h2_dv_o[364+:52] = sm1_s1n_4[0+:52];
+ assign s1n_sm1_4[86+:86] = h1_dv_i[0+:86];
+ assign s1n_sm1_4[0+:86] = h2_dv_i[602+:86];
+ assign h2_dv_o[312+:52] = sm1_s1n_5[52+:52];
+ assign h3_dv_o[260+:52] = sm1_s1n_5[0+:52];
+ assign s1n_sm1_5[86+:86] = h2_dv_i[516+:86];
+ assign s1n_sm1_5[0+:86] = h3_dv_i[430+:86];
+ assign h2_dv_o[260+:52] = sm1_s1n_6[52+:52];
+ assign h3_dv_o[208+:52] = sm1_s1n_6[0+:52];
+ assign s1n_sm1_6[86+:86] = h2_dv_i[430+:86];
+ assign s1n_sm1_6[0+:86] = h3_dv_i[344+:86];
+ assign h2_dv_o[208+:52] = sm1_s1n_7[52+:52];
+ assign h3_dv_o[156+:52] = sm1_s1n_7[0+:52];
+ assign s1n_sm1_7[86+:86] = h2_dv_i[344+:86];
+ assign s1n_sm1_7[0+:86] = h3_dv_i[258+:86];
+ assign h2_dv_o[156+:52] = sm1_s1n_8[52+:52];
+ assign h3_dv_o[104+:52] = sm1_s1n_8[0+:52];
+ assign s1n_sm1_8[86+:86] = h2_dv_i[258+:86];
+ assign s1n_sm1_8[0+:86] = h3_dv_i[172+:86];
+ assign h2_dv_o[104+:52] = sm1_s1n_9[52+:52];
+ assign h3_dv_o[52+:52] = sm1_s1n_9[0+:52];
+ assign s1n_sm1_9[86+:86] = h2_dv_i[172+:86];
+ assign s1n_sm1_9[0+:86] = h3_dv_i[86+:86];
+ assign h2_dv_o[52+:52] = sm1_s1n_10[52+:52];
+ assign h3_dv_o[0+:52] = sm1_s1n_10[0+:52];
+ assign s1n_sm1_10[86+:86] = h2_dv_i[86+:86];
+ assign s1n_sm1_10[0+:86] = h3_dv_i[0+:86];
+ assign brqifu_to_s1n = tl_brqif_i;
+ assign tl_brqif_o = s1n_to_brqifu;
+ assign brqlsu_to_s1n = tl_brqlsu_i;
+ assign tl_brqlsu_o = s1n_to_brqlsu;
+ assign dbg_to_s1n = tl_dm_sba_i;
+ assign tl_dm_sba_o = s1n_to_dbg;
+ localparam [31:0] tl_main_pkg_ADDR_MASK_DEBUG_ROM = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_MASK_ICCM = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_DEBUG_ROM = 32'h10040000;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_ICCM = 32'h20000000;
+ always @(*) begin
+ device_sel_1 = 2'd2;
+ if ((brqifu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_ICCM) == tl_main_pkg_ADDR_SPACE_ICCM)
+ device_sel_1 = 2'd0;
+ else if ((brqifu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_DEBUG_ROM) == tl_main_pkg_ADDR_SPACE_DEBUG_ROM)
+ device_sel_1 = 2'd1;
+ end
+ tlul_socket_1n #(
+ .HReqDepth(4'h0),
+ .HRspDepth(4'h0),
+ .DReqDepth(12'h000),
+ .DRspDepth(12'h000),
+ .N(2)
+ ) host_1(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(brqifu_to_s1n),
+ .tl_h_o(s1n_to_brqifu),
+ .tl_d_o(h1_dv_i),
+ .tl_d_i(h1_dv_o),
+ .dev_select_i(device_sel_1)
+ );
+ localparam [31:0] tl_main_pkg_ADDR_MASK_DCCM = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_MASK_GPIO = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_MASK_PLIC = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_MASK_PWM = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_MASK_SPI0 = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_MASK_TIMER0 = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_MASK_UART0 = 32'h0000ffff;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_DCCM = 32'h10000000;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_GPIO = 32'h400c0000;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_PLIC = 32'h40050000;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_PWM = 32'h400b0000;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_SPI0 = 32'h40080000;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_TIMER0 = 32'h40000000;
+ localparam [31:0] tl_main_pkg_ADDR_SPACE_UART0 = 32'h40060000;
+ always @(*) begin
+ device_sel_2 = 4'd9;
+ if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_DCCM) == tl_main_pkg_ADDR_SPACE_DCCM)
+ device_sel_2 = 4'd0;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_DEBUG_ROM) == tl_main_pkg_ADDR_SPACE_DEBUG_ROM)
+ device_sel_2 = 4'd1;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_TIMER0) == tl_main_pkg_ADDR_SPACE_TIMER0)
+ device_sel_2 = 4'd2;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_UART0) == tl_main_pkg_ADDR_SPACE_UART0)
+ device_sel_2 = 4'd3;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_SPI0) == tl_main_pkg_ADDR_SPACE_SPI0)
+ device_sel_2 = 4'd4;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_PWM) == tl_main_pkg_ADDR_SPACE_PWM)
+ device_sel_2 = 4'd5;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_GPIO) == tl_main_pkg_ADDR_SPACE_GPIO)
+ device_sel_2 = 4'd6;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_PLIC) == tl_main_pkg_ADDR_SPACE_PLIC)
+ device_sel_2 = 4'd7;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_ICCM) == tl_main_pkg_ADDR_SPACE_ICCM)
+ device_sel_2 = 4'd8;
+ end
+ tlul_socket_1n #(
+ .HReqDepth(4'h0),
+ .HRspDepth(4'h0),
+ .DReqDepth(36'h000000000),
+ .DRspDepth(36'h000000000),
+ .N(9)
+ ) host_2(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(brqlsu_to_s1n),
+ .tl_h_o(s1n_to_brqlsu),
+ .tl_d_o(h2_dv_i),
+ .tl_d_i(h2_dv_o),
+ .dev_select_i(device_sel_2)
+ );
+ always @(*) begin
+ device_sel_3 = 4'd8;
+ if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_DCCM) == tl_main_pkg_ADDR_SPACE_DCCM)
+ device_sel_3 = 4'd0;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_ICCM) == tl_main_pkg_ADDR_SPACE_ICCM)
+ device_sel_3 = 4'd1;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_TIMER0) == tl_main_pkg_ADDR_SPACE_TIMER0)
+ device_sel_3 = 4'd2;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_UART0) == tl_main_pkg_ADDR_SPACE_UART0)
+ device_sel_3 = 4'd3;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_SPI0) == tl_main_pkg_ADDR_SPACE_SPI0)
+ device_sel_3 = 4'd4;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_PWM) == tl_main_pkg_ADDR_SPACE_PWM)
+ device_sel_3 = 4'd5;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_GPIO) == tl_main_pkg_ADDR_SPACE_GPIO)
+ device_sel_3 = 4'd6;
+ else if ((brqlsu_to_s1n[68-:32] & ~tl_main_pkg_ADDR_MASK_PLIC) == tl_main_pkg_ADDR_SPACE_PLIC)
+ device_sel_3 = 4'd7;
+ end
+ tlul_socket_1n #(
+ .HReqDepth(4'h0),
+ .HRspDepth(4'h0),
+ .DReqDepth(36'h000000000),
+ .DRspDepth(36'h000000000),
+ .N(8)
+ ) host_3(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(dbg_to_s1n),
+ .tl_h_o(s1n_to_dbg),
+ .tl_d_o(h3_dv_i),
+ .tl_d_i(h3_dv_o),
+ .dev_select_i(device_sel_3)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(3)
+ ) ICCM(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_1),
+ .tl_h_o(sm1_s1n_1),
+ .tl_d_o(tl_iccm_o),
+ .tl_d_i(tl_iccm_i)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(2)
+ ) DCCM(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_2),
+ .tl_h_o(sm1_s1n_2),
+ .tl_d_o(tl_dccm_o),
+ .tl_d_i(tl_dccm_i)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(2)
+ ) DEBUG_ROM(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_4),
+ .tl_h_o(sm1_s1n_4),
+ .tl_d_o(tl_debug_rom_o),
+ .tl_d_i(tl_debug_rom_i)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(2)
+ ) TIMER(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_5),
+ .tl_h_o(sm1_s1n_5),
+ .tl_d_o(tl_timer0_o),
+ .tl_d_i(tl_timer0_i)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(2)
+ ) UART(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_6),
+ .tl_h_o(sm1_s1n_6),
+ .tl_d_o(tl_uart_o),
+ .tl_d_i(tl_uart_i)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(2)
+ ) SPI(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_7),
+ .tl_h_o(sm1_s1n_7),
+ .tl_d_o(tl_spi_o),
+ .tl_d_i(tl_spi_i)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(2)
+ ) PWM(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_8),
+ .tl_h_o(sm1_s1n_8),
+ .tl_d_o(tl_pwm_o),
+ .tl_d_i(tl_pwm_i)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(2)
+ ) GPIO(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_9),
+ .tl_h_o(sm1_s1n_9),
+ .tl_d_o(tl_gpio_o),
+ .tl_d_i(tl_gpio_i)
+ );
+ tlul_socket_m1 #(
+ .HReqDepth(8'h00),
+ .HRspDepth(8'h00),
+ .DReqDepth(4'h0),
+ .DRspDepth(4'h0),
+ .M(2)
+ ) PLIC(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_h_i(s1n_sm1_10),
+ .tl_h_o(sm1_s1n_10),
+ .tl_d_o(tl_plic_o),
+ .tl_d_i(tl_plic_i)
+ );
+endmodule
+module uart_core (
+ clk_i,
+ rst_ni,
+ ren,
+ we,
+ wdata,
+ rdata,
+ addr,
+ tx_o,
+ rx_i,
+ intr_tx
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire ren;
+ input wire we;
+ input wire [31:0] wdata;
+ output wire [31:0] rdata;
+ input wire [3:0] addr;
+ output wire tx_o;
+ input wire rx_i;
+ output wire intr_tx;
+ localparam ADDR_CTRL = 0;
+ localparam ADDR_TX = 4;
+ localparam ADDR_RX = 8;
+ reg [18:0] control;
+ reg [7:0] tx;
+ wire [7:0] rx;
+ wire rx_status;
+ always @(posedge clk_i)
+ if (~rst_ni) begin
+ control <= 0;
+ tx <= 0;
+ end
+ else if (~ren & we)
+ if (addr == ADDR_CTRL) begin
+ control[1:0] <= wdata[1:0];
+ control[18:3] <= wdata[18:3];
+ control[2] <= rx_status;
+ end
+ else if (addr == ADDR_TX)
+ tx <= wdata[7:0];
+ else if (addr == ADDR_RX)
+ ;
+ else begin
+ control <= 0;
+ tx <= 0;
+ end
+ uart_tx u_tx(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tx_en(control[0]),
+ .i_TX_Byte(tx),
+ .CLKS_PER_BIT(control[18:3]),
+ .o_TX_Serial(tx_o),
+ .o_TX_Done(intr_tx)
+ );
+ uart_rx u_rx(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .i_Rx_Serial(rx_i),
+ .o_Rx_DV(rx_status),
+ .rx_en(control[1]),
+ .CLKS_PER_BIT(control[18:3]),
+ .o_Rx_Byte(rx)
+ );
+ assign rdata = (addr == 0 ? control : (addr == 8 ? rx : 0));
+endmodule
+module uart_rx_prog (
+ clk_i,
+ rst_ni,
+ i_Rx_Serial,
+ CLKS_PER_BIT,
+ o_Rx_DV,
+ o_Rx_Byte
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire i_Rx_Serial;
+ input wire [15:0] CLKS_PER_BIT;
+ output wire o_Rx_DV;
+ output wire [7:0] o_Rx_Byte;
+ parameter s_IDLE = 3'b000;
+ parameter s_RX_START_BIT = 3'b001;
+ parameter s_RX_DATA_BITS = 3'b010;
+ parameter s_RX_STOP_BIT = 3'b011;
+ parameter s_CLEANUP = 3'b100;
+ reg r_Rx_Data_R;
+ reg r_Rx_Data;
+ reg [15:0] r_Clock_Count;
+ reg [2:0] r_Bit_Index;
+ reg [7:0] r_Rx_Byte;
+ reg r_Rx_DV;
+ reg [2:0] r_SM_Main;
+ always @(posedge clk_i)
+ if (~rst_ni) begin
+ r_Rx_Data_R <= 1'b1;
+ r_Rx_Data <= 1'b1;
+ end
+ else begin
+ r_Rx_Data_R <= i_Rx_Serial;
+ r_Rx_Data <= r_Rx_Data_R;
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni) begin
+ r_SM_Main <= s_IDLE;
+ r_Rx_DV <= 1'b0;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_Bit_Index <= 3'b000;
+ r_Rx_Byte <= 8'b00000000;
+ end
+ else
+ case (r_SM_Main)
+ s_IDLE: begin
+ r_Rx_DV <= 1'b0;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_Bit_Index <= 3'b000;
+ r_Rx_Byte <= 8'b00000000;
+ if (r_Rx_Data == 1'b0)
+ r_SM_Main <= s_RX_START_BIT;
+ else
+ r_SM_Main <= s_IDLE;
+ end
+ s_RX_START_BIT:
+ if (r_Clock_Count == ((CLKS_PER_BIT - 1) >> 1)) begin
+ if (r_Rx_Data == 1'b0) begin
+ r_Clock_Count <= 16'b0000000000000000;
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else
+ r_SM_Main <= s_IDLE;
+ end
+ else begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= s_RX_START_BIT;
+ end
+ s_RX_DATA_BITS:
+ if (r_Clock_Count < (CLKS_PER_BIT - 1)) begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else begin
+ r_Clock_Count <= 16'b0000000000000000;
+ r_Rx_Byte[r_Bit_Index] <= r_Rx_Data;
+ if (r_Bit_Index < 7) begin
+ r_Bit_Index <= r_Bit_Index + 3'b001;
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else begin
+ r_Bit_Index <= 3'b000;
+ r_SM_Main <= s_RX_STOP_BIT;
+ end
+ end
+ s_RX_STOP_BIT:
+ if (r_Clock_Count < (CLKS_PER_BIT - 1)) begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= s_RX_STOP_BIT;
+ end
+ else begin
+ r_Rx_DV <= 1'b1;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_SM_Main <= s_CLEANUP;
+ end
+ s_CLEANUP: begin
+ r_SM_Main <= s_IDLE;
+ r_Rx_DV <= 1'b0;
+ end
+ default: r_SM_Main <= s_IDLE;
+ endcase
+ assign o_Rx_DV = r_Rx_DV;
+ assign o_Rx_Byte = r_Rx_Byte;
+endmodule
+module uart_rx (
+ clk_i,
+ rst_ni,
+ rx_en,
+ i_Rx_Serial,
+ CLKS_PER_BIT,
+ o_Rx_DV,
+ o_Rx_Byte
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire rx_en;
+ input wire i_Rx_Serial;
+ input wire [15:0] CLKS_PER_BIT;
+ output wire o_Rx_DV;
+ output wire [7:0] o_Rx_Byte;
+ parameter s_IDLE = 3'b000;
+ parameter s_RX_START_BIT = 3'b001;
+ parameter s_RX_DATA_BITS = 3'b010;
+ parameter s_RX_STOP_BIT = 3'b011;
+ parameter s_CLEANUP = 3'b100;
+ reg r_Rx_Data_R;
+ reg r_Rx_Data;
+ reg [15:0] r_Clock_Count;
+ reg [2:0] r_Bit_Index;
+ reg [7:0] r_Rx_Byte;
+ reg r_Rx_DV;
+ reg [2:0] r_SM_Main;
+ always @(posedge clk_i)
+ if (~rst_ni) begin
+ r_Rx_Data_R <= 1'b1;
+ r_Rx_Data <= 1'b1;
+ end
+ else begin
+ r_Rx_Data_R <= i_Rx_Serial;
+ r_Rx_Data <= r_Rx_Data_R;
+ end
+ always @(posedge clk_i or negedge rst_ni)
+ if (~rst_ni) begin
+ r_SM_Main <= s_IDLE;
+ r_Rx_DV <= 1'b0;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_Bit_Index <= 3'b000;
+ end
+ else
+ case (r_SM_Main)
+ s_IDLE: begin
+ r_Rx_DV <= 1'b0;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_Bit_Index <= 3'b000;
+ if (r_Rx_Data == 1'b0) begin
+ if (rx_en == 1'b1)
+ r_SM_Main <= s_RX_START_BIT;
+ else
+ r_SM_Main <= s_IDLE;
+ end
+ else
+ r_SM_Main <= s_IDLE;
+ end
+ s_RX_START_BIT:
+ if (r_Clock_Count == ((CLKS_PER_BIT - 1) >> 1)) begin
+ if (r_Rx_Data == 1'b0) begin
+ r_Clock_Count <= 16'b0000000000000000;
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else
+ r_SM_Main <= s_IDLE;
+ end
+ else begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= s_RX_START_BIT;
+ end
+ s_RX_DATA_BITS:
+ if (r_Clock_Count < (CLKS_PER_BIT - 16'b0000000000000001)) begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else begin
+ r_Clock_Count <= 16'b0000000000000000;
+ r_Rx_Byte[r_Bit_Index] <= r_Rx_Data;
+ if (r_Bit_Index < 7) begin
+ r_Bit_Index <= r_Bit_Index + 3'b001;
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else begin
+ r_Bit_Index <= 3'b000;
+ r_SM_Main <= s_RX_STOP_BIT;
+ end
+ end
+ s_RX_STOP_BIT:
+ if (r_Clock_Count < (CLKS_PER_BIT - 16'b0000000000000001)) begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= s_RX_STOP_BIT;
+ end
+ else begin
+ r_Rx_DV <= 1'b1;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_SM_Main <= s_CLEANUP;
+ end
+ s_CLEANUP: begin
+ r_SM_Main <= s_IDLE;
+ r_Rx_DV <= 1'b0;
+ end
+ default: r_SM_Main <= s_IDLE;
+ endcase
+ assign o_Rx_DV = r_Rx_DV;
+ assign o_Rx_Byte = r_Rx_Byte;
+endmodule
+module uart_top (
+ clk_i,
+ rst_ni,
+ tl_i,
+ tl_o,
+ tx_o,
+ rx_i,
+ intr_tx
+);
+ input wire clk_i;
+ input wire rst_ni;
+ localparam signed [31:0] tlul_pkg_TL_AIW = 8;
+ localparam signed [31:0] tlul_pkg_TL_AW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DW = 32;
+ localparam signed [31:0] tlul_pkg_TL_DBW = 4;
+ localparam signed [31:0] tlul_pkg_TL_SZW = 2;
+ input wire [85:0] tl_i;
+ localparam signed [31:0] tlul_pkg_TL_DIW = 1;
+ output wire [51:0] tl_o;
+ output wire tx_o;
+ input wire rx_i;
+ output wire intr_tx;
+ wire [31:0] wdata;
+ wire [3:0] addr;
+ wire we;
+ wire re;
+ wire [31:0] rdata;
+ wire [3:0] be;
+ uart_core u_uart_core(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .ren(re),
+ .we(we),
+ .wdata(wdata),
+ .rdata(rdata),
+ .addr(addr),
+ .tx_o(tx_o),
+ .rx_i(rx_i),
+ .intr_tx(intr_tx)
+ );
+ tlul_adapter_reg #(
+ .RegAw(4),
+ .RegDw(32)
+ ) u_reg_if(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .tl_i(tl_i),
+ .tl_o(tl_o),
+ .we_o(we),
+ .re_o(re),
+ .addr_o(addr),
+ .wdata_o(wdata),
+ .be_o(be),
+ .rdata_i(rdata),
+ .error_i(1'b0)
+ );
+endmodule
+module uart_tx (
+ clk_i,
+ rst_ni,
+ tx_en,
+ i_TX_Byte,
+ CLKS_PER_BIT,
+ o_TX_Serial,
+ o_TX_Done
+);
+ input wire clk_i;
+ input wire rst_ni;
+ input wire tx_en;
+ input wire [7:0] i_TX_Byte;
+ input wire [15:0] CLKS_PER_BIT;
+ output reg o_TX_Serial;
+ output wire o_TX_Done;
+ localparam IDLE = 3'b000;
+ localparam TX_START_BIT = 3'b001;
+ localparam TX_DATA_BITS = 3'b010;
+ localparam TX_STOP_BIT = 3'b011;
+ localparam CLEANUP = 3'b100;
+ reg [2:0] r_SM_Main;
+ reg [15:0] r_Clock_Count;
+ reg [2:0] r_Bit_Index;
+ reg [7:0] r_TX_Data;
+ reg r_TX_Done;
+ always @(posedge clk_i)
+ if (~rst_ni) begin
+ r_SM_Main <= 3'b000;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_Bit_Index <= 3'b000;
+ r_TX_Data <= 8'b00000000;
+ r_TX_Done <= 1'b0;
+ end
+ else
+ case (r_SM_Main)
+ IDLE: begin
+ o_TX_Serial <= 1'b1;
+ r_TX_Done <= 1'b0;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_Bit_Index <= 3'b000;
+ if (tx_en == 1'b1) begin
+ r_TX_Data <= i_TX_Byte;
+ r_SM_Main <= TX_START_BIT;
+ end
+ else
+ r_SM_Main <= IDLE;
+ end
+ TX_START_BIT: begin
+ o_TX_Serial <= 1'b0;
+ if (r_Clock_Count < (CLKS_PER_BIT - 1)) begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= TX_START_BIT;
+ end
+ else begin
+ r_Clock_Count <= 16'b0000000000000000;
+ r_SM_Main <= TX_DATA_BITS;
+ end
+ end
+ TX_DATA_BITS: begin
+ o_TX_Serial <= r_TX_Data[r_Bit_Index];
+ if (r_Clock_Count < (CLKS_PER_BIT - 16'b0000000000000001)) begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= TX_DATA_BITS;
+ end
+ else begin
+ r_Clock_Count <= 3'b000;
+ if (r_Bit_Index < 7) begin
+ r_Bit_Index <= r_Bit_Index + 3'b001;
+ r_SM_Main <= TX_DATA_BITS;
+ end
+ else begin
+ r_Bit_Index <= 3'b000;
+ r_SM_Main <= TX_STOP_BIT;
+ end
+ end
+ end
+ TX_STOP_BIT: begin
+ o_TX_Serial <= 1'b1;
+ if (r_Clock_Count < (CLKS_PER_BIT - 16'b0000000000000001)) begin
+ r_Clock_Count <= r_Clock_Count + 16'b0000000000000001;
+ r_SM_Main <= TX_STOP_BIT;
+ end
+ else begin
+ r_TX_Done <= 1'b1;
+ r_Clock_Count <= 16'b0000000000000000;
+ r_SM_Main <= CLEANUP;
+ end
+ end
+ CLEANUP: begin
+ r_TX_Done <= 1'b1;
+ r_SM_Main <= IDLE;
+ end
+ default: r_SM_Main <= IDLE;
+ endcase
+ assign o_TX_Done = r_TX_Done;
+endmodule
+
+(* blackbox *)
+module sky130_sram_4kbyte_1rw1r_32x1024_8 (clk0, csb0, web0, wmask0, addr0, din0, dout0, clk1, csb1, addr1, dout1);
+ parameter NUM_WMASKS = 4;
+ parameter DATA_WIDTH = 32;
+ parameter ADDR_WIDTH = 10;
+ parameter RAM_DEPTH = 1 << ADDR_WIDTH;
+ parameter DELAY = 3;
+ parameter VERBOSE = 1;
+ parameter T_HOLD = 1;
+ `ifdef USE_POWER_PINS
+ inout vccd1;
+ inout vssd1;
+ `endif
+ input clk0;
+ input csb0;
+ input web0;
+ input [NUM_WMASKS - 1:0] wmask0;
+ input [ADDR_WIDTH - 1:0] addr0;
+ input [DATA_WIDTH - 1:0] din0;
+ output [DATA_WIDTH - 1:0] dout0;
+ input clk1;
+ input csb1;
+ input [ADDR_WIDTH - 1:0] addr1;
+ output [DATA_WIDTH - 1:0] dout1;
+endmodule
diff --git a/verilog/rtl/azadi_soc_top_caravel.v b/verilog/rtl/azadi_soc_top_caravel.v
deleted file mode 100644
index 702fada..0000000
--- a/verilog/rtl/azadi_soc_top_caravel.v
+++ /dev/null
@@ -1,218 +0,0 @@
-// Designed by a Team at Micro Electronics Research Lab, Usman Institute of Technology.
-// https://www.merledupk.org
-
-module azadi_soc_top_caravel #(
- parameter BITS = 32
-) (
- `ifdef USE_POWER_PINS
- inout vdda1, // User area 1 3.3V supply
- inout vdda2, // User area 2 3.3V supply
- inout vssa1, // User area 1 analog ground
- inout vssa2, // User area 2 analog ground
- inout vccd1, // User area 1 1.8V supply
- inout vccd2, // User area 2 1.8v supply
- inout vssd1, // User area 1 digital ground
- inout vssd2, // User area 2 digital ground
- `endif
-
- // Wishbone Slave ports (WB MI A)
- input wb_clk_i,
- input wb_rst_i,
- input wbs_stb_i,
- input wbs_cyc_i,
- input wbs_we_i,
- input [3:0] wbs_sel_i,
- input [31:0] wbs_dat_i,
- input [31:0] wbs_adr_i,
- output wbs_ack_o,
- output [31:0] wbs_dat_o,
-
- // Logic Analyzer Signals
- input [127:0] la_data_in,
- output [127:0] la_data_out,
- input [127:0] la_oenb,
-
- // IOs, MPRJ_IO_PADS = 38
- input [`MPRJ_IO_PADS-1:0] io_in,
- output [`MPRJ_IO_PADS-1:0] io_out,
- output [`MPRJ_IO_PADS-1:0] io_oeb,
-
- // Analog (direct connection to GPIO pad---use with caution)
- // Note that analog I/O is not available on the 7 lowest-numbered
- // GPIO pads, and so the analog_io indexing is offset from the
- // GPIO indexing by 7 (also upper 2 GPIOs do not have analog_io).
- inout [`MPRJ_IO_PADS-10:0] analog_io,
-
- // Independent clock (on independent integer divider)
- input user_clock2,
-
- // User maskable interrupt signals
- output [2:0] user_irq
-);
-
- wire clk_i;
- wire rst_ni;
- wire prog;
-
- // Clocks per bit
- wire [15:0] clk_per_bits;
-
- // gpios interface
- wire [31:0] gpio_i;
- wire [31:0] gpio_o;
- wire [31:0] gpio_oe;
-
- // jtag interface
- wire jtag_tck;
- wire jtag_tms;
- wire jtag_trst;
- wire jtag_tdi;
- wire jtag_tdo;
- wire jtag_tdo_oe;
-
- // uart-periph interface
- wire uart_tx;
- wire uart_rx;
-
- // PWM interface
- wire pwm_o_1;
- wire pwm_o_2;
- wire pwm1_oe;
- wire pwm2_oe;
-
- // SPI interface
- wire [3:0] ss_o;
- wire sclk_o;
- wire sd_o;
- wire sd_oe;
- wire sd_i;
-
- // Note: Output enable is active low for IO pads
- assign io_oeb[0] = ~jtag_tdo_oe;
- assign jtag_tdi = io_in[0];
- assign io_out[0] = jtag_tdo;
-
- // SPI 0
- assign io_oeb[1] = sd_oe;
- assign io_out[1] = sd_o;
-
- assign io_oeb[2] = 1'b1;
- assign io_out[2] = 1'b0; // todo
- assign sdi = io_in[2];
-
- assign io_oeb[3] = 1'b0;
- assign io_out[3] = ss_o[0];
-
- assign io_oeb[4] = sd_oe;
- assign io_out[4] = sclk_o;
-
- // UART
- assign io_oeb[5] = 1'b0;
- assign io_out[5] = uart_tx;
-
- assign io_oeb[6] = 1'b1;
- assign uart_rx = io_in[6];
-
- // Programming Button
- assign io_oeb[7] = 1'b1;
- assign prog = io_in[7];
-
- // GPIO 0-18
- assign io_oeb[25:8] = ~gpio_oe[25:8];
- assign gpio_i[25:8] = io_in [25:8];
- assign io_out[25:8] = gpio_o [25:8];
-
- // GPIO 19-21, SPI SS
- assign io_oeb[27] = sd_oe ? ~sd_oe : ~gpio_oe[27];
- assign io_out[27] = sd_oe ? sd_o[1] : gpio_o [27]; // SPI slave sel[1]
- assign gpio_i[27] = io_in[27];
-
- assign io_oeb[28] = sd_oe ? ~sd_oe : ~gpio_oe[28];
- assign io_out[28] = sd_oe ? sd_o[2] : gpio_o [28]; // SPI slave sel[2]
- assign gpio_i[28] = io_in[28];
-
- assign io_oeb[29] = sd_oe ? ~sd_oe : ~gpio_oe[29];
- assign io_out[29] = sd_oe ? sd_o[3] : gpio_o [29]; // SPI slave sel[3]
- assign gpio_i[29] = io_in[29];
-
- // GPIO 22-24, JTAG in
- assign io_oeb[30] = ~gpio_oe[30];
- assign io_out[30] = gpio_o [30];
- assign gpio_i[30] = io_in[30];
- assign jtag_tck[30] = io_in[30]; // JTAG TCK
-
- assign io_oeb[31] = ~gpio_oe[31];
- assign io_out[31] = gpio_o [31];
- assign gpio_i[31] = io_in[31];
- assign jtag_tms[31] = io_in[31]; // JTAG TMS
-
- assign io_oeb[32] = ~gpio_oe[32];
- assign io_out[32] = gpio_o [32];
- assign gpio_i[32] = io_in[32];
- assign jtag_trst[32] = io_in[32]; // JTAG TRST
-
- // GPIO 25-26, PWM 1, 2
- assign io_oeb[33] = ~pwm1_oe | ~gpio_oe[33]; // PWM1
- assign io_out[33] = pwm1_oe ? pwm_o_1 : gpio_o [33];
- assign gpio_i[33] = io_in[33];
-
- assign io_oeb[34] = ~pwm2_oe | ~gpio_oe[34]; // PWM2
- assign io_out[34] = pwm2_oe ? pwm_o_2 : gpio_o [34];
- assign gpio_i[34] = io_in[34];
-
- // GPIO 27-29
- assign io_oeb[37:35] = ~gpio_oe[37:35];
- assign gpio_i[37:35] = io_in [37:35];
- assign io_out[37:35] = gpio_o [37:35];
-
- // GPIO 30-31
- // TBD
-
- // Logic Analyzer ports
- assign la_oenb[15:0] = 16'hffff;
- assign clk_per_bits = la_data_in[15:0];
-
- azadi_soc_top azadi_soc(
- `ifdef USE_POWER_PINS
- .vccd1 (vccd1),
- .vssd1 (vssd1),
- `endif
- .clk_i(wb_clk_i),
- .rst_ni(wb_rst_i),
- .prog(prog),
-
- // Clocks per bits
- .clks_per_bit(clks_per_bit),
-
- // gpios interface
- .gpio_i(gpio_i),
- .gpio_o(gpio_o),
- .gpio_oe(gpio_oe),
-
- // jtag interface
- .jtag_tck_i(jtag_tck),
- .jtag_tms_i(jtag_tms),
- .jtag_trst_ni(jtag_trst),
- .jtag_tdi_i(jtag_tdi),
- .jtag_tdo_o(jtag_tdo),
- .jtag_tdo_oe_o(jtag_tdo_oe),
-
- // uart-periph interface
- .uart_tx(uart_tx), // output
- .uart_rx(uart_rx), // input
-
- // PWM interface
- .pwm_o(pwm_o_1),
- .pwm_o_2(pwm_o_2),
- .pwm1_oe(pwm1_oe),
- .pwm2_oe(pwm2_oe),
-
- // SPI interface
- .ss_o(ss_o), // [3:0]
- .sclk_o(sclk_o),
- .sd_o(sd_o),
- .sd_oe(sd_oe),
- .sd_i(sd_i)
- );
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/brq_core.sv b/verilog/rtl/brq_core.sv
deleted file mode 100644
index b42e487..0000000
--- a/verilog/rtl/brq_core.sv
+++ /dev/null
@@ -1,1593 +0,0 @@
-`ifdef RISCV_FORMAL
- `define RVFI
-`endif
-
-
-/**
- * Top level module of the brq RISC-V core
- */
-module brq_core #(
- parameter bit PMPEnable = 1'b0,
- parameter int unsigned PMPGranularity = 0,
- parameter int unsigned PMPNumRegions = 0,
- parameter int unsigned MHPMCounterNum = 0,
- parameter int unsigned MHPMCounterWidth = 40,
- parameter bit RV32E = 1'b0,
- parameter brq_pkg::rv32m_e RV32M = brq_pkg::RV32MFast,
- parameter brq_pkg::rv32b_e RV32B = brq_pkg::RV32BNone,
- parameter brq_pkg::regfile_e RegFile = brq_pkg::RegFileFF,
- parameter brq_pkg::rvfloat_e RVF = brq_pkg::RV32FSingle, // for floating point
- parameter int unsigned FloatingPoint = 1'b1,
- parameter bit BranchTargetALU = 1'b0,
- parameter bit WritebackStage = 1'b1,
- parameter bit ICache = 1'b0,
- parameter bit ICacheECC = 1'b0,
- parameter bit BranchPredictor = 1'b0,
- parameter bit DbgTriggerEn = 1'b0,
- parameter int unsigned DbgHwBreakNum = 1,
- parameter bit Securebrq = 1'b0,
- parameter int unsigned DmHaltAddr = 32'h1A110800,
- parameter int unsigned DmExceptionAddr = 32'h1A110808
-) (
- // Clock and Reset
- input logic clk_i,
- input logic rst_ni,
-
- // input logic test_en_i, // enable all clock gates for testing
-
- input logic [31:0] hart_id_i,
- input logic [31:0] boot_addr_i,
-
- // Instruction memory interface
- output logic instr_req_o,
- input logic instr_gnt_i,
- input logic instr_rvalid_i,
- output logic [31:0] instr_addr_o,
- input logic [31:0] instr_rdata_i,
- input logic instr_err_i,
-
- // Data memory interface
- output logic data_req_o,
- input logic data_gnt_i,
- input logic data_rvalid_i,
- output logic data_we_o,
- output logic [3:0] data_be_o,
- output logic [31:0] data_addr_o,
- output logic [31:0] data_wdata_o,
- input logic [31:0] data_rdata_i,
- input logic data_err_i,
-
- // Interrupt inputs
- input logic irq_software_i,
- input logic irq_timer_i,
- input logic irq_external_i,
- input logic [14:0] irq_fast_i,
- input logic irq_nm_i, // non-maskeable interrupt
-
- // Debug Interface
- input logic debug_req_i,
-
- // RISC-V Formal Interface
- // Does not comply with the coding standards of _i/_o suffixes, but follows
- // the convention of RISC-V Formal Interface Specification.
-`ifdef RVFI
- output logic rvfi_valid,
- output logic [63:0] rvfi_order,
- output logic [31:0] rvfi_insn,
- output logic rvfi_trap,
- output logic rvfi_halt,
- output logic rvfi_intr,
- output logic [ 1:0] rvfi_mode,
- output logic [ 1:0] rvfi_ixl,
- output logic [ 4:0] rvfi_rs1_addr,
- output logic [ 4:0] rvfi_rs2_addr,
- output logic [ 4:0] rvfi_rs3_addr,
- output logic [31:0] rvfi_rs1_rdata,
- output logic [31:0] rvfi_rs2_rdata,
- output logic [31:0] rvfi_rs3_rdata,
- output logic [ 4:0] rvfi_rd_addr,
- output logic [31:0] rvfi_rd_wdata,
- output logic [31:0] rvfi_pc_rdata,
- output logic [31:0] rvfi_pc_wdata,
- output logic [31:0] rvfi_mem_addr,
- output logic [ 3:0] rvfi_mem_rmask,
- output logic [ 3:0] rvfi_mem_wmask,
- output logic [31:0] rvfi_mem_rdata,
- output logic [31:0] rvfi_mem_wdata,
-`endif
-
- // CPU Control Signals
- input logic fetch_enable_i,
- output logic alert_minor_o,
- output logic alert_major_o,
- output logic core_sleep_o
-);
-logic test_en_i;
-assign test_en_i = 1'b0;
- import brq_pkg::*;
-
- // floating point
- localparam int unsigned W = 32;
- logic fp_flush;
- logic in_ready_c2fpu; // ready - from core to FPU
- logic in_valid_c2fpu; // valid - from FPU to core
- logic out_ready_fpu2c; // ready - from FPU to core
- logic out_valid_fpu2c; // valid - from core to FPU
- logic valid_id_fpu; // select which valid signal will go to dec
- logic fp_rm_dynamic;
- logic fp_alu_op_mod;
- logic [4:0] fp_rf_raddr_a;
- logic [4:0] fp_rf_raddr_b;
- logic [4:0] fp_rf_raddr_c;
- logic [W-1:0] fp_rf_rdata_a;
- logic [W-1:0] fp_rf_rdata_b;
- logic [W-1:0] fp_rf_rdata_c;
- logic fp_rf_wen_id;
- logic is_fp_instr;
- logic [2:0][W-1:0] fp_operands; // three operands in fpu
- logic fp_busy;
- logic fpu_busy_idu;
- logic [W-1:0] fp_result;
- logic [ 31:0] data_wb;
- logic [4:0] fp_rf_waddr_id;
- logic [4:0] fp_rf_waddr_wb;
- logic fp_rf_we;
- logic fp_rf_wen_wb;
- logic use_fp_rs1;
- logic use_fp_rs2;
- logic use_fp_rd;
- logic fp_rf_write_wb;
- logic [31:0] rf_int_fp_lsu;
- logic fp_swap_oprnds;
- logic fpu_is_busy;
- logic fp_load;
- logic [31:0] fp_rf_wdata_wb;
- fpnew_pkg::status_t fp_status;
- fpnew_pkg::operation_e fp_operation;
- fpnew_pkg::roundmode_e fp_rounding_mode;
- fpnew_pkg::roundmode_e fp_frm_csr;
- fpnew_pkg::roundmode_e fp_frm_fpnew;
- fpnew_pkg::operation_e fp_alu_operator;
- fpnew_pkg::fp_format_e fp_src_fmt;
- fpnew_pkg::fp_format_e fp_dst_fmt;
-
- // brq
- localparam int unsigned PMP_NUM_CHAN = 2;
- localparam bit DataIndTiming = Securebrq;
- localparam bit DummyInstructions = Securebrq;
- localparam bit PCIncrCheck = Securebrq;
- localparam bit ShadowCSR = Securebrq;
- // Speculative branch option, trades-off performance against timing.
- // Setting this to 1 eases branch target critical paths significantly but reduces performance
- // by ~3% (based on CoreMark/MHz score).
- // Set by default in the max PMP config which has the tightest budget for branch target timing.
- localparam bit SpecBranch = PMPEnable & (PMPNumRegions == 16);
- localparam bit RegFileECC = Securebrq;
- localparam int unsigned RegFileDataWidth = RegFileECC ? 32 + 7 : 32;
-
- // IF/ID signals
- logic dummy_instr_id;
- logic instr_valid_id;
- logic instr_new_id;
- logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
- logic [31:0] instr_rdata_alu_id; // Instruction sampled inside IF stage (replicated to
- // ease fan-out)
- logic [15:0] instr_rdata_c_id; // Compressed instruction sampled inside IF stage
- logic instr_is_compressed_id;
- logic instr_perf_count_id;
- // logic instr_bp_taken_id;
- logic instr_fetch_err; // Bus error on instr fetch
- logic instr_fetch_err_plus2; // Instruction error is misaligned
- logic illegal_c_insn_id; // Illegal compressed instruction sent to ID stage
- logic [31:0] pc_if; // Program counter in IF stage
- logic [31:0] pc_id; // Program counter in ID stage
- logic [31:0] pc_wb; // Program counter in WB stage
- logic [33:0] imd_val_d_ex[2]; // Intermediate register for multicycle Ops
- logic [33:0] imd_val_q_ex[2]; // Intermediate register for multicycle Ops
- logic [1:0] imd_val_we_ex;
-
- logic data_ind_timing;
- logic dummy_instr_en;
- logic [2:0] dummy_instr_mask;
- logic dummy_instr_seed_en;
- logic [31:0] dummy_instr_seed;
- logic icache_enable;
- logic icache_inval;
- logic pc_mismatch_alert;
- logic csr_shadow_err;
-
- logic instr_first_cycle_id;
- logic instr_valid_clear;
- logic pc_set;
- logic pc_set_spec;
- //logic nt_branch_mispredict;
- pc_sel_e pc_mux_id; // Mux selector for next PC
- exc_pc_sel_e exc_pc_mux_id; // Mux selector for exception PC
- exc_cause_e exc_cause; // Exception cause
-
- logic lsu_load_err;
- logic lsu_store_err;
-
- // LSU signals
- logic lsu_addr_incr_req;
- logic [31:0] lsu_addr_last;
-
- // Jump and branch target and decision (EX->IF)
- logic [31:0] branch_target_ex;
- logic branch_decision;
-
- // Core busy signals
- logic ctrl_busy;
- logic if_busy;
- logic lsu_busy;
- logic core_busy_d, core_busy_q;
-
- // Register File
- logic [4:0] rf_raddr_a;
- logic [31:0] rf_rdata_a;
- logic [4:0] rf_raddr_b;
- logic [31:0] rf_rdata_b;
- logic rf_ren_a;
- logic rf_ren_b;
- logic [4:0] rf_waddr_wb;
- logic [31:0] rf_wdata_wb;
- // Writeback register write data that can be used on the forwarding path (doesn't factor in memory
- // read data as this is too late for the forwarding path)
- logic [31:0] rf_wdata_fwd_wb;
- logic [31:0] rf_wdata_lsu;
- logic rf_we_wb;
- logic rf_we_lsu;
-
- logic [4:0] rf_waddr_id;
- logic [31:0] rf_wdata_id;
- logic rf_we_id;
- logic rf_rd_a_wb_match;
- logic rf_rd_b_wb_match;
-
- // ALU Control
- alu_op_e alu_operator_ex;
- logic [31:0] alu_operand_a_ex;
- logic [31:0] alu_operand_b_ex;
-
- logic [31:0] bt_a_operand;
- logic [31:0] bt_b_operand;
-
- logic [31:0] alu_adder_result_ex; // Used to forward computed address to LSU
- logic [31:0] result_ex;
-
- // Multiplier Control
- logic mult_en_ex;
- logic div_en_ex;
- logic mult_sel_ex;
- logic div_sel_ex;
- md_op_e multdiv_operator_ex;
- logic [1:0] multdiv_signed_mode_ex;
- logic [31:0] multdiv_operand_a_ex;
- logic [31:0] multdiv_operand_b_ex;
- logic multdiv_ready_id;
-
- // CSR control
- logic csr_access;
- csr_op_e csr_op;
- logic csr_op_en;
- csr_num_e csr_addr;
- logic [31:0] csr_rdata;
- logic [31:0] csr_wdata;
- logic illegal_csr_insn_id; // CSR access to non-existent register,
- // with wrong priviledge level,
- // or missing write permissions
-
- // Data Memory Controlpc_mismatch_alert_o
- logic lsu_we;
- logic [1:0] lsu_type;
- logic lsu_sign_ext;
- logic lsu_req;
- logic [31:0] lsu_wdata;
- logic lsu_req_done;
-
- // stall control
- logic id_in_ready;
- logic ex_valid;
-
- logic lsu_resp_valid;
- logic lsu_resp_err;
-
- // Signals between instruction core interface and pipe (if and id stages)
- logic instr_req_int; // Id stage asserts a req to instruction core interface
-
- // Writeback stage
- logic en_wb;
- wb_instr_type_e instr_type_wb;
- logic ready_wb;
- logic rf_write_wb;
- logic outstanding_load_wb;
- logic outstanding_store_wb;
-
- // Interrupts
- logic irq_pending;
- logic nmi_mode;
- irqs_t irqs;
- logic csr_mstatus_mie;
- logic [31:0] csr_mepc, csr_depc;
-
- // PMP signals
- logic [33:0] csr_pmp_addr [PMPNumRegions];
- pmp_cfg_t csr_pmp_cfg [PMPNumRegions];
- logic pmp_req_err [PMP_NUM_CHAN];
- logic instr_req_out;
- logic data_req_out;
-
- logic csr_save_if;
- logic csr_save_id;
- logic csr_save_wb;
- logic csr_restore_mret_id;
- logic csr_restore_dret_id;
- logic csr_save_cause;
- logic csr_mtvec_init;
- logic [31:0] csr_mtvec;
- logic [31:0] csr_mtval;
- logic csr_mstatus_tw;
- priv_lvl_e priv_mode_id;
- priv_lvl_e priv_mode_if;
- priv_lvl_e priv_mode_lsu;
-
- // debug mode and dcsr configuration
- logic debug_mode;
- dbg_cause_e debug_cause;
- logic debug_csr_save;
- logic debug_single_step;
- logic debug_ebreakm;
- logic debug_ebreaku;
- logic trigger_match;
-
- // signals relating to instruction movements between pipeline stages
- // used by performance counters and RVFI
- logic instr_id_done;
- logic instr_done_wb;
-
- logic perf_instr_ret_wb;
- logic perf_instr_ret_compressed_wb;
- logic perf_iside_wait;
- logic perf_dside_wait;
- logic perf_mul_wait;
- logic perf_div_wait;
- logic perf_jump;
- logic perf_branch;
- logic perf_tbranch;
- logic perf_load;
- logic perf_store;
-
- // for RVFI
- logic illegal_insn_id, unused_illegal_insn_id; // ID stage sees an illegal instruction
-
- // RISC-V Formal Interface signals
-`ifdef RVFI
- logic rvfi_instr_new_wb;
- logic rvfi_intr_d;
- logic rvfi_intr_q;
- logic rvfi_set_trap_pc_d;
- logic rvfi_set_trap_pc_q;
- logic [31:0] rvfi_insn_id;
- logic [4:0] rvfi_rs1_addr_d;
- logic [4:0] rvfi_rs1_addr_q;
- logic [4:0] rvfi_rs2_addr_d;
- logic [4:0] rvfi_rs2_addr_q;
- logic [4:0] rvfi_rs3_addr_d;
- logic [31:0] rvfi_rs1_data_d;
- logic [31:0] rvfi_rs1_data_q;
- logic [31:0] rvfi_rs2_data_d;
- logic [31:0] rvfi_rs2_data_q;
- logic [31:0] rvfi_rs3_data_d;
- logic [4:0] rvfi_rd_addr_wb;
- logic [4:0] rvfi_rd_addr_q;
- logic [4:0] rvfi_rd_addr_d;
- logic [31:0] rvfi_rd_wdata_wb;
- logic [31:0] rvfi_rd_wdata_d;
- logic [31:0] rvfi_rd_wdata_q;
- logic rvfi_rd_we_wb;
- logic [3:0] rvfi_mem_mask_int;
- logic [31:0] rvfi_mem_rdata_d;
- logic [31:0] rvfi_mem_rdata_q;
- logic [31:0] rvfi_mem_wdata_d;
- logic [31:0] rvfi_mem_wdata_q;
- logic [31:0] rvfi_mem_addr_d;
- logic [31:0] rvfi_mem_addr_q;
-`endif
-
- //////////////////////
- // Clock management //
- //////////////////////
-
- logic clk;
-
- logic clock_en;
-
- // Before going to sleep, wait for I- and D-side
- // interfaces to finish ongoing operations.
- assign core_busy_d = ctrl_busy | if_busy | lsu_busy | fp_busy;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- core_busy_q <= 1'b0;
- end else begin
- core_busy_q <= core_busy_d;
- end
- end
- // capture fetch_enable_i in fetch_enable_q, once for ever
- logic fetch_enable_q;
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- fetch_enable_q <= 1'b0;
- end else if (fetch_enable_i) begin
- fetch_enable_q <= 1'b1;
- end
- end
-
- assign clock_en = fetch_enable_q & (core_busy_q | debug_req_i | irq_pending | irq_nm_i);
- assign core_sleep_o = ~clock_en;
-
- // main clock gate of the core
- // generates all clocks except the one for the debug unit which is
- // independent
- prim_clock_gating core_clock_gate_i (
- .clk_i ( clk_i ),
- .en_i ( clock_en ),
- .test_en_i ( test_en_i ),
- .clk_o ( clk )
- );
-
- //////////////
- // IF stage //
- //////////////
-
- brq_ifu #(
- .DmHaltAddr ( DmHaltAddr ),
- .DmExceptionAddr ( DmExceptionAddr ),
- .DummyInstructions ( DummyInstructions ),
- .ICache ( ICache ),
- .ICacheECC ( ICacheECC ),
- .PCIncrCheck ( PCIncrCheck ),
- .BranchPredictor ( BranchPredictor )
- ) if_stage_i (
- .clk_i ( clk ),
- .rst_ni ( rst_ni ),
-
- .boot_addr_i ( boot_addr_i ),
- .req_i ( instr_req_int ), // instruction request control
-
- // instruction cache interface
- .instr_req_o ( instr_req_out ),
- .instr_addr_o ( instr_addr_o ),
- .instr_gnt_i ( instr_gnt_i ),
- .instr_rvalid_i ( instr_rvalid_i ),
- .instr_rdata_i ( instr_rdata_i ),
- .instr_err_i ( instr_err_i ),
- .instr_pmp_err_i ( pmp_req_err[PMP_I] ),
-
- // outputs to ID stage
- .instr_valid_id_o ( instr_valid_id ),
- .instr_new_id_o ( instr_new_id ),
- .instr_rdata_id_o ( instr_rdata_id ),
- .instr_rdata_alu_id_o ( instr_rdata_alu_id ),
- .instr_rdata_c_id_o ( instr_rdata_c_id ),
- .instr_is_compressed_id_o ( instr_is_compressed_id ),
- // .instr_bp_taken_o ( instr_bp_taken_id ),
- .instr_fetch_err_o ( instr_fetch_err ),
- .instr_fetch_err_plus2_o ( instr_fetch_err_plus2 ),
- .illegal_c_insn_id_o ( illegal_c_insn_id ),
- //.dummy_instr_id_o ( dummy_instr_id ),
- .pc_if_o ( pc_if ),
- .pc_id_o ( pc_id ),
-
- // control signals
- .instr_valid_clear_i ( instr_valid_clear ),
- .pc_set_i ( pc_set ),
- .pc_set_spec_i ( pc_set_spec ),
- .pc_mux_i ( pc_mux_id ),
- // .nt_branch_mispredict_i ( nt_branch_mispredict ),
- .exc_pc_mux_i ( exc_pc_mux_id ),
- // .exc_cause ( exc_cause ),
- // .dummy_instr_en_i ( dummy_instr_en ),
- // .dummy_instr_mask_i ( dummy_instr_mask ),
- // .dummy_instr_seed_en_i ( dummy_instr_seed_en ),
- // .dummy_instr_seed_i ( dummy_instr_seed ),
- // .icache_enable_i ( icache_enable ),
- // .icache_inval_i ( icache_inval ),
-
- // branch targets
- .branch_target_ex_i ( branch_target_ex ),
-
- // CSRs
- .csr_mepc_i ( csr_mepc ), // exception return address
- .csr_depc_i ( csr_depc ), // debug return address
- .csr_mtvec_i ( csr_mtvec ), // trap-vector base address
- .csr_mtvec_init_o ( csr_mtvec_init ),
-
- // pipeline stalls
- .id_in_ready_i ( id_in_ready ),
- .pc_mismatch_alert_o ( pc_mismatch_alert ),
- .if_busy_o ( if_busy )
- );
-
- // Core is waiting for the ISide when ID/EX stage is ready for a new instruction but none are
- // available
- assign perf_iside_wait = id_in_ready & ~instr_valid_id;
-
- // Qualify the instruction request with PMP error
- assign instr_req_o = instr_req_out & ~pmp_req_err[PMP_I];
-
- //////////////
- // ID stage //
- //////////////
-
- brq_idu #(
- .RV32E ( RV32E ),
- .RV32M ( RV32M ),
- .RV32B ( RV32B ),
- .BranchTargetALU ( BranchTargetALU ),
- .DataIndTiming ( DataIndTiming ),
- .SpecBranch ( SpecBranch ),
- .WritebackStage ( WritebackStage ),
- .BranchPredictor ( BranchPredictor )
- ) id_stage_i (
- .clk_i ( clk ),
- .rst_ni ( rst_ni ),
-
- // Processor Enable
- .ctrl_busy_o ( ctrl_busy ),
- .illegal_insn_o ( illegal_insn_id ),
-
- // from/to IF-ID pipeline register
- .instr_valid_i ( instr_valid_id ),
- .instr_rdata_i ( instr_rdata_id ),
- .instr_rdata_alu_i ( instr_rdata_alu_id ),
- .instr_rdata_c_i ( instr_rdata_c_id ),
- .instr_is_compressed_i ( instr_is_compressed_id ),
- //.instr_bp_taken_i ( instr_bp_taken_id ),
-
- // Jumps and branches
- .branch_decision_i ( branch_decision ),
-
- // IF and ID control signals
- .instr_first_cycle_id_o ( instr_first_cycle_id ),
- .instr_valid_clear_o ( instr_valid_clear ),
- .id_in_ready_o ( id_in_ready ),
- .instr_req_o ( instr_req_int ),
- .pc_set_o ( pc_set ),
- .pc_set_spec_o ( pc_set_spec ),
- .pc_mux_o ( pc_mux_id ),
- //.nt_branch_mispredict_o ( nt_branch_mispredict ),
- .exc_pc_mux_o ( exc_pc_mux_id ),
- .exc_cause_o ( exc_cause ),
- .icache_inval_o ( icache_inval ),
-
- .instr_fetch_err_i ( instr_fetch_err ),
- .instr_fetch_err_plus2_i ( instr_fetch_err_plus2 ),
- .illegal_c_insn_i ( illegal_c_insn_id ),
-
- .pc_id_i ( pc_id ),
-
- // Stalls
- .ex_valid_i ( valid_id_fpu ), // changed by zeeshan from
- // ex_valid to valid_id_fpu
- // for ready selection
- .lsu_resp_valid_i ( lsu_resp_valid ),
-
- .alu_operator_ex_o ( alu_operator_ex ),
- .alu_operand_a_ex_o ( alu_operand_a_ex ),
- .alu_operand_b_ex_o ( alu_operand_b_ex ),
-
- .imd_val_q_ex_o ( imd_val_q_ex ),
- .imd_val_d_ex_i ( imd_val_d_ex ),
- .imd_val_we_ex_i ( imd_val_we_ex ),
-
- .bt_a_operand_o ( bt_a_operand ),
- .bt_b_operand_o ( bt_b_operand ),
-
- .mult_en_ex_o ( mult_en_ex ),
- .div_en_ex_o ( div_en_ex ),
- .mult_sel_ex_o ( mult_sel_ex ),
- .div_sel_ex_o ( div_sel_ex ),
- .multdiv_operator_ex_o ( multdiv_operator_ex ),
- .multdiv_signed_mode_ex_o ( multdiv_signed_mode_ex ),
- .multdiv_operand_a_ex_o ( multdiv_operand_a_ex ),
- .multdiv_operand_b_ex_o ( multdiv_operand_b_ex ),
- .multdiv_ready_id_o ( multdiv_ready_id ),
-
- // CSR ID/EX
- .csr_access_o ( csr_access ),
- .csr_op_o ( csr_op ),
- .csr_op_en_o ( csr_op_en ),
- .csr_save_if_o ( csr_save_if ), // control signal to save PC
- .csr_save_id_o ( csr_save_id ), // control signal to save PC
- .csr_save_wb_o ( csr_save_wb ), // control signal to save PC
- .csr_restore_mret_id_o ( csr_restore_mret_id ), // restore mstatus upon MRET
- .csr_restore_dret_id_o ( csr_restore_dret_id ), // restore mstatus upon MRET
- .csr_save_cause_o ( csr_save_cause ),
- .csr_mtval_o ( csr_mtval ),
- .priv_mode_i ( priv_mode_id ),
- .csr_mstatus_tw_i ( csr_mstatus_tw ),
- .illegal_csr_insn_i ( illegal_csr_insn_id ),
- .data_ind_timing_i ( data_ind_timing ),
-
- // LSU
- .lsu_req_o ( lsu_req ), // to load store unit
- .lsu_we_o ( lsu_we ), // to load store unit
- .lsu_type_o ( lsu_type ), // to load store unit
- .lsu_sign_ext_o ( lsu_sign_ext ), // to load store unit
- .lsu_wdata_o ( lsu_wdata ), // to load store unit
- .lsu_req_done_i ( lsu_req_done ), // from load store unit
-
- .lsu_addr_incr_req_i ( lsu_addr_incr_req ),
- .lsu_addr_last_i ( lsu_addr_last ),
-
- .lsu_load_err_i ( lsu_load_err ),
- .lsu_store_err_i ( lsu_store_err ),
-
- // Interrupt Signals
- .csr_mstatus_mie_i ( csr_mstatus_mie ),
- .irq_pending_i ( irq_pending ),
- .irqs_i ( irqs ),
- .irq_nm_i ( irq_nm_i ),
- .nmi_mode_o ( nmi_mode ),
-
- // Debug Signal
- .debug_mode_o ( debug_mode ),
- .debug_cause_o ( debug_cause ),
- .debug_csr_save_o ( debug_csr_save ),
- .debug_req_i ( debug_req_i ),
- .debug_single_step_i ( debug_single_step ),
- .debug_ebreakm_i ( debug_ebreakm ),
- .debug_ebreaku_i ( debug_ebreaku ),
- .trigger_match_i ( trigger_match ),
-
- // write data to commit in the register file
- .result_ex_i ( data_wb ), // changed by zeeshan from result_ex
- // to data_wb for FVCT, FMV.WX ins
- .csr_rdata_i ( csr_rdata ),
-
- .rf_raddr_a_o ( rf_raddr_a ),
- .rf_rdata_a_i ( rf_rdata_a ),
- .rf_raddr_b_o ( rf_raddr_b ),
- .rf_rdata_b_i ( rf_int_fp_lsu ),
- .rf_ren_a_o ( rf_ren_a ),
- .rf_ren_b_o ( rf_ren_b ),
- .rf_waddr_id_o ( rf_waddr_id ),
- .rf_wdata_id_o ( rf_wdata_id ),
- .rf_we_id_o ( rf_we_id ),
- .rf_rd_a_wb_match_o ( rf_rd_a_wb_match ),
- .rf_rd_b_wb_match_o ( rf_rd_b_wb_match ),
-
- .rf_waddr_wb_i ( rf_waddr_wb ),
- .rf_wdata_fwd_wb_i ( rf_wdata_fwd_wb ),
- .rf_write_wb_i ( rf_write_wb ),
-
- .en_wb_o ( en_wb ),
- .instr_type_wb_o ( instr_type_wb ),
- .instr_perf_count_id_o ( instr_perf_count_id ),
- .ready_wb_i ( ready_wb ),
- .outstanding_load_wb_i ( outstanding_load_wb ),
- .outstanding_store_wb_i ( outstanding_store_wb ),
-
- // Performance Counters
- .perf_jump_o ( perf_jump ),
- .perf_branch_o ( perf_branch ),
- .perf_tbranch_o ( perf_tbranch ),
- .perf_dside_wait_o ( perf_dside_wait ),
- .perf_mul_wait_o ( perf_mul_wait ),
- .perf_div_wait_o ( perf_div_wait ),
- .instr_id_done_o ( instr_id_done ),
-
- // Floating point extensions IO
- .fp_rounding_mode_o ( fp_rounding_mode ), // defines the rounding mode
- .fp_rf_rdata_a_i ( fp_rf_rdata_a ),
- .fp_rf_rdata_b_i ( fp_rf_rdata_b ),
- .fp_rf_rdata_c_i ( fp_rf_rdata_c ),
- .fp_rf_raddr_a_o ( fp_rf_raddr_a ),
- .fp_rf_raddr_b_o ( fp_rf_raddr_b ),
- .fp_rf_raddr_c_o ( fp_rf_raddr_c ),
- .fp_rf_waddr_o ( fp_rf_waddr_id ),
- .fp_rf_we_o ( fp_rf_wen_id ),
- .fp_alu_operator_o ( fp_alu_operator ),
- .fp_alu_op_mod_o ( fp_alu_op_mod ),
- .fp_src_fmt_o ( fp_src_fmt ),
- .fp_dst_fmt_o ( fp_dst_fmt ),
- .fp_rm_dynamic_o ( fp_rm_dynamic ),
- .fp_flush_o ( fp_flush ),
- .is_fp_instr_o ( is_fp_instr ),
- .use_fp_rs1_o ( use_fp_rs1 ),
- .use_fp_rs2_o ( use_fp_rs2 ),
- .use_fp_rs3_o ( use_fp_rs3 ),
- .use_fp_rd_o ( use_fp_rd ),
- .fpu_busy_i ( fpu_busy_idu ),
- .fp_rf_write_wb_i ( fp_rf_write_wb ),
- .fp_rf_wdata_fwd_wb_i ( fp_rf_wdata_wb ),
- .fp_operands_o ( fp_operands ),
- .fp_load_o ( fp_load )
- );
-
- // for RVFI only
- assign unused_illegal_insn_id = illegal_insn_id;
-
- brq_exu #(
- .RV32M ( RV32M ),
- .RV32B ( RV32B ),
- .BranchTargetALU ( BranchTargetALU )
- ) ex_block_i (
- .clk_i ( clk ),
- .rst_ni ( rst_ni ),
-
- // ALU signal from ID stage
- .alu_operator_i ( alu_operator_ex ),
- .alu_operand_a_i ( alu_operand_a_ex ),
- .alu_operand_b_i ( alu_operand_b_ex ),
- .alu_instr_first_cycle_i ( instr_first_cycle_id ),
-
- // Branch target ALU signal from ID stage
- .bt_a_operand_i ( bt_a_operand ),
- .bt_b_operand_i ( bt_b_operand ),
-
- // Multipler/Divider signal from ID stage
- .multdiv_operator_i ( multdiv_operator_ex ),
- .mult_en_i ( mult_en_ex ),
- .div_en_i ( div_en_ex ),
- .mult_sel_i ( mult_sel_ex ),
- .div_sel_i ( div_sel_ex ),
- .multdiv_signed_mode_i ( multdiv_signed_mode_ex ),
- .multdiv_operand_a_i ( multdiv_operand_a_ex ),
- .multdiv_operand_b_i ( multdiv_operand_b_ex ),
- .multdiv_ready_id_i ( multdiv_ready_id ),
- .data_ind_timing_i ( data_ind_timing ),
-
- // Intermediate value register
- .imd_val_we_o ( imd_val_we_ex ),
- .imd_val_d_o ( imd_val_d_ex ),
- .imd_val_q_i ( imd_val_q_ex ),
-
- // Outputs
- .alu_adder_result_ex_o ( alu_adder_result_ex ), // to LSU
- .result_ex_o ( result_ex ), // to ID
-
- .branch_target_o ( branch_target_ex ), // to IF
- .branch_decision_o ( branch_decision ), // to ID
-
- .ex_valid_o ( ex_valid )
- );
-
- /////////////////////
- // Load/store unit //
- /////////////////////
-
- assign data_req_o = data_req_out & ~pmp_req_err[PMP_D];
- assign lsu_resp_err = lsu_load_err | lsu_store_err;
-
- brq_lsu load_store_unit_i (
- .clk_i ( clk ),
- .rst_ni ( rst_ni ),
-
- // data interface
- .data_req_o ( data_req_out ),
- .data_gnt_i ( data_gnt_i ),
- .data_rvalid_i ( data_rvalid_i ),
- .data_err_i ( data_err_i ),
- .data_pmp_err_i ( pmp_req_err[PMP_D] ),
-
- .data_addr_o ( data_addr_o ),
- .data_we_o ( data_we_o ),
- .data_be_o ( data_be_o ),
- .data_wdata_o ( data_wdata_o ),
- .data_rdata_i ( data_rdata_i ),
-
- // signals to/from ID/EX stage
- .lsu_we_i ( lsu_we ),
- .lsu_type_i ( lsu_type ),
- .lsu_wdata_i ( lsu_wdata ),
- .lsu_sign_ext_i ( lsu_sign_ext ),
-
- .lsu_rdata_o ( rf_wdata_lsu ),
- .lsu_rdata_valid_o ( rf_we_lsu ),
- .lsu_req_i ( lsu_req ),
- .lsu_req_done_o ( lsu_req_done ),
-
- .adder_result_ex_i ( alu_adder_result_ex ),
-
- .addr_incr_req_o ( lsu_addr_incr_req ),
- .addr_last_o ( lsu_addr_last ),
-
-
- .lsu_resp_valid_o ( lsu_resp_valid ),
-
- // exception signals
- .load_err_o ( lsu_load_err ),
- .store_err_o ( lsu_store_err ),
-
- .busy_o ( lsu_busy ),
-
- .perf_load_o ( perf_load ),
- .perf_store_o ( perf_store )
- );
-
- brq_wbu #(
- .WritebackStage ( WritebackStage )
- ) wb_stage_i (
- .clk_i ( clk ),
- .rst_ni ( rst_ni ),
- .en_wb_i ( en_wb ),
- .instr_type_wb_i ( instr_type_wb ),
- .pc_id_i ( pc_id ),
- .instr_is_compressed_id_i ( instr_is_compressed_id ),
- .instr_perf_count_id_i ( instr_perf_count_id ),
-
- .ready_wb_o ( ready_wb ),
- .rf_write_wb_o ( rf_write_wb ),
- .outstanding_load_wb_o ( outstanding_load_wb ),
- .outstanding_store_wb_o ( outstanding_store_wb ),
- .pc_wb_o ( pc_wb ),
- .perf_instr_ret_wb_o ( perf_instr_ret_wb ),
- .perf_instr_ret_compressed_wb_o ( perf_instr_ret_compressed_wb ),
-
- .rf_waddr_id_i ( rf_waddr_id ),
- .rf_wdata_id_i ( rf_wdata_id ),
- .rf_we_id_i ( rf_we_id ),
-
- .rf_wdata_lsu_i ( rf_wdata_lsu ),
- .rf_we_lsu_i ( rf_we_lsu ),
-
- .rf_wdata_fwd_wb_o ( rf_wdata_fwd_wb ),
-
- .rf_waddr_wb_o ( rf_waddr_wb ),
- .rf_wdata_wb_o ( rf_wdata_wb ),
- .rf_we_wb_o ( rf_we_wb ),
-
- .lsu_resp_valid_i ( lsu_resp_valid ),
- .lsu_resp_err_i ( lsu_resp_err ),
-
- .instr_done_wb_o ( instr_done_wb ),
-
- // floating point
- .fp_rf_write_wb_o ( fp_rf_write_wb ),
- .fp_rf_wen_wb_o ( fp_rf_wen_wb ),
- .fp_rf_waddr_wb_o ( fp_rf_waddr_wb ),
- .fp_rf_wen_id_i ( fp_rf_wen_id ),
- .fp_rf_waddr_id_i ( fp_rf_waddr_id ),
- .fp_rf_wdata_wb_o ( fp_rf_wdata_wb ),
- .fp_load_i ( fp_load )
- );
-
- ///////////////////////
- // Register file ECC //
- ///////////////////////
-
- logic [RegFileDataWidth-1:0] rf_wdata_wb_ecc;
- logic [RegFileDataWidth-1:0] rf_rdata_a_ecc;
- logic [RegFileDataWidth-1:0] rf_rdata_b_ecc;
- logic rf_ecc_err_comb;
-
- if (RegFileECC) begin : gen_regfile_ecc
-
- logic [1:0] rf_ecc_err_a, rf_ecc_err_b;
- logic rf_ecc_err_a_id, rf_ecc_err_b_id;
-
- // ECC checkbit generation for regiter file wdata
- prim_secded_39_32_enc regfile_ecc_enc (
- .in (rf_wdata_wb),
- .out (rf_wdata_wb_ecc)
- );
-
- // ECC checking on register file rdata
- prim_secded_39_32_dec regfile_ecc_dec_a (
- .in (rf_rdata_a_ecc),
- .d_o (),
- .syndrome_o (),
- .err_o (rf_ecc_err_a)
- );
- prim_secded_39_32_dec regfile_ecc_dec_b (
- .in (rf_rdata_b_ecc),
- .d_o (),
- .syndrome_o (),
- .err_o (rf_ecc_err_b)
- );
-
- // Assign read outputs - no error correction, just trigger an alert
- assign rf_rdata_a = rf_rdata_a_ecc[31:0];
- assign rf_rdata_b = rf_rdata_b_ecc[31:0];
-
- // Calculate errors - qualify with WB forwarding to avoid xprop into the alert signal
- assign rf_ecc_err_a_id = |rf_ecc_err_a & rf_ren_a & ~rf_rd_a_wb_match;
- assign rf_ecc_err_b_id = |rf_ecc_err_b & rf_ren_b & ~rf_rd_b_wb_match;
-
- // Combined error
- assign rf_ecc_err_comb = instr_valid_id & (rf_ecc_err_a_id | rf_ecc_err_b_id);
-
- end else begin : gen_no_regfile_ecc
- logic unused_rf_ren_a, unused_rf_ren_b;
- logic unused_rf_rd_a_wb_match, unused_rf_rd_b_wb_match;
-
- assign unused_rf_ren_a = rf_ren_a;
- assign unused_rf_ren_b = rf_ren_b;
- assign unused_rf_rd_a_wb_match = rf_rd_a_wb_match;
- assign unused_rf_rd_b_wb_match = rf_rd_b_wb_match;
- assign rf_wdata_wb_ecc = rf_wdata_wb;
- assign rf_rdata_a = rf_rdata_a_ecc;
- assign rf_rdata_b = rf_rdata_b_ecc;
- assign rf_ecc_err_comb = 1'b0;
- end
-
- assign rf_int_fp_lsu = (is_fp_instr & use_fp_rs2) ? fp_rf_rdata_b : rf_rdata_b;
-
- if (RegFile == RegFileFF) begin : gen_regfile_ff
- brq_register_file_ff #(
- .RV32E ( RV32E ),
- .DataWidth ( RegFileDataWidth ),
- .DummyInstructions ( DummyInstructions )
- ) register_file_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
-
- // .test_en_i ( test_en_i ),
- .dummy_instr_id_i ( dummy_instr_id ),
-
- .raddr_a_i ( rf_raddr_a ),
- .rdata_a_o ( rf_rdata_a_ecc ),
- .raddr_b_i ( rf_raddr_b ),
- .rdata_b_o ( rf_rdata_b_ecc ),
- .waddr_a_i ( rf_waddr_wb ),
- .wdata_a_i ( rf_wdata_wb_ecc ),
- .we_a_i ( rf_we_wb )
- );
- end else if (RegFile == RegFileFPGA) begin : gen_regfile_fpga
- brq_register_file_fpga #(
- .RV32E ( RV32E ),
- .DataWidth ( RegFileDataWidth ),
- .DummyInstructions ( DummyInstructions )
- ) register_file_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
-
- .test_en_i ( test_en_i ),
- .dummy_instr_id_i ( dummy_instr_id ),
-
- .raddr_a_i ( rf_raddr_a ),
- .rdata_a_o ( rf_rdata_a_ecc ),
- .raddr_b_i ( rf_raddr_b ),
- .rdata_b_o ( rf_rdata_b_ecc ),
- .waddr_a_i ( rf_waddr_wb ),
- .wdata_a_i ( rf_wdata_wb_ecc ),
- .we_a_i ( rf_we_wb )
- );
- end else if (RegFile == RegFileLatch) begin : gen_regfile_latch
- brq_register_file_latch #(
- .RV32E ( RV32E ),
- .DataWidth ( RegFileDataWidth ),
- .DummyInstructions ( DummyInstructions )
- ) register_file_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
-
- .test_en_i ( test_en_i ),
- .dummy_instr_id_i ( dummy_instr_id ),
-
- .raddr_a_i ( rf_raddr_a ),
- .rdata_a_o ( rf_rdata_a_ecc ),
- .raddr_b_i ( rf_raddr_b ),
- .rdata_b_o ( rf_rdata_b_ecc ),
- .waddr_a_i ( rf_waddr_wb ),
- .wdata_a_i ( rf_wdata_wb_ecc ),
- .we_a_i ( rf_we_wb )
- );
- end
-
- if (FloatingPoint) begin : gen_fp_regfile
- brq_fp_register_file_ff #(
- .RVF ( RVF ),
- .DataWidth ( W )
- ) fp_register_file (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
-
- .raddr_a_i ( fp_rf_raddr_a ),
- .rdata_a_o ( fp_rf_rdata_a ),
-
- .raddr_b_i ( fp_rf_raddr_b ),
- .rdata_b_o ( fp_rf_rdata_b ),
-
- .raddr_c_i ( fp_rf_raddr_c ),
- .rdata_c_o ( fp_rf_rdata_c ),
-
- .waddr_a_i ( fp_rf_waddr_wb ),
- .wdata_a_i ( fp_rf_wdata_wb ),
- .we_a_i ( fp_rf_wen_wb )
-);
- end
-
- ///////////////////
- // Alert outputs //
- ///////////////////
-
- // Minor alert - core is in a recoverable state
- // TODO add I$ ECC errors here
- assign alert_minor_o = 1'b0;
-
- // Major alert - core is unrecoverable
- assign alert_major_o = (rf_ecc_err_comb | pc_mismatch_alert | csr_shadow_err);
-
-
-
- // Explict INC_ASSERT block to avoid unused signal lint warnings were asserts are not included
- `ifdef INC_ASSERT
- // Signals used for assertions only
- logic outstanding_load_resp;
- logic outstanding_store_resp;
-
- logic outstanding_load_id;
- logic outstanding_store_id;
-
- assign outstanding_load_id = id_stage_i.instr_executing & id_stage_i.lsu_req_dec &
- ~id_stage_i.lsu_we;
- assign outstanding_store_id = id_stage_i.instr_executing & id_stage_i.lsu_req_dec &
- id_stage_i.lsu_we;
-
- if (WritebackStage) begin : gen_wb_stage
- // When the writeback stage is present a load/store could be in ID or WB. A Load/store in ID can
- // see a response before it moves to WB when it is unaligned otherwise we should only see
- // a response when load/store is in WB.
- assign outstanding_load_resp = outstanding_load_wb |
- (outstanding_load_id & load_store_unit_i.split_misaligned_access);
-
- assign outstanding_store_resp = outstanding_store_wb |
- (outstanding_store_id & load_store_unit_i.split_misaligned_access);
-
- // When writing back the result of a load, the load must have made it to writeback
-
- end else begin : gen_no_wb_stage
- // Without writeback stage only look into whether load or store is in ID to determine if
- // a response is expected.
- assign outstanding_load_resp = outstanding_load_id;
- assign outstanding_store_resp = outstanding_store_id;
- end
- `endif
-
-
- ////////////////////////
- // RF (Register File) //
- ////////////////////////
-`ifdef RVFI
- assign rvfi_rd_addr_wb = rf_waddr_wb;
- assign rvfi_rd_wdata_wb = rf_we_wb ? rf_wdata_wb : rf_wdata_lsu;
- assign rvfi_rd_we_wb = rf_we_wb | rf_we_lsu;
-`endif
-
-
- /////////////////////////////////////////
- // CSRs (Control and Status Registers) //
- /////////////////////////////////////////
-
- assign csr_wdata = alu_operand_a_ex;
- assign csr_addr = csr_num_e'(csr_access ? alu_operand_b_ex[11:0] : 12'b0);
-
- brq_cs_registers #(
- .DbgTriggerEn ( DbgTriggerEn ),
- .DbgHwBreakNum ( DbgHwBreakNum ),
- .DataIndTiming ( DataIndTiming ),
- .DummyInstructions ( DummyInstructions ),
- .ShadowCSR ( ShadowCSR ),
- .ICache ( ICache ),
- .MHPMCounterNum ( MHPMCounterNum ),
- .MHPMCounterWidth ( MHPMCounterWidth ),
- .PMPEnable ( PMPEnable ),
- .PMPGranularity ( PMPGranularity ),
- .PMPNumRegions ( PMPNumRegions ),
- .RV32E ( RV32E ),
- .RV32M ( RV32M )
- ) cs_registers_i (
- .clk_i ( clk ),
- .rst_ni ( rst_ni ),
-
- // Hart ID from outside
- .hart_id_i ( hart_id_i ),
- .priv_mode_id_o ( priv_mode_id ),
- .priv_mode_if_o ( priv_mode_if ),
- .priv_mode_lsu_o ( priv_mode_lsu ),
-
- // mtvec
- .csr_mtvec_o ( csr_mtvec ),
- .csr_mtvec_init_i ( csr_mtvec_init ),
- .boot_addr_i ( boot_addr_i ),
-
- // Interface to CSRs ( SRAM like )
- .csr_access_i ( csr_access ),
- .csr_addr_i ( csr_addr ),
- .csr_wdata_i ( csr_wdata ),
- .csr_op_i ( csr_op ),
- .csr_op_en_i ( csr_op_en ),
- .csr_rdata_o ( csr_rdata ),
-
- // Interrupt related control signals
- .irq_software_i ( irq_software_i ),
- .irq_timer_i ( irq_timer_i ),
- .irq_external_i ( irq_external_i ),
- .irq_fast_i ( irq_fast_i ),
- .nmi_mode_i ( nmi_mode ),
- .irq_pending_o ( irq_pending ),
- .irqs_o ( irqs ),
- .csr_mstatus_mie_o ( csr_mstatus_mie ),
- .csr_mstatus_tw_o ( csr_mstatus_tw ),
- .csr_mepc_o ( csr_mepc ),
-
- // PMP
- .csr_pmp_cfg_o ( csr_pmp_cfg ),
- .csr_pmp_addr_o ( csr_pmp_addr ),
-
- // debug
- .csr_depc_o ( csr_depc ),
- .debug_mode_i ( debug_mode ),
- .debug_cause_i ( debug_cause ),
- .debug_csr_save_i ( debug_csr_save ),
- .debug_single_step_o ( debug_single_step ),
- .debug_ebreakm_o ( debug_ebreakm ),
- .debug_ebreaku_o ( debug_ebreaku ),
- .trigger_match_o ( trigger_match ),
-
- .pc_if_i ( pc_if ),
- .pc_id_i ( pc_id ),
- .pc_wb_i ( pc_wb ),
-
- .data_ind_timing_o ( data_ind_timing ),
- // .dummy_instr_en_o ( dummy_instr_en ),
- // .dummy_instr_mask_o ( dummy_instr_mask ),
- // .dummy_instr_seed_en_o ( dummy_instr_seed_en ),
- // .dummy_instr_seed_o ( dummy_instr_seed ),
- // .icache_enable_o ( icache_enable ),
- .csr_shadow_err_o ( csr_shadow_err ),
-
- .csr_save_if_i ( csr_save_if ),
- .csr_save_id_i ( csr_save_id ),
- .csr_save_wb_i ( csr_save_wb ),
- .csr_restore_mret_i ( csr_restore_mret_id ),
- .csr_restore_dret_i ( csr_restore_dret_id ),
- .csr_save_cause_i ( csr_save_cause ),
- .csr_mcause_i ( exc_cause ),
- .csr_mtval_i ( csr_mtval ),
- .illegal_csr_insn_o ( illegal_csr_insn_id ),
-
- // performance counter related signals
- .instr_ret_i ( perf_instr_ret_wb ),
- .instr_ret_compressed_i ( perf_instr_ret_compressed_wb ),
- .iside_wait_i ( perf_iside_wait ),
- .jump_i ( perf_jump ),
- .branch_i ( perf_branch ),
- .branch_taken_i ( perf_tbranch ),
- .mem_load_i ( perf_load ),
- .mem_store_i ( perf_store ),
- .dside_wait_i ( perf_dside_wait ),
- .mul_wait_i ( perf_mul_wait ),
- .div_wait_i ( perf_div_wait ),
-
- // floating point
- .fp_rm_dynamic_i ( fp_rm_dynamic ),
- .fp_frm_o ( fp_frm_csr ),
- .fp_status_i ( fp_status ),
- .is_fp_instr_i ( is_fp_instr )
- );
-
- assign fp_frm_fpnew = fp_rm_dynamic ? fp_frm_csr : fp_rounding_mode;
- assign in_ready_c2fpu = id_in_ready; //multdiv_ready_id;
- assign in_valid_c2fpu = (instr_valid_id & is_fp_instr);
- // assign ready_id_fpu = id_in_ready; // (is_fp_instr) ? out_ready_fpu2c : id_in_ready;
- assign valid_id_fpu = (is_fp_instr) ? out_valid_fpu2c : ex_valid;
-
-// FPU instance
- fpnew_top #(
- .Features ( fpnew_pkg::RV32F ),
- .Implementation ( fpnew_pkg::DEFAULT_NOREGS ),
- .TagType ( logic )
- ) i_fpnew_top (
- .clk_i ( clk ),
- .rst_ni ( rst_ni ),
- .operands_i ( fp_operands ),
- .rnd_mode_i ( fp_frm_fpnew ),
- .op_i ( fp_alu_operator ),
- .op_mod_i ( fp_alu_op_mod ),
- .src_fmt_i ( fp_src_fmt ),
- .dst_fmt_i ( fp_dst_fmt ),
- .int_fmt_i ( fpnew_pkg::INT32 ),
- .vectorial_op_i ( 1'b0 ),
- .tag_i ( '1 ),
- .in_valid_i ( in_valid_c2fpu ),
- .in_ready_o ( out_ready_fpu2c ),
- .flush_i ( fp_flush ),
- .result_o ( fp_result ),
- .status_o ( fp_status ),
- .tag_o ( ),
- .out_valid_o ( out_valid_fpu2c ),
- .out_ready_i ( in_ready_c2fpu ),
- .busy_o ( fp_busy )
- );
-
- assign fpu_busy_idu = fp_busy & (~out_valid_fpu2c);
- assign data_wb = is_fp_instr ? fp_result : result_ex;
-
- // These assertions are in top-level as instr_valid_id required as the enable term
-
- if (PMPEnable) begin : g_pmp
- logic [33:0] pmp_req_addr [PMP_NUM_CHAN];
- pmp_req_e pmp_req_type [PMP_NUM_CHAN];
- priv_lvl_e pmp_priv_lvl [PMP_NUM_CHAN];
-
- assign pmp_req_addr[PMP_I] = {2'b00,instr_addr_o[31:0]};
- assign pmp_req_type[PMP_I] = PMP_ACC_EXEC;
- assign pmp_priv_lvl[PMP_I] = priv_mode_if;
- assign pmp_req_addr[PMP_D] = {2'b00,data_addr_o[31:0]};
- assign pmp_req_type[PMP_D] = data_we_o ? PMP_ACC_WRITE : PMP_ACC_READ;
- assign pmp_priv_lvl[PMP_D] = priv_mode_lsu;
-
- brq_pmp #(
- .PMPGranularity ( PMPGranularity ),
- .PMPNumChan ( PMP_NUM_CHAN ),
- .PMPNumRegions ( PMPNumRegions )
- ) pmp_i (
- .clk_i ( clk ),
- .rst_ni ( rst_ni ),
- // Interface to CSRs
- .csr_pmp_cfg_i ( csr_pmp_cfg ),
- .csr_pmp_addr_i ( csr_pmp_addr ),
- .priv_mode_i ( pmp_priv_lvl ),
- // Access checking channels
- .pmp_req_addr_i ( pmp_req_addr ),
- .pmp_req_type_i ( pmp_req_type ),
- .pmp_req_err_o ( pmp_req_err )
- );
- end else begin : g_no_pmp
- // Unused signal tieoff
- priv_lvl_e unused_priv_lvl_if, unused_priv_lvl_ls;
- logic [33:0] unused_csr_pmp_addr [PMPNumRegions];
- pmp_cfg_t unused_csr_pmp_cfg [PMPNumRegions];
- assign unused_priv_lvl_if = priv_mode_if;
- assign unused_priv_lvl_ls = priv_mode_lsu;
- assign unused_csr_pmp_addr = csr_pmp_addr;
- assign unused_csr_pmp_cfg = csr_pmp_cfg;
-
- // Output tieoff
- assign pmp_req_err[PMP_I] = 1'b0;
- assign pmp_req_err[PMP_D] = 1'b0;
- end
-
-`ifdef RVFI
- // When writeback stage is present RVFI information is emitted when instruction is finished in
- // third stage but some information must be captured whilst the instruction is in the second
- // stage. Without writeback stage RVFI information is all emitted when instruction retires in
- // second stage. RVFI outputs are all straight from flops. So 2 stage pipeline requires a single
- // set of flops (instr_info => RVFI_out), 3 stage pipeline requires two sets (instr_info => wb
- // => RVFI_out)
- localparam int RVFI_STAGES = WritebackStage ? 2 : 1;
-
- logic rvfi_stage_valid [RVFI_STAGES];
- logic [63:0] rvfi_stage_order [RVFI_STAGES];
- logic [31:0] rvfi_stage_insn [RVFI_STAGES];
- logic rvfi_stage_trap [RVFI_STAGES];
- logic rvfi_stage_halt [RVFI_STAGES];
- logic rvfi_stage_intr [RVFI_STAGES];
- logic [ 1:0] rvfi_stage_mode [RVFI_STAGES];
- logic [ 1:0] rvfi_stage_ixl [RVFI_STAGES];
- logic [ 4:0] rvfi_stage_rs1_addr [RVFI_STAGES];
- logic [ 4:0] rvfi_stage_rs2_addr [RVFI_STAGES];
- logic [ 4:0] rvfi_stage_rs3_addr [RVFI_STAGES];
- logic [31:0] rvfi_stage_rs1_rdata [RVFI_STAGES];
- logic [31:0] rvfi_stage_rs2_rdata [RVFI_STAGES];
- logic [31:0] rvfi_stage_rs3_rdata [RVFI_STAGES];
- logic [ 4:0] rvfi_stage_rd_addr [RVFI_STAGES];
- logic [31:0] rvfi_stage_rd_wdata [RVFI_STAGES];
- logic [31:0] rvfi_stage_pc_rdata [RVFI_STAGES];
- logic [31:0] rvfi_stage_pc_wdata [RVFI_STAGES];
- logic [31:0] rvfi_stage_mem_addr [RVFI_STAGES];
- logic [ 3:0] rvfi_stage_mem_rmask [RVFI_STAGES];
- logic [ 3:0] rvfi_stage_mem_wmask [RVFI_STAGES];
- logic [31:0] rvfi_stage_mem_rdata [RVFI_STAGES];
- logic [31:0] rvfi_stage_mem_wdata [RVFI_STAGES];
-
- logic rvfi_stage_valid_d [RVFI_STAGES];
-
- assign rvfi_valid = rvfi_stage_valid [RVFI_STAGES-1];
- assign rvfi_order = rvfi_stage_order [RVFI_STAGES-1];
- assign rvfi_insn = rvfi_stage_insn [RVFI_STAGES-1];
- assign rvfi_trap = rvfi_stage_trap [RVFI_STAGES-1];
- assign rvfi_halt = rvfi_stage_halt [RVFI_STAGES-1];
- assign rvfi_intr = rvfi_stage_intr [RVFI_STAGES-1];
- assign rvfi_mode = rvfi_stage_mode [RVFI_STAGES-1];
- assign rvfi_ixl = rvfi_stage_ixl [RVFI_STAGES-1];
- assign rvfi_rs1_addr = rvfi_stage_rs1_addr [RVFI_STAGES-1];
- assign rvfi_rs2_addr = rvfi_stage_rs2_addr [RVFI_STAGES-1];
- assign rvfi_rs3_addr = rvfi_stage_rs3_addr [RVFI_STAGES-1];
- assign rvfi_rs1_rdata = rvfi_stage_rs1_rdata[RVFI_STAGES-1];
- assign rvfi_rs2_rdata = rvfi_stage_rs2_rdata[RVFI_STAGES-1];
- assign rvfi_rs3_rdata = rvfi_stage_rs3_rdata[RVFI_STAGES-1];
- assign rvfi_rd_addr = rvfi_stage_rd_addr [RVFI_STAGES-1];
- assign rvfi_rd_wdata = rvfi_stage_rd_wdata [RVFI_STAGES-1];
- assign rvfi_pc_rdata = rvfi_stage_pc_rdata [RVFI_STAGES-1];
- assign rvfi_pc_wdata = rvfi_stage_pc_wdata [RVFI_STAGES-1];
- assign rvfi_mem_addr = rvfi_stage_mem_addr [RVFI_STAGES-1];
- assign rvfi_mem_rmask = rvfi_stage_mem_rmask[RVFI_STAGES-1];
- assign rvfi_mem_wmask = rvfi_stage_mem_wmask[RVFI_STAGES-1];
- assign rvfi_mem_rdata = rvfi_stage_mem_rdata[RVFI_STAGES-1];
- assign rvfi_mem_wdata = rvfi_stage_mem_wdata[RVFI_STAGES-1];
-
- if (WritebackStage) begin : gen_rvfi_wb_stage
- logic unused_instr_new_id;
-
- assign unused_instr_new_id = instr_new_id;
-
- // With writeback stage first RVFI stage buffers instruction information captured in ID/EX
- // awaiting instruction retirement and RF Write data/Mem read data whilst instruction is in WB
- // So first stage becomes valid when instruction leaves ID/EX stage and remains valid until
- // instruction leaves WB
- assign rvfi_stage_valid_d[0] = (instr_id_done & ~dummy_instr_id) |
- (rvfi_stage_valid[0] & ~instr_done_wb);
- // Second stage is output stage so simple valid cycle after instruction leaves WB (and so has
- // retired)
- assign rvfi_stage_valid_d[1] = instr_done_wb;
-
- // Signal new instruction in WB cycle after instruction leaves ID/EX (to enter WB)
- logic rvfi_instr_new_wb_q;
-
- assign rvfi_instr_new_wb = rvfi_instr_new_wb_q;
-
- always_ff @(posedge clk or negedge rst_ni) begin
- if (~rst_ni) begin
- rvfi_instr_new_wb_q <= 0;
- end else begin
- rvfi_instr_new_wb_q <= instr_id_done;
- end
- end
- end else begin : gen_rvfi_no_wb_stage
- // Without writeback stage first RVFI stage is output stage so simply valid the cycle after
- // instruction leaves ID/EX (and so has retired)
- assign rvfi_stage_valid_d[0] = instr_id_done & ~dummy_instr_id;
- // Without writeback stage signal new instr_new_wb when instruction enters ID/EX to correctly
- // setup register write signals
- assign rvfi_instr_new_wb = instr_new_id;
- end
-
- for (genvar i = 0;i < RVFI_STAGES; i = i + 1) begin : g_rvfi_stages
- always_ff @(posedge clk or negedge rst_ni) begin
- if (!rst_ni) begin
- rvfi_stage_halt[i] <= '0;
- rvfi_stage_trap[i] <= '0;
- rvfi_stage_intr[i] <= '0;
- rvfi_stage_order[i] <= '0;
- rvfi_stage_insn[i] <= '0;
- rvfi_stage_mode[i] <= {PRIV_LVL_M};
- rvfi_stage_ixl[i] <= CSR_MISA_MXL;
- rvfi_stage_rs1_addr[i] <= '0;
- rvfi_stage_rs2_addr[i] <= '0;
- rvfi_stage_rs3_addr[i] <= '0;
- rvfi_stage_pc_rdata[i] <= '0;
- rvfi_stage_pc_wdata[i] <= '0;
- rvfi_stage_mem_rmask[i] <= '0;
- rvfi_stage_mem_wmask[i] <= '0;
- rvfi_stage_valid[i] <= '0;
- rvfi_stage_rs1_rdata[i] <= '0;
- rvfi_stage_rs2_rdata[i] <= '0;
- rvfi_stage_rs3_rdata[i] <= '0;
- rvfi_stage_rd_wdata[i] <= '0;
- rvfi_stage_rd_addr[i] <= '0;
- rvfi_stage_mem_rdata[i] <= '0;
- rvfi_stage_mem_wdata[i] <= '0;
- rvfi_stage_mem_addr[i] <= '0;
- end else begin
- rvfi_stage_valid[i] <= rvfi_stage_valid_d[i];
-
- if (i == 0) begin
- if(instr_id_done) begin
- rvfi_stage_halt[i] <= '0;
- rvfi_stage_trap[i] <= illegal_insn_id;
- rvfi_stage_intr[i] <= rvfi_intr_d;
- rvfi_stage_order[i] <= rvfi_stage_order[i] + 64'(rvfi_stage_valid_d[i]);
- rvfi_stage_insn[i] <= rvfi_insn_id;
- rvfi_stage_mode[i] <= {priv_mode_id};
- rvfi_stage_ixl[i] <= CSR_MISA_MXL;
- rvfi_stage_rs1_addr[i] <= rvfi_rs1_addr_d;
- rvfi_stage_rs2_addr[i] <= rvfi_rs2_addr_d;
- rvfi_stage_rs3_addr[i] <= rvfi_rs3_addr_d;
- rvfi_stage_pc_rdata[i] <= pc_id;
- rvfi_stage_pc_wdata[i] <= pc_set ? branch_target_ex : pc_if;
- rvfi_stage_mem_rmask[i] <= rvfi_mem_mask_int;
- rvfi_stage_mem_wmask[i] <= data_we_o ? rvfi_mem_mask_int : 4'b0000;
- rvfi_stage_rs1_rdata[i] <= rvfi_rs1_data_d;
- rvfi_stage_rs2_rdata[i] <= rvfi_rs2_data_d;
- rvfi_stage_rs3_rdata[i] <= rvfi_rs3_data_d;
- rvfi_stage_rd_addr[i] <= rvfi_rd_addr_d;
- rvfi_stage_rd_wdata[i] <= rvfi_rd_wdata_d;
- rvfi_stage_mem_rdata[i] <= rvfi_mem_rdata_d;
- rvfi_stage_mem_wdata[i] <= rvfi_mem_wdata_d;
- rvfi_stage_mem_addr[i] <= rvfi_mem_addr_d;
- end
- end else begin
- if(instr_done_wb) begin
- rvfi_stage_halt[i] <= rvfi_stage_halt[i-1];
- rvfi_stage_trap[i] <= rvfi_stage_trap[i-1];
- rvfi_stage_intr[i] <= rvfi_stage_intr[i-1];
- rvfi_stage_order[i] <= rvfi_stage_order[i-1];
- rvfi_stage_insn[i] <= rvfi_stage_insn[i-1];
- rvfi_stage_mode[i] <= rvfi_stage_mode[i-1];
- rvfi_stage_ixl[i] <= rvfi_stage_ixl[i-1];
- rvfi_stage_rs1_addr[i] <= rvfi_stage_rs1_addr[i-1];
- rvfi_stage_rs2_addr[i] <= rvfi_stage_rs2_addr[i-1];
- rvfi_stage_rs3_addr[i] <= rvfi_stage_rs3_addr[i-1];
- rvfi_stage_pc_rdata[i] <= rvfi_stage_pc_rdata[i-1];
- rvfi_stage_pc_wdata[i] <= rvfi_stage_pc_wdata[i-1];
- rvfi_stage_mem_rmask[i] <= rvfi_stage_mem_rmask[i-1];
- rvfi_stage_mem_wmask[i] <= rvfi_stage_mem_wmask[i-1];
- rvfi_stage_rs1_rdata[i] <= rvfi_stage_rs1_rdata[i-1];
- rvfi_stage_rs2_rdata[i] <= rvfi_stage_rs2_rdata[i-1];
- rvfi_stage_rs3_rdata[i] <= rvfi_stage_rs3_rdata[i-1];
- rvfi_stage_mem_wdata[i] <= rvfi_stage_mem_wdata[i-1];
- rvfi_stage_mem_addr[i] <= rvfi_stage_mem_addr[i-1];
-
- // For 2 RVFI_STAGES/Writeback Stage ignore first stage flops for rd_addr, rd_wdata and
- // mem_rdata. For RF write addr/data actual write happens in writeback so capture
- // address/data there. For mem_rdata that is only available from the writeback stage.
- // Previous stage flops still exist in RTL as they are used by the non writeback config
- rvfi_stage_rd_addr[i] <= rvfi_rd_addr_d;
- rvfi_stage_rd_wdata[i] <= rvfi_rd_wdata_d;
- rvfi_stage_mem_rdata[i] <= rvfi_mem_rdata_d;
- end
- end
- end
- end
- end
-
-
- // Memory adddress/write data available first cycle of ld/st instruction from register read
- always_comb begin
- if (instr_first_cycle_id) begin
- rvfi_mem_addr_d = alu_adder_result_ex;
- rvfi_mem_wdata_d = lsu_wdata;
- end else begin
- rvfi_mem_addr_d = rvfi_mem_addr_q;
- rvfi_mem_wdata_d = rvfi_mem_wdata_q;
- end
- end
-
- // Capture read data from LSU when it becomes valid
- always_comb begin
- if (lsu_resp_valid) begin
- rvfi_mem_rdata_d = rf_wdata_lsu;
- end else begin
- rvfi_mem_rdata_d = rvfi_mem_rdata_q;
- end
- end
-
- always_ff @(posedge clk or negedge rst_ni) begin
- if (!rst_ni) begin
- rvfi_mem_addr_q <= '0;
- rvfi_mem_rdata_q <= '0;
- rvfi_mem_wdata_q <= '0;
- end else begin
- rvfi_mem_addr_q <= rvfi_mem_addr_d;
- rvfi_mem_rdata_q <= rvfi_mem_rdata_d;
- rvfi_mem_wdata_q <= rvfi_mem_wdata_d;
- end
- end
- // Byte enable based on data type
- always_comb begin
- unique case (lsu_type)
- 2'b00: rvfi_mem_mask_int = 4'b1111;
- 2'b01: rvfi_mem_mask_int = 4'b0011;
- 2'b10: rvfi_mem_mask_int = 4'b0001;
- default: rvfi_mem_mask_int = 4'b0000;
- endcase
- end
-
- always_comb begin
- if (instr_is_compressed_id) begin
- rvfi_insn_id = {16'b0, instr_rdata_c_id};
- end else begin
- rvfi_insn_id = instr_rdata_id;
- end
- end
-
- // Source registers 1 and 2 are read in the first instruction cycle
- // Source register 3 is read in the second instruction cycle.
- always_comb begin
- if (instr_first_cycle_id) begin
- rvfi_rs1_data_d = rf_ren_a ? multdiv_operand_a_ex : '0;
- rvfi_rs1_addr_d = rf_ren_a ? rf_raddr_a : '0;
- rvfi_rs2_data_d = rf_ren_b ? multdiv_operand_b_ex : '0;
- rvfi_rs2_addr_d = rf_ren_b ? rf_raddr_b : '0;
- rvfi_rs3_data_d = '0;
- rvfi_rs3_addr_d = '0;
- end else begin
- rvfi_rs1_data_d = rvfi_rs1_data_q;
- rvfi_rs1_addr_d = rvfi_rs1_addr_q;
- rvfi_rs2_data_d = rvfi_rs2_data_q;
- rvfi_rs2_addr_d = rvfi_rs2_addr_q;
- rvfi_rs3_data_d = multdiv_operand_a_ex;
- rvfi_rs3_addr_d = rf_raddr_a;
- end
- end
- always_ff @(posedge clk or negedge rst_ni) begin
- if (!rst_ni) begin
- rvfi_rs1_data_q <= '0;
- rvfi_rs1_addr_q <= '0;
- rvfi_rs2_data_q <= '0;
- rvfi_rs2_addr_q <= '0;
-
- end else begin
- rvfi_rs1_data_q <= rvfi_rs1_data_d;
- rvfi_rs1_addr_q <= rvfi_rs1_addr_d;
- rvfi_rs2_data_q <= rvfi_rs2_data_d;
- rvfi_rs2_addr_q <= rvfi_rs2_addr_d;
- end
- end
-
- always_comb begin
- if(rvfi_rd_we_wb) begin
- // Capture address/data of write to register file
- rvfi_rd_addr_d = rvfi_rd_addr_wb;
- // If writing to x0 zero write data as required by RVFI specification
- if(rvfi_rd_addr_wb == 5'b0) begin
- rvfi_rd_wdata_d = '0;
- end else begin
- rvfi_rd_wdata_d = rvfi_rd_wdata_wb;
- end
- end else if(rvfi_instr_new_wb) begin
- // If no RF write but new instruction in Writeback (when present) or ID/EX (when no writeback
- // stage present) then zero RF write address/data as required by RVFI specification
- rvfi_rd_addr_d = '0;
- rvfi_rd_wdata_d = '0;
- end else begin
- // Otherwise maintain previous value
- rvfi_rd_addr_d = rvfi_rd_addr_q;
- rvfi_rd_wdata_d = rvfi_rd_wdata_q;
- end
- end
-
- // RD write register is refreshed only once per cycle and
- // then it is kept stable for the cycle.
- always_ff @(posedge clk or negedge rst_ni) begin
- if (!rst_ni) begin
- rvfi_rd_addr_q <= '0;
- rvfi_rd_wdata_q <= '0;
- end else begin
- rvfi_rd_addr_q <= rvfi_rd_addr_d;
- rvfi_rd_wdata_q <= rvfi_rd_wdata_d;
- end
- end
-
- // rvfi_intr must be set for first instruction that is part of a trap handler.
- // On the first cycle of a new instruction see if a trap PC was set by the previous instruction,
- // otherwise maintain value.
- assign rvfi_intr_d = instr_first_cycle_id ? rvfi_set_trap_pc_q : rvfi_intr_q;
-
- always_comb begin
- rvfi_set_trap_pc_d = rvfi_set_trap_pc_q;
-
- if (pc_set && pc_mux_id == PC_EXC &&
- (exc_pc_mux_id == EXC_PC_EXC || exc_pc_mux_id == EXC_PC_IRQ)) begin
- // PC is set to enter a trap handler
- rvfi_set_trap_pc_d = 1'b1;
- end else if (rvfi_set_trap_pc_q && instr_id_done) begin
- // first instruction has been executed after PC is set to trap handler
- rvfi_set_trap_pc_d = 1'b0;
- end
- end
-
- always_ff @(posedge clk or negedge rst_ni) begin
- if (!rst_ni) begin
- rvfi_set_trap_pc_q <= 1'b0;
- rvfi_intr_q <= 1'b0;
- end else begin
- rvfi_set_trap_pc_q <= rvfi_set_trap_pc_d;
- rvfi_intr_q <= rvfi_intr_d;
- end
- end
-
-`else
- logic unused_instr_new_id, unused_instr_done_wb;
- assign unused_instr_new_id = instr_new_id;
- assign unused_instr_done_wb = instr_done_wb;
-`endif
-
-
-
-endmodule
diff --git a/verilog/rtl/brq_core_top.sv b/verilog/rtl/brq_core_top.sv
deleted file mode 100644
index 93079df..0000000
--- a/verilog/rtl/brq_core_top.sv
+++ /dev/null
@@ -1,215 +0,0 @@
-//`include "/home/usman/Documents/ibex/rtl/ibex_pkg.sv"
-//`include "/home/merl/Documents/ibex/rtl/prim_pkg.sv"
-
-module brq_core_top #(
- parameter bit PMPEnable = 1'b0,
- parameter int unsigned PMPGranularity = 0,
- parameter int unsigned PMPNumRegions = 0,
- parameter int unsigned MHPMCounterNum = 0,
- parameter int unsigned MHPMCounterWidth = 40,
- parameter bit RV32E = 1'b0,
- parameter brq_pkg::rv32m_e RV32M = brq_pkg::RV32MFast,
- parameter brq_pkg::rv32b_e RV32B = brq_pkg::RV32BNone,
- parameter brq_pkg::regfile_e RegFile = brq_pkg::RegFileFF,
- parameter bit BranchTargetALU = 1'b0,
- parameter bit WritebackStage = 1'b1,
- parameter bit ICache = 1'b0,
- parameter bit ICacheECC = 1'b0,
- parameter bit BranchPredictor = 1'b0,
- parameter bit DbgTriggerEn = 1'b0,
- parameter int unsigned DbgHwBreakNum = 1,
- parameter bit Securebrq = 1'b0,
- parameter int unsigned DmHaltAddr = 0,
- parameter int unsigned DmExceptionAddr = 0
-)
-(
- input clk_i,
- input rst_ni,
-
- // instruction memory interface
- input tlul_pkg::tl_d2h_t tl_i_i,
- output tlul_pkg::tl_h2d_t tl_i_o,
-
- // data memory interface
- input tlul_pkg::tl_d2h_t tl_d_i,
- output tlul_pkg::tl_h2d_t tl_d_o,
-
- // input logic test_en_i, // enable all clk_i gates for testing
-
- input logic [31:0] hart_id_i,
- input logic [31:0] boot_addr_i,
-
- // Interrupt inputs
- input logic irq_software_i,
- input logic irq_timer_i,
- input logic irq_external_i,
- input logic [14:0] irq_fast_i,
- input logic irq_nm_i, // non-maskeable interrupt
-
- // Debug Interface
- input logic debug_req_i,
-
- // CPU Control Signals
- input logic fetch_enable_i,
- output logic alert_minor_o,
- output logic alert_major_o,
- output logic core_sleep_o
-);
-import brq_pkg::*;
-
- //logic rst_ni;
- //assign rst_ni = rst_ni;
- // Instruction interface (internal)
- logic instr_req;
- logic instr_gnt;
- logic instr_rvalid;
- logic [31:0] instr_addr;
- logic [31:0] instr_rdata;
- logic instr_err;
-
- // Data interface (internal)
- logic data_req;
- logic data_gnt;
- logic data_rvalid;
- logic data_we;
- logic [3:0] data_be;
- logic [31:0] data_addr;
- logic [31:0] data_wdata;
- logic [31:0] data_rdata;
- logic data_err;
-
-
-
-brq_core #(
- .PMPEnable (PMPEnable),
- .PMPGranularity (PMPGranularity),
- .PMPNumRegions (PMPNumRegions),
- .MHPMCounterNum (MHPMCounterNum),
- .MHPMCounterWidth (MHPMCounterWidth),
- .RV32E (RV32E),
- .RV32M (RV32M),
- .RV32B (RV32B),
- .RegFile (RegFile),
- .BranchTargetALU (BranchTargetALU),
- .WritebackStage (WritebackStage),
- .ICache (ICache),
- .ICacheECC (ICacheECC),
- .BranchPredictor (BranchPredictor),
- .DbgTriggerEn (DbgTriggerEn),
- .DbgHwBreakNum (DbgHwBreakNum),
- .Securebrq (Securebrq),
- .DmHaltAddr (DmHaltAddr),
- .DmExceptionAddr (DmExceptionAddr)
-) u_core (
- // clk_i and rst_ni
- .clk_i (clk_i),
- .rst_ni(rst_ni),
-
- // .test_en_i (test_en_i), // enable all clk_i gates for testing
-
- .hart_id_i (hart_id_i),
- .boot_addr_i(boot_addr_i),
-
- // Instruction memory interface
- .instr_req_o (instr_req),
- .instr_gnt_i (instr_gnt),
- .instr_rvalid_i (instr_rvalid),
- .instr_addr_o (instr_addr),
- .instr_rdata_i (instr_rdata),
- .instr_err_i (instr_err),
-
- // Data memory interface
- .data_req_o (data_req),
- .data_gnt_i (data_gnt),
- .data_rvalid_i (data_rvalid),
- .data_we_o (data_we),
- .data_be_o (data_be),
- .data_addr_o (data_addr),
- .data_wdata_o (data_wdata),
- .data_rdata_i (data_rdata),
- .data_err_i (data_err),
-
- // Interrupt inputs
- .irq_software_i (irq_software_i),
- .irq_timer_i (irq_timer_i),
- .irq_external_i (irq_external_i),
- .irq_fast_i (irq_fast_i),
- .irq_nm_i (irq_nm_i), // non-maskeable interrupt
-
- // Debug Interface
- .debug_req_i (debug_req_i),
-
- // RISC-V Formal Interface
- // Does not comply with the coding standards of _i/_o suffixes, but follows
- // the convention of RISC-V Formal Interface Specification.
-`ifdef RVFI
- .rvfi_valid (),
- .rvfi_order (),
- .rvfi_insn (),
- .rvfi_trap (),
- .rvfi_halt (),
- .rvfi_intr (),
- .rvfi_mode (),
- .rvfi_ixl (),
- .rvfi_rs1_addr (),
- .rvfi_rs2_addr (),
- .rvfi_rs3_addr (),
- .rvfi_rs1_rdata (),
- .rvfi_rs2_rdata (),
- .rvfi_rs3_rdata (),
- .rvfi_rd_addr (),
- .rvfi_rd_wdata (),
- .rvfi_pc_rdata (),
- .rvfi_pc_wdata (),
- .rvfi_mem_addr (),
- .rvfi_mem_rmask (),
- .rvfi_mem_wmask (),
- .rvfi_mem_rdata (),
- .rvfi_mem_wdata (),
-`endif
-
- // CPU Control Signals
- .fetch_enable_i (fetch_enable_i),
- .alert_minor_o (alert_minor_o),
- .alert_major_o (alert_major_o),
- .core_sleep_o (core_sleep_o)
-);
-
-tlul_host_adapter #(
- .MAX_REQS(2)
-) intr_interface (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .req_i (instr_req),
- .gnt_o (instr_gnt),
- .addr_i (instr_addr),
- .we_i (1'b0),
- .wdata_i (32'b0),
- .be_i (4'hF),
- .valid_o (instr_rvalid),
- .rdata_o (instr_rdata),
- .err_o (instr_err),
- .tl_h_c_a (tl_i_o),
- .tl_h_c_d (tl_i_i)
-);
-
-tlul_host_adapter #(
- .MAX_REQS (2)
-) data_interface (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .req_i (data_req),
- .gnt_o (data_gnt),
- .addr_i (data_addr),
- .we_i (data_we),
- .wdata_i (data_wdata),
- .be_i (data_be),
- .valid_o (data_rvalid),
- .rdata_o (data_rdata),
- .err_o (data_err),
- .tl_h_c_a (tl_d_o),
- .tl_h_c_d (tl_d_i)
-);
-
-
-endmodule
diff --git a/verilog/rtl/brq_counter.sv b/verilog/rtl/brq_counter.sv
deleted file mode 100644
index 3fedb28..0000000
--- a/verilog/rtl/brq_counter.sv
+++ /dev/null
@@ -1,82 +0,0 @@
-module brq_counter #(
- parameter int CounterWidth = 32
-) (
- input logic clk_i,
- input logic rst_ni,
-
- input logic counter_inc_i,
- input logic counterh_we_i,
- input logic counter_we_i,
- input logic [31:0] counter_val_i,
- output logic [63:0] counter_val_o
-);
-
- logic [63:0] counter;
- logic [CounterWidth-1:0] counter_upd;
- logic [63:0] counter_load;
- logic we;
- logic [CounterWidth-1:0] counter_d;
-
- // Update
- always_comb begin
-
- // Write
- we = counter_we_i | counterh_we_i;
- counter_load[63:32] = counter[63:32];
- counter_load[31:0] = counter_val_i;
- if (counterh_we_i) begin
- counter_load[63:32] = counter_val_i;
- counter_load[31:0] = counter[31:0];
- end
-
- // Increment
- counter_upd = counter[CounterWidth-1:0] + {{CounterWidth-1{1'b0}},1'b1};
-
- // Next value logic
- if (we) begin
- counter_d = counter_load[CounterWidth-1:0];
- end else if (counter_inc_i)begin
- counter_d = counter_upd[CounterWidth-1:0];
- end else begin
- counter_d = counter[CounterWidth-1:0];
- end
- 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
-`else
- 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;
- end
- end
-
- if (CounterWidth < 64) begin : g_counter_narrow
- logic [63:CounterWidth] unused_counter_load;
-
- assign counter[CounterWidth-1:0] = counter_q;
- assign counter[63:CounterWidth] = '0;
- assign unused_counter_load = counter_load[63:CounterWidth];
- end else begin : g_counter_full
- assign counter = counter_q;
- end
-
- assign counter_val_o = counter;
-
-endmodule
-
-// Keep helper defines file-local.
-`undef COUNTER_FLOP_RST
diff --git a/verilog/rtl/brq_cs_registers.sv b/verilog/rtl/brq_cs_registers.sv
deleted file mode 100644
index 39c7967..0000000
--- a/verilog/rtl/brq_cs_registers.sv
+++ /dev/null
@@ -1,1527 +0,0 @@
-
-/**
- * Control and Status Registers
- *
- * Control and Status Registers (CSRs) following the RISC-V Privileged
- * Specification, draft version 1.11
- */
-
-module brq_cs_registers #(
- parameter bit DbgTriggerEn = 0,
- parameter int unsigned DbgHwBreakNum = 1,
- parameter bit DataIndTiming = 1'b0,
- parameter bit DummyInstructions = 1'b0,
- parameter bit ShadowCSR = 1'b0,
- parameter bit ICache = 1'b0,
- parameter int unsigned MHPMCounterNum = 10,
- parameter int unsigned MHPMCounterWidth = 40,
- parameter bit PMPEnable = 0,
- parameter int unsigned PMPGranularity = 0,
- parameter int unsigned PMPNumRegions = 4,
- parameter bit RV32E = 0,
- parameter brq_pkg::rv32m_e RV32M = brq_pkg::RV32MFast,
- parameter brq_pkg::rvfloat_e RVF = brq_pkg::RV64FDouble // for floating point
-) (
- // Clock and Reset
- input logic clk_i,
- input logic rst_ni,
-
- // Hart ID
- input logic [31:0] hart_id_i,
-
- // Privilege mode
- output brq_pkg::priv_lvl_e priv_mode_id_o,
- output brq_pkg::priv_lvl_e priv_mode_if_o,
- output brq_pkg::priv_lvl_e priv_mode_lsu_o,
- output logic csr_mstatus_tw_o,
-
- // mtvec
- output logic [31:0] csr_mtvec_o,
- input logic csr_mtvec_init_i,
- input logic [31:0] boot_addr_i,
-
- // Interface to registers (SRAM like)
- input logic csr_access_i,
- input brq_pkg::csr_num_e csr_addr_i,
- input logic [31:0] csr_wdata_i,
- input brq_pkg::csr_op_e csr_op_i,
- input csr_op_en_i,
- output logic [31:0] csr_rdata_o,
-
- // interrupts
- input logic irq_software_i,
- input logic irq_timer_i,
- input logic irq_external_i,
- input logic [14:0] irq_fast_i,
- input logic nmi_mode_i,
- output logic irq_pending_o, // interrupt request pending
- output brq_pkg::irqs_t irqs_o, // interrupt requests qualified with mie
- output logic csr_mstatus_mie_o,
- output logic [31:0] csr_mepc_o,
-
- // PMP
- output brq_pkg::pmp_cfg_t csr_pmp_cfg_o [PMPNumRegions],
- output logic [33:0] csr_pmp_addr_o [PMPNumRegions],
-
- // debug
- input logic debug_mode_i,
- input brq_pkg::dbg_cause_e debug_cause_i,
- input logic debug_csr_save_i,
- output logic [31:0] csr_depc_o,
- output logic debug_single_step_o,
- output logic debug_ebreakm_o,
- output logic debug_ebreaku_o,
- output logic trigger_match_o,
-
- input logic [31:0] pc_if_i,
- input logic [31:0] pc_id_i,
- input logic [31:0] pc_wb_i,
-
- // CPU control bits
- output logic data_ind_timing_o,
- output logic csr_shadow_err_o,
-
- // Exception save/restore
- input logic csr_save_if_i,
- input logic csr_save_id_i,
- input logic csr_save_wb_i,
- input logic csr_restore_mret_i,
- input logic csr_restore_dret_i,
- input logic csr_save_cause_i,
- input brq_pkg::exc_cause_e csr_mcause_i,
- input logic [31:0] csr_mtval_i,
- output logic illegal_csr_insn_o, // access to non-existent CSR,
- // with wrong priviledge level, or
- // missing write permissions
- // Performance Counters
- input logic instr_ret_i, // instr retired in ID/EX stage
- input logic instr_ret_compressed_i, // compressed instr retired
- input logic iside_wait_i, // core waiting for the iside
- input logic jump_i, // jump instr seen (j, jr, jal, jalr)
- input logic branch_i, // branch instr seen (bf, bnf)
- input logic branch_taken_i, // branch was taken
- input logic mem_load_i, // load from memory in this cycle
- input logic mem_store_i, // store to memory in this cycle
- input logic dside_wait_i, // core waiting for the dside
- input logic mul_wait_i, // core waiting for multiply
- input logic div_wait_i, // core waiting for divide
-
- // floating point
- input logic fp_rm_dynamic_i,
- output fpnew_pkg::roundmode_e fp_frm_o,
- input fpnew_pkg::status_t fp_status_i,
- input logic is_fp_instr_i
-);
- import brq_pkg::*;
- import fpnew_pkg::roundmode_e;
-
- logic dummy_instr_en_o;
- logic [2:0] dummy_instr_mask_o;
- logic dummy_instr_seed_en_o;
- logic [31:0] dummy_instr_seed_o;
- logic icache_enable_o;
-
- localparam int unsigned RV32MEnabled = (RV32M == RV32MNone) ? 0 : 1;
- localparam int unsigned PMPAddrWidth = (PMPGranularity > 0) ? 33 - PMPGranularity : 32;
-
- localparam int unsigned SinglePrecision = (RVF == RV32FSingle) ? 1 : 0;
- localparam int unsigned DoublePrecision = (RVF == RV64FDouble) ? 1 : 0;
-
- // misa
- localparam logic [31:0] MISA_VALUE =
- (0 << 0) // A - Atomic Instructions extension
- | (1 << 2) // C - Compressed extension
- | (DoublePrecision << 3) // D - Double precision floating-point extension
- | (32'(RV32E) << 4) // E - RV32E base ISA
- | (SinglePrecision << 5) // F - Single precision floating-point extension
- | (32'(!RV32E) << 8) // I - RV32I/64I/128I base ISA
- | (RV32MEnabled << 12) // M - Integer Multiply/Divide extension
- | (0 << 13) // N - User level interrupts supported
- | (0 << 18) // S - Supervisor mode implemented
- | (1 << 20) // U - User mode implemented
- | (0 << 23) // X - Non-standard extensions present
- | (32'(CSR_MISA_MXL) << 30); // M-XLEN
-
- typedef struct packed {
- logic mie;
- logic mpie;
- priv_lvl_e mpp;
- logic mprv;
- logic tw;
- } status_t;
-
- typedef struct packed {
- logic mpie;
- priv_lvl_e mpp;
- } status_stk_t;
-
- typedef struct packed {
- x_debug_ver_e xdebugver;
- logic [11:0] zero2;
- logic ebreakm;
- logic zero1;
- logic ebreaks;
- logic ebreaku;
- logic stepie;
- logic stopcount;
- logic stoptime;
- dbg_cause_e cause;
- logic zero0;
- logic mprven;
- logic nmip;
- logic step;
- priv_lvl_e prv;
- } dcsr_t;
-
- // CPU control register fields
- typedef struct packed {
- logic [2:0] dummy_instr_mask;
- logic dummy_instr_en;
- logic data_ind_timing;
- logic icache_enable;
- } cpu_ctrl_t;
-
- // Interrupt and exception control signals
- logic [31:0] exception_pc;
-
- // CSRs
- fpnew_pkg::status_t fflags_q, fflags_d, fflag_wdata;
-
- logic fflags_en;
- logic frm_en;
- roundmode_e frm_q, frm_d;
- priv_lvl_e priv_lvl_q, priv_lvl_d;
- status_t mstatus_q, mstatus_d;
- logic mstatus_err;
- logic mstatus_en;
- irqs_t mie_q, mie_d;
- logic mie_en;
- logic [31:0] mscratch_q;
- logic mscratch_en;
- logic [31:0] mepc_q, mepc_d;
- logic mepc_en;
- logic [5:0] mcause_q, mcause_d;
- logic mcause_en;
- logic [31:0] mtval_q, mtval_d;
- logic mtval_en;
- logic [31:0] mtvec_q, mtvec_d;
- logic mtvec_err;
- logic mtvec_en;
- irqs_t mip;
- dcsr_t dcsr_q, dcsr_d;
- logic dcsr_en;
- logic [31:0] depc_q, depc_d;
- logic depc_en;
- logic [31:0] dscratch0_q;
- logic [31:0] dscratch1_q;
- logic dscratch0_en, dscratch1_en;
-
- // CSRs for recoverable NMIs
- // NOTE: these CSRS are nonstandard, see https://github.com/riscv/riscv-isa-manual/issues/261
- status_stk_t mstack_q, mstack_d;
- logic mstack_en;
- logic [31:0] mstack_epc_q, mstack_epc_d;
- logic [5:0] mstack_cause_q, mstack_cause_d;
-
- // PMP Signals
- logic [31:0] pmp_addr_rdata [PMP_MAX_REGIONS];
- logic [PMP_CFG_W-1:0] pmp_cfg_rdata [PMP_MAX_REGIONS];
- logic pmp_csr_err;
-
- // Hardware performance monitor signals
- logic [31:0] mcountinhibit;
- // Only have mcountinhibit flops for counters that actually exist
- logic [MHPMCounterNum+3-1:0] mcountinhibit_d, mcountinhibit_q;
- logic mcountinhibit_we;
-
- // mhpmcounter flops are elaborated below providing only the precise number that is required based
- // on MHPMCounterNum/MHPMCounterWidth. This signal connects to the Q output of these flops
- // where they exist and is otherwise 0.
- logic [63:0] mhpmcounter [32];
- logic [31:0] mhpmcounter_we;
- logic [31:0] mhpmcounterh_we;
- logic [31:0] mhpmcounter_incr;
- logic [31:0] mhpmevent [32];
- logic [4:0] mhpmcounter_idx;
- logic unused_mhpmcounter_we_1;
- logic unused_mhpmcounterh_we_1;
- logic unused_mhpmcounter_incr_1;
-
- // Debug / trigger registers
- logic [31:0] tselect_rdata;
- logic [31:0] tmatch_control_rdata;
- logic [31:0] tmatch_value_rdata;
-
- // CPU control bits
- cpu_ctrl_t cpuctrl_q, cpuctrl_d, cpuctrl_wdata;
- logic cpuctrl_we;
- logic cpuctrl_err;
-
- // CSR update logic
- logic [31:0] csr_wdata_int;
- logic [31:0] csr_rdata_int;
- logic csr_we_int;
- logic csr_wreq;
-
- // Access violation signals
- logic illegal_csr;
- logic illegal_csr_priv;
- logic illegal_csr_write;
-
- logic [7:0] unused_boot_addr;
- logic [2:0] unused_csr_addr;
-
- assign unused_boot_addr = boot_addr_i[7:0];
-
- /////////////
- // CSR reg //
- /////////////
-
- logic illegal_dyn_mod;
- logic illegal_csr_dyn_mod;
- logic [$bits(csr_num_e)-1:0] csr_addr;
- assign csr_addr = {csr_addr_i};
- assign unused_csr_addr = csr_addr[7:5];
- assign mhpmcounter_idx = csr_addr[4:0];
-
- assign illegal_csr_dyn_mod = illegal_dyn_mod & fp_rm_dynamic_i;
-
- // See RISC-V Privileged Specification, version 1.11, Section 2.1
- assign illegal_csr_priv = (csr_addr[9:8] > {priv_lvl_q});
- assign illegal_csr_write = (csr_addr[11:10] == 2'b11) && csr_wreq;
- assign illegal_csr_insn_o = (csr_access_i & (illegal_csr | illegal_csr_write | illegal_csr_priv)) | illegal_csr_dyn_mod;
-
- // mip CSR is purely combinational - must be able to re-enable the clock upon WFI
- assign mip.irq_software = irq_software_i;
- assign mip.irq_timer = irq_timer_i;
- assign mip.irq_external = irq_external_i;
- assign mip.irq_fast = irq_fast_i;
-
- // Floating point
- always_comb begin
- unique case (frm_q)
- 3'b000,
- 3'b001,
- 3'b010,
- 3'b011,
- 3'b100: illegal_dyn_mod = 1'b0;
- 3'b101,
- 3'b110,
- 3'b111: illegal_dyn_mod = 1'b1;
- endcase
- fp_frm_o = frm_q;
- end
-
- // read logic
- always_comb begin
- csr_rdata_int = '0;
- illegal_csr = 1'b0;
-
- unique case (csr_addr_i)
- // fcsr: floating-point control and status register (frm+fflags)
- CSR_FCSR: csr_rdata_int = {24'b0 , frm_q, fflags_q};
-
- // fflags: floating-point accrued exception
- CSR_FFLAG: csr_rdata_int = {27'b0 , fflags_q};
-
- // frm: floating-point dynamic rounding mode
- CSR_FRM: begin
- csr_rdata_int = {29'b0 , frm_q};
- end
-
- // mhartid: unique hardware thread id
- CSR_MHARTID: csr_rdata_int = hart_id_i;
-
- // mstatus: always M-mode, contains IE bit
- CSR_MSTATUS: begin
- csr_rdata_int = '0;
- csr_rdata_int[CSR_MSTATUS_MIE_BIT] = mstatus_q.mie;
- csr_rdata_int[CSR_MSTATUS_MPIE_BIT] = mstatus_q.mpie;
- csr_rdata_int[CSR_MSTATUS_MPP_BIT_HIGH:CSR_MSTATUS_MPP_BIT_LOW] = mstatus_q.mpp;
- csr_rdata_int[CSR_MSTATUS_MPRV_BIT] = mstatus_q.mprv;
- csr_rdata_int[CSR_MSTATUS_TW_BIT] = mstatus_q.tw;
- end
-
- // misa
- CSR_MISA: csr_rdata_int = MISA_VALUE;
-
- // interrupt enable
- CSR_MIE: begin
- csr_rdata_int = '0;
- csr_rdata_int[CSR_MSIX_BIT] = mie_q.irq_software;
- csr_rdata_int[CSR_MTIX_BIT] = mie_q.irq_timer;
- csr_rdata_int[CSR_MEIX_BIT] = mie_q.irq_external;
- csr_rdata_int[CSR_MFIX_BIT_HIGH:CSR_MFIX_BIT_LOW] = mie_q.irq_fast;
- end
-
- CSR_MSCRATCH: csr_rdata_int = mscratch_q;
-
- // mtvec: trap-vector base address
- CSR_MTVEC: csr_rdata_int = mtvec_q;
-
- // mepc: exception program counter
- CSR_MEPC: csr_rdata_int = mepc_q;
-
- // mcause: exception cause
- CSR_MCAUSE: csr_rdata_int = {mcause_q[5], 26'b0, mcause_q[4:0]};
-
- // mtval: trap value
- CSR_MTVAL: csr_rdata_int = mtval_q;
-
- // mip: interrupt pending
- CSR_MIP: begin
- csr_rdata_int = '0;
- csr_rdata_int[CSR_MSIX_BIT] = mip.irq_software;
- csr_rdata_int[CSR_MTIX_BIT] = mip.irq_timer;
- csr_rdata_int[CSR_MEIX_BIT] = mip.irq_external;
- csr_rdata_int[CSR_MFIX_BIT_HIGH:CSR_MFIX_BIT_LOW] = mip.irq_fast;
- end
-
- // PMP registers
- CSR_PMPCFG0: csr_rdata_int = {pmp_cfg_rdata[3], pmp_cfg_rdata[2],
- pmp_cfg_rdata[1], pmp_cfg_rdata[0]};
- CSR_PMPCFG1: csr_rdata_int = {pmp_cfg_rdata[7], pmp_cfg_rdata[6],
- pmp_cfg_rdata[5], pmp_cfg_rdata[4]};
- CSR_PMPCFG2: csr_rdata_int = {pmp_cfg_rdata[11], pmp_cfg_rdata[10],
- pmp_cfg_rdata[9], pmp_cfg_rdata[8]};
- CSR_PMPCFG3: csr_rdata_int = {pmp_cfg_rdata[15], pmp_cfg_rdata[14],
- pmp_cfg_rdata[13], pmp_cfg_rdata[12]};
- CSR_PMPADDR0: csr_rdata_int = pmp_addr_rdata[0];
- CSR_PMPADDR1: csr_rdata_int = pmp_addr_rdata[1];
- CSR_PMPADDR2: csr_rdata_int = pmp_addr_rdata[2];
- CSR_PMPADDR3: csr_rdata_int = pmp_addr_rdata[3];
- CSR_PMPADDR4: csr_rdata_int = pmp_addr_rdata[4];
- CSR_PMPADDR5: csr_rdata_int = pmp_addr_rdata[5];
- CSR_PMPADDR6: csr_rdata_int = pmp_addr_rdata[6];
- CSR_PMPADDR7: csr_rdata_int = pmp_addr_rdata[7];
- CSR_PMPADDR8: csr_rdata_int = pmp_addr_rdata[8];
- CSR_PMPADDR9: csr_rdata_int = pmp_addr_rdata[9];
- CSR_PMPADDR10: csr_rdata_int = pmp_addr_rdata[10];
- CSR_PMPADDR11: csr_rdata_int = pmp_addr_rdata[11];
- CSR_PMPADDR12: csr_rdata_int = pmp_addr_rdata[12];
- CSR_PMPADDR13: csr_rdata_int = pmp_addr_rdata[13];
- CSR_PMPADDR14: csr_rdata_int = pmp_addr_rdata[14];
- CSR_PMPADDR15: csr_rdata_int = pmp_addr_rdata[15];
-
- CSR_DCSR: begin
- csr_rdata_int = dcsr_q;
- illegal_csr = ~debug_mode_i;
- end
- CSR_DPC: begin
- csr_rdata_int = depc_q;
- illegal_csr = ~debug_mode_i;
- end
- CSR_DSCRATCH0: begin
- csr_rdata_int = dscratch0_q;
- illegal_csr = ~debug_mode_i;
- end
- CSR_DSCRATCH1: begin
- csr_rdata_int = dscratch1_q;
- illegal_csr = ~debug_mode_i;
- end
-
- // machine counter/timers
- CSR_MCOUNTINHIBIT: csr_rdata_int = mcountinhibit;
- CSR_MHPMEVENT3,
- CSR_MHPMEVENT4, CSR_MHPMEVENT5, CSR_MHPMEVENT6, CSR_MHPMEVENT7,
- CSR_MHPMEVENT8, CSR_MHPMEVENT9, CSR_MHPMEVENT10, CSR_MHPMEVENT11,
- CSR_MHPMEVENT12, CSR_MHPMEVENT13, CSR_MHPMEVENT14, CSR_MHPMEVENT15,
- CSR_MHPMEVENT16, CSR_MHPMEVENT17, CSR_MHPMEVENT18, CSR_MHPMEVENT19,
- CSR_MHPMEVENT20, CSR_MHPMEVENT21, CSR_MHPMEVENT22, CSR_MHPMEVENT23,
- CSR_MHPMEVENT24, CSR_MHPMEVENT25, CSR_MHPMEVENT26, CSR_MHPMEVENT27,
- CSR_MHPMEVENT28, CSR_MHPMEVENT29, CSR_MHPMEVENT30, CSR_MHPMEVENT31: begin
- csr_rdata_int = mhpmevent[mhpmcounter_idx];
- end
-
- CSR_MCYCLE,
- CSR_MINSTRET,
- CSR_MHPMCOUNTER3,
- CSR_MHPMCOUNTER4, CSR_MHPMCOUNTER5, CSR_MHPMCOUNTER6, CSR_MHPMCOUNTER7,
- CSR_MHPMCOUNTER8, CSR_MHPMCOUNTER9, CSR_MHPMCOUNTER10, CSR_MHPMCOUNTER11,
- CSR_MHPMCOUNTER12, CSR_MHPMCOUNTER13, CSR_MHPMCOUNTER14, CSR_MHPMCOUNTER15,
- CSR_MHPMCOUNTER16, CSR_MHPMCOUNTER17, CSR_MHPMCOUNTER18, CSR_MHPMCOUNTER19,
- CSR_MHPMCOUNTER20, CSR_MHPMCOUNTER21, CSR_MHPMCOUNTER22, CSR_MHPMCOUNTER23,
- CSR_MHPMCOUNTER24, CSR_MHPMCOUNTER25, CSR_MHPMCOUNTER26, CSR_MHPMCOUNTER27,
- CSR_MHPMCOUNTER28, CSR_MHPMCOUNTER29, CSR_MHPMCOUNTER30, CSR_MHPMCOUNTER31: begin
- csr_rdata_int = mhpmcounter[mhpmcounter_idx][31:0];
- end
-
- CSR_MCYCLEH,
- CSR_MINSTRETH,
- CSR_MHPMCOUNTER3H,
- CSR_MHPMCOUNTER4H, CSR_MHPMCOUNTER5H, CSR_MHPMCOUNTER6H, CSR_MHPMCOUNTER7H,
- CSR_MHPMCOUNTER8H, CSR_MHPMCOUNTER9H, CSR_MHPMCOUNTER10H, CSR_MHPMCOUNTER11H,
- CSR_MHPMCOUNTER12H, CSR_MHPMCOUNTER13H, CSR_MHPMCOUNTER14H, CSR_MHPMCOUNTER15H,
- CSR_MHPMCOUNTER16H, CSR_MHPMCOUNTER17H, CSR_MHPMCOUNTER18H, CSR_MHPMCOUNTER19H,
- CSR_MHPMCOUNTER20H, CSR_MHPMCOUNTER21H, CSR_MHPMCOUNTER22H, CSR_MHPMCOUNTER23H,
- CSR_MHPMCOUNTER24H, CSR_MHPMCOUNTER25H, CSR_MHPMCOUNTER26H, CSR_MHPMCOUNTER27H,
- CSR_MHPMCOUNTER28H, CSR_MHPMCOUNTER29H, CSR_MHPMCOUNTER30H, CSR_MHPMCOUNTER31H: begin
- csr_rdata_int = mhpmcounter[mhpmcounter_idx][63:32];
- end
-
- // Debug triggers
- CSR_TSELECT: begin
- csr_rdata_int = tselect_rdata;
- illegal_csr = ~DbgTriggerEn;
- end
- CSR_TDATA1: begin
- csr_rdata_int = tmatch_control_rdata;
- illegal_csr = ~DbgTriggerEn;
- end
- CSR_TDATA2: begin
- csr_rdata_int = tmatch_value_rdata;
- illegal_csr = ~DbgTriggerEn;
- end
- CSR_TDATA3: begin
- csr_rdata_int = '0;
- illegal_csr = ~DbgTriggerEn;
- end
- CSR_MCONTEXT: begin
- csr_rdata_int = '0;
- illegal_csr = ~DbgTriggerEn;
- end
- CSR_SCONTEXT: begin
- csr_rdata_int = '0;
- illegal_csr = ~DbgTriggerEn;
- end
-
- // Custom CSR for controlling CPU features
- CSR_CPUCTRL: begin
- csr_rdata_int = {{32-$bits(cpu_ctrl_t){1'b0}},cpuctrl_q};
- end
-
- // Custom CSR for LFSR re-seeding (cannot be read)
- CSR_SECURESEED: begin
- csr_rdata_int = '0;
- end
-
- default: begin
- illegal_csr = 1'b1;
- end
- endcase
- end
-
- // write logic
- always_comb begin
- exception_pc = pc_id_i;
-
- // Floating point
- fflags_d = fflags_q;
- fflags_en = 1'b0;
-
- frm_d = frm_q;
- frm_en = 1'b0;
-
- priv_lvl_d = priv_lvl_q;
- mstatus_en = 1'b0;
- mstatus_d = mstatus_q;
- mie_en = 1'b0;
- mscratch_en = 1'b0;
- mepc_en = 1'b0;
- mepc_d = {csr_wdata_int[31:1], 1'b0};
- mcause_en = 1'b0;
- mcause_d = {csr_wdata_int[31], csr_wdata_int[4:0]};
- mtval_en = 1'b0;
- mtval_d = csr_wdata_int;
- mtvec_en = csr_mtvec_init_i;
- // mtvec.MODE set to vectored
- // mtvec.BASE must be 256-byte aligned
- mtvec_d = csr_mtvec_init_i ? {boot_addr_i[31:2], 2'b00} :
- {csr_wdata_int[31:2], 2'b00};
- dcsr_en = 1'b0;
- dcsr_d = dcsr_q;
- depc_d = {csr_wdata_int[31:1], 1'b0};
- depc_en = 1'b0;
- dscratch0_en = 1'b0;
- dscratch1_en = 1'b0;
-
- mstack_en = 1'b0;
- mstack_d.mpie = mstatus_q.mpie;
- mstack_d.mpp = mstatus_q.mpp;
- mstack_epc_d = mepc_q;
- mstack_cause_d = mcause_q;
-
- mcountinhibit_we = 1'b0;
- mhpmcounter_we = '0;
- mhpmcounterh_we = '0;
-
- cpuctrl_we = 1'b0;
-
- if (csr_we_int) begin
- unique case (csr_addr_i)
- // mstatus: IE bit
-
- CSR_FCSR: begin
- fflags_en = 1'b1;
- frm_en = 1'b1;
- fflags_d = csr_wdata_int[4:0];
- frm_d = roundmode_e'(csr_wdata_int[7:5]);
- end
-
-
- CSR_FFLAG : begin
- fflags_en = 1'b1;
- fflags_d = fpnew_pkg::status_t'(csr_wdata_int[4:0]);
- end
-
- CSR_FRM: begin
- frm_en = 1'b1;
- frm_d = roundmode_e'(csr_wdata_int[2:0]);
- end
-
- CSR_MSTATUS: begin
- mstatus_en = 1'b1;
- mstatus_d = '{
- mie: csr_wdata_int[CSR_MSTATUS_MIE_BIT],
- mpie: csr_wdata_int[CSR_MSTATUS_MPIE_BIT],
- mpp: priv_lvl_e'(csr_wdata_int[CSR_MSTATUS_MPP_BIT_HIGH:CSR_MSTATUS_MPP_BIT_LOW]),
- mprv: csr_wdata_int[CSR_MSTATUS_MPRV_BIT],
- tw: csr_wdata_int[CSR_MSTATUS_TW_BIT]
- };
- // Convert illegal values to M-mode
- if ((mstatus_d.mpp != PRIV_LVL_M) && (mstatus_d.mpp != PRIV_LVL_U)) begin
- mstatus_d.mpp = PRIV_LVL_M;
- end
- end
-
- // interrupt enable
- CSR_MIE: mie_en = 1'b1;
-
- CSR_MSCRATCH: mscratch_en = 1'b1;
-
- // mepc: exception program counter
- CSR_MEPC: mepc_en = 1'b1;
-
- // mcause
- CSR_MCAUSE: mcause_en = 1'b1;
-
- // mtval: trap value
- CSR_MTVAL: mtval_en = 1'b1;
-
- // mtvec
- CSR_MTVEC: mtvec_en = 1'b1;
-
- CSR_DCSR: begin
- dcsr_d = csr_wdata_int;
- dcsr_d.xdebugver = XDEBUGVER_STD;
- // Change to PRIV_LVL_M if software writes an unsupported value
- if ((dcsr_d.prv != PRIV_LVL_M) && (dcsr_d.prv != PRIV_LVL_U)) begin
- dcsr_d.prv = PRIV_LVL_M;
- end
-
- // Read-only for SW
- dcsr_d.cause = dcsr_q.cause;
-
- // currently not supported:
- dcsr_d.nmip = 1'b0;
- dcsr_d.mprven = 1'b0;
- dcsr_d.stopcount = 1'b0;
- dcsr_d.stoptime = 1'b0;
-
- // forced to be zero
- dcsr_d.zero0 = 1'b0;
- dcsr_d.zero1 = 1'b0;
- dcsr_d.zero2 = 12'h0;
- dcsr_en = 1'b1;
- end
-
- // dpc: debug program counter
- CSR_DPC: depc_en = 1'b1;
-
- CSR_DSCRATCH0: dscratch0_en = 1'b1;
- CSR_DSCRATCH1: dscratch1_en = 1'b1;
-
- // machine counter/timers
- CSR_MCOUNTINHIBIT: mcountinhibit_we = 1'b1;
-
- CSR_MCYCLE,
- CSR_MINSTRET,
- CSR_MHPMCOUNTER3,
- CSR_MHPMCOUNTER4, CSR_MHPMCOUNTER5, CSR_MHPMCOUNTER6, CSR_MHPMCOUNTER7,
- CSR_MHPMCOUNTER8, CSR_MHPMCOUNTER9, CSR_MHPMCOUNTER10, CSR_MHPMCOUNTER11,
- CSR_MHPMCOUNTER12, CSR_MHPMCOUNTER13, CSR_MHPMCOUNTER14, CSR_MHPMCOUNTER15,
- CSR_MHPMCOUNTER16, CSR_MHPMCOUNTER17, CSR_MHPMCOUNTER18, CSR_MHPMCOUNTER19,
- CSR_MHPMCOUNTER20, CSR_MHPMCOUNTER21, CSR_MHPMCOUNTER22, CSR_MHPMCOUNTER23,
- CSR_MHPMCOUNTER24, CSR_MHPMCOUNTER25, CSR_MHPMCOUNTER26, CSR_MHPMCOUNTER27,
- CSR_MHPMCOUNTER28, CSR_MHPMCOUNTER29, CSR_MHPMCOUNTER30, CSR_MHPMCOUNTER31: begin
- mhpmcounter_we[mhpmcounter_idx] = 1'b1;
- end
-
- CSR_MCYCLEH,
- CSR_MINSTRETH,
- CSR_MHPMCOUNTER3H,
- CSR_MHPMCOUNTER4H, CSR_MHPMCOUNTER5H, CSR_MHPMCOUNTER6H, CSR_MHPMCOUNTER7H,
- CSR_MHPMCOUNTER8H, CSR_MHPMCOUNTER9H, CSR_MHPMCOUNTER10H, CSR_MHPMCOUNTER11H,
- CSR_MHPMCOUNTER12H, CSR_MHPMCOUNTER13H, CSR_MHPMCOUNTER14H, CSR_MHPMCOUNTER15H,
- CSR_MHPMCOUNTER16H, CSR_MHPMCOUNTER17H, CSR_MHPMCOUNTER18H, CSR_MHPMCOUNTER19H,
- CSR_MHPMCOUNTER20H, CSR_MHPMCOUNTER21H, CSR_MHPMCOUNTER22H, CSR_MHPMCOUNTER23H,
- CSR_MHPMCOUNTER24H, CSR_MHPMCOUNTER25H, CSR_MHPMCOUNTER26H, CSR_MHPMCOUNTER27H,
- CSR_MHPMCOUNTER28H, CSR_MHPMCOUNTER29H, CSR_MHPMCOUNTER30H, CSR_MHPMCOUNTER31H: begin
- mhpmcounterh_we[mhpmcounter_idx] = 1'b1;
- end
-
- CSR_CPUCTRL: cpuctrl_we = 1'b1;
-
- default:;
- endcase
- end
-
- // exception controller gets priority over other writes
- unique case (1'b1)
-
- csr_save_cause_i: begin
- unique case (1'b1)
- csr_save_if_i: begin
- exception_pc = pc_if_i;
- end
- csr_save_id_i: begin
- exception_pc = pc_id_i;
- end
- csr_save_wb_i: begin
- exception_pc = pc_wb_i;
- end
- default:;
- endcase
-
- // Any exception, including debug mode, causes a switch to M-mode
- priv_lvl_d = PRIV_LVL_M;
-
- if (debug_csr_save_i) begin
- // all interrupts are masked
- // do not update cause, epc, tval, epc and status
- dcsr_d.prv = priv_lvl_q;
- dcsr_d.cause = debug_cause_i;
- dcsr_en = 1'b1;
- depc_d = exception_pc;
- depc_en = 1'b1;
- end else if (!debug_mode_i) begin
- // In debug mode, "exceptions do not update any registers. That
- // includes cause, epc, tval, dpc and mstatus." [Debug Spec v0.13.2, p.39]
- mtval_en = 1'b1;
- mtval_d = csr_mtval_i;
- mstatus_en = 1'b1;
- mstatus_d.mie = 1'b0; // disable interrupts
- // save current status
- mstatus_d.mpie = mstatus_q.mie;
- mstatus_d.mpp = priv_lvl_q;
- mepc_en = 1'b1;
- mepc_d = exception_pc;
- mcause_en = 1'b1;
- mcause_d = {csr_mcause_i};
- // save previous status for recoverable NMI
- mstack_en = 1'b1;
- end
- end // csr_save_cause_i
-
- csr_restore_dret_i: begin // DRET
- priv_lvl_d = dcsr_q.prv;
- end // csr_restore_dret_i
-
- csr_restore_mret_i: begin // MRET
- priv_lvl_d = mstatus_q.mpp;
- mstatus_en = 1'b1;
- mstatus_d.mie = mstatus_q.mpie; // re-enable interrupts
-
- if (nmi_mode_i) begin
- // when returning from an NMI restore state from mstack CSR
- mstatus_d.mpie = mstack_q.mpie;
- mstatus_d.mpp = mstack_q.mpp;
- mepc_en = 1'b1;
- mepc_d = mstack_epc_q;
- mcause_en = 1'b1;
- mcause_d = mstack_cause_q;
- end else begin
- // otherwise just set mstatus.MPIE/MPP
- // See RISC-V Privileged Specification, version 1.11, Section 3.1.6.1
- mstatus_d.mpie = 1'b1;
- mstatus_d.mpp = PRIV_LVL_U;
- end
- end // csr_restore_mret_i
-
- default:;
- endcase
- end
-
- // Update current priv level
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- priv_lvl_q <= PRIV_LVL_M;
- end else begin
- priv_lvl_q <= priv_lvl_d;
- end
- end
-
- // Send current priv level to the decoder
- assign priv_mode_id_o = priv_lvl_q;
- // New instruction fetches need to account for updates to priv_lvl_q this cycle
- assign priv_mode_if_o = priv_lvl_d;
- // Load/store instructions must factor in MPRV for PMP checking
- assign priv_mode_lsu_o = mstatus_q.mprv ? mstatus_q.mpp : priv_lvl_q;
-
- // CSR operation logic
- always_comb begin
- unique case (csr_op_i)
- CSR_OP_WRITE: csr_wdata_int = csr_wdata_i;
- CSR_OP_SET: csr_wdata_int = csr_wdata_i | csr_rdata_o;
- CSR_OP_CLEAR: csr_wdata_int = ~csr_wdata_i & csr_rdata_o;
- CSR_OP_READ: csr_wdata_int = csr_wdata_i;
- // default: csr_wdata_int = csr_wdata_i;
- endcase
- end
-
- assign csr_wreq = csr_op_en_i &
- (csr_op_i inside {CSR_OP_WRITE,
- CSR_OP_SET,
- CSR_OP_CLEAR});
-
- // only write CSRs during one clock cycle
- assign csr_we_int = csr_wreq & ~illegal_csr_insn_o;
-
- assign csr_rdata_o = csr_rdata_int;
-
- // directly output some registers
- assign csr_mepc_o = mepc_q;
- assign csr_depc_o = depc_q;
- assign csr_mtvec_o = mtvec_q;
-
- assign csr_mstatus_mie_o = mstatus_q.mie;
- assign csr_mstatus_tw_o = mstatus_q.tw;
- assign debug_single_step_o = dcsr_q.step;
- assign debug_ebreakm_o = dcsr_q.ebreakm;
- assign debug_ebreaku_o = dcsr_q.ebreaku;
-
- // Qualify incoming interrupt requests in mip CSR with mie CSR for controller and to re-enable
- // clock upon WFI (must be purely combinational).
- assign irqs_o = mip & mie_q;
- assign irq_pending_o = |irqs_o;
-
- ////////////////////////
- // CSR instantiations //
- ////////////////////////
- logic unused_error1;
- logic unused_error2;
- logic unused_error3;
- logic unused_error4;
- logic unused_error5;
- logic unused_error6;
- logic unused_error7;
- logic unused_error8;
- logic unused_error9;
- logic unused_error10;
- logic unused_error11;
- logic unused_error12;
- logic unused_error13;
- logic unused_error14;
- logic unused_error15;
- logic unused_error16;
- logic unused_error17;
- // MSTATUS
- localparam status_t MSTATUS_RST_VAL = '{mie: 1'b0,
- mpie: 1'b1,
- mpp: PRIV_LVL_U,
- mprv: 1'b0,
- tw: 1'b0};
- brq_csr #(
- .Width ($bits(status_t)),
- .ShadowCopy (ShadowCSR),
- .ResetValue ({MSTATUS_RST_VAL})
- ) u_mstatus_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i ({mstatus_d}),
- .wr_en_i (mstatus_en),
- .rd_data_o (mstatus_q),
- .rd_error_o (mstatus_err)
- );
-
- assign fflag_wdata = is_fp_instr_i ? fp_status_i : fflags_d;
- // FFLAGS
- brq_csr #(
- .Width (5),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) fflags_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (fflag_wdata),
- .wr_en_i (fflags_en | is_fp_instr_i),
- .rd_data_o (fflags_q),
- .rd_error_o (unused_error1)
- );
-
- // FRM
- brq_csr #(
- .Width (3),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) frm_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (frm_d),
- .wr_en_i (frm_en),
- .rd_data_o (frm_q),
- .rd_error_o (unused_error2)
- );
-
- // MEPC
- brq_csr #(
- .Width (32),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_mepc_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (mepc_d),
- .wr_en_i (mepc_en),
- .rd_data_o (mepc_q),
- .rd_error_o (unused_error3)
- );
-
- // MIE
- assign mie_d.irq_software = csr_wdata_int[CSR_MSIX_BIT];
- assign mie_d.irq_timer = csr_wdata_int[CSR_MTIX_BIT];
- assign mie_d.irq_external = csr_wdata_int[CSR_MEIX_BIT];
- assign mie_d.irq_fast = csr_wdata_int[CSR_MFIX_BIT_HIGH:CSR_MFIX_BIT_LOW];
- brq_csr #(
- .Width ($bits(irqs_t)),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_mie_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i ({mie_d}),
- .wr_en_i (mie_en),
- .rd_data_o (mie_q),
- .rd_error_o (unused_error4)
- );
-
- // MSCRATCH
- brq_csr #(
- .Width (32),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_mscratch_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (csr_wdata_int),
- .wr_en_i (mscratch_en),
- .rd_data_o (mscratch_q),
- .rd_error_o (unused_error5)
- );
-
- // MCAUSE
- brq_csr #(
- .Width (6),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_mcause_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (mcause_d),
- .wr_en_i (mcause_en),
- .rd_data_o (mcause_q),
- .rd_error_o (unused_error6)
- );
-
- // MTVAL
- brq_csr #(
- .Width (32),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_mtval_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (mtval_d),
- .wr_en_i (mtval_en),
- .rd_data_o (mtval_q),
- .rd_error_o (unused_error7)
- );
-
- // MTVEC
- brq_csr #(
- .Width (32),
- .ShadowCopy (ShadowCSR),
- .ResetValue (32'd1)
- ) u_mtvec_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (mtvec_d),
- .wr_en_i (mtvec_en),
- .rd_data_o (mtvec_q),
- .rd_error_o (mtvec_err)
- );
-
- // DCSR
- localparam dcsr_t DCSR_RESET_VAL = '{
- xdebugver: XDEBUGVER_STD,
- cause: DBG_CAUSE_NONE, // 3'h0
- prv: PRIV_LVL_M,
- default: '0
- };
- brq_csr #(
- .Width ($bits(dcsr_t)),
- .ShadowCopy (1'b0),
- .ResetValue ({DCSR_RESET_VAL})
- ) u_dcsr_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i ({dcsr_d}),
- .wr_en_i (dcsr_en),
- .rd_data_o (dcsr_q),
- .rd_error_o (unused_error8)
- );
-
- // DEPC
- brq_csr #(
- .Width (32),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_depc_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (depc_d),
- .wr_en_i (depc_en),
- .rd_data_o (depc_q),
- .rd_error_o (unused_error9)
- );
-
- // DSCRATCH0
- brq_csr #(
- .Width (32),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_dscratch0_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (csr_wdata_int),
- .wr_en_i (dscratch0_en),
- .rd_data_o (dscratch0_q),
- .rd_error_o (unused_error10)
- );
-
- // DSCRATCH1
- brq_csr #(
- .Width (32),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_dscratch1_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (csr_wdata_int),
- .wr_en_i (dscratch1_en),
- .rd_data_o (dscratch1_q),
- .rd_error_o (unused_error11)
- );
-
- // MSTACK
- localparam status_stk_t MSTACK_RESET_VAL = '{
- mpie: 1'b1,
- mpp: PRIV_LVL_U
- };
- brq_csr #(
- .Width ($bits(status_stk_t)),
- .ShadowCopy (1'b0),
- .ResetValue ({MSTACK_RESET_VAL})
- ) u_mstack_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i ({mstack_d}),
- .wr_en_i (mstack_en),
- .rd_data_o (mstack_q),
- .rd_error_o (unused_error12)
- );
-
- // MSTACK_EPC
- brq_csr #(
- .Width (32),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_mstack_epc_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (mstack_epc_d),
- .wr_en_i (mstack_en),
- .rd_data_o (mstack_epc_q),
- .rd_error_o (unused_error13)
- );
-
- // MSTACK_CAUSE
- brq_csr #(
- .Width (6),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_mstack_cause_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (mstack_cause_d),
- .wr_en_i (mstack_en),
- .rd_data_o (mstack_cause_q),
- .rd_error_o (unused_error14)
- );
-
- // -----------------
- // PMP registers
- // -----------------
-
- if (PMPEnable) begin : g_pmp_registers
- pmp_cfg_t pmp_cfg [PMPNumRegions];
- pmp_cfg_t pmp_cfg_wdata [PMPNumRegions];
- logic [PMPAddrWidth-1:0] pmp_addr [PMPNumRegions];
- logic [PMPNumRegions-1:0] pmp_cfg_we;
- logic [PMPNumRegions-1:0] pmp_cfg_err;
- logic [PMPNumRegions-1:0] pmp_addr_we;
- logic [PMPNumRegions-1:0] pmp_addr_err;
-
- // Expanded / qualified register read data
- for (genvar i = 0; i < PMP_MAX_REGIONS; i++) begin : g_exp_rd_data
- if (i < PMPNumRegions) begin : g_implemented_regions
- // Add in zero padding for reserved fields
- assign pmp_cfg_rdata[i] = {pmp_cfg[i].lock, 2'b00, pmp_cfg[i].mode,
- pmp_cfg[i].exec, pmp_cfg[i].write, pmp_cfg[i].read};
-
- // Address field read data depends on the current programmed mode and the granularity
- // See RISC-V Privileged Specification, version 1.11, Section 3.6.1
- if (PMPGranularity == 0) begin : g_pmp_g0
- // If G == 0, read data is unmodified
- assign pmp_addr_rdata[i] = pmp_addr[i];
-
- end else if (PMPGranularity == 1) begin : g_pmp_g1
- // If G == 1, bit [G-1] reads as zero in TOR or OFF mode
- always_comb begin
- pmp_addr_rdata[i] = pmp_addr[i];
- if ((pmp_cfg[i].mode == PMP_MODE_OFF) || (pmp_cfg[i].mode == PMP_MODE_TOR)) begin
- pmp_addr_rdata[i][PMPGranularity-1:0] = '0;
- end
- end
-
- end else begin : g_pmp_g2
- // For G >= 2, bits are masked to one or zero depending on the mode
- always_comb begin
- // In NAPOT mode, bits [G-2:0] must read as one
- pmp_addr_rdata[i] = {pmp_addr[i], {PMPGranularity-1{1'b1}}};
-
- if ((pmp_cfg[i].mode == PMP_MODE_OFF) || (pmp_cfg[i].mode == PMP_MODE_TOR)) begin
- // In TOR or OFF mode, bits [G-1:0] must read as zero
- pmp_addr_rdata[i][PMPGranularity-1:0] = '0;
- end
- end
- end
-
- end else begin : g_other_regions
- // Non-implemented regions read as zero
- assign pmp_cfg_rdata[i] = '0;
- assign pmp_addr_rdata[i] = '0;
- end
- end
-
- // Write data calculation
- for (genvar i = 0; i < PMPNumRegions; i++) begin : g_pmp_csrs
- // -------------------------
- // Instantiate cfg registers
- // -------------------------
- assign pmp_cfg_we[i] = csr_we_int & ~pmp_cfg[i].lock &
- (csr_addr == (CSR_OFF_PMP_CFG + (i[11:0] >> 2)));
-
- // Select the correct WDATA (each CSR contains 4 CFG fields, each with 2 RES bits)
- assign pmp_cfg_wdata[i].lock = csr_wdata_int[(i%4)*PMP_CFG_W+7];
- // NA4 mode is not selectable when G > 0, mode is treated as OFF
- always_comb begin
- unique case (csr_wdata_int[(i%4)*PMP_CFG_W+3+:2])
- 2'b00 : pmp_cfg_wdata[i].mode = PMP_MODE_OFF;
- 2'b01 : pmp_cfg_wdata[i].mode = PMP_MODE_TOR;
- 2'b10 : pmp_cfg_wdata[i].mode = (PMPGranularity == 0) ? PMP_MODE_NA4:
- PMP_MODE_OFF;
- 2'b11 : pmp_cfg_wdata[i].mode = PMP_MODE_NAPOT;
- default : pmp_cfg_wdata[i].mode = PMP_MODE_OFF;
- endcase
- end
- assign pmp_cfg_wdata[i].exec = csr_wdata_int[(i%4)*PMP_CFG_W+2];
- // W = 1, R = 0 is a reserved combination. For now, we force W to 0 if R == 0
- assign pmp_cfg_wdata[i].write = &csr_wdata_int[(i%4)*PMP_CFG_W+:2];
- assign pmp_cfg_wdata[i].read = csr_wdata_int[(i%4)*PMP_CFG_W];
-
- brq_csr #(
- .Width ($bits(pmp_cfg_t)),
- .ShadowCopy (ShadowCSR),
- .ResetValue ('0)
- ) u_pmp_cfg_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i ({pmp_cfg_wdata[i]}),
- .wr_en_i (pmp_cfg_we[i]),
- .rd_data_o (pmp_cfg[i]),
- .rd_error_o (pmp_cfg_err[i])
- );
-
- // --------------------------
- // Instantiate addr registers
- // --------------------------
- if (i < PMPNumRegions - 1) begin : g_lower
- assign pmp_addr_we[i] = csr_we_int & ~pmp_cfg[i].lock &
- (~pmp_cfg[i+1].lock | (pmp_cfg[i+1].mode != PMP_MODE_TOR)) &
- (csr_addr == (CSR_OFF_PMP_ADDR + i[11:0]));
- end else begin : g_upper
- assign pmp_addr_we[i] = csr_we_int & ~pmp_cfg[i].lock &
- (csr_addr == (CSR_OFF_PMP_ADDR + i[11:0]));
- end
-
- brq_csr #(
- .Width (PMPAddrWidth),
- .ShadowCopy (ShadowCSR),
- .ResetValue ('0)
- ) u_pmp_addr_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (csr_wdata_int[31-:PMPAddrWidth]),
- .wr_en_i (pmp_addr_we[i]),
- .rd_data_o (pmp_addr[i]),
- .rd_error_o (pmp_addr_err[i])
- );
-
- assign csr_pmp_cfg_o[i] = pmp_cfg[i];
- assign csr_pmp_addr_o[i] = {pmp_addr_rdata[i], 2'b00};
- end
-
- assign pmp_csr_err = (|pmp_cfg_err) | (|pmp_addr_err);
-
- end else begin : g_no_pmp_tieoffs
- // Generate tieoffs when PMP is not configured
- for (genvar i = 0; i < PMP_MAX_REGIONS; i++) begin : g_rdata
- assign pmp_addr_rdata[i] = '0;
- assign pmp_cfg_rdata[i] = '0;
- end
- for (genvar i = 0; i < PMPNumRegions; i++) begin : g_outputs
- assign csr_pmp_cfg_o[i] = pmp_cfg_t'(1'b0);
- assign csr_pmp_addr_o[i] = '0;
- end
- assign pmp_csr_err = 1'b0;
- end
-
- //////////////////////////
- // Performance monitor //
- //////////////////////////
-
- // update enable signals
- always_comb begin : mcountinhibit_update
- if (mcountinhibit_we == 1'b1) begin
- // bit 1 must always be 0
- mcountinhibit_d = {csr_wdata_int[MHPMCounterNum+2:2], 1'b0, csr_wdata_int[0]};
- end else begin
- mcountinhibit_d = mcountinhibit_q;
- end
- end
-
- // event selection (hardwired) & control
- always_comb begin : gen_mhpmcounter_incr
-
- // Assign inactive counters (first to prevent latch inference)
- for (int unsigned i=0; i<32; i++) begin : gen_mhpmcounter_incr_inactive
- mhpmcounter_incr[i] = 1'b0;
- end
-
- // When adding or altering performance counter meanings and default
- // mappings please update dv/verilator/pcount/cpp/brq_pcounts.cc
- // appropriately.
- //
- // active counters
- mhpmcounter_incr[0] = 1'b1; // mcycle
- mhpmcounter_incr[1] = 1'b0; // reserved
- mhpmcounter_incr[2] = instr_ret_i; // minstret
- mhpmcounter_incr[3] = dside_wait_i; // cycles waiting for data memory
- mhpmcounter_incr[4] = iside_wait_i; // cycles waiting for instr fetches
- mhpmcounter_incr[5] = mem_load_i; // num of loads
- mhpmcounter_incr[6] = mem_store_i; // num of stores
- mhpmcounter_incr[7] = jump_i; // num of jumps (unconditional)
- mhpmcounter_incr[8] = branch_i; // num of branches (conditional)
- mhpmcounter_incr[9] = branch_taken_i; // num of taken branches (conditional)
- mhpmcounter_incr[10] = instr_ret_compressed_i; // num of compressed instr
- mhpmcounter_incr[11] = mul_wait_i; // cycles waiting for multiply
- mhpmcounter_incr[12] = div_wait_i; // cycles waiting for divide
- end
-
- // event selector (hardwired, 0 means no event)
- always_comb begin : gen_mhpmevent
-
- // activate all
- for (int i=0; i<32; i++) begin : gen_mhpmevent_active
- mhpmevent[i] = '0;
- mhpmevent[i][i] = 1'b1;
- end
-
- // deactivate
- mhpmevent[1] = '0; // not existing, reserved
- for (int unsigned i=3+MHPMCounterNum; i<32; i++) begin : gen_mhpmevent_inactive
- mhpmevent[i] = '0;
- end
- end
-
- // mcycle
- brq_counter #(
- .CounterWidth(64)
- ) mcycle_counter_i (
- .clk_i(clk_i),
- .rst_ni(rst_ni),
- .counter_inc_i(mhpmcounter_incr[0] & ~mcountinhibit[0]),
- .counterh_we_i(mhpmcounterh_we[0]),
- .counter_we_i(mhpmcounter_we[0]),
- .counter_val_i(csr_wdata_int),
- .counter_val_o(mhpmcounter[0])
- );
-
- // minstret
- brq_counter #(
- .CounterWidth(64)
- ) minstret_counter_i (
- .clk_i(clk_i),
- .rst_ni(rst_ni),
- .counter_inc_i(mhpmcounter_incr[2] & ~mcountinhibit[2]),
- .counterh_we_i(mhpmcounterh_we[2]),
- .counter_we_i(mhpmcounter_we[2]),
- .counter_val_i(csr_wdata_int),
- .counter_val_o(mhpmcounter[2])
- );
-
- // reserved:
- assign mhpmcounter[1] = '0;
- assign unused_mhpmcounter_we_1 = mhpmcounter_we[1];
- assign unused_mhpmcounterh_we_1 = mhpmcounterh_we[1];
- assign unused_mhpmcounter_incr_1 = mhpmcounter_incr[1];
-
- for (genvar cnt=0; cnt < 29; cnt++) begin : gen_cntrs
- if (cnt < MHPMCounterNum) begin : gen_imp
- brq_counter #(
- .CounterWidth(MHPMCounterWidth)
- ) mcounters_variable_i (
- .clk_i(clk_i),
- .rst_ni(rst_ni),
- .counter_inc_i(mhpmcounter_incr[cnt+3] & ~mcountinhibit[cnt+3]),
- .counterh_we_i(mhpmcounterh_we[cnt+3]),
- .counter_we_i(mhpmcounter_we[cnt+3]),
- .counter_val_i(csr_wdata_int),
- .counter_val_o(mhpmcounter[cnt+3])
- );
- end else begin : gen_unimp
- assign mhpmcounter[cnt+3] = '0;
- end
- end
-
- if(MHPMCounterNum < 29) begin : g_mcountinhibit_reduced
- logic [29-MHPMCounterNum-1:0] unused_mhphcounter_we;
- logic [29-MHPMCounterNum-1:0] unused_mhphcounterh_we;
- logic [29-MHPMCounterNum-1:0] unused_mhphcounter_incr;
-
- assign mcountinhibit = {{29-MHPMCounterNum{1'b1}}, mcountinhibit_q};
- // Lint tieoffs for unused bits
- assign unused_mhphcounter_we = mhpmcounter_we[31:MHPMCounterNum+3];
- assign unused_mhphcounterh_we = mhpmcounterh_we[31:MHPMCounterNum+3];
- assign unused_mhphcounter_incr = mhpmcounter_incr[31:MHPMCounterNum+3];
- end else begin : g_mcountinhibit_full
- assign mcountinhibit = mcountinhibit_q;
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- mcountinhibit_q <= '0;
- end else begin
- mcountinhibit_q <= mcountinhibit_d;
- end
- end
-
- /////////////////////////////
- // Debug trigger registers //
- /////////////////////////////
-
- if (DbgTriggerEn) begin : gen_trigger_regs
- localparam int unsigned DbgHwNumLen = DbgHwBreakNum > 1 ? $clog2(DbgHwBreakNum) : 1;
- // Register values
- logic [DbgHwNumLen-1:0] tselect_d, tselect_q;
- logic tmatch_control_d;
- logic [DbgHwBreakNum-1:0] tmatch_control_q;
- logic [31:0] tmatch_value_d;
- logic [31:0] tmatch_value_q[DbgHwBreakNum];
- // Write enables
- logic tselect_we;
- logic [DbgHwBreakNum-1:0] tmatch_control_we;
- logic [DbgHwBreakNum-1:0] tmatch_value_we;
- // Trigger comparison result
- logic [DbgHwBreakNum-1:0] trigger_match;
-
- // Write select
- assign tselect_we = csr_we_int & debug_mode_i & (csr_addr_i == CSR_TSELECT);
- for (genvar i = 0; i < DbgHwBreakNum; i++) begin : g_dbg_tmatch_we
- assign tmatch_control_we[i] = (i[DbgHwNumLen-1:0] == tselect_q) & csr_we_int & debug_mode_i &
- (csr_addr_i == CSR_TDATA1);
- assign tmatch_value_we[i] = (i[DbgHwNumLen-1:0] == tselect_q) & csr_we_int & debug_mode_i &
- (csr_addr_i == CSR_TDATA2);
- end
-
- // Debug interface tests the available number of triggers by writing and reading the trigger
- // select register. Only allow changes to the register if it is within the supported region.
- assign tselect_d = (csr_wdata_int < DbgHwBreakNum) ? csr_wdata_int[DbgHwNumLen-1:0] :
- DbgHwBreakNum-1;
- // tmatch_control is enabled when the execute bit is set
- assign tmatch_control_d = csr_wdata_int[2];
- assign tmatch_value_d = csr_wdata_int[31:0];
-
- // Registers
- brq_csr #(
- .Width (DbgHwNumLen),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_tselect_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (tselect_d),
- .wr_en_i (tselect_we),
- .rd_data_o (tselect_q),
- .rd_error_o (unused_error15)
- );
-
- for (genvar i = 0; i < DbgHwBreakNum; i++) begin : g_dbg_tmatch_reg
- brq_csr #(
- .Width (1),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_tmatch_control_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (tmatch_control_d),
- .wr_en_i (tmatch_control_we[i]),
- .rd_data_o (tmatch_control_q[i]),
- .rd_error_o (unused_error16)
- );
-
- brq_csr #(
- .Width (32),
- .ShadowCopy (1'b0),
- .ResetValue ('0)
- ) u_tmatch_value_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i (tmatch_value_d),
- .wr_en_i (tmatch_value_we[i]),
- .rd_data_o (tmatch_value_q[i]),
- .rd_error_o (unused_error7)
- );
- end
-
- // Assign read data
- // TSELECT - number of supported triggers defined by parameter DbgHwBreakNum
- localparam int unsigned TSelectRdataPadlen = DbgHwNumLen >= 32 ? 0 : (32 - DbgHwNumLen);
- assign tselect_rdata = {{TSelectRdataPadlen{1'b0}}, tselect_q};
-
- // TDATA0 - only support simple address matching
- assign tmatch_control_rdata = {4'h2, // type : address/data match
- 1'b1, // dmode : access from D mode only
- 6'h00, // maskmax : exact match only
- 1'b0, // hit : not supported
- 1'b0, // select : address match only
- 1'b0, // timing : match before execution
- 2'b00, // sizelo : match any access
- 4'h1, // action : enter debug mode
- 1'b0, // chain : not supported
- 4'h0, // match : simple match
- 1'b1, // m : match in m-mode
- 1'b0, // 0 : zero
- 1'b0, // s : not supported
- 1'b1, // u : match in u-mode
- tmatch_control_q[tselect_q], // execute : match instruction address
- 1'b0, // store : not supported
- 1'b0}; // load : not supported
- // TDATA1 - address match value only
- assign tmatch_value_rdata = tmatch_value_q[tselect_q];
-
- // Breakpoint matching
- // We match against the next address, as the breakpoint must be taken before execution
- for (genvar i = 0; i < DbgHwBreakNum; i++) begin : g_dbg_trigger_match
- assign trigger_match[i] = tmatch_control_q[i] & (pc_if_i[31:0] == tmatch_value_q[i]);
- end
- assign trigger_match_o = |trigger_match;
-
- end else begin : gen_no_trigger_regs
- assign tselect_rdata = 'b0;
- assign tmatch_control_rdata = 'b0;
- assign tmatch_value_rdata = 'b0;
- assign trigger_match_o = 'b0;
- end
-
- //////////////////////////
- // CPU control register //
- //////////////////////////
-
- // Cast register write data
- assign cpuctrl_wdata = cpu_ctrl_t'(csr_wdata_int[$bits(cpu_ctrl_t)-1:0]);
-
- // Generate fixed time execution bit
- if (DataIndTiming) begin : gen_dit
- assign cpuctrl_d.data_ind_timing = cpuctrl_wdata.data_ind_timing;
-
- end else begin : gen_no_dit
- // tieoff for the unused bit
- logic unused_dit;
- assign unused_dit = cpuctrl_wdata.data_ind_timing;
-
- // field will always read as zero if not configured
- assign cpuctrl_d.data_ind_timing = 1'b0;
- end
-
- assign data_ind_timing_o = cpuctrl_q.data_ind_timing;
-
- // Generate dummy instruction signals
- if (DummyInstructions) begin : gen_dummy
- assign cpuctrl_d.dummy_instr_en = cpuctrl_wdata.dummy_instr_en;
- assign cpuctrl_d.dummy_instr_mask = cpuctrl_wdata.dummy_instr_mask;
-
- // Signal a write to the seed register
- assign dummy_instr_seed_en_o = csr_we_int && (csr_addr == CSR_SECURESEED);
- assign dummy_instr_seed_o = csr_wdata_int;
-
- end else begin : gen_no_dummy
- // tieoff for the unused bit
- logic unused_dummy_en;
- logic [2:0] unused_dummy_mask;
- assign unused_dummy_en = cpuctrl_wdata.dummy_instr_en;
- assign unused_dummy_mask = cpuctrl_wdata.dummy_instr_mask;
-
- // field will always read as zero if not configured
- assign cpuctrl_d.dummy_instr_en = 1'b0;
- assign cpuctrl_d.dummy_instr_mask = 3'b000;
- assign dummy_instr_seed_en_o = 1'b0;
- assign dummy_instr_seed_o = '0;
- end
-
- assign dummy_instr_en_o = cpuctrl_q.dummy_instr_en;
- assign dummy_instr_mask_o = cpuctrl_q.dummy_instr_mask;
-
- // Generate icache enable bit
- if (ICache) begin : gen_icache_enable
- assign cpuctrl_d.icache_enable = cpuctrl_wdata.icache_enable;
- end else begin : gen_no_icache
- // tieoff for the unused icen bit
- logic unused_icen;
- assign unused_icen = cpuctrl_wdata.icache_enable;
-
- // icen field will always read as zero if ICache not configured
- assign cpuctrl_d.icache_enable = 1'b0;
- end
-
- assign icache_enable_o = cpuctrl_q.icache_enable;
-
- brq_csr #(
- .Width ($bits(cpu_ctrl_t)),
- .ShadowCopy (ShadowCSR),
- .ResetValue ('0)
- ) u_cpuctrl_csr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .wr_data_i ({cpuctrl_d}),
- .wr_en_i (cpuctrl_we),
- .rd_data_o (cpuctrl_q),
- .rd_error_o (cpuctrl_err)
- );
-
- assign csr_shadow_err_o = mstatus_err | mtvec_err | pmp_csr_err | cpuctrl_err;
-
-
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/brq_csr.sv b/verilog/rtl/brq_csr.sv
deleted file mode 100644
index b1c4477..0000000
--- a/verilog/rtl/brq_csr.sv
+++ /dev/null
@@ -1,53 +0,0 @@
-
-
-/**
- * Control / status register primitive
- */
-
-
-module brq_csr #(
- parameter int unsigned Width = 32,
- parameter bit ShadowCopy = 1'b0,
- parameter bit [Width-1:0] ResetValue = '0
- ) (
- input logic clk_i,
- input logic rst_ni,
-
- input logic [Width-1:0] wr_data_i,
- input logic wr_en_i,
- output logic [Width-1:0] rd_data_o,
-
- output logic rd_error_o
-);
-
- logic [Width-1:0] rdata_q;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rdata_q <= ResetValue;
- end else if (wr_en_i) begin
- rdata_q <= wr_data_i;
- end
- end
-
- assign rd_data_o = rdata_q;
-
- if (ShadowCopy) begin : gen_shadow
- logic [Width-1:0] shadow_q;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- shadow_q <= ~ResetValue;
- end else if (wr_en_i) begin
- shadow_q <= ~wr_data_i;
- end
- end
-
- assign rd_error_o = rdata_q != ~shadow_q;
-
- end else begin : gen_no_shadow
- assign rd_error_o = 1'b0;
- end
-
-
-endmodule
diff --git a/verilog/rtl/brq_exu.sv b/verilog/rtl/brq_exu.sv
deleted file mode 100644
index 883cf7a..0000000
--- a/verilog/rtl/brq_exu.sv
+++ /dev/null
@@ -1,194 +0,0 @@
-/**
- * Execution stage
- *
- * Execution block: Hosts ALU and MUL/DIV unit
- */
-module brq_exu #(
- parameter brq_pkg::rv32m_e RV32M = brq_pkg::RV32MFast,
- parameter brq_pkg::rv32b_e RV32B = brq_pkg::RV32BNone,
- parameter bit BranchTargetALU = 0
-) (
- input logic clk_i,
- input logic rst_ni,
-
- // ALU
- input brq_pkg::alu_op_e alu_operator_i,
- input logic [31:0] alu_operand_a_i,
- input logic [31:0] alu_operand_b_i,
- input logic alu_instr_first_cycle_i,
-
- // Branch Target ALU
- // All of these signals are unusued when BranchTargetALU == 0
- input logic [31:0] bt_a_operand_i,
- input logic [31:0] bt_b_operand_i,
-
- // Multiplier/Divider
- input brq_pkg::md_op_e multdiv_operator_i,
- input logic mult_en_i, // dynamic enable signal, for FSM control
- input logic div_en_i, // dynamic enable signal, for FSM control
- input logic mult_sel_i, // static decoder output, for data muxes
- input logic div_sel_i, // static decoder output, for data muxes
- input logic [1:0] multdiv_signed_mode_i,
- input logic [31:0] multdiv_operand_a_i,
- input logic [31:0] multdiv_operand_b_i,
- input logic multdiv_ready_id_i,
- input logic data_ind_timing_i,
-
- // intermediate val reg
- output logic [1:0] imd_val_we_o,
- output logic [33:0] imd_val_d_o[2],
- input logic [33:0] imd_val_q_i[2],
-
- // Outputs
- output logic [31:0] alu_adder_result_ex_o, // to LSU
- output logic [31:0] result_ex_o,
- output logic [31:0] branch_target_o, // to IF
- output logic branch_decision_o, // to ID
-
- output logic ex_valid_o // EX has valid output
-);
-
- import brq_pkg::*;
-
- logic [31:0] alu_result, multdiv_result;
-
- logic [32:0] multdiv_alu_operand_b, multdiv_alu_operand_a;
- logic [33:0] alu_adder_result_ext;
- logic alu_cmp_result, alu_is_equal_result;
- logic multdiv_valid;
- logic multdiv_sel;
- logic [31:0] alu_imd_val_q[2];
- logic [31:0] alu_imd_val_d[2];
- logic [ 1:0] alu_imd_val_we;
- logic [33:0] multdiv_imd_val_d[2];
- logic [ 1:0] multdiv_imd_val_we;
-
- /*
- The multdiv_i output is never selected if RV32M=RV32MNone
- At synthesis time, all the combinational and sequential logic
- from the multdiv_i module are eliminated
- */
- if (RV32M != RV32MNone) begin : gen_multdiv_m
- assign multdiv_sel = mult_sel_i | div_sel_i;
- end else begin : gen_multdiv_no_m
- assign multdiv_sel = 1'b0;
- end
-
- // Intermediate Value Register Mux
- assign imd_val_d_o[0] = multdiv_sel ? multdiv_imd_val_d[0] : {2'b0, alu_imd_val_d[0]};
- assign imd_val_d_o[1] = multdiv_sel ? multdiv_imd_val_d[1] : {2'b0, alu_imd_val_d[1]};
- assign imd_val_we_o = multdiv_sel ? multdiv_imd_val_we : alu_imd_val_we;
-
- assign alu_imd_val_q = '{imd_val_q_i[0][31:0], imd_val_q_i[1][31:0]};
-
- assign result_ex_o = multdiv_sel ? multdiv_result : alu_result;
-
- // branch handling
- assign branch_decision_o = alu_cmp_result;
-
- if (BranchTargetALU) begin : g_branch_target_alu
- logic [32:0] bt_alu_result;
- logic unused_bt_carry;
-
- assign bt_alu_result = bt_a_operand_i + bt_b_operand_i;
-
- assign unused_bt_carry = bt_alu_result[32];
- assign branch_target_o = bt_alu_result[31:0];
- end else begin : g_no_branch_target_alu
- // Unused bt_operand signals cause lint errors, this avoids them
- logic [31:0] unused_bt_a_operand, unused_bt_b_operand;
-
- assign unused_bt_a_operand = bt_a_operand_i;
- assign unused_bt_b_operand = bt_b_operand_i;
-
- assign branch_target_o = alu_adder_result_ex_o;
- end
-
- /////////
- // ALU //
- /////////
-
- brq_exu_alu #(
- .RV32B(RV32B)
- ) alu_i (
- .operator_i ( alu_operator_i ),
- .operand_a_i ( alu_operand_a_i ),
- .operand_b_i ( alu_operand_b_i ),
- .instr_first_cycle_i ( alu_instr_first_cycle_i ),
- .imd_val_q_i ( alu_imd_val_q ),
- .imd_val_we_o ( alu_imd_val_we ),
- .imd_val_d_o ( alu_imd_val_d ),
- .multdiv_operand_a_i ( multdiv_alu_operand_a ),
- .multdiv_operand_b_i ( multdiv_alu_operand_b ),
- .multdiv_sel_i ( multdiv_sel ),
- .adder_result_o ( alu_adder_result_ex_o ),
- .adder_result_ext_o ( alu_adder_result_ext ),
- .result_o ( alu_result ),
- .comparison_result_o ( alu_cmp_result ),
- .is_equal_result_o ( alu_is_equal_result )
- );
-
- ////////////////
- // Multiplier //
- ////////////////
-
- if (RV32M == RV32MSlow) begin : gen_multdiv_slow
- brq_exu_multdiv_slow multdiv_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
- .mult_en_i ( mult_en_i ),
- .div_en_i ( div_en_i ),
- .mult_sel_i ( mult_sel_i ),
- .div_sel_i ( div_sel_i ),
- .operator_i ( multdiv_operator_i ),
- .signed_mode_i ( multdiv_signed_mode_i ),
- .op_a_i ( multdiv_operand_a_i ),
- .op_b_i ( multdiv_operand_b_i ),
- .alu_adder_ext_i ( alu_adder_result_ext ),
- .alu_adder_i ( alu_adder_result_ex_o ),
- .equal_to_zero_i ( alu_is_equal_result ),
- .data_ind_timing_i ( data_ind_timing_i ),
- .valid_o ( multdiv_valid ),
- .alu_operand_a_o ( multdiv_alu_operand_a ),
- .alu_operand_b_o ( multdiv_alu_operand_b ),
- .imd_val_q_i ( imd_val_q_i ),
- .imd_val_d_o ( multdiv_imd_val_d ),
- .imd_val_we_o ( multdiv_imd_val_we ),
- .multdiv_ready_id_i ( multdiv_ready_id_i ),
- .multdiv_result_o ( multdiv_result )
- );
- end else if (RV32M == RV32MFast || RV32M == RV32MSingleCycle) begin : gen_multdiv_fast
- brq_exu_multdiv_fast # (
- .RV32M ( RV32M )
- ) multdiv_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
- .mult_en_i ( mult_en_i ),
- .div_en_i ( div_en_i ),
- .mult_sel_i ( mult_sel_i ),
- .div_sel_i ( div_sel_i ),
- .operator_i ( multdiv_operator_i ),
- .signed_mode_i ( multdiv_signed_mode_i ),
- .op_a_i ( multdiv_operand_a_i ),
- .op_b_i ( multdiv_operand_b_i ),
- .alu_operand_a_o ( multdiv_alu_operand_a ),
- .alu_operand_b_o ( multdiv_alu_operand_b ),
- .alu_adder_ext_i ( alu_adder_result_ext ),
- .alu_adder_i ( alu_adder_result_ex_o ),
- .equal_to_zero_i ( alu_is_equal_result ),
- .data_ind_timing_i ( data_ind_timing_i ),
- .imd_val_q_i ( imd_val_q_i ),
- .imd_val_d_o ( multdiv_imd_val_d ),
- .imd_val_we_o ( multdiv_imd_val_we ),
- .multdiv_ready_id_i ( multdiv_ready_id_i ),
- .valid_o ( multdiv_valid ),
- .multdiv_result_o ( multdiv_result )
- );
- end
-
- // Multiplier/divider may require multiple cycles. The ALU output is valid in the same cycle
- // unless the intermediate result register is being written (which indicates this isn't the
- // final cycle of ALU operation).
- assign ex_valid_o = multdiv_sel ? multdiv_valid : ~(|alu_imd_val_we);
-
-endmodule
diff --git a/verilog/rtl/brq_exu_alu.sv b/verilog/rtl/brq_exu_alu.sv
deleted file mode 100644
index 99fe60a..0000000
--- a/verilog/rtl/brq_exu_alu.sv
+++ /dev/null
@@ -1,1267 +0,0 @@
-
-/**
- * Arithmetic logic unit
- */
-module brq_exu_alu #(
- parameter brq_pkg::rv32b_e RV32B = brq_pkg::RV32BNone
-) (
- input brq_pkg::alu_op_e operator_i,
- input logic [31:0] operand_a_i,
- input logic [31:0] operand_b_i,
-
- input logic instr_first_cycle_i,
-
- input logic [32:0] multdiv_operand_a_i,
- input logic [32:0] multdiv_operand_b_i,
-
- input logic multdiv_sel_i,
-
- input logic [31:0] imd_val_q_i[2],
- output logic [31:0] imd_val_d_o[2],
- output logic [1:0] imd_val_we_o,
-
- output logic [31:0] adder_result_o,
- output logic [33:0] adder_result_ext_o,
-
- output logic [31:0] result_o,
- output logic comparison_result_o,
- output logic is_equal_result_o
-);
- import brq_pkg::*;
-
- logic [31:0] operand_a_rev;
- logic [32:0] operand_b_neg;
-
- // bit reverse operand_a for left shifts and bit counting
- for (genvar k = 0; k < 32; k++) begin : gen_rev_operand_a
- assign operand_a_rev[k] = operand_a_i[31-k];
- end
-
- ///////////
- // Adder //
- ///////////
-
- logic adder_op_b_negate;
- logic [32:0] adder_in_a, adder_in_b;
- logic [31:0] adder_result;
-
- always_comb begin
- adder_op_b_negate = 1'b0;
- unique case (operator_i)
- // Adder OPs
- ALU_SUB,
-
- // Comparator OPs
- ALU_EQ, ALU_NE,
- ALU_GE, ALU_GEU,
- ALU_LT, ALU_LTU,
- ALU_SLT, ALU_SLTU,
-
- // MinMax OPs (RV32B Ops)
- ALU_MIN, ALU_MINU,
- ALU_MAX, ALU_MAXU: adder_op_b_negate = 1'b1;
-
- default:;
- endcase
- end
-
- // prepare operand a
- assign adder_in_a = multdiv_sel_i ? multdiv_operand_a_i : {operand_a_i,1'b1};
-
- // prepare operand b
- assign operand_b_neg = {operand_b_i,1'b0} ^ {33{1'b1}};
- always_comb begin
- unique case(1'b1)
- multdiv_sel_i: adder_in_b = multdiv_operand_b_i;
- adder_op_b_negate: adder_in_b = operand_b_neg;
- default : adder_in_b = {operand_b_i, 1'b0};
- endcase
- end
-
- // actual adder
- assign adder_result_ext_o = $unsigned(adder_in_a) + $unsigned(adder_in_b);
-
- assign adder_result = adder_result_ext_o[32:1];
-
- assign adder_result_o = adder_result;
-
- ////////////////
- // Comparison //
- ////////////////
-
- logic is_equal;
- logic is_greater_equal; // handles both signed and unsigned forms
- logic cmp_signed;
-
- always_comb begin
- unique case (operator_i)
- ALU_GE,
- ALU_LT,
- ALU_SLT,
- // RV32B only
- ALU_MIN,
- ALU_MAX: cmp_signed = 1'b1;
-
- default: cmp_signed = 1'b0;
- endcase
- end
-
- assign is_equal = (adder_result == 32'b0);
- assign is_equal_result_o = is_equal;
-
- // Is greater equal
- always_comb begin
- if ((operand_a_i[31] ^ operand_b_i[31]) == 1'b0) begin
- is_greater_equal = (adder_result[31] == 1'b0);
- end else begin
- is_greater_equal = operand_a_i[31] ^ (cmp_signed);
- end
- end
-
- // GTE unsigned:
- // (a[31] == 1 && b[31] == 1) => adder_result[31] == 0
- // (a[31] == 0 && b[31] == 0) => adder_result[31] == 0
- // (a[31] == 1 && b[31] == 0) => 1
- // (a[31] == 0 && b[31] == 1) => 0
-
- // GTE signed:
- // (a[31] == 1 && b[31] == 1) => adder_result[31] == 0
- // (a[31] == 0 && b[31] == 0) => adder_result[31] == 0
- // (a[31] == 1 && b[31] == 0) => 0
- // (a[31] == 0 && b[31] == 1) => 1
-
- // generate comparison result
- logic cmp_result;
-
- always_comb begin
- unique case (operator_i)
- ALU_EQ: cmp_result = is_equal;
- ALU_NE: cmp_result = ~is_equal;
- ALU_GE, ALU_GEU,
- ALU_MAX, ALU_MAXU: cmp_result = is_greater_equal; // RV32B only
- ALU_LT, ALU_LTU,
- ALU_MIN, ALU_MINU, //RV32B only
- ALU_SLT, ALU_SLTU: cmp_result = ~is_greater_equal;
-
- default: cmp_result = is_equal;
- endcase
- end
-
- assign comparison_result_o = cmp_result;
-
- ///////////
- // Shift //
- ///////////
-
- // The shifter structure consists of a 33-bit shifter: 32-bit operand + 1 bit extension for
- // arithmetic shifts and one-shift support.
- // Rotations and funnel shifts are implemented as multi-cycle instructions.
- // The shifter is also used for single-bit instructions and bit-field place as detailed below.
- //
- // Standard Shifts
- // ===============
- // For standard shift instructions, the direction of the shift is to the right by default. For
- // left shifts, the signal shift_left signal is set. If so, the operand is initially reversed,
- // shifted to the right by the specified amount and shifted back again. For arithmetic- and
- // one-shifts the 33rd bit of the shifter operand can is set accordingly.
- //
- // Multicycle Shifts
- // =================
- //
- // Rotation
- // --------
- // For rotations, the operand signals operand_a_i and operand_b_i are kept constant to rs1 and
- // rs2 respectively.
- //
- // Rotation pseudocode:
- // shift_amt = rs2 & 31;
- // multicycle_result = (rs1 >> shift_amt) | (rs1 << (32 - shift_amt));
- // ^-- cycle 0 -----^ ^-- cycle 1 --------------^
- //
- // Funnel Shifts
- // -------------
- // For funnel shifs, operand_a_i is tied to rs1 in the first cycle and rs3 in the
- // second cycle. operand_b_i is always tied to rs2. The order of applying the shift amount or
- // its complement is determined by bit [5] of shift_amt.
- //
- // Funnel shift Pseudocode: (fsl)
- // shift_amt = rs2 & 63;
- // shift_amt_compl = 32 - shift_amt[4:0]
- // if (shift_amt >=33):
- // multicycle_result = (rs1 >> shift_amt_compl[4:0]) | (rs3 << shift_amt[4:0]);
- // ^-- cycle 0 ----------------^ ^-- cycle 1 ------------^
- // else if (shift_amt <= 31 && shift_amt > 0):
- // multicycle_result = (rs1 << shift_amt[4:0]) | (rs3 >> shift_amt_compl[4:0]);
- // ^-- cycle 0 ----------^ ^-- cycle 1 -------------------^
- // For shift_amt == 0, 32, both shift_amt[4:0] and shift_amt_compl[4:0] == '0.
- // these cases need to be handled separately outside the shifting structure:
- // else if (shift_amt == 32):
- // multicycle_result = rs3
- // else if (shift_amt == 0):
- // multicycle_result = rs1.
- //
- // Single-Bit Instructions
- // =======================
- // Single bit instructions operate on bit operand_b_i[4:0] of operand_a_i.
-
- // The operations sbset, sbclr and sbinv are implemented by generation of a bit-mask using the
- // shifter structure. This is done by left-shifting the operand 32'h1 by the required amount.
- // The signal shift_sbmode multiplexes the shifter input and sets the signal shift_left.
- // Further processing is taken care of by a separate structure.
- //
- // For sbext, the bit defined by operand_b_i[4:0] is to be returned. This is done by simply
- // shifting operand_a_i to the right by the required amount and returning bit [0] of the result.
- //
- // Bit-Field Place
- // ===============
- // The shifter structure is shared to compute bfp_mask << bfp_off.
-
- logic shift_left;
- logic shift_ones;
- logic shift_arith;
- logic shift_funnel;
- logic shift_sbmode;
- logic [5:0] shift_amt;
- logic [5:0] shift_amt_compl; // complementary shift amount (32 - shift_amt)
-
- logic [31:0] shift_operand;
- logic [32:0] shift_result_ext;
- logic unused_shift_result_ext;
- logic [31:0] shift_result;
- logic [31:0] shift_result_rev;
-
- // zbf
- logic bfp_op;
- logic [4:0] bfp_len;
- logic [4:0] bfp_off;
- logic [31:0] bfp_mask;
- logic [31:0] bfp_mask_rev;
- logic [31:0] bfp_result;
-
- // bfp: shares the shifter structure to compute bfp_mask << bfp_off
- assign bfp_op = (RV32B != RV32BNone) ? (operator_i == ALU_BFP) : 1'b0;
- assign bfp_len = {~(|operand_b_i[27:24]), operand_b_i[27:24]}; // len = 0 encodes for len = 16
- assign bfp_off = operand_b_i[20:16];
- assign bfp_mask = (RV32B != RV32BNone) ? ~(32'hffff_ffff << bfp_len) : '0;
- for (genvar i=0; i<32; i++) begin : gen_rev_bfp_mask
- assign bfp_mask_rev[i] = bfp_mask[31-i];
- end
-
- assign bfp_result =(RV32B != RV32BNone) ?
- (~shift_result & operand_a_i) | ((operand_b_i & bfp_mask) << bfp_off) : '0;
-
- // bit shift_amt[5]: word swap bit: only considered for FSL/FSR.
- // if set, reverse operations in first and second cycle.
- assign shift_amt[5] = operand_b_i[5] & shift_funnel;
- assign shift_amt_compl = 32 - operand_b_i[4:0];
-
- always_comb begin
- if (bfp_op) begin
- shift_amt[4:0] = bfp_off ; // length field of bfp control word
- end else begin
- shift_amt[4:0] = instr_first_cycle_i ?
- (operand_b_i[5] && shift_funnel ? shift_amt_compl[4:0] : operand_b_i[4:0]) :
- (operand_b_i[5] && shift_funnel ? operand_b_i[4:0] : shift_amt_compl[4:0]);
- end
- end
-
- // single-bit mode: shift
- assign shift_sbmode = (RV32B != RV32BNone) ?
- (operator_i == ALU_SBSET) | (operator_i == ALU_SBCLR) | (operator_i == ALU_SBINV) : 1'b0;
-
- // left shift if this is:
- // * a standard left shift (slo, sll)
- // * a rol in the first cycle
- // * a ror in the second cycle
- // * fsl: without word-swap bit: first cycle, else: second cycle
- // * fsr: without word-swap bit: second cycle, else: first cycle
- // * a single-bit instruction: sbclr, sbset, sbinv (excluding sbext)
- // * bfp: bfp_mask << bfp_off
- always_comb begin
- unique case (operator_i)
- ALU_SLL: shift_left = 1'b1;
- ALU_SLO,
- ALU_BFP: shift_left = (RV32B != RV32BNone) ? 1'b1 : 1'b0;
- ALU_ROL: shift_left = (RV32B != RV32BNone) ? instr_first_cycle_i : 0;
- ALU_ROR: shift_left = (RV32B != RV32BNone) ? ~instr_first_cycle_i : 0;
- ALU_FSL: shift_left = (RV32B != RV32BNone) ?
- (shift_amt[5] ? ~instr_first_cycle_i : instr_first_cycle_i) : 1'b0;
- ALU_FSR: shift_left = (RV32B != RV32BNone) ?
- (shift_amt[5] ? instr_first_cycle_i : ~instr_first_cycle_i) : 1'b0;
- default: shift_left = 1'b0;
- endcase
- if (shift_sbmode) begin
- shift_left = 1'b1;
- end
- end
-
- assign shift_arith = (operator_i == ALU_SRA);
- assign shift_ones =
- (RV32B != RV32BNone) ? (operator_i == ALU_SLO) | (operator_i == ALU_SRO) : 1'b0;
- assign shift_funnel =
- (RV32B != RV32BNone) ? (operator_i == ALU_FSL) | (operator_i == ALU_FSR) : 1'b0;
-
- // shifter structure.
- always_comb begin
- // select shifter input
- // for bfp, sbmode and shift_left the corresponding bit-reversed input is chosen.
- if (RV32B == RV32BNone) begin
- shift_operand = shift_left ? operand_a_rev : operand_a_i;
- end else begin
- unique case (1'b1)
- bfp_op: shift_operand = bfp_mask_rev;
- shift_sbmode: shift_operand = 32'h8000_0000;
- default: shift_operand = shift_left ? operand_a_rev : operand_a_i;
- endcase
- end
-
- shift_result_ext =
- $unsigned($signed({shift_ones | (shift_arith & shift_operand[31]), shift_operand}) >>>
- shift_amt[4:0]);
-
- shift_result = shift_result_ext[31:0];
- unused_shift_result_ext = shift_result_ext[32];
-
- for (int unsigned i=0; i<32; i++) begin
- shift_result_rev[i] = shift_result[31-i];
- end
-
- shift_result = shift_left ? shift_result_rev : shift_result;
-
- end
-
- ///////////////////
- // Bitwise Logic //
- ///////////////////
-
- logic bwlogic_or;
- logic bwlogic_and;
- logic [31:0] bwlogic_operand_b;
- logic [31:0] bwlogic_or_result;
- logic [31:0] bwlogic_and_result;
- logic [31:0] bwlogic_xor_result;
- logic [31:0] bwlogic_result;
-
- logic bwlogic_op_b_negate;
-
- always_comb begin
- unique case (operator_i)
- // Logic-with-negate OPs (RV32B Ops)
- ALU_XNOR,
- ALU_ORN,
- ALU_ANDN: bwlogic_op_b_negate = (RV32B != RV32BNone) ? 1'b1 : 1'b0;
- ALU_CMIX: bwlogic_op_b_negate = (RV32B != RV32BNone) ? ~instr_first_cycle_i : 1'b0;
- default: bwlogic_op_b_negate = 1'b0;
- endcase
- end
-
- assign bwlogic_operand_b = bwlogic_op_b_negate ? operand_b_neg[32:1] : operand_b_i;
-
- assign bwlogic_or_result = operand_a_i | bwlogic_operand_b;
- assign bwlogic_and_result = operand_a_i & bwlogic_operand_b;
- assign bwlogic_xor_result = operand_a_i ^ bwlogic_operand_b;
-
- assign bwlogic_or = (operator_i == ALU_OR) | (operator_i == ALU_ORN);
- assign bwlogic_and = (operator_i == ALU_AND) | (operator_i == ALU_ANDN);
-
- always_comb begin
- unique case (1'b1)
- bwlogic_or: bwlogic_result = bwlogic_or_result;
- bwlogic_and: bwlogic_result = bwlogic_and_result;
- default: bwlogic_result = bwlogic_xor_result;
- endcase
- end
-
- logic [5:0] bitcnt_result;
- logic [31:0] minmax_result;
- logic [31:0] pack_result;
- logic [31:0] sext_result;
- logic [31:0] singlebit_result;
- logic [31:0] rev_result;
- logic [31:0] shuffle_result;
- logic [31:0] butterfly_result;
- logic [31:0] invbutterfly_result;
- logic [31:0] clmul_result;
- logic [31:0] multicycle_result;
-
- if (RV32B != RV32BNone) begin : g_alu_rvb
-
- /////////////////
- // Bitcounting //
- /////////////////
-
- // The bit-counter structure computes the number of set bits in its operand. Partial results
- // (from left to right) are needed to compute the control masks for computation of bext/bdep
- // by the butterfly network, if implemented.
- // For pcnt, clz and ctz, only the end result is used.
-
- logic zbe_op;
- logic bitcnt_ctz;
- logic bitcnt_clz;
- logic bitcnt_cz;
- logic [31:0] bitcnt_bits;
- logic [31:0] bitcnt_mask_op;
- logic [31:0] bitcnt_bit_mask;
- logic [ 5:0] bitcnt_partial [32];
- logic [31:0] bitcnt_partial_lsb_d;
- logic [31:0] bitcnt_partial_msb_d;
-
-
- assign bitcnt_ctz = operator_i == ALU_CTZ;
- assign bitcnt_clz = operator_i == ALU_CLZ;
- assign bitcnt_cz = bitcnt_ctz | bitcnt_clz;
- assign bitcnt_result = bitcnt_partial[31];
-
- // Bit-mask generation for clz and ctz:
- // The bit mask is generated by spreading the lowest-order set bit in the operand to all
- // higher order bits. The resulting mask is inverted to cover the lowest order zeros. In order
- // to create the bit mask for leading zeros, the input operand needs to be reversed.
- assign bitcnt_mask_op = bitcnt_clz ? operand_a_rev : operand_a_i;
-
- always_comb begin
- bitcnt_bit_mask = bitcnt_mask_op;
- bitcnt_bit_mask |= bitcnt_bit_mask << 1;
- bitcnt_bit_mask |= bitcnt_bit_mask << 2;
- bitcnt_bit_mask |= bitcnt_bit_mask << 4;
- bitcnt_bit_mask |= bitcnt_bit_mask << 8;
- bitcnt_bit_mask |= bitcnt_bit_mask << 16;
- bitcnt_bit_mask = ~bitcnt_bit_mask;
- end
-
- assign zbe_op = (operator_i == ALU_BEXT) | (operator_i == ALU_BDEP);
-
- always_comb begin
- case(1'b1)
- zbe_op: bitcnt_bits = operand_b_i;
- bitcnt_cz: bitcnt_bits = bitcnt_bit_mask & ~bitcnt_mask_op; // clz / ctz
- default: bitcnt_bits = operand_a_i; // pcnt
- endcase
- end
-
- // The parallel prefix counter is of the structure of a Brent-Kung Adder. In the first
- // log2(width) stages, the sum of the n preceding bit lines is computed for the bit lines at
- // positions 2**n-1 (power-of-two positions) where n denotes the current stage.
- // In stage n=log2(width), the count for position width-1 (the MSB) is finished.
- // For the intermediate values, an inverse adder tree then computes the bit counts for the bit
- // lines at positions
- // m = 2**(n-1) + i*2**(n-2), where i = [1 ... width / 2**(n-1)-1] and n = [log2(width) ... 2].
- // Thus, at every subsequent stage the result of two previously unconnected sub-trees is
- // summed, starting at the node summing bits [width/2-1 : 0] and [3*width/4-1: width/2]
- // and moving to iteratively sum up all the sub-trees.
- // The inverse adder tree thus features log2(width) - 1 stages the first of these stages is a
- // single addition at position 3*width/4 - 1. It does not interfere with the last
- // stage of the primary adder tree. These stages can thus be folded together, resulting in a
- // total of 2*log2(width)-2 stages.
- // For more details refer to R. Brent, H. T. Kung, "A Regular Layout for Parallel Adders",
- // (1982).
- // For a bitline at position p, only bits
- // bitcnt_partial[max(i, such that p % log2(i) == 0)-1 : 0] are needed for generation of the
- // butterfly network control signals. The adders in the intermediate value adder tree thus need
- // not be full 5-bit adders. We leave the optimization to the synthesis tools.
- //
- // Consider the following 8-bit example for illustraton.
- //
- // let bitcnt_bits = 8'babcdefgh.
- //
- // a b c d e f g h
- // | /: | /: | /: | /:
- // |/ : |/ : |/ : |/ :
- // stage 1: + : + : + : + :
- // | : /: : | : /: :
- // |,--+ : : |,--+ : :
- // stage 2: + : : : + : : :
- // | : | : /: : : :
- // |,-----,--+ : : : : ^-primary adder tree
- // stage 3: + : + : : : : : -------------------------
- // : | /| /| /| /| /| : ,-intermediate adder tree
- // : |/ |/ |/ |/ |/ : :
- // stage 4 : + + + + + : :
- // : : : : : : : :
- // bitcnt_partial[i] 7 6 5 4 3 2 1 0
-
- always_comb begin
- bitcnt_partial = '{default: '0};
- // stage 1
- for (int unsigned i=1; i<32; i+=2) begin
- bitcnt_partial[i] = {5'h0, bitcnt_bits[i]} + {5'h0, bitcnt_bits[i-1]};
- end
- // stage 2
- for (int unsigned i=3; i<32; i+=4) begin
- bitcnt_partial[i] = bitcnt_partial[i-2] + bitcnt_partial[i];
- end
- // stage 3
- for (int unsigned i=7; i<32; i+=8) begin
- bitcnt_partial[i] = bitcnt_partial[i-4] + bitcnt_partial[i];
- end
- // stage 4
- for (int unsigned i=15; i <32; i+=16) begin
- bitcnt_partial[i] = bitcnt_partial[i-8] + bitcnt_partial[i];
- end
- // stage 5
- bitcnt_partial[31] = bitcnt_partial[15] + bitcnt_partial[31];
- // ^- primary adder tree
- // -------------------------------
- // ,-intermediate value adder tree
- bitcnt_partial[23] = bitcnt_partial[15] + bitcnt_partial[23];
-
- // stage 6
- for (int unsigned i=11; i<32; i+=8) begin
- bitcnt_partial[i] = bitcnt_partial[i-4] + bitcnt_partial[i];
- end
-
- // stage 7
- for (int unsigned i=5; i<32; i+=4) begin
- bitcnt_partial[i] = bitcnt_partial[i-2] + bitcnt_partial[i];
- end
- // stage 8
- bitcnt_partial[0] = {5'h0, bitcnt_bits[0]};
- for (int unsigned i=2; i<32; i+=2) begin
- bitcnt_partial[i] = bitcnt_partial[i-1] + {5'h0, bitcnt_bits[i]};
- end
- end
-
- ///////////////
- // Min / Max //
- ///////////////
-
- assign minmax_result = cmp_result ? operand_a_i : operand_b_i;
-
- //////////
- // Pack //
- //////////
-
- logic packu;
- logic packh;
- assign packu = operator_i == ALU_PACKU;
- assign packh = operator_i == ALU_PACKH;
-
- always_comb begin
- unique case (1'b1)
- packu: pack_result = {operand_b_i[31:16], operand_a_i[31:16]};
- packh: pack_result = {16'h0, operand_b_i[7:0], operand_a_i[7:0]};
- default: pack_result = {operand_b_i[15:0], operand_a_i[15:0]};
- endcase
- end
-
- //////////
- // Sext //
- //////////
-
- assign sext_result = (operator_i == ALU_SEXTB) ?
- { {24{operand_a_i[7]}}, operand_a_i[7:0]} : { {16{operand_a_i[15]}}, operand_a_i[15:0]};
-
- /////////////////////////////
- // Single-bit Instructions //
- /////////////////////////////
-
- always_comb begin
- unique case (operator_i)
- ALU_SBSET: singlebit_result = operand_a_i | shift_result;
- ALU_SBCLR: singlebit_result = operand_a_i & ~shift_result;
- ALU_SBINV: singlebit_result = operand_a_i ^ shift_result;
- default: singlebit_result = {31'h0, shift_result[0]}; // ALU_SBEXT
- endcase
- end
-
- ////////////////////////////////////
- // General Reverse and Or-combine //
- ////////////////////////////////////
-
- // Only a subset of the General reverse and or-combine instructions are implemented in the
- // balanced version of the B extension. Currently rev, rev8 and orc.b are supported in the
- // base extension.
-
- logic [4:0] zbp_shift_amt;
- logic gorc_op;
-
- assign gorc_op = (operator_i == ALU_GORC);
- assign zbp_shift_amt[2:0] = (RV32B == RV32BFull) ? shift_amt[2:0] : {3{&shift_amt[2:0]}};
- assign zbp_shift_amt[4:3] = (RV32B == RV32BFull) ? shift_amt[4:3] : {2{&shift_amt[4:3]}};
-
- always_comb begin
- rev_result = operand_a_i;
-
- if (zbp_shift_amt[0]) begin
- rev_result = (gorc_op ? rev_result : 32'h0) |
- ((rev_result & 32'h5555_5555) << 1) |
- ((rev_result & 32'haaaa_aaaa) >> 1);
- end
-
- if (zbp_shift_amt[1]) begin
- rev_result = (gorc_op ? rev_result : 32'h0) |
- ((rev_result & 32'h3333_3333) << 2) |
- ((rev_result & 32'hcccc_cccc) >> 2);
- end
-
- if (zbp_shift_amt[2]) begin
- rev_result = (gorc_op ? rev_result : 32'h0) |
- ((rev_result & 32'h0f0f_0f0f) << 4) |
- ((rev_result & 32'hf0f0_f0f0) >> 4);
- end
-
- if (zbp_shift_amt[3]) begin
- rev_result = (gorc_op & (RV32B == RV32BFull) ? rev_result : 32'h0) |
- ((rev_result & 32'h00ff_00ff) << 8) |
- ((rev_result & 32'hff00_ff00) >> 8);
- end
-
- if (zbp_shift_amt[4]) begin
- rev_result = (gorc_op & (RV32B == RV32BFull) ? rev_result : 32'h0) |
- ((rev_result & 32'h0000_ffff) << 16) |
- ((rev_result & 32'hffff_0000) >> 16);
- end
- end
-
- logic crc_hmode;
- logic crc_bmode;
- logic [31:0] clmul_result_rev;
-
- if (RV32B == RV32BFull) begin : gen_alu_rvb_full
-
- /////////////////////////
- // Shuffle / Unshuffle //
- /////////////////////////
-
- localparam logic [31:0] SHUFFLE_MASK_L [4] =
- '{32'h00ff_0000, 32'h0f00_0f00, 32'h3030_3030, 32'h4444_4444};
- localparam logic [31:0] SHUFFLE_MASK_R [4] =
- '{32'h0000_ff00, 32'h00f0_00f0, 32'h0c0c_0c0c, 32'h2222_2222};
-
- localparam logic [31:0] FLIP_MASK_L [4] =
- '{32'h2200_1100, 32'h0044_0000, 32'h4411_0000, 32'h1100_0000};
- localparam logic [31:0] FLIP_MASK_R [4] =
- '{32'h0088_0044, 32'h0000_2200, 32'h0000_8822, 32'h0000_0088};
-
- logic [31:0] SHUFFLE_MASK_NOT [4];
- for(genvar i = 0; i < 4; i++) begin : gen_shuffle_mask_not
- assign SHUFFLE_MASK_NOT[i] = ~(SHUFFLE_MASK_L[i] | SHUFFLE_MASK_R[i]);
- end
-
- logic shuffle_flip;
- assign shuffle_flip = operator_i == ALU_UNSHFL;
-
- logic [3:0] shuffle_mode;
-
- always_comb begin
- shuffle_result = operand_a_i;
-
- if (shuffle_flip) begin
- shuffle_mode[3] = shift_amt[0];
- shuffle_mode[2] = shift_amt[1];
- shuffle_mode[1] = shift_amt[2];
- shuffle_mode[0] = shift_amt[3];
- end else begin
- shuffle_mode = shift_amt[3:0];
- end
-
- if (shuffle_flip) begin
- shuffle_result = (shuffle_result & 32'h8822_4411) |
- ((shuffle_result << 6) & FLIP_MASK_L[0]) |
- ((shuffle_result >> 6) & FLIP_MASK_R[0]) |
- ((shuffle_result << 9) & FLIP_MASK_L[1]) |
- ((shuffle_result >> 9) & FLIP_MASK_R[1]) |
- ((shuffle_result << 15) & FLIP_MASK_L[2]) |
- ((shuffle_result >> 15) & FLIP_MASK_R[2]) |
- ((shuffle_result << 21) & FLIP_MASK_L[3]) |
- ((shuffle_result >> 21) & FLIP_MASK_R[3]);
- end
-
- if (shuffle_mode[3]) begin
- shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[0]) |
- (((shuffle_result << 8) & SHUFFLE_MASK_L[0]) |
- ((shuffle_result >> 8) & SHUFFLE_MASK_R[0]));
- end
- if (shuffle_mode[2]) begin
- shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[1]) |
- (((shuffle_result << 4) & SHUFFLE_MASK_L[1]) |
- ((shuffle_result >> 4) & SHUFFLE_MASK_R[1]));
- end
- if (shuffle_mode[1]) begin
- shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[2]) |
- (((shuffle_result << 2) & SHUFFLE_MASK_L[2]) |
- ((shuffle_result >> 2) & SHUFFLE_MASK_R[2]));
- end
- if (shuffle_mode[0]) begin
- shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[3]) |
- (((shuffle_result << 1) & SHUFFLE_MASK_L[3]) |
- ((shuffle_result >> 1) & SHUFFLE_MASK_R[3]));
- end
-
- if (shuffle_flip) begin
- shuffle_result = (shuffle_result & 32'h8822_4411) |
- ((shuffle_result << 6) & FLIP_MASK_L[0]) |
- ((shuffle_result >> 6) & FLIP_MASK_R[0]) |
- ((shuffle_result << 9) & FLIP_MASK_L[1]) |
- ((shuffle_result >> 9) & FLIP_MASK_R[1]) |
- ((shuffle_result << 15) & FLIP_MASK_L[2]) |
- ((shuffle_result >> 15) & FLIP_MASK_R[2]) |
- ((shuffle_result << 21) & FLIP_MASK_L[3]) |
- ((shuffle_result >> 21) & FLIP_MASK_R[3]);
- end
- end
-
- ///////////////
- // Butterfly //
- ///////////////
-
- // The butterfly / inverse butterfly network executing bext/bdep (zbe) instructions.
- // For bdep, the control bits mask of a local left region is generated by
- // the inverse of a n-bit left rotate and complement upon wrap (LROTC) operation by the number
- // of ones in the deposit bitmask to the right of the segment. n hereby denotes the width
- // of the according segment. The bitmask for a pertaining local right region is equal to the
- // corresponding local left region. Bext uses an analogue inverse process.
- // Consider the following 8-bit example. For details, see Hilewitz et al. "Fast Bit Gather,
- // Bit Scatter and Bit Permuation Instructions for Commodity Microprocessors", (2008).
- //
- // The bext/bdep instructions are completed in 2 cycles. In the first cycle, the control
- // bitmask is prepared by executing the parallel prefix bit count. In the second cycle,
- // the bit swapping is executed according to the control masks.
-
- // 8-bit example: (Hilewitz et al.)
- // Consider the instruction bdep operand_a_i deposit_mask
- // Let operand_a_i = 8'babcd_efgh
- // deposit_mask = 8'b1010_1101
- //
- // control bitmask for stage 1:
- // - number of ones in the right half of the deposit bitmask: 3
- // - width of the segment: 4
- // - control bitmask = ~LROTC(4'b0, 3)[3:0] = 4'b1000
- //
- // control bitmask: c3 c2 c1 c0 c3 c2 c1 c0
- // 1 0 0 0 1 0 0 0
- // <- L -----> <- R ----->
- // operand_a_i a b c d e f g h
- // :\ | | | /: | | |
- // : +|---|--|-+ : | | |
- // :/ | | | \: | | |
- // stage 1 e b c d a f g h
- // <L-> <R-> <L-> <R->
- // control bitmask: c3 c2 c3 c2 c1 c0 c1 c0
- // 1 1 1 1 1 0 1 0
- // :\ :\ /: /: :\ | /: |
- // : +:-+-:+ : : +|-+ : |
- // :/ :/ \: \: :/ | \: |
- // stage 2 c d e b g f a h
- // L R L R L R L R
- // control bitmask: c3 c3 c2 c2 c1 c1 c0 c0
- // 1 1 0 0 1 1 0 0
- // :\/: | | :\/: | |
- // : : | | : : | |
- // :/\: | | :/\: | |
- // stage 3 d c e b f g a h
- // & deposit bitmask: 1 0 1 0 1 1 0 1
- // result: d 0 e 0 f g 0 h
-
- logic [ 5:0] bitcnt_partial_q [32];
-
- // first cycle
- // Store partial bitcnts
- for (genvar i=0; i<32; i++) begin : gen_bitcnt_reg_in_lsb
- assign bitcnt_partial_lsb_d[i] = bitcnt_partial[i][0];
- end
-
- for (genvar i=0; i<16; i++) begin : gen_bitcnt_reg_in_b1
- assign bitcnt_partial_msb_d[i] = bitcnt_partial[2*i+1][1];
- end
-
- for (genvar i=0; i<8; i++) begin : gen_bitcnt_reg_in_b2
- assign bitcnt_partial_msb_d[16+i] = bitcnt_partial[4*i+3][2];
- end
-
- for (genvar i=0; i<4; i++) begin : gen_bitcnt_reg_in_b3
- assign bitcnt_partial_msb_d[24+i] = bitcnt_partial[8*i+7][3];
- end
-
- for (genvar i=0; i<2; i++) begin : gen_bitcnt_reg_in_b4
- assign bitcnt_partial_msb_d[28+i] = bitcnt_partial[16*i+15][4];
- end
-
- assign bitcnt_partial_msb_d[30] = bitcnt_partial[31][5];
- assign bitcnt_partial_msb_d[31] = 1'b0; // unused
-
- // Second cycle
- // Load partial bitcnts
- always_comb begin
- bitcnt_partial_q = '{default: '0};
-
- for (int unsigned i=0; i<32; i++) begin : gen_bitcnt_reg_out_lsb
- bitcnt_partial_q[i][0] = imd_val_q_i[0][i];
- end
-
- for (int unsigned i=0; i<16; i++) begin : gen_bitcnt_reg_out_b1
- bitcnt_partial_q[2*i+1][1] = imd_val_q_i[1][i];
- end
-
- for (int unsigned i=0; i<8; i++) begin : gen_bitcnt_reg_out_b2
- bitcnt_partial_q[4*i+3][2] = imd_val_q_i[1][16+i];
- end
-
- for (int unsigned i=0; i<4; i++) begin : gen_bitcnt_reg_out_b3
- bitcnt_partial_q[8*i+7][3] = imd_val_q_i[1][24+i];
- end
-
- for (int unsigned i=0; i<2; i++) begin : gen_bitcnt_reg_out_b4
- bitcnt_partial_q[16*i+15][4] = imd_val_q_i[1][28+i];
- end
-
- bitcnt_partial_q[31][5] = imd_val_q_i[1][30];
- end
-
- logic [31:0] butterfly_mask_l[5];
- logic [31:0] butterfly_mask_r[5];
- logic [31:0] butterfly_mask_not[5];
- logic [31:0] lrotc_stage [5]; // left rotate and complement upon wrap
-
- // number of bits in local r = 32 / 2**(stage + 1) = 16/2**stage
- `define _N(stg) (16 >> stg)
-
- // bext / bdep control bit generation
- for (genvar stg=0; stg<5; stg++) begin : gen_butterfly_ctrl_stage
- // number of segs: 2** stg
- for (genvar seg=0; seg<2**stg; seg++) begin : gen_butterfly_ctrl
-
- assign lrotc_stage[stg][2*`_N(stg)*(seg+1)-1 : 2*`_N(stg)*seg] =
- {{`_N(stg){1'b0}},{`_N(stg){1'b1}}} <<
- bitcnt_partial_q[`_N(stg)*(2*seg+1)-1][$clog2(`_N(stg)):0];
-
- assign butterfly_mask_l[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)]
- = ~lrotc_stage[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)];
-
- assign butterfly_mask_r[stg][`_N(stg)*(2*seg+1)-1 : `_N(stg)*(2*seg)]
- = ~lrotc_stage[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)];
-
- assign butterfly_mask_l[stg][`_N(stg)*(2*seg+1)-1 : `_N(stg)*(2*seg)] = '0;
- assign butterfly_mask_r[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)] = '0;
- end
- end
- `undef _N
-
- for (genvar stg=0; stg<5; stg++) begin : gen_butterfly_not
- assign butterfly_mask_not[stg] =
- ~(butterfly_mask_l[stg] | butterfly_mask_r[stg]);
- end
-
- always_comb begin
- butterfly_result = operand_a_i;
-
- butterfly_result = butterfly_result & butterfly_mask_not[0] |
- ((butterfly_result & butterfly_mask_l[0]) >> 16)|
- ((butterfly_result & butterfly_mask_r[0]) << 16);
-
- butterfly_result = butterfly_result & butterfly_mask_not[1] |
- ((butterfly_result & butterfly_mask_l[1]) >> 8)|
- ((butterfly_result & butterfly_mask_r[1]) << 8);
-
- butterfly_result = butterfly_result & butterfly_mask_not[2] |
- ((butterfly_result & butterfly_mask_l[2]) >> 4)|
- ((butterfly_result & butterfly_mask_r[2]) << 4);
-
- butterfly_result = butterfly_result & butterfly_mask_not[3] |
- ((butterfly_result & butterfly_mask_l[3]) >> 2)|
- ((butterfly_result & butterfly_mask_r[3]) << 2);
-
- butterfly_result = butterfly_result & butterfly_mask_not[4] |
- ((butterfly_result & butterfly_mask_l[4]) >> 1)|
- ((butterfly_result & butterfly_mask_r[4]) << 1);
-
- butterfly_result = butterfly_result & operand_b_i;
- end
-
- always_comb begin
- invbutterfly_result = operand_a_i & operand_b_i;
-
- invbutterfly_result = invbutterfly_result & butterfly_mask_not[4] |
- ((invbutterfly_result & butterfly_mask_l[4]) >> 1)|
- ((invbutterfly_result & butterfly_mask_r[4]) << 1);
-
- invbutterfly_result = invbutterfly_result & butterfly_mask_not[3] |
- ((invbutterfly_result & butterfly_mask_l[3]) >> 2)|
- ((invbutterfly_result & butterfly_mask_r[3]) << 2);
-
- invbutterfly_result = invbutterfly_result & butterfly_mask_not[2] |
- ((invbutterfly_result & butterfly_mask_l[2]) >> 4)|
- ((invbutterfly_result & butterfly_mask_r[2]) << 4);
-
- invbutterfly_result = invbutterfly_result & butterfly_mask_not[1] |
- ((invbutterfly_result & butterfly_mask_l[1]) >> 8)|
- ((invbutterfly_result & butterfly_mask_r[1]) << 8);
-
- invbutterfly_result = invbutterfly_result & butterfly_mask_not[0] |
- ((invbutterfly_result & butterfly_mask_l[0]) >> 16)|
- ((invbutterfly_result & butterfly_mask_r[0]) << 16);
- end
-
- ///////////////////////////////////////////////////
- // Carry-less Multiply + Cyclic Redundancy Check //
- ///////////////////////////////////////////////////
-
- // Carry-less multiplication can be understood as multiplication based on
- // the addition interpreted as the bit-wise xor operation.
- //
- // Example: 1101 X 1011 = 1111111:
- //
- // 1011 X 1101
- // -----------
- // 1101
- // xor 1101
- // ---------
- // 10111
- // xor 0000
- // ----------
- // 010111
- // xor 1101
- // -----------
- // 1111111
- //
- // Architectural details:
- // A 32 x 32-bit array
- // [ operand_b[i] ? (operand_a << i) : '0 for i in 0 ... 31 ]
- // is generated. The entries of the array are pairwise 'xor-ed'
- // together in a 5-stage binary tree.
- //
- //
- // Cyclic Redundancy Check:
- //
- // CRC-32 (CRC-32/ISO-HDLC) and CRC-32C (CRC-32/ISCSI) are directly implemented. For
- // documentation of the crc configuration (crc-polynomials, initialization, reflection, etc.)
- // see http://reveng.sourceforge.net/crc-catalogue/all.htm
- // A useful guide to crc arithmetic and algorithms is given here:
- // http://www.piclist.com/techref/method/math/crcguide.html.
- //
- // The CRC operation solves the following equation using binary polynomial arithmetic:
- //
- // rev(rd)(x) = rev(rs1)(x) * x**n mod {1, P}(x)
- //
- // where P denotes lower 32 bits of the corresponding CRC polynomial, rev(a) the bit reversal
- // of a, n = 8,16, or 32 for .b, .h, .w -variants. {a, b} denotes bit concatenation.
- //
- // Using barret reduction, one can show that
- //
- // M(x) mod P(x) = R(x) =
- // (M(x) * x**n) & {deg(P(x)'{1'b1}}) ^ (M(x) x**-(deg(P(x) - n)) cx mu(x) cx P(x),
- //
- // Where mu(x) = polydiv(x**64, {1,P}) & 0xffffffff. Here, 'cx' refers to carry-less
- // multiplication. Substituting rev(rd)(x) for R(x) and rev(rs1)(x) for M(x) and solving for
- // rd(x) with P(x) a crc32 polynomial (deg(P(x)) = 32), we get
- //
- // rd = rev( (rev(rs1) << n) ^ ((rev(rs1) >> (32-n)) cx mu cx P)
- // = (rs1 >> n) ^ rev(rev( (rs1 << (32-n)) cx rev(mu)) cx P)
- // ^-- cycle 0--------------------^
- // ^- cycle 1 -------------------------------------------^
- //
- // In the last step we used the fact that carry-less multiplication is bit-order agnostic:
- // rev(a cx b) = rev(a) cx rev(b).
-
- logic clmul_rmode;
- logic clmul_hmode;
- logic [31:0] clmul_op_a;
- logic [31:0] clmul_op_b;
- logic [31:0] operand_b_rev;
- logic [31:0] clmul_and_stage[32];
- logic [31:0] clmul_xor_stage1[16];
- logic [31:0] clmul_xor_stage2[8];
- logic [31:0] clmul_xor_stage3[4];
- logic [31:0] clmul_xor_stage4[2];
-
- logic [31:0] clmul_result_raw;
-
- for (genvar i=0; i<32; i++) begin: gen_rev_operand_b
- assign operand_b_rev[i] = operand_b_i[31-i];
- end
-
- assign clmul_rmode = operator_i == ALU_CLMULR;
- assign clmul_hmode = operator_i == ALU_CLMULH;
-
- // CRC
- localparam logic [31:0] CRC32_POLYNOMIAL = 32'h04c1_1db7;
- localparam logic [31:0] CRC32_MU_REV = 32'hf701_1641;
-
- localparam logic [31:0] CRC32C_POLYNOMIAL = 32'h1edc_6f41;
- localparam logic [31:0] CRC32C_MU_REV = 32'hdea7_13f1;
-
- logic crc_op;
-
- logic crc_cpoly;
-
- logic [31:0] crc_operand;
- logic [31:0] crc_poly;
- logic [31:0] crc_mu_rev;
-
- assign crc_op = (operator_i == ALU_CRC32C_W) | (operator_i == ALU_CRC32_W) |
- (operator_i == ALU_CRC32C_H) | (operator_i == ALU_CRC32_H) |
- (operator_i == ALU_CRC32C_B) | (operator_i == ALU_CRC32_B);
-
- assign crc_cpoly = (operator_i == ALU_CRC32C_W) |
- (operator_i == ALU_CRC32C_H) |
- (operator_i == ALU_CRC32C_B);
-
- assign crc_hmode = (operator_i == ALU_CRC32_H) | (operator_i == ALU_CRC32C_H);
- assign crc_bmode = (operator_i == ALU_CRC32_B) | (operator_i == ALU_CRC32C_B);
-
- assign crc_poly = crc_cpoly ? CRC32C_POLYNOMIAL : CRC32_POLYNOMIAL;
- assign crc_mu_rev = crc_cpoly ? CRC32C_MU_REV : CRC32_MU_REV;
-
- always_comb begin
- unique case(1'b1)
- crc_bmode: crc_operand = {operand_a_i[7:0], 24'h0};
- crc_hmode: crc_operand = {operand_a_i[15:0], 16'h0};
- default: crc_operand = operand_a_i;
- endcase
- end
-
- // Select clmul input
- always_comb begin
- if (crc_op) begin
- clmul_op_a = instr_first_cycle_i ? crc_operand : imd_val_q_i[0];
- clmul_op_b = instr_first_cycle_i ? crc_mu_rev : crc_poly;
- end else begin
- clmul_op_a = clmul_rmode | clmul_hmode ? operand_a_rev : operand_a_i;
- clmul_op_b = clmul_rmode | clmul_hmode ? operand_b_rev : operand_b_i;
- end
- end
-
- for (genvar i=0; i<32; i++) begin : gen_clmul_and_op
- assign clmul_and_stage[i] = clmul_op_b[i] ? clmul_op_a << i : '0;
- end
-
- for (genvar i=0; i<16; i++) begin : gen_clmul_xor_op_l1
- assign clmul_xor_stage1[i] = clmul_and_stage[2*i] ^ clmul_and_stage[2*i+1];
- end
-
- for (genvar i=0; i<8; i++) begin : gen_clmul_xor_op_l2
- assign clmul_xor_stage2[i] = clmul_xor_stage1[2*i] ^ clmul_xor_stage1[2*i+1];
- end
-
- for (genvar i=0; i<4; i++) begin : gen_clmul_xor_op_l3
- assign clmul_xor_stage3[i] = clmul_xor_stage2[2*i] ^ clmul_xor_stage2[2*i+1];
- end
-
- for (genvar i=0; i<2; i++) begin : gen_clmul_xor_op_l4
- assign clmul_xor_stage4[i] = clmul_xor_stage3[2*i] ^ clmul_xor_stage3[2*i+1];
- end
-
- assign clmul_result_raw = clmul_xor_stage4[0] ^ clmul_xor_stage4[1];
-
- for (genvar i=0; i<32; i++) begin : gen_rev_clmul_result
- assign clmul_result_rev[i] = clmul_result_raw[31-i];
- end
-
- // clmulr_result = rev(clmul(rev(a), rev(b)))
- // clmulh_result = clmulr_result >> 1
- always_comb begin
- case(1'b1)
- clmul_rmode: clmul_result = clmul_result_rev;
- clmul_hmode: clmul_result = {1'b0, clmul_result_rev[31:1]};
- default: clmul_result = clmul_result_raw;
- endcase
- end
- end else begin : gen_alu_rvb_notfull
- logic [31:0] unused_imd_val_q_1;
- assign unused_imd_val_q_1 = imd_val_q_i[1];
- assign shuffle_result = '0;
- assign butterfly_result = '0;
- assign invbutterfly_result = '0;
- assign clmul_result = '0;
- // support signals
- assign bitcnt_partial_lsb_d = '0;
- assign bitcnt_partial_msb_d = '0;
- assign clmul_result_rev = '0;
- assign crc_bmode = '0;
- assign crc_hmode = '0;
- end
-
- //////////////////////////////////////
- // Multicycle Bitmanip Instructions //
- //////////////////////////////////////
- // Ternary instructions + Shift Rotations + Bit extract/deposit + CRC
- // For ternary instructions (zbt), operand_a_i is tied to rs1 in the first cycle and rs3 in the
- // second cycle. operand_b_i is always tied to rs2.
-
- always_comb begin
- unique case (operator_i)
- ALU_CMOV: begin
- multicycle_result = (operand_b_i == 32'h0) ? operand_a_i : imd_val_q_i[0];
- imd_val_d_o = '{operand_a_i, 32'h0};
- if (instr_first_cycle_i) begin
- imd_val_we_o = 2'b01;
- end else begin
- imd_val_we_o = 2'b00;
- end
- end
-
- ALU_CMIX: begin
- multicycle_result = imd_val_q_i[0] | bwlogic_and_result;
- imd_val_d_o = '{bwlogic_and_result, 32'h0};
- if (instr_first_cycle_i) begin
- imd_val_we_o = 2'b01;
- end else begin
- imd_val_we_o = 2'b00;
- end
- end
-
- ALU_FSR, ALU_FSL,
- ALU_ROL, ALU_ROR: begin
- if (shift_amt[4:0] == 5'h0) begin
- multicycle_result = shift_amt[5] ? operand_a_i : imd_val_q_i[0];
- end else begin
- multicycle_result = imd_val_q_i[0] | shift_result;
- end
- imd_val_d_o = '{shift_result, 32'h0};
- if (instr_first_cycle_i) begin
- imd_val_we_o = 2'b01;
- end else begin
- imd_val_we_o = 2'b00;
- end
- end
-
- ALU_CRC32_W, ALU_CRC32C_W,
- ALU_CRC32_H, ALU_CRC32C_H,
- ALU_CRC32_B, ALU_CRC32C_B: begin
- if (RV32B == RV32BFull) begin
- unique case(1'b1)
- crc_bmode: multicycle_result = clmul_result_rev ^ (operand_a_i >> 8);
- crc_hmode: multicycle_result = clmul_result_rev ^ (operand_a_i >> 16);
- default: multicycle_result = clmul_result_rev;
- endcase
- imd_val_d_o = '{clmul_result_rev, 32'h0};
- if (instr_first_cycle_i) begin
- imd_val_we_o = 2'b01;
- end else begin
- imd_val_we_o = 2'b00;
- end
- end else begin
- imd_val_d_o = '{operand_a_i, 32'h0};
- imd_val_we_o = 2'b00;
- multicycle_result = '0;
- end
- end
-
- ALU_BEXT, ALU_BDEP: begin
- if (RV32B == RV32BFull) begin
- multicycle_result = (operator_i == ALU_BDEP) ? butterfly_result : invbutterfly_result;
- imd_val_d_o = '{bitcnt_partial_lsb_d, bitcnt_partial_msb_d};
- if (instr_first_cycle_i) begin
- imd_val_we_o = 2'b11;
- end else begin
- imd_val_we_o = 2'b00;
- end
- end else begin
- imd_val_d_o = '{operand_a_i, 32'h0};
- imd_val_we_o = 2'b00;
- multicycle_result = '0;
- end
- end
-
- default: begin
- imd_val_d_o = '{operand_a_i, 32'h0};
- imd_val_we_o = 2'b00;
- multicycle_result = '0;
- end
- endcase
- end
-
-
- end else begin : g_no_alu_rvb
- logic [31:0] unused_imd_val_q[2];
- assign unused_imd_val_q = imd_val_q_i;
- logic [31:0] unused_butterfly_result;
- assign unused_butterfly_result = butterfly_result;
- logic [31:0] unused_invbutterfly_result;
- assign unused_invbutterfly_result = invbutterfly_result;
- // RV32B result signals
- assign bitcnt_result = '0;
- assign minmax_result = '0;
- assign pack_result = '0;
- assign sext_result = '0;
- assign singlebit_result = '0;
- assign rev_result = '0;
- assign shuffle_result = '0;
- assign butterfly_result = '0;
- assign invbutterfly_result = '0;
- assign clmul_result = '0;
- assign multicycle_result = '0;
- // RV32B support signals
- assign imd_val_d_o = '{default: '0};
- assign imd_val_we_o = '{default: '0};
- end
-
- ////////////////
- // Result mux //
- ////////////////
-
- always_comb begin
- result_o = '0;
-
- unique case (operator_i)
- // Bitwise Logic Operations (negate: RV32B)
- ALU_XOR, ALU_XNOR,
- ALU_OR, ALU_ORN,
- ALU_AND, ALU_ANDN: result_o = bwlogic_result;
-
- // Adder Operations
- ALU_ADD, ALU_SUB: result_o = adder_result;
-
- // Shift Operations
- ALU_SLL, ALU_SRL,
- ALU_SRA,
- // RV32B
- ALU_SLO, ALU_SRO: result_o = shift_result;
-
- // Shuffle Operations (RV32B)
- ALU_SHFL, ALU_UNSHFL: result_o = shuffle_result;
-
- // Comparison Operations
- ALU_EQ, ALU_NE,
- ALU_GE, ALU_GEU,
- ALU_LT, ALU_LTU,
- ALU_SLT, ALU_SLTU: result_o = {31'h0,cmp_result};
-
- // MinMax Operations (RV32B)
- ALU_MIN, ALU_MAX,
- ALU_MINU, ALU_MAXU: result_o = minmax_result;
-
- // Bitcount Operations (RV32B)
- ALU_CLZ, ALU_CTZ,
- ALU_PCNT: result_o = {26'h0, bitcnt_result};
-
- // Pack Operations (RV32B)
- ALU_PACK, ALU_PACKH,
- ALU_PACKU: result_o = pack_result;
-
- // Sign-Extend (RV32B)
- ALU_SEXTB, ALU_SEXTH: result_o = sext_result;
-
- // Ternary Bitmanip Operations (RV32B)
- ALU_CMIX, ALU_CMOV,
- ALU_FSL, ALU_FSR,
- // Rotate Shift (RV32B)
- ALU_ROL, ALU_ROR,
- // Cyclic Redundancy Checks (RV32B)
- ALU_CRC32_W, ALU_CRC32C_W,
- ALU_CRC32_H, ALU_CRC32C_H,
- ALU_CRC32_B, ALU_CRC32C_B,
- // Bit Extract / Deposit (RV32B)
- ALU_BEXT, ALU_BDEP: result_o = multicycle_result;
-
- // Single-Bit Bitmanip Operations (RV32B)
- ALU_SBSET, ALU_SBCLR,
- ALU_SBINV, ALU_SBEXT: result_o = singlebit_result;
-
- // General Reverse / Or-combine (RV32B)
- ALU_GREV, ALU_GORC: result_o = rev_result;
-
- // Bit Field Place (RV32B)
- ALU_BFP: result_o = bfp_result;
-
- // Carry-less Multiply Operations (RV32B)
- ALU_CLMUL, ALU_CLMULR,
- ALU_CLMULH: result_o = clmul_result;
-
- default: ;
- endcase
- end
-
- logic unused_shift_amt_compl;
- assign unused_shift_amt_compl = shift_amt_compl[5];
-
-endmodule
diff --git a/verilog/rtl/brq_exu_multdiv_fast.sv b/verilog/rtl/brq_exu_multdiv_fast.sv
deleted file mode 100644
index 3bb8217..0000000
--- a/verilog/rtl/brq_exu_multdiv_fast.sv
+++ /dev/null
@@ -1,514 +0,0 @@
-
-`define OP_L 15:0
-`define OP_H 31:16
-
-/**
- * Fast Multiplier and Division
- *
- * 16x16 kernel multiplier and Long Division
- */
-
-
-
-module brq_exu_multdiv_fast #(
- parameter brq_pkg::rv32m_e RV32M = brq_pkg::RV32MFast
- ) (
- input logic clk_i,
- input logic rst_ni,
- input logic mult_en_i, // dynamic enable signal, for FSM control
- input logic div_en_i, // dynamic enable signal, for FSM control
- input logic mult_sel_i, // static decoder output, for data muxes
- input logic div_sel_i, // static decoder output, for data muxes
- input brq_pkg::md_op_e operator_i,
- input logic [1:0] signed_mode_i,
- input logic [31:0] op_a_i,
- input logic [31:0] op_b_i,
- input logic [33:0] alu_adder_ext_i,
- input logic [31:0] alu_adder_i,
- input logic equal_to_zero_i,
- input logic data_ind_timing_i,
-
- output logic [32:0] alu_operand_a_o,
- output logic [32:0] alu_operand_b_o,
-
- input logic [33:0] imd_val_q_i[2],
- output logic [33:0] imd_val_d_o[2],
- output logic [1:0] imd_val_we_o,
-
- input logic multdiv_ready_id_i,
-
- output logic [31:0] multdiv_result_o,
- output logic valid_o
-);
-
- import brq_pkg::*;
-
- // Both multiplier variants
- logic signed [34:0] mac_res_signed;
- logic [34:0] mac_res_ext;
- logic [33:0] accum;
- logic sign_a, sign_b;
- logic mult_valid;
- logic signed_mult;
-
- // Results that become intermediate value depending on whether mul or div is being calculated
- logic [33:0] mac_res_d, op_remainder_d;
- // Raw output of MAC calculation
- logic [33:0] mac_res;
-
- // Divider signals
- logic div_sign_a, div_sign_b;
- logic is_greater_equal;
- logic div_change_sign, rem_change_sign;
- logic [31:0] one_shift;
- logic [31:0] op_denominator_q;
- logic [31:0] op_numerator_q;
- logic [31:0] op_quotient_q;
- logic [31:0] op_denominator_d;
- logic [31:0] op_numerator_d;
- logic [31:0] op_quotient_d;
- logic [31:0] next_remainder;
- logic [32:0] next_quotient;
- logic [31:0] res_adder_h;
- logic div_valid;
- logic [ 4:0] div_counter_q, div_counter_d;
- logic multdiv_en;
- logic mult_hold;
- logic div_hold;
- logic div_by_zero_d, div_by_zero_q;
-
- logic mult_en_internal;
- logic div_en_internal;
-
- typedef enum logic [2:0] {
- MD_IDLE, MD_ABS_A, MD_ABS_B, MD_COMP, MD_LAST, MD_CHANGE_SIGN, MD_FINISH
- } md_fsm_e;
- md_fsm_e md_state_q, md_state_d;
-
- logic unused_mult_sel_i;
- assign unused_mult_sel_i = mult_sel_i;
-
- assign mult_en_internal = mult_en_i & ~mult_hold;
- assign div_en_internal = div_en_i & ~div_hold;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- div_counter_q <= '0;
- md_state_q <= MD_IDLE;
- op_numerator_q <= '0;
- op_quotient_q <= '0;
- div_by_zero_q <= '0;
- end else if (div_en_internal) begin
- div_counter_q <= div_counter_d;
- op_numerator_q <= op_numerator_d;
- op_quotient_q <= op_quotient_d;
- md_state_q <= md_state_d;
- div_by_zero_q <= div_by_zero_d;
- end
- end
-
-
- assign multdiv_en = mult_en_internal | div_en_internal;
-
- // Intermediate value register shared with ALU
- assign imd_val_d_o[0] = div_sel_i ? op_remainder_d : mac_res_d;
- assign imd_val_we_o[0] = multdiv_en;
-
- assign imd_val_d_o[1] = {2'b0, op_denominator_d};
- assign imd_val_we_o[1] = div_en_internal;
- assign op_denominator_q = imd_val_q_i[1][31:0];
- logic [1:0] unused_imd_val;
- assign unused_imd_val = imd_val_q_i[1][33:32];
- logic unused_mac_res_ext;
- assign unused_mac_res_ext = mac_res_ext[34];
-
- assign signed_mult = (signed_mode_i != 2'b00);
- assign multdiv_result_o = div_sel_i ? imd_val_q_i[0][31:0] : mac_res_d[31:0];
-
- // The single cycle multiplier uses three 17 bit multipliers to compute MUL instructions in a
- // single cycle and MULH instructions in two cycles.
- if (RV32M == RV32MSingleCycle) begin : gen_mult_single_cycle
-
- typedef enum logic {
- MULL, MULH
- } mult_fsm_e;
- mult_fsm_e mult_state_q, mult_state_d;
-
- logic signed [33:0] mult1_res, mult2_res, mult3_res;
- logic [33:0] mult1_res_uns;
- logic [33:32] unused_mult1_res_uns;
- logic [15:0] mult1_op_a, mult1_op_b;
- logic [15:0] mult2_op_a, mult2_op_b;
- logic [15:0] mult3_op_a, mult3_op_b;
- logic mult1_sign_a, mult1_sign_b;
- logic mult2_sign_a, mult2_sign_b;
- logic mult3_sign_a, mult3_sign_b;
- logic [33:0] summand1, summand2, summand3;
-
- assign mult1_res = $signed({mult1_sign_a, mult1_op_a}) * $signed({mult1_sign_b, mult1_op_b});
- assign mult2_res = $signed({mult2_sign_a, mult2_op_a}) * $signed({mult2_sign_b, mult2_op_b});
- assign mult3_res = $signed({mult3_sign_a, mult3_op_a}) * $signed({mult3_sign_b, mult3_op_b});
-
- assign mac_res_signed = $signed(summand1) + $signed(summand2) + $signed(summand3);
-
- assign mult1_res_uns = $unsigned(mult1_res);
- assign mac_res_ext = $unsigned(mac_res_signed);
- assign mac_res = mac_res_ext[33:0];
-
- assign sign_a = signed_mode_i[0] & op_a_i[31];
- assign sign_b = signed_mode_i[1] & op_b_i[31];
-
- // The first two multipliers are only used in state 1 (MULL). We can assign them statically.
- // al*bl
- assign mult1_sign_a = 1'b0;
- assign mult1_sign_b = 1'b0;
- assign mult1_op_a = op_a_i[`OP_L];
- assign mult1_op_b = op_b_i[`OP_L];
-
- // al*bh
- assign mult2_sign_a = 1'b0;
- assign mult2_sign_b = sign_b;
- assign mult2_op_a = op_a_i[`OP_L];
- assign mult2_op_b = op_b_i[`OP_H];
-
- // used in MULH
- assign accum[17:0] = imd_val_q_i[0][33:16];
- assign accum[33:18] = {16{signed_mult & imd_val_q_i[0][33]}};
-
- always_comb begin
- // Default values == MULL
-
- // ah*bl
- mult3_sign_a = sign_a;
- mult3_sign_b = 1'b0;
- mult3_op_a = op_a_i[`OP_H];
- mult3_op_b = op_b_i[`OP_L];
-
- summand1 = {18'h0, mult1_res_uns[`OP_H]};
- summand2 = $unsigned(mult2_res);
- summand3 = $unsigned(mult3_res);
-
- // mac_res = A*B[47:16], mult1_res = A*B[15:0]
- mac_res_d = {2'b0, mac_res[`OP_L], mult1_res_uns[`OP_L]};
- mult_valid = mult_en_i;
- mult_state_d = MULL;
-
- mult_hold = 1'b0;
-
- unique case (mult_state_q)
-
- MULL: begin
- if (operator_i != MD_OP_MULL) begin
- mac_res_d = mac_res;
- mult_valid = 1'b0;
- mult_state_d = MULH;
- end else begin
- mult_hold = ~multdiv_ready_id_i;
- end
- end
-
- MULH: begin
- // ah*bh
- mult3_sign_a = sign_a;
- mult3_sign_b = sign_b;
- mult3_op_a = op_a_i[`OP_H];
- mult3_op_b = op_b_i[`OP_H];
- mac_res_d = mac_res;
-
- summand1 = '0;
- summand2 = accum;
- summand3 = mult3_res;
-
- mult_state_d = MULL;
- mult_valid = 1'b1;
-
- mult_hold = ~multdiv_ready_id_i;
- end
-
- default: begin
- mult_state_d = MULL;
- end
-
- endcase // mult_state_q
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- mult_state_q <= MULL;
- end else begin
- if (mult_en_internal) begin
- mult_state_q <= mult_state_d;
- end
- end
- end
-
- assign unused_mult1_res_uns = mult1_res_uns[33:32];
-
- // States must be knwon/valid.
-
-
- // The fast multiplier uses one 17 bit multiplier to compute MUL instructions in 3 cycles
- // and MULH instructions in 4 cycles.
- end else begin : gen_mult_fast
- logic [15:0] mult_op_a;
- logic [15:0] mult_op_b;
-
- typedef enum logic [1:0] {
- ALBL, ALBH, AHBL, AHBH
- } mult_fsm_e;
- mult_fsm_e mult_state_q, mult_state_d;
-
- // The 2 MSBs of mac_res_ext (mac_res_ext[34:33]) are always equal since:
- // 1. The 2 MSBs of the multiplicants are always equal, and
- // 2. The 16 MSBs of the addend (accum[33:18]) are always equal.
- // Thus, it is safe to ignore mac_res_ext[34].
- assign mac_res_signed =
- $signed({sign_a, mult_op_a}) * $signed({sign_b, mult_op_b}) + $signed(accum);
- assign mac_res_ext = $unsigned(mac_res_signed);
- assign mac_res = mac_res_ext[33:0];
-
- always_comb begin
- mult_op_a = op_a_i[`OP_L];
- mult_op_b = op_b_i[`OP_L];
- sign_a = 1'b0;
- sign_b = 1'b0;
- accum = imd_val_q_i[0];
- mac_res_d = mac_res;
- mult_state_d = mult_state_q;
- mult_valid = 1'b0;
- mult_hold = 1'b0;
-
- unique case (mult_state_q)
-
- ALBL: begin
- // al*bl
- mult_op_a = op_a_i[`OP_L];
- mult_op_b = op_b_i[`OP_L];
- sign_a = 1'b0;
- sign_b = 1'b0;
- accum = '0;
- mac_res_d = mac_res;
- mult_state_d = ALBH;
- end
-
- ALBH: begin
- // al*bh<<16
- mult_op_a = op_a_i[`OP_L];
- mult_op_b = op_b_i[`OP_H];
- sign_a = 1'b0;
- sign_b = signed_mode_i[1] & op_b_i[31];
- // result of AL*BL (in imd_val_q_i[0]) always unsigned with no carry
- accum = {18'b0, imd_val_q_i[0][31:16]};
- if (operator_i == MD_OP_MULL) begin
- mac_res_d = {2'b0, mac_res[`OP_L], imd_val_q_i[0][`OP_L]};
- end else begin
- // MD_OP_MULH
- mac_res_d = mac_res;
- end
- mult_state_d = AHBL;
- end
-
- AHBL: begin
- // ah*bl<<16
- mult_op_a = op_a_i[`OP_H];
- mult_op_b = op_b_i[`OP_L];
- sign_a = signed_mode_i[0] & op_a_i[31];
- sign_b = 1'b0;
- if (operator_i == MD_OP_MULL) begin
- accum = {18'b0, imd_val_q_i[0][31:16]};
- mac_res_d = {2'b0, mac_res[15:0], imd_val_q_i[0][15:0]};
- mult_valid = 1'b1;
-
- // Note no state transition will occur if mult_hold is set
- mult_state_d = ALBL;
- mult_hold = ~multdiv_ready_id_i;
- end else begin
- accum = imd_val_q_i[0];
- mac_res_d = mac_res;
- mult_state_d = AHBH;
- end
- end
-
- AHBH: begin
- // only MD_OP_MULH here
- // ah*bh
- mult_op_a = op_a_i[`OP_H];
- mult_op_b = op_b_i[`OP_H];
- sign_a = signed_mode_i[0] & op_a_i[31];
- sign_b = signed_mode_i[1] & op_b_i[31];
- accum[17: 0] = imd_val_q_i[0][33:16];
- accum[33:18] = {16{signed_mult & imd_val_q_i[0][33]}};
- // result of AH*BL is not signed only if signed_mode_i == 2'b00
- mac_res_d = mac_res;
- mult_valid = 1'b1;
-
- // Note no state transition will occur if mult_hold is set
- mult_state_d = ALBL;
- mult_hold = ~multdiv_ready_id_i;
- end
- default: begin
- mult_state_d = ALBL;
- end
- endcase // mult_state_q
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- mult_state_q <= ALBL;
- end else begin
- if (mult_en_internal) begin
- mult_state_q <= mult_state_d;
- end
- end
- end
-
- // States must be knwon/valid.
-
- end // gen_mult_fast
-
- // Divider
- assign res_adder_h = alu_adder_ext_i[32:1];
- logic [1:0] unused_alu_adder_ext;
- assign unused_alu_adder_ext = {alu_adder_ext_i[33],alu_adder_ext_i[0]};
-
- assign next_remainder = is_greater_equal ? res_adder_h[31:0] : imd_val_q_i[0][31:0];
- assign next_quotient = is_greater_equal ? {1'b0, op_quotient_q} | {1'b0, one_shift} :
- {1'b0, op_quotient_q};
-
- assign one_shift = {31'b0, 1'b1} << div_counter_q;
-
- // The adder in the ALU computes alu_operand_a_o + alu_operand_b_o which means
- // Remainder - Divisor. If Remainder - Divisor >= 0, is_greater_equal is equal to 1,
- // the next Remainder is Remainder - Divisor contained in res_adder_h and the
- always_comb begin
- if ((imd_val_q_i[0][31] ^ op_denominator_q[31]) == 1'b0) begin
- is_greater_equal = (res_adder_h[31] == 1'b0);
- end else begin
- is_greater_equal = imd_val_q_i[0][31];
- end
- end
-
- assign div_sign_a = op_a_i[31] & signed_mode_i[0];
- assign div_sign_b = op_b_i[31] & signed_mode_i[1];
- assign div_change_sign = (div_sign_a ^ div_sign_b) & ~div_by_zero_q;
- assign rem_change_sign = div_sign_a;
-
-
- always_comb begin
- div_counter_d = div_counter_q - 5'h1;
- op_remainder_d = imd_val_q_i[0];
- op_quotient_d = op_quotient_q;
- md_state_d = md_state_q;
- op_numerator_d = op_numerator_q;
- op_denominator_d = op_denominator_q;
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~op_b_i, 1'b1};
- div_valid = 1'b0;
- div_hold = 1'b0;
- div_by_zero_d = div_by_zero_q;
-
- unique case(md_state_q)
- MD_IDLE: begin
- if (operator_i == MD_OP_DIV) begin
- // Check if the Denominator is 0
- // quotient for division by 0 is specified to be -1
- // Note with data-independent time option, the full divide operation will proceed as
- // normal and will naturally return -1
- op_remainder_d = '1;
- md_state_d = (!data_ind_timing_i && equal_to_zero_i) ? MD_FINISH : MD_ABS_A;
- // Record that this is a div by zero to stop the sign change at the end of the
- // division (in data_ind_timing mode).
- div_by_zero_d = equal_to_zero_i;
- end else begin
- // Check if the Denominator is 0
- // remainder for division by 0 is specified to be the numerator (operand a)
- // Note with data-independent time option, the full divide operation will proceed as
- // normal and will naturally return operand a
- op_remainder_d = {2'b0, op_a_i};
- md_state_d = (!data_ind_timing_i && equal_to_zero_i) ? MD_FINISH : MD_ABS_A;
- end
- // 0 - B = 0 iff B == 0
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~op_b_i, 1'b1};
- div_counter_d = 5'd31;
- end
-
- MD_ABS_A: begin
- // quotient
- op_quotient_d = '0;
- // A abs value
- op_numerator_d = div_sign_a ? alu_adder_i : op_a_i;
- md_state_d = MD_ABS_B;
- div_counter_d = 5'd31;
- // ABS(A) = 0 - A
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~op_a_i, 1'b1};
- end
-
- MD_ABS_B: begin
- // remainder
- op_remainder_d = { 33'h0, op_numerator_q[31]};
- // B abs value
- op_denominator_d = div_sign_b ? alu_adder_i : op_b_i;
- md_state_d = MD_COMP;
- div_counter_d = 5'd31;
- // ABS(B) = 0 - B
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~op_b_i, 1'b1};
- end
-
- MD_COMP: begin
- op_remainder_d = {1'b0, next_remainder[31:0], op_numerator_q[div_counter_d]};
- op_quotient_d = next_quotient[31:0];
- md_state_d = (div_counter_q == 5'd1) ? MD_LAST : MD_COMP;
- // Division
- alu_operand_a_o = {imd_val_q_i[0][31:0], 1'b1}; // it contains the remainder
- alu_operand_b_o = {~op_denominator_q[31:0], 1'b1}; // -denominator two's compliment
- end
-
- MD_LAST: begin
- if (operator_i == MD_OP_DIV) begin
- // this time we save the quotient in op_remainder_d (i.e. imd_val_q_i[0]) since
- // we do not need anymore the remainder
- op_remainder_d = {1'b0, next_quotient};
- end else begin
- // this time we do not save the quotient anymore since we need only the remainder
- op_remainder_d = {2'b0, next_remainder[31:0]};
- end
- // Division
- alu_operand_a_o = {imd_val_q_i[0][31:0], 1'b1}; // it contains the remainder
- alu_operand_b_o = {~op_denominator_q[31:0], 1'b1}; // -denominator two's compliment
-
- md_state_d = MD_CHANGE_SIGN;
- end
-
- MD_CHANGE_SIGN: begin
- md_state_d = MD_FINISH;
- if (operator_i == MD_OP_DIV) begin
- op_remainder_d = (div_change_sign) ? {2'h0, alu_adder_i} : imd_val_q_i[0];
- end else begin
- op_remainder_d = (rem_change_sign) ? {2'h0, alu_adder_i} : imd_val_q_i[0];
- end
- // ABS(Quotient) = 0 - Quotient (or Remainder)
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~imd_val_q_i[0][31:0], 1'b1};
- end
-
- MD_FINISH: begin
- // Hold result until ID stage is ready to accept it
- // Note no state transition will occur if div_hold is set
- md_state_d = MD_IDLE;
- div_hold = ~multdiv_ready_id_i;
- div_valid = 1'b1;
- end
-
- default: begin
- md_state_d = MD_IDLE;
- end
- endcase // md_state_q
- end
-
- assign valid_o = mult_valid | div_valid;
-
-
-endmodule // brq_mult
diff --git a/verilog/rtl/brq_exu_multdiv_slow.sv b/verilog/rtl/brq_exu_multdiv_slow.sv
deleted file mode 100644
index 5592cb6..0000000
--- a/verilog/rtl/brq_exu_multdiv_slow.sv
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
-/**
- * Slow Multiplier and Division
- *
- * Baugh-Wooley multiplier and Long Division
- */
-
-
-module brq_exu_multdiv_slow
-(
- input logic clk_i,
- input logic rst_ni,
- input logic mult_en_i, // dynamic enable signal, for FSM control
- input logic div_en_i, // dynamic enable signal, for FSM control
- input logic mult_sel_i, // static decoder output, for data muxes
- input logic div_sel_i, // static decoder output, for data muxes
- input brq_pkg::md_op_e operator_i,
- input logic [1:0] signed_mode_i,
- input logic [31:0] op_a_i,
- input logic [31:0] op_b_i,
- input logic [33:0] alu_adder_ext_i,
- input logic [31:0] alu_adder_i,
- input logic equal_to_zero_i,
- input logic data_ind_timing_i,
-
- output logic [32:0] alu_operand_a_o,
- output logic [32:0] alu_operand_b_o,
-
- input logic [33:0] imd_val_q_i[2],
- output logic [33:0] imd_val_d_o[2],
- output logic [1:0] imd_val_we_o,
-
- input logic multdiv_ready_id_i,
-
- output logic [31:0] multdiv_result_o,
-
- output logic valid_o
-);
-
- import brq_pkg::*;
-
- typedef enum logic [2:0] {
- MD_IDLE, MD_ABS_A, MD_ABS_B, MD_COMP, MD_LAST, MD_CHANGE_SIGN, MD_FINISH
- } md_fsm_e;
- md_fsm_e md_state_q, md_state_d;
-
- logic [32:0] accum_window_q, accum_window_d;
- logic unused_imd_val0;
- logic [ 1:0] unused_imd_val1;
-
- logic [32:0] res_adder_l;
- logic [32:0] res_adder_h;
-
- logic [ 4:0] multdiv_count_q, multdiv_count_d;
- logic [32:0] op_b_shift_q, op_b_shift_d;
- logic [32:0] op_a_shift_q, op_a_shift_d;
- logic [32:0] op_a_ext, op_b_ext;
- logic [32:0] one_shift;
- logic [32:0] op_a_bw_pp, op_a_bw_last_pp;
- logic [31:0] b_0;
- logic sign_a, sign_b;
- logic [32:0] next_quotient;
- logic [31:0] next_remainder;
- logic [31:0] op_numerator_q, op_numerator_d;
- logic is_greater_equal;
- logic div_change_sign, rem_change_sign;
- logic div_by_zero_d, div_by_zero_q;
- logic multdiv_hold;
- logic multdiv_en;
-
- // (accum_window_q + op_a_shift_q)
- assign res_adder_l = alu_adder_ext_i[32:0];
- // (accum_window_q + op_a_shift_q)>>1
- assign res_adder_h = alu_adder_ext_i[33:1];
-
- /////////////////////
- // ALU Operand MUX //
- /////////////////////
-
- // Intermediate value register shared with ALU
- assign imd_val_d_o[0] = {1'b0,accum_window_d};
- assign imd_val_we_o[0] = ~multdiv_hold;
- assign accum_window_q = imd_val_q_i[0][32:0];
- assign unused_imd_val0 = imd_val_q_i[0][33];
-
- assign imd_val_d_o[1] = {2'b00, op_numerator_d};
- assign imd_val_we_o[1] = multdiv_en;
- assign op_numerator_q = imd_val_q_i[1][31:0];
- assign unused_imd_val1 = imd_val_q_i[1][33:32];
-
- always_comb begin
- alu_operand_a_o = accum_window_q;
-
- unique case(operator_i)
-
- MD_OP_MULL: begin
- alu_operand_b_o = op_a_bw_pp;
- end
-
- MD_OP_MULH: begin
- alu_operand_b_o = (md_state_q == MD_LAST) ? op_a_bw_last_pp : op_a_bw_pp;
- end
-
- MD_OP_DIV,
- MD_OP_REM: begin
- unique case(md_state_q)
- MD_IDLE: begin
- // 0 - B = 0 iff B == 0
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~op_b_i, 1'b1};
- end
- MD_ABS_A: begin
- // ABS(A) = 0 - A
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~op_a_i, 1'b1};
- end
- MD_ABS_B: begin
- // ABS(B) = 0 - B
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~op_b_i, 1'b1};
- end
- MD_CHANGE_SIGN: begin
- // ABS(Quotient) = 0 - Quotient (or Reminder)
- alu_operand_a_o = {32'h0 , 1'b1};
- alu_operand_b_o = {~accum_window_q[31:0], 1'b1};
- end
- default: begin
- // Division
- alu_operand_a_o = {accum_window_q[31:0], 1'b1}; // it contains the remainder
- alu_operand_b_o = {~op_b_shift_q[31:0], 1'b1}; // -denominator two's compliment
- end
- endcase
- end
- //default: begin
- // alu_operand_a_o = accum_window_q;
- // alu_operand_b_o = {~op_b_shift_q[31:0], 1'b1};
- // end
- endcase
- end
-
- // Multiplier partial product calculation
- assign b_0 = {32{op_b_shift_q[0]}};
- assign op_a_bw_pp = { ~(op_a_shift_q[32] & op_b_shift_q[0]), (op_a_shift_q[31:0] & b_0) };
- assign op_a_bw_last_pp = { (op_a_shift_q[32] & op_b_shift_q[0]), ~(op_a_shift_q[31:0] & b_0) };
-
- // Sign extend the input operands
- assign sign_a = op_a_i[31] & signed_mode_i[0];
- assign sign_b = op_b_i[31] & signed_mode_i[1];
-
- assign op_a_ext = {sign_a, op_a_i};
- assign op_b_ext = {sign_b, op_b_i};
-
- // Divider calculations
-
- // The adder in the ALU computes Remainder - Divisor. If Remainder - Divisor >= 0,
- // is_greater_equal is true, the next Remainder is the subtraction result and the Quotient
- // multdiv_count_q-th bit is set to 1.
- assign is_greater_equal = (accum_window_q[31] == op_b_shift_q[31]) ?
- ~res_adder_h[31] : accum_window_q[31];
-
- assign one_shift = {32'b0, 1'b1} << multdiv_count_q;
-
- assign next_remainder = is_greater_equal ? res_adder_h[31:0] : accum_window_q[31:0];
- assign next_quotient = is_greater_equal ? op_a_shift_q | one_shift : op_a_shift_q;
-
- assign div_change_sign = (sign_a ^ sign_b) & ~div_by_zero_q;
- assign rem_change_sign = sign_a;
-
- always_comb begin
- multdiv_count_d = multdiv_count_q;
- accum_window_d = accum_window_q;
- op_b_shift_d = op_b_shift_q;
- op_a_shift_d = op_a_shift_q;
- op_numerator_d = op_numerator_q;
- md_state_d = md_state_q;
- multdiv_hold = 1'b0;
- div_by_zero_d = div_by_zero_q;
- if (mult_sel_i || div_sel_i) begin
- unique case(md_state_q)
- MD_IDLE: begin
- unique case(operator_i)
- MD_OP_MULL: begin
- op_a_shift_d = op_a_ext << 1;
- accum_window_d = { ~(op_a_ext[32] & op_b_i[0]),
- op_a_ext[31:0] & {32{op_b_i[0]}} };
- op_b_shift_d = op_b_ext >> 1;
- // Proceed with multiplication by 0/1 in data-independent time mode
- md_state_d = (!data_ind_timing_i && ((op_b_ext >> 1) == 0)) ? MD_LAST : MD_COMP;
- end
- MD_OP_MULH: begin
- op_a_shift_d = op_a_ext;
- accum_window_d = { 1'b1, ~(op_a_ext[32] & op_b_i[0]),
- op_a_ext[31:1] & {31{op_b_i[0]}} };
- op_b_shift_d = op_b_ext >> 1;
- md_state_d = MD_COMP;
- end
- MD_OP_DIV: begin
- // Check if the denominator is 0
- // quotient for division by 0 is specified to be -1
- // Note with data-independent time option, the full divide operation will proceed as
- // normal and will naturally return -1
- accum_window_d = {33{1'b1}};
- md_state_d = (!data_ind_timing_i && equal_to_zero_i) ? MD_FINISH : MD_ABS_A;
- // Record that this is a div by zero to stop the sign change at the end of the
- // division (in data_ind_timing mode).
- div_by_zero_d = equal_to_zero_i;
- end
- MD_OP_REM: begin
- // Check if the denominator is 0
- // remainder for division by 0 is specified to be the numerator (operand a)
- // Note with data-independent time option, the full divide operation will proceed as
- // normal and will naturally return operand a
- accum_window_d = op_a_ext;
- md_state_d = (!data_ind_timing_i && equal_to_zero_i) ? MD_FINISH : MD_ABS_A;
- end
- // default:;
- endcase
- multdiv_count_d = 5'd31;
- end
-
- MD_ABS_A: begin
- // quotient
- op_a_shift_d = '0;
- // A abs value
- op_numerator_d = sign_a ? alu_adder_i : op_a_i;
- md_state_d = MD_ABS_B;
- end
-
- MD_ABS_B: begin
- // remainder
- accum_window_d = {32'h0,op_numerator_q[31]};
- // B abs value
- op_b_shift_d = sign_b ? {1'b0,alu_adder_i} : {1'b0,op_b_i};
- md_state_d = MD_COMP;
- end
-
- MD_COMP: begin
- multdiv_count_d = multdiv_count_q - 5'h1;
- unique case(operator_i)
- MD_OP_MULL: begin
- accum_window_d = res_adder_l;
- op_a_shift_d = op_a_shift_q << 1;
- op_b_shift_d = op_b_shift_q >> 1;
- // Multiplication is complete once op_b is zero, unless in data_ind_timing mode where
- // the maximum possible shift-add operations will be completed regardless of op_b
- md_state_d = ((!data_ind_timing_i && (op_b_shift_d == 0)) ||
- (multdiv_count_q == 5'd1)) ? MD_LAST : MD_COMP;
- end
- MD_OP_MULH: begin
- accum_window_d = res_adder_h;
- op_a_shift_d = op_a_shift_q;
- op_b_shift_d = op_b_shift_q >> 1;
- md_state_d = (multdiv_count_q == 5'd1) ? MD_LAST : MD_COMP;
- end
- MD_OP_DIV,
- MD_OP_REM: begin
- accum_window_d = {next_remainder[31:0], op_numerator_q[multdiv_count_d]};
- op_a_shift_d = next_quotient;
- md_state_d = (multdiv_count_q == 5'd1) ? MD_LAST : MD_COMP;
- end
- // default: ;
- endcase
- end
-
- MD_LAST: begin
- unique case(operator_i)
- MD_OP_MULL: begin
- accum_window_d = res_adder_l;
-
- // Note no state transition will occur if multdiv_hold is set
- md_state_d = MD_IDLE;
- multdiv_hold = ~multdiv_ready_id_i;
- end
- MD_OP_MULH: begin
- accum_window_d = res_adder_l;
- md_state_d = MD_IDLE;
-
- // Note no state transition will occur if multdiv_hold is set
- md_state_d = MD_IDLE;
- multdiv_hold = ~multdiv_ready_id_i;
- end
- MD_OP_DIV: begin
- // this time we save the quotient in accum_window_q since we do not need anymore the
- // remainder
- accum_window_d = next_quotient;
- md_state_d = MD_CHANGE_SIGN;
- end
- MD_OP_REM: begin
- // this time we do not save the quotient anymore since we need only the remainder
- accum_window_d = {1'b0, next_remainder[31:0]};
- md_state_d = MD_CHANGE_SIGN;
- end
- // default: ;
- endcase
- end
-
- MD_CHANGE_SIGN: begin
- md_state_d = MD_FINISH;
- unique case(operator_i)
- MD_OP_DIV:
- accum_window_d = div_change_sign ? {1'b0,alu_adder_i} : accum_window_q;
- MD_OP_REM:
- accum_window_d = rem_change_sign ? {1'b0,alu_adder_i} : accum_window_q;
- default: ;
- endcase
- end
-
- MD_FINISH: begin
- // Note no state transition will occur if multdiv_hold is set
- md_state_d = MD_IDLE;
- multdiv_hold = ~multdiv_ready_id_i;
- end
-
- default: begin
- md_state_d = MD_IDLE;
- end
- endcase // md_state_q
- end // (mult_sel_i || div_sel_i)
- end
-
- //////////////////////////////////////////
- // Mutliplier / Divider state registers //
- //////////////////////////////////////////
-
- assign multdiv_en = (mult_en_i | div_en_i) & ~multdiv_hold;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- multdiv_count_q <= 5'h0;
- op_b_shift_q <= 33'h0;
- op_a_shift_q <= 33'h0;
- md_state_q <= MD_IDLE;
- div_by_zero_q <= 1'b0;
- end else if (multdiv_en) begin
- multdiv_count_q <= multdiv_count_d;
- op_b_shift_q <= op_b_shift_d;
- op_a_shift_q <= op_a_shift_d;
- md_state_q <= md_state_d;
- div_by_zero_q <= div_by_zero_d;
- end
- end
-
- /////////////
- // Outputs //
- /////////////
-
- assign valid_o = (md_state_q == MD_FINISH) |
- (md_state_q == MD_LAST &
- (operator_i == MD_OP_MULL |
- operator_i == MD_OP_MULH));
-
- assign multdiv_result_o = div_en_i ? accum_window_q[31:0] : res_adder_l[31:0];
-
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/brq_fp_register_file_ff.sv b/verilog/rtl/brq_fp_register_file_ff.sv
deleted file mode 100644
index 3b1b597..0000000
--- a/verilog/rtl/brq_fp_register_file_ff.sv
+++ /dev/null
@@ -1,77 +0,0 @@
-//`timescale 1ns/1ps
-// Copyright lowRISC contributors.
-// Copyright 2018 ETH Zurich and University of Bologna, see also CREDITS.md.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-/**
- * RISC-V register file
- *
- * Register file with 31 or 15x 32 bit wide registers. Register 0 is fixed to 0.
- * This register file is based on flip flops. Use this register file when
- * targeting FPGA synthesis or Verilator simulation.
- */
-
-module brq_fp_register_file_ff #(
- parameter brq_pkg::rvfloat_e RVF = brq_pkg::RV32FSingle,
- parameter int unsigned DataWidth = 32
- ) (
- // Clock and Reset
- input logic clk_i,
- input logic rst_ni,
-
- //Read port R1
- input logic [4:0] raddr_a_i,
- output logic [DataWidth-1:0] rdata_a_o,
-
- //Read port R2
- input logic [4:0] raddr_b_i,
- output logic [DataWidth-1:0] rdata_b_o,
-
- //Read port R2
- input logic [4:0] raddr_c_i,
- output logic [DataWidth-1:0] rdata_c_o,
-
-
- // Write port W1
- input logic [4:0] waddr_a_i,
- input logic [DataWidth-1:0] wdata_a_i,
- input logic we_a_i
-
-);
-import brq_pkg::rvfloat_e;
-
- localparam int unsigned ADDR_WIDTH = (RVF==brq_pkg::RV64FDouble) ? 6 : 5;
- localparam int unsigned NUM_WORDS = (RVF==brq_pkg::RV64FDouble) ? 64 : 32;
-
- logic [NUM_WORDS-1:0][DataWidth-1:0] rf_reg;
- logic [NUM_WORDS-1:0][DataWidth-1:0] rf_reg_q;
- logic [NUM_WORDS-1:0] we_a_dec;
-
- always_comb begin : we_a_decoder
- for (int unsigned i = 0; i < NUM_WORDS; i++) begin
- we_a_dec[i] = (waddr_a_i == 5'(i)) ? we_a_i : 1'b0;
- end
- end
-
- for (genvar i = 0; i < NUM_WORDS; i++) begin : g_rf_flops
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rf_reg_q[i] <= '0;
- end else if(we_a_dec[i]) begin
- rf_reg_q[i] <= wdata_a_i;
- end
-// else begin
-// rf_reg_q[5] <= 32'h41a00000;
-// rf_reg_q[6] <= 32'h41200000;
-// end
- end
- end
-
- assign rf_reg[NUM_WORDS-1:0] = rf_reg_q[NUM_WORDS-1:0];
-
- assign rdata_a_o = rf_reg[raddr_a_i];
- assign rdata_b_o = rf_reg[raddr_b_i];
- assign rdata_c_o = rf_reg[raddr_c_i];
-
-endmodule
diff --git a/verilog/rtl/brq_idu.sv b/verilog/rtl/brq_idu.sv
deleted file mode 100644
index 45c8c9c..0000000
--- a/verilog/rtl/brq_idu.sv
+++ /dev/null
@@ -1,1077 +0,0 @@
-
-
-`ifdef RISCV_FORMAL
- `define RVFI
-`endif
-
-/**
- * Instruction Decode Stage
- *
- * Decode stage of the core. It decodes the instructions and hosts the register
- * file.
- */
-
-module brq_idu #(
- parameter bit RV32E = 0,
- parameter brq_pkg::rv32m_e RV32M = brq_pkg::RV32MFast,
- parameter brq_pkg::rv32b_e RV32B = brq_pkg::RV32BNone,
- parameter brq_pkg::rvfloat_e RVF = brq_pkg::RV64FDouble,
- parameter bit DataIndTiming = 1'b0,
- parameter bit BranchTargetALU = 0,
- parameter bit SpecBranch = 0,
- parameter bit WritebackStage = 0,
- parameter bit BranchPredictor = 0
-) (
- input logic clk_i,
- input logic rst_ni,
-
- output logic ctrl_busy_o,
- output logic illegal_insn_o,
-
- // Interface to IF stage
- input logic instr_valid_i,
- input logic [31:0] instr_rdata_i, // from IF-ID pipeline registers
- input logic [31:0] instr_rdata_alu_i, // from IF-ID pipeline registers
- input logic [15:0] instr_rdata_c_i, // from IF-ID pipeline registers
- input logic instr_is_compressed_i,
- // input logic instr_bp_taken_i,
- output logic instr_req_o,
- output logic instr_first_cycle_id_o,
- output logic instr_valid_clear_o, // kill instr in IF-ID reg
- output logic id_in_ready_o, // ID stage is ready for next instr
- output logic icache_inval_o,
-
- // Jumps and branches
- input logic branch_decision_i,
-
- // IF and ID stage signals
- output logic pc_set_o,
- output logic pc_set_spec_o,
- output brq_pkg::pc_sel_e pc_mux_o,
- //output logic nt_branch_mispredict_o,
- output brq_pkg::exc_pc_sel_e exc_pc_mux_o,
- output brq_pkg::exc_cause_e exc_cause_o,
-
- input logic illegal_c_insn_i,
- input logic instr_fetch_err_i,
- input logic instr_fetch_err_plus2_i,
-
- input logic [31:0] pc_id_i,
-
- // Stalls
- input logic ex_valid_i, // EX stage has valid output
- input logic lsu_resp_valid_i, // LSU has valid output, or is done
- // ALU
- output brq_pkg::alu_op_e alu_operator_ex_o,
- output logic [31:0] alu_operand_a_ex_o,
- output logic [31:0] alu_operand_b_ex_o,
-
- // Multicycle Operation Stage Register
- input logic [1:0] imd_val_we_ex_i,
- input logic [33:0] imd_val_d_ex_i[2],
- output logic [33:0] imd_val_q_ex_o[2],
-
- // Branch target ALU
- output logic [31:0] bt_a_operand_o,
- output logic [31:0] bt_b_operand_o,
-
- // MUL, DIV
- output logic mult_en_ex_o,
- output logic div_en_ex_o,
- output logic mult_sel_ex_o,
- output logic div_sel_ex_o,
- output brq_pkg::md_op_e multdiv_operator_ex_o,
- output logic [1:0] multdiv_signed_mode_ex_o,
- output logic [31:0] multdiv_operand_a_ex_o,
- output logic [31:0] multdiv_operand_b_ex_o,
- output logic multdiv_ready_id_o,
-
- // CSR
- output logic csr_access_o,
- output brq_pkg::csr_op_e csr_op_o,
- output logic csr_op_en_o,
- output logic csr_save_if_o,
- output logic csr_save_id_o,
- output logic csr_save_wb_o,
- output logic csr_restore_mret_id_o,
- output logic csr_restore_dret_id_o,
- output logic csr_save_cause_o,
- output logic [31:0] csr_mtval_o,
- input brq_pkg::priv_lvl_e priv_mode_i,
- input logic csr_mstatus_tw_i,
- input logic illegal_csr_insn_i,
- input logic data_ind_timing_i,
-
- // Interface to load store unit
- output logic lsu_req_o,
- output logic lsu_we_o,
- output logic [1:0] lsu_type_o,
- output logic lsu_sign_ext_o,
- output logic [31:0] lsu_wdata_o,
-
- input logic lsu_req_done_i, // Data req to LSU is complete and
- // instruction can move to writeback
- // (only relevant where writeback stage is
- // present)
-
- input logic lsu_addr_incr_req_i,
- input logic [31:0] lsu_addr_last_i,
-
- // Interrupt signals
- input logic csr_mstatus_mie_i,
- input logic irq_pending_i,
- input brq_pkg::irqs_t irqs_i,
- input logic irq_nm_i,
- output logic nmi_mode_o,
-
- input logic lsu_load_err_i,
- input logic lsu_store_err_i,
-
- // Debug Signal
- output logic debug_mode_o,
- output brq_pkg::dbg_cause_e debug_cause_o,
- output logic debug_csr_save_o,
- input logic debug_req_i,
- input logic debug_single_step_i,
- input logic debug_ebreakm_i,
- input logic debug_ebreaku_i,
- input logic trigger_match_i,
-
- // Write back signal
- input logic [31:0] result_ex_i,
- input logic [31:0] csr_rdata_i,
-
- // Register file read
- output logic [4:0] rf_raddr_a_o,
- input logic [31:0] rf_rdata_a_i,
- output logic [4:0] rf_raddr_b_o,
- input logic [31:0] rf_rdata_b_i,
- output logic rf_ren_a_o,
- output logic rf_ren_b_o,
-
- // Register file write (via writeback)
- output logic [4:0] rf_waddr_id_o,
- output logic [31:0] rf_wdata_id_o,
- output logic rf_we_id_o,
- output logic rf_rd_a_wb_match_o,
- output logic rf_rd_b_wb_match_o,
-
- // Register write information from writeback (for resolving data hazards)
- input logic [4:0] rf_waddr_wb_i,
- input logic [31:0] rf_wdata_fwd_wb_i,
- input logic rf_write_wb_i,
-
- output logic en_wb_o,
- output brq_pkg::wb_instr_type_e instr_type_wb_o,
- output logic instr_perf_count_id_o,
- input logic ready_wb_i,
- input logic outstanding_load_wb_i,
- input logic outstanding_store_wb_i,
-
- // Performance Counters
- output logic perf_jump_o, // executing a jump instr
- output logic perf_branch_o, // executing a branch instr
- output logic perf_tbranch_o, // executing a taken branch instr
- output logic perf_dside_wait_o, // instruction in ID/EX is awaiting memory
- // access to finish before proceeding
- output logic perf_mul_wait_o,
- output logic perf_div_wait_o,
- output logic instr_id_done_o,
-
- // Floating point extensions IO
- output fpnew_pkg::roundmode_e fp_rounding_mode_o, // defines the rounding mode
- // output brq_pkg::op_b_sel_e fp_alu_op_b_mux_sel_o, // operand b selection: reg value or
- // immediate
- input logic [31:0] fp_rf_rdata_a_i,
- input logic [31:0] fp_rf_rdata_b_i,
- input logic [31:0] fp_rf_rdata_c_i,
- output logic [4:0] fp_rf_raddr_a_o,
- output logic [4:0] fp_rf_raddr_b_o,
- output logic [4:0] fp_rf_raddr_c_o,
- //output logic fp_rf_ren_a_o,
- //output logic fp_rf_ren_b_o,
- //output logic fp_rf_ren_c_o,
- output logic [4:0] fp_rf_waddr_o,
- output logic fp_rf_we_o,
-
- output fpnew_pkg::operation_e fp_alu_operator_o,
- output logic fp_alu_op_mod_o,
- output fpnew_pkg::fp_format_e fp_src_fmt_o,
- output fpnew_pkg::fp_format_e fp_dst_fmt_o,
- output logic fp_rm_dynamic_o,
- output logic fp_flush_o,
- output logic is_fp_instr_o,
- output logic use_fp_rs1_o,
- output logic use_fp_rs2_o,
- output logic use_fp_rs3_o,
- output logic use_fp_rd_o,
- input logic fpu_busy_i,
- input logic fp_rf_write_wb_i,
- input logic [31:0] fp_rf_wdata_fwd_wb_i,
- output logic [2:0][31:0] fp_operands_o,
- output logic fp_load_o
-);
-
- import brq_pkg::*;
-
- // Decoder/Controller, ID stage internal signals
- logic illegal_insn_dec;
- logic ebrk_insn;
- logic mret_insn_dec;
- logic dret_insn_dec;
- logic ecall_insn_dec;
- logic wfi_insn_dec;
-
- logic wb_exception;
-
- logic branch_in_dec;
- logic branch_spec, branch_set_spec;
- logic branch_set, branch_set_d;
- logic branch_not_set;
- logic branch_taken;
- logic jump_in_dec;
- logic jump_set_dec;
- logic jump_set;
-
- logic instr_first_cycle;
- logic instr_executing;
- logic instr_done;
- logic controller_run;
- logic stall_ld_hz;
- logic stall_mem;
- logic stall_multdiv;
- logic stall_branch;
- logic stall_jump;
- logic stall_id;
- logic stall_wb;
- logic flush_id;
- logic multicycle_done;
-
- // Immediate decoding and sign extension
- logic [31:0] imm_i_type;
- logic [31:0] imm_s_type;
- logic [31:0] imm_b_type;
- logic [31:0] imm_u_type;
- logic [31:0] imm_j_type;
- logic [31:0] zimm_rs1_type;
-
- logic [31:0] imm_a; // contains the immediate for operand b
- logic [31:0] imm_b; // contains the immediate for operand b
-
- // Register file interface
-
- rf_wd_sel_e rf_wdata_sel;
- logic rf_we_dec, rf_we_raw;
- logic rf_ren_a, rf_ren_b;
-
- assign rf_ren_a_o = rf_ren_a;
- assign rf_ren_b_o = rf_ren_b;
-
- logic [31:0] rf_rdata_a_fwd;
- logic [31:0] rf_rdata_b_fwd;
-
- // ALU Control
- alu_op_e alu_operator;
- op_a_sel_e alu_op_a_mux_sel, alu_op_a_mux_sel_dec;
- op_b_sel_e alu_op_b_mux_sel, alu_op_b_mux_sel_dec;
- logic alu_multicycle_dec;
- logic stall_alu;
-
- logic [33:0] imd_val_q[2];
-
- op_a_sel_e bt_a_mux_sel;
- imm_b_sel_e bt_b_mux_sel;
-
- imm_a_sel_e imm_a_mux_sel;
- imm_b_sel_e imm_b_mux_sel, imm_b_mux_sel_dec;
-
- // Multiplier Control
- logic mult_en_id, mult_en_dec; // use integer multiplier
- logic div_en_id, div_en_dec; // use integer division or reminder
- logic multdiv_en_dec;
- md_op_e multdiv_operator;
- logic [1:0] multdiv_signed_mode;
-
- // Data Memory Control
- logic lsu_we;
- logic [1:0] lsu_type;
- logic lsu_sign_ext;
- logic lsu_req, lsu_req_dec;
- logic data_req_allowed;
-
- // CSR control
- logic csr_pipe_flush;
-
- logic [31:0] alu_operand_a;
- logic [31:0] alu_operand_b;
-
- // Floating point
- logic fp_swap_oprnds;
- logic [31:0] fp_rf_rdata_a_fwd;
- logic [31:0] fp_rf_rdata_b_fwd;
- logic [31:0] fp_rf_rdata_c_fwd;
- logic [31:0] temp;
- logic [31:0] fpu_op_a;
- logic [31:0] fpu_op_b;
- logic [31:0] fpu_op_c;
- logic mv_instr;
- logic [31:0] result_wb;
-
- /////////////
- // LSU Mux //
- /////////////
-
- // Misaligned loads/stores result in two aligned loads/stores, compute second address
- assign alu_op_a_mux_sel = lsu_addr_incr_req_i ? OP_A_FWD : alu_op_a_mux_sel_dec;
- assign alu_op_b_mux_sel = lsu_addr_incr_req_i ? OP_B_IMM : alu_op_b_mux_sel_dec;
- assign imm_b_mux_sel = lsu_addr_incr_req_i ? IMM_B_INCR_ADDR : imm_b_mux_sel_dec;
-
- ///////////////////
- // Operand MUXES //
- ///////////////////
-
- // Main ALU immediate MUX for Operand A
- assign imm_a = (imm_a_mux_sel == IMM_A_Z) ? zimm_rs1_type : '0;
-
- // Main ALU MUX for Operand A
- always_comb begin : alu_operand_a_mux
- unique case (alu_op_a_mux_sel)
- OP_A_REG_A: alu_operand_a = rf_rdata_a_fwd;
- OP_A_FWD: alu_operand_a = lsu_addr_last_i;
- OP_A_CURRPC: alu_operand_a = pc_id_i;
- OP_A_IMM: alu_operand_a = imm_a;
- //default: alu_operand_a = pc_id_i;
- endcase
- end
-
- if (BranchTargetALU) begin : g_btalu_muxes
- // Branch target ALU operand A mux
- always_comb begin : bt_operand_a_mux
- unique case (bt_a_mux_sel)
- OP_A_REG_A: bt_a_operand_o = rf_rdata_a_fwd;
- OP_A_CURRPC: bt_a_operand_o = pc_id_i;
- default: bt_a_operand_o = pc_id_i;
- endcase
- end
-
- // Branch target ALU operand B mux
- always_comb begin : bt_immediate_b_mux
- unique case (bt_b_mux_sel)
- IMM_B_I: bt_b_operand_o = imm_i_type;
- IMM_B_B: bt_b_operand_o = imm_b_type;
- IMM_B_J: bt_b_operand_o = imm_j_type;
- IMM_B_INCR_PC: bt_b_operand_o = instr_is_compressed_i ? 32'h2 : 32'h4;
- default: bt_b_operand_o = instr_is_compressed_i ? 32'h2 : 32'h4;
- endcase
- end
-
- // Reduced main ALU immediate MUX for Operand B
- always_comb begin : immediate_b_mux
- unique case (imm_b_mux_sel)
- IMM_B_I: imm_b = imm_i_type;
- IMM_B_S: imm_b = imm_s_type;
- IMM_B_U: imm_b = imm_u_type;
- IMM_B_INCR_PC: imm_b = instr_is_compressed_i ? 32'h2 : 32'h4;
- IMM_B_INCR_ADDR: imm_b = 32'h4;
- default: imm_b = 32'h4;
- endcase
- end
-
- end else begin : g_nobtalu
- op_a_sel_e unused_a_mux_sel;
- imm_b_sel_e unused_b_mux_sel;
-
- assign unused_a_mux_sel = bt_a_mux_sel;
- assign unused_b_mux_sel = bt_b_mux_sel;
- assign bt_a_operand_o = '0;
- assign bt_b_operand_o = '0;
-
- // Full main ALU immediate MUX for Operand B
- always_comb begin : immediate_b_mux
- unique case (imm_b_mux_sel)
- IMM_B_I: imm_b = imm_i_type;
- IMM_B_S: imm_b = imm_s_type;
- IMM_B_B: imm_b = imm_b_type;
- IMM_B_U: imm_b = imm_u_type;
- IMM_B_J: imm_b = imm_j_type;
- IMM_B_INCR_PC: imm_b = instr_is_compressed_i ? 32'h2 : 32'h4;
- IMM_B_INCR_ADDR: imm_b = 32'h4;
- default: imm_b = 32'h4;
- endcase
- end
-
- end
-
- // ALU MUX for Operand B
- assign alu_operand_b = (alu_op_b_mux_sel == OP_B_IMM) ? imm_b : rf_rdata_b_fwd;
-
- /////////////////////////////////////////
- // Multicycle Operation Stage Register //
- /////////////////////////////////////////
-
- for (genvar i=0; i<2; i++) begin : gen_intermediate_val_reg
- always_ff @(posedge clk_i or negedge rst_ni) begin : intermediate_val_reg
- if (!rst_ni) begin
- imd_val_q[i] <= '0;
- end else if (imd_val_we_ex_i[i]) begin
- imd_val_q[i] <= imd_val_d_ex_i[i];
- end
- end
- end
-
- assign imd_val_q_ex_o = imd_val_q;
-
- /////////////
- // Decoder //
- /////////////
-
- brq_idu_decoder #(
- .RV32E ( RV32E ),
- .RV32M ( RV32M ),
- .RV32B ( RV32B ),
- .BranchTargetALU ( BranchTargetALU )
- ) decoder_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
-
- // controller
- .illegal_insn_o ( illegal_insn_dec ),
- .ebrk_insn_o ( ebrk_insn ),
- .mret_insn_o ( mret_insn_dec ),
- .dret_insn_o ( dret_insn_dec ),
- .ecall_insn_o ( ecall_insn_dec ),
- .wfi_insn_o ( wfi_insn_dec ),
- .jump_set_o ( jump_set_dec ),
- .branch_taken_i ( branch_taken ),
- .icache_inval_o ( icache_inval_o ),
-
- // from IF-ID pipeline register
- .instr_first_cycle_i ( instr_first_cycle ),
- .instr_rdata_i ( instr_rdata_i ),
- .instr_rdata_alu_i ( instr_rdata_alu_i ),
- .illegal_c_insn_i ( illegal_c_insn_i ),
-
- // immediates
- .imm_a_mux_sel_o ( imm_a_mux_sel ),
- .imm_b_mux_sel_o ( imm_b_mux_sel_dec ),
- .bt_a_mux_sel_o ( bt_a_mux_sel ),
- .bt_b_mux_sel_o ( bt_b_mux_sel ),
-
- .imm_i_type_o ( imm_i_type ),
- .imm_s_type_o ( imm_s_type ),
- .imm_b_type_o ( imm_b_type ),
- .imm_u_type_o ( imm_u_type ),
- .imm_j_type_o ( imm_j_type ),
- .zimm_rs1_type_o ( zimm_rs1_type ),
-
- // register file
- .rf_wdata_sel_o ( rf_wdata_sel ),
- .rf_we_o ( rf_we_dec ),
-
- .rf_raddr_a_o ( rf_raddr_a_o ),
- .rf_raddr_b_o ( rf_raddr_b_o ),
- .rf_waddr_o ( rf_waddr_id_o ),
- .rf_ren_a_o ( rf_ren_a ),
- .rf_ren_b_o ( rf_ren_b ),
-
- // ALU
- .alu_operator_o ( alu_operator ),
- .alu_op_a_mux_sel_o ( alu_op_a_mux_sel_dec ),
- .alu_op_b_mux_sel_o ( alu_op_b_mux_sel_dec ),
- .alu_multicycle_o ( alu_multicycle_dec ),
-
- // MULT & DIV
- .mult_en_o ( mult_en_dec ),
- .div_en_o ( div_en_dec ),
- .mult_sel_o ( mult_sel_ex_o ),
- .div_sel_o ( div_sel_ex_o ),
- .multdiv_operator_o ( multdiv_operator ),
- .multdiv_signed_mode_o ( multdiv_signed_mode ),
-
- // CSRs
- .csr_access_o ( csr_access_o ),
- .csr_op_o ( csr_op_o ),
-
- // LSU
- .data_req_o ( lsu_req_dec ),
- .data_we_o ( lsu_we ),
- .data_type_o ( lsu_type ),
- .data_sign_extension_o ( lsu_sign_ext ),
-
- // jump/branches
- .jump_in_dec_o ( jump_in_dec ),
- .branch_in_dec_o ( branch_in_dec ),
-
- // Floating point extensions IO
- .fp_rounding_mode_o ( fp_rounding_mode_o ), // defines the rounding mode
- .fp_rf_raddr_a_o ( fp_rf_raddr_a_o ),
- .fp_rf_raddr_b_o ( fp_rf_raddr_b_o ),
- .fp_rf_raddr_c_o ( fp_rf_raddr_c_o ),
- .fp_rf_waddr_o ( fp_rf_waddr_o ),
- .fp_rf_we_o ( fp_rf_we_o ),
- .fp_alu_operator_o ( fp_alu_operator_o ),
- .fp_alu_op_mod_o ( fp_alu_op_mod_o ),
- .fp_src_fmt_o ( fp_src_fmt_o ),
- .fp_dst_fmt_o ( fp_dst_fmt_o ),
- .fp_rm_dynamic_o ( fp_rm_dynamic_o ),
- .is_fp_instr_o ( is_fp_instr_o ),
- .use_fp_rs1_o ( use_fp_rs1_o ),
- .use_fp_rs2_o ( use_fp_rs2_o ),
- .use_fp_rs3_o ( use_fp_rs3_o ),
- .use_fp_rd_o ( use_fp_rd_o ),
- .fp_swap_oprnds_o ( fp_swap_oprnds ),
- .fp_load_o ( fp_load_o ),
- .mv_instr_o ( mv_instr )
- );
-
-// assign fpu_op_a = use_fp_rs1_o ? fp_rf_rdata_a_fwd : rf_rdata_a_fwd;
-// assign fpu_op_b = use_fp_rs2_o ? fp_rf_rdata_b_fwd : rf_rdata_b_fwd;
-// assign fpu_op_c = fp_rf_rdata_c_fwd;
-
- ///////////////////////
- // Register File MUX //
- ///////////////////////
-
- // Suppress register write if there is an illegal CSR access or instruction is not executing
- assign rf_we_id_o = rf_we_raw & instr_executing & ~illegal_csr_insn_i;
-
- // Register file write data mux
- always_comb begin : rf_wdata_id_mux
- unique case (rf_wdata_sel)
- RF_WD_EX: rf_wdata_id_o = result_wb;
- RF_WD_CSR: rf_wdata_id_o = csr_rdata_i;
- // default: rf_wdata_id_o = result_wb;
- endcase
- end
-
- /////////////////////////////////
- // CSR-related pipline flushes //
- /////////////////////////////////
- always_comb begin : csr_pipeline_flushes
- csr_pipe_flush = 1'b0;
-
- // A pipeline flush is needed to let the controller react after modifying certain CSRs:
- // - When enabling interrupts, pending IRQs become visible to the controller only during
- // the next cycle. If during that cycle the core disables interrupts again, it does not
- // see any pending IRQs and consequently does not start to handle interrupts.
- // - When modifying debug CSRs - TODO: Check if this is really needed
- if (csr_op_en_o == 1'b1 && (csr_op_o == CSR_OP_WRITE || csr_op_o == CSR_OP_SET)) begin
- if (csr_num_e'(instr_rdata_i[31:20]) == CSR_MSTATUS ||
- csr_num_e'(instr_rdata_i[31:20]) == CSR_MIE) begin
- csr_pipe_flush = 1'b1;
- end
- end else if (csr_op_en_o == 1'b1 && csr_op_o != CSR_OP_READ) begin
- if (csr_num_e'(instr_rdata_i[31:20]) == CSR_DCSR ||
- csr_num_e'(instr_rdata_i[31:20]) == CSR_DPC ||
- csr_num_e'(instr_rdata_i[31:20]) == CSR_DSCRATCH0 ||
- csr_num_e'(instr_rdata_i[31:20]) == CSR_DSCRATCH1) begin
- csr_pipe_flush = 1'b1;
- end
- end
- end
-
- ////////////////
- // Controller //
- ////////////////
-
- assign illegal_insn_o = instr_valid_i & (illegal_insn_dec | illegal_csr_insn_i);
-
- brq_idu_controller #(
- .WritebackStage ( WritebackStage ),
- .BranchPredictor ( BranchPredictor )
- ) controller_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
-
- .ctrl_busy_o ( ctrl_busy_o ),
-
- // decoder related signals
- .illegal_insn_i ( illegal_insn_o ),
- .ecall_insn_i ( ecall_insn_dec ),
- .mret_insn_i ( mret_insn_dec ),
- .dret_insn_i ( dret_insn_dec ),
- .wfi_insn_i ( wfi_insn_dec ),
- .ebrk_insn_i ( ebrk_insn ),
- .csr_pipe_flush_i ( csr_pipe_flush ),
-
- // from IF-ID pipeline
- .instr_valid_i ( instr_valid_i ),
- .instr_i ( instr_rdata_i ),
- .instr_compressed_i ( instr_rdata_c_i ),
- .instr_is_compressed_i ( instr_is_compressed_i ),
- // .instr_bp_taken_i ( instr_bp_taken_i ),
- .instr_fetch_err_i ( instr_fetch_err_i ),
- .instr_fetch_err_plus2_i ( instr_fetch_err_plus2_i ),
- .pc_id_i ( pc_id_i ),
-
- // to IF-ID pipeline
- .instr_valid_clear_o ( instr_valid_clear_o ),
- .id_in_ready_o ( id_in_ready_o ),
- .controller_run_o ( controller_run ),
-
- // to prefetcher
- .instr_req_o ( instr_req_o ),
- .pc_set_o ( pc_set_o ),
- .pc_set_spec_o ( pc_set_spec_o ),
- .pc_mux_o ( pc_mux_o ),
- // .nt_branch_mispredict_o ( nt_branch_mispredict_o ),
- .exc_pc_mux_o ( exc_pc_mux_o ),
- .exc_cause_o ( exc_cause_o ),
-
- // LSU
- .lsu_addr_last_i ( lsu_addr_last_i ),
- .load_err_i ( lsu_load_err_i ),
- .store_err_i ( lsu_store_err_i ),
- .wb_exception_o ( wb_exception ),
-
- // jump/branch control
- .branch_set_i ( branch_set ),
- .branch_set_spec_i ( branch_set_spec ),
- //.branch_not_set_i ( branch_not_set ),
- .jump_set_i ( jump_set ),
-
- // interrupt signals
- .csr_mstatus_mie_i ( csr_mstatus_mie_i ),
- .irq_pending_i ( irq_pending_i ),
- .irqs_i ( irqs_i ),
- .irq_nm_i ( irq_nm_i ),
- .nmi_mode_o ( nmi_mode_o ),
-
- // CSR Controller Signals
- .csr_save_if_o ( csr_save_if_o ),
- .csr_save_id_o ( csr_save_id_o ),
- .csr_save_wb_o ( csr_save_wb_o ),
- .csr_restore_mret_id_o ( csr_restore_mret_id_o ),
- .csr_restore_dret_id_o ( csr_restore_dret_id_o ),
- .csr_save_cause_o ( csr_save_cause_o ),
- .csr_mtval_o ( csr_mtval_o ),
- .priv_mode_i ( priv_mode_i ),
- .csr_mstatus_tw_i ( csr_mstatus_tw_i ),
-
- // Debug Signal
- .debug_mode_o ( debug_mode_o ),
- .debug_cause_o ( debug_cause_o ),
- .debug_csr_save_o ( debug_csr_save_o ),
- .debug_req_i ( debug_req_i ),
- .debug_single_step_i ( debug_single_step_i ),
- .debug_ebreakm_i ( debug_ebreakm_i ),
- .debug_ebreaku_i ( debug_ebreaku_i ),
- .trigger_match_i ( trigger_match_i ),
-
- .stall_id_i ( stall_id ),
- .stall_wb_i ( stall_wb ),
- .flush_id_o ( flush_id ),
- .ready_wb_i ( ready_wb_i ),
-
- // Performance Counters
- .perf_jump_o ( perf_jump_o ),
- .perf_tbranch_o ( perf_tbranch_o ),
- .fpu_busy_i ( fpu_busy_i )
- );
-
- assign fp_flush_o = flush_id;
- assign multdiv_en_dec = mult_en_dec | div_en_dec;
-
- assign lsu_req = instr_executing ? data_req_allowed & lsu_req_dec : 1'b0;
- assign mult_en_id = instr_executing ? mult_en_dec : 1'b0;
- assign div_en_id = instr_executing ? div_en_dec : 1'b0;
-
- assign lsu_req_o = lsu_req;
- assign lsu_we_o = lsu_we;
- assign lsu_type_o = lsu_type;
- assign lsu_sign_ext_o = lsu_sign_ext;
- assign lsu_wdata_o = fpu_op_b; //rf_rdata_b_fwd;
- // csr_op_en_o is set when CSR access should actually happen.
- // csv_access_o is set when CSR access instruction is present and is used to compute whether a CSR
- // access is illegal. A combinational loop would be created if csr_op_en_o was used along (as
- // asserting it for an illegal csr access would result in a flush that would need to deassert it).
- assign csr_op_en_o = csr_access_o & instr_executing & instr_id_done_o;
-
- assign alu_operator_ex_o = alu_operator;
- assign alu_operand_a_ex_o = alu_operand_a;
- assign alu_operand_b_ex_o = alu_operand_b;
-
- assign mult_en_ex_o = mult_en_id;
- assign div_en_ex_o = div_en_id;
-
- assign multdiv_operator_ex_o = multdiv_operator;
- assign multdiv_signed_mode_ex_o = multdiv_signed_mode;
- assign multdiv_operand_a_ex_o = rf_rdata_a_fwd;
- assign multdiv_operand_b_ex_o = rf_rdata_b_fwd;
-
- ////////////////////////
- // Branch set control //
- ////////////////////////
-
- if (BranchTargetALU && !DataIndTiming) begin : g_branch_set_direct
- // Branch set fed straight to controller with branch target ALU
- // (condition pass/fail used same cycle as generated instruction request)
- assign branch_set = branch_set_d;
- assign branch_set_spec = branch_spec;
- end else begin : g_branch_set_flop
- // Branch set flopped without branch target ALU, or in fixed time execution mode
- // (condition pass/fail used next cycle where branch target is calculated)
- logic branch_set_q;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- branch_set_q <= 1'b0;
- end else begin
- branch_set_q <= branch_set_d;
- end
- end
-
- // Branches always take two cycles in fixed time execution mode, with or without the branch
- // target ALU (to avoid a path from the branch decision into the branch target ALU operand
- // muxing).
- assign branch_set = (BranchTargetALU && !data_ind_timing_i) ? branch_set_d : branch_set_q;
- // Use the speculative branch signal when BTALU is enabled
- assign branch_set_spec = (BranchTargetALU && !data_ind_timing_i) ? branch_spec : branch_set_q;
- end
-
- // Branch condition is calculated in the first cycle and flopped for use in the second cycle
- // (only used in fixed time execution mode to determine branch destination).
- if (DataIndTiming) begin : g_sec_branch_taken
- logic branch_taken_q;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- branch_taken_q <= 1'b0;
- end else begin
- branch_taken_q <= branch_decision_i;
- end
- end
-
- assign branch_taken = ~data_ind_timing_i | branch_taken_q;
-
- end else begin : g_nosec_branch_taken
-
- // Signal unused without fixed time execution mode - only taken branches will trigger branch_set
- assign branch_taken = 1'b1;
-
- end
-
- // Holding branch_set/jump_set high for more than one cycle should not cause a functional issue.
- // However it could generate needless prefetch buffer flushes and instruction fetches. The ID/EX
- // designs ensures that this never happens for non-predicted branches.
-
-
- ///////////////
- // ID-EX FSM //
- ///////////////
-
- typedef enum logic { FIRST_CYCLE, MULTI_CYCLE } id_fsm_e;
- id_fsm_e id_fsm_q, id_fsm_d;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin : id_pipeline_reg
- if (!rst_ni) begin
- id_fsm_q <= FIRST_CYCLE;
- end else begin
- id_fsm_q <= id_fsm_d;
- end
- end
-
- // ID/EX stage can be in two states, FIRST_CYCLE and MULTI_CYCLE. An instruction enters
- // MULTI_CYCLE if it requires multiple cycles to complete regardless of stalls and other
- // considerations. An instruction may be held in FIRST_CYCLE if it's unable to begin executing
- // (this is controlled by instr_executing).
-
- always_comb begin
- id_fsm_d = id_fsm_q;
- rf_we_raw = rf_we_dec;
- stall_multdiv = 1'b0;
- stall_jump = 1'b0;
- stall_branch = 1'b0;
- stall_alu = 1'b0;
- branch_set_d = 1'b0;
- branch_spec = 1'b0;
- branch_not_set = 1'b0;
- jump_set = 1'b0;
- perf_branch_o = 1'b0;
-
- if (instr_executing) begin
- unique case (id_fsm_q)
- FIRST_CYCLE: begin
- unique case (1'b1)
- lsu_req_dec: begin
- if (!WritebackStage) begin
- // LSU operation
- id_fsm_d = MULTI_CYCLE;
- end else begin
- if(~lsu_req_done_i) begin
- id_fsm_d = MULTI_CYCLE;
- end
- end
- end
- multdiv_en_dec: begin
- // MUL or DIV operation
- if (~ex_valid_i) begin
- // When single-cycle multiply is configured mul can finish in the first cycle so
- // only enter MULTI_CYCLE state if a result isn't immediately available
- id_fsm_d = MULTI_CYCLE;
- rf_we_raw = 1'b0;
- stall_multdiv = 1'b1;
- end
- end
- branch_in_dec: begin
- // cond branch operation
- // All branches take two cycles in fixed time execution mode, regardless of branch
- // condition.
- id_fsm_d = (data_ind_timing_i || (!BranchTargetALU && branch_decision_i)) ?
- MULTI_CYCLE : FIRST_CYCLE;
- stall_branch = (~BranchTargetALU & branch_decision_i) | data_ind_timing_i;
- branch_set_d = branch_decision_i | data_ind_timing_i;
-
- if (BranchPredictor) begin
- branch_not_set = ~branch_decision_i;
- end
-
- // Speculative branch (excludes branch_decision_i)
- branch_spec = SpecBranch ? 1'b1 : branch_decision_i;
- perf_branch_o = 1'b1;
- end
- jump_in_dec: begin
- // uncond branch operation
- // BTALU means jumps only need one cycle
- id_fsm_d = BranchTargetALU ? FIRST_CYCLE : MULTI_CYCLE;
- stall_jump = ~BranchTargetALU;
- jump_set = jump_set_dec;
- end
- alu_multicycle_dec: begin
- stall_alu = 1'b1;
- id_fsm_d = MULTI_CYCLE;
- rf_we_raw = 1'b0;
- end
- default: begin
- id_fsm_d = FIRST_CYCLE;
- end
- endcase
- end
-
- MULTI_CYCLE: begin
- if(multdiv_en_dec) begin
- rf_we_raw = rf_we_dec & ex_valid_i;
- end
-
- if (multicycle_done & ready_wb_i) begin
- id_fsm_d = FIRST_CYCLE;
- end else begin
- stall_multdiv = multdiv_en_dec;
- stall_branch = branch_in_dec;
- stall_jump = jump_in_dec;
- end
- end
-
- // default: begin
- // id_fsm_d = FIRST_CYCLE;
- // end
- endcase
- end
- end
-
- // Note for the two-stage configuration ready_wb_i is always set
- assign multdiv_ready_id_o = ready_wb_i;
-
-
- // Stall ID/EX stage for reason that relates to instruction in ID/EX
- assign stall_id = stall_ld_hz | stall_mem | stall_multdiv | stall_jump | stall_branch |
- stall_alu;
-
- assign instr_done = ~stall_id & ~flush_id & instr_executing;
-
- // Signal instruction in ID is in it's first cycle. It can remain in its
- // first cycle if it is stalled.
- assign instr_first_cycle = instr_valid_i & (id_fsm_q == FIRST_CYCLE);
- // Used by RVFI to know when to capture register read data
- // Used by ALU to access RS3 if ternary instruction.
- assign instr_first_cycle_id_o = instr_first_cycle;
-
- if (WritebackStage) begin : gen_stall_mem
- // Register read address matches write address in WB
- logic rf_rd_a_wb_match;
- logic rf_rd_b_wb_match;
- logic fp_rf_rd_a_wb_match;
- logic fp_rf_rd_b_wb_match;
- logic fp_rf_rd_c_wb_match;
- // Hazard between registers being read and written
- logic rf_rd_a_hz;
- logic rf_rd_b_hz;
- logic rf_rd_c_hz;
-
- logic outstanding_memory_access;
-
- logic instr_kill;
-
- assign multicycle_done = lsu_req_dec ? ~stall_mem : ex_valid_i;
-
- // Is a memory access ongoing that isn't finishing this cycle
- assign outstanding_memory_access = (outstanding_load_wb_i | outstanding_store_wb_i) &
- ~lsu_resp_valid_i;
-
- // Can start a new memory access if any previous one has finished or is finishing
- assign data_req_allowed = ~outstanding_memory_access;
-
- // Instruction won't execute because:
- // - There is a pending exception in writeback
- // The instruction in ID/EX will be flushed and the core will jump to an exception handler
- // - The controller isn't running instructions
- // This either happens in preparation for a flush and jump to an exception handler e.g. in
- // response to an IRQ or debug request or whilst the core is sleeping or resetting/fetching
- // first instruction in which case any valid instruction in ID/EX should be ignored.
- // - There was an error on instruction fetch
- assign instr_kill = instr_fetch_err_i |
- wb_exception |
- ~controller_run;
-
- // With writeback stage instructions must be prevented from executing if there is:
- // - A load hazard
- // - A pending memory access
- // If it receives an error response this results in a precise exception from WB so ID/EX
- // instruction must not execute until error response is known).
- // - A load/store error
- // This will cause a precise exception for the instruction in WB so ID/EX instruction must not
- // execute
- assign instr_executing = instr_valid_i &
- ~instr_kill &
- ~stall_ld_hz &
- ~outstanding_memory_access;
-
-
- // Stall for reasons related to memory:
- // * There is an outstanding memory access that won't resolve this cycle (need to wait to allow
- // precise exceptions)
- // * There is a load/store request not being granted or which is unaligned and waiting to issue
- // a second request (needs to stay in ID for the address calculation)
- assign stall_mem = instr_valid_i &
- (outstanding_memory_access | (lsu_req_dec & ~lsu_req_done_i));
-
- // If we stall a load in ID for any reason, it must not make an LSU request
- // (otherwide we might issue two requests for the same instruction)
-
-
- assign rf_rd_a_wb_match = (rf_waddr_wb_i == rf_raddr_a_o) & |rf_raddr_a_o;
- assign rf_rd_b_wb_match = (rf_waddr_wb_i == rf_raddr_b_o) & |rf_raddr_b_o;
-
- assign fp_rf_rd_a_wb_match = (rf_waddr_wb_i == rf_raddr_a_o);
- assign fp_rf_rd_b_wb_match = (rf_waddr_wb_i == rf_raddr_b_o);
-
- assign fp_rf_rd_c_wb_match = (rf_waddr_wb_i == fp_rf_raddr_c_o);
-
- assign rf_rd_a_wb_match_o = rf_rd_a_wb_match;
- assign rf_rd_b_wb_match_o = rf_rd_b_wb_match;
-
- // If instruction is reading register that load will be writing stall in
- // ID until load is complete. No need to stall when reading zero register.
- assign rf_rd_a_hz = rf_rd_a_wb_match & (rf_ren_a | use_fp_rs1_o);
- assign rf_rd_b_hz = rf_rd_b_wb_match & (rf_ren_b | use_fp_rs2_o);
- assign rf_rd_c_hz = rf_rd_b_wb_match & use_fp_rs3_o;
-
- // If instruction is read register that writeback is writing forward writeback data to read
- // data. Note this doesn't factor in load data as it arrives too late, such hazards are
- // resolved via a stall (see above).
-
- assign rf_rdata_a_fwd = rf_rd_a_wb_match & rf_write_wb_i ? rf_wdata_fwd_wb_i : rf_rdata_a_i;
- assign rf_rdata_b_fwd = rf_rd_b_wb_match & rf_write_wb_i ? rf_wdata_fwd_wb_i : rf_rdata_b_i;
-
- // forwarding for floating point unit
- assign fp_rf_rdata_a_fwd = fp_rf_rd_a_wb_match & fp_rf_write_wb_i ? fp_rf_wdata_fwd_wb_i : fp_rf_rdata_a_i;
- assign fp_rf_rdata_b_fwd = fp_rf_rd_b_wb_match & fp_rf_write_wb_i ? fp_rf_wdata_fwd_wb_i : fp_rf_rdata_b_i;
- assign fp_rf_rdata_c_fwd = fp_rf_rd_c_wb_match & fp_rf_write_wb_i ? fp_rf_wdata_fwd_wb_i : fp_rf_rdata_c_i;
-
- assign stall_ld_hz = outstanding_load_wb_i & (rf_rd_a_hz | rf_rd_b_hz | rf_rd_c_hz);
-
- assign instr_type_wb_o = ~lsu_req_dec ? WB_INSTR_OTHER :
- lsu_we ? WB_INSTR_STORE :
- WB_INSTR_LOAD;
-
- assign instr_id_done_o = en_wb_o & ready_wb_i;
-
- // Stall ID/EX as instruction in ID/EX cannot proceed to writeback yet
- assign stall_wb = en_wb_o & ~ready_wb_i;
-
- assign perf_dside_wait_o = instr_valid_i & ~instr_kill &
- (outstanding_memory_access | stall_ld_hz);
- end else begin : gen_no_stall_mem
-
- assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i;
-
- assign data_req_allowed = instr_first_cycle;
-
- // Without Writeback Stage always stall the first cycle of a load/store.
- // Then stall until it is complete
- assign stall_mem = instr_valid_i & (lsu_req_dec & (~lsu_resp_valid_i | instr_first_cycle));
-
- // No load hazards without Writeback Stage
- assign stall_ld_hz = 1'b0;
-
- // Without writeback stage any valid instruction that hasn't seen an error will execute
- assign instr_executing = instr_valid_i & ~instr_fetch_err_i & controller_run;
-
-
- // No data forwarding without writeback stage so always take source register data direct from
- // register file
- assign rf_rdata_a_fwd = rf_rdata_a_i;
- assign rf_rdata_b_fwd = rf_rdata_b_i;
-
- assign fp_rf_rdata_a_fwd = fp_rf_rdata_a_i;
- assign fp_rf_rdata_b_fwd = fp_rf_rdata_b_i;
- assign fp_rf_rdata_c_fwd = fp_rf_rdata_c_i;
-
- assign rf_rd_a_wb_match_o = 1'b0;
- assign rf_rd_b_wb_match_o = 1'b0;
-
- // Unused Writeback stage only IO & wiring
- // Assign inputs and internal wiring to unused signals to satisfy lint checks
- // Tie-off outputs to constant values
- logic unused_data_req_done_ex;
- logic [4:0] unused_rf_waddr_wb;
- logic unused_rf_write_wb;
- logic unused_outstanding_load_wb;
- logic unused_outstanding_store_wb;
- logic unused_wb_exception;
- logic [31:0] unused_rf_wdata_fwd_wb;
-
- assign unused_data_req_done_ex = lsu_req_done_i;
- assign unused_rf_waddr_wb = rf_waddr_wb_i;
- assign unused_rf_write_wb = rf_write_wb_i;
- assign unused_outstanding_load_wb = outstanding_load_wb_i;
- assign unused_outstanding_store_wb = outstanding_store_wb_i;
- assign unused_wb_exception = wb_exception;
- assign unused_rf_wdata_fwd_wb = rf_wdata_fwd_wb_i;
-
- assign instr_type_wb_o = WB_INSTR_OTHER;
- assign stall_wb = 1'b0;
-
- assign perf_dside_wait_o = instr_executing & lsu_req_dec & ~lsu_resp_valid_i;
-
- assign instr_id_done_o = instr_done;
- end
-
- /* Swap operands */
- always_comb begin : swapping
- fpu_op_a = use_fp_rs1_o ? fp_rf_rdata_a_fwd : rf_rdata_a_fwd;
- fpu_op_b = use_fp_rs2_o ? fp_rf_rdata_b_fwd : rf_rdata_b_fwd;
- if (fp_swap_oprnds) begin
- fpu_op_c = fpu_op_a;
- end else begin
- fpu_op_c = fp_rf_rdata_c_fwd;
- end
- fp_operands_o = {fpu_op_c , fpu_op_b , fpu_op_a};
- end
-
- assign result_wb = mv_instr ? fpu_op_a : result_ex_i;
-
- // Signal which instructions to count as retired in minstret, all traps along with ebrk and
- // ecall instructions are not counted.
- assign instr_perf_count_id_o = ~ebrk_insn & ~ecall_insn_dec & ~illegal_insn_dec &
- ~illegal_csr_insn_i & ~instr_fetch_err_i;
-
- // An instruction is ready to move to the writeback stage (or retire if there is no writeback
- // stage)
- assign en_wb_o = instr_done;
-
- assign perf_mul_wait_o = stall_multdiv & mult_en_dec;
- assign perf_div_wait_o = stall_multdiv & div_en_dec;
-
-
-endmodule
diff --git a/verilog/rtl/brq_idu_controller.sv b/verilog/rtl/brq_idu_controller.sv
deleted file mode 100644
index 1a66fbb..0000000
--- a/verilog/rtl/brq_idu_controller.sv
+++ /dev/null
@@ -1,816 +0,0 @@
-/**
- * Main controller of the processor
- */
-
-module brq_idu_controller #(
- parameter bit WritebackStage = 0,
- parameter bit BranchPredictor = 0
- ) (
- input logic clk_i,
- input logic rst_ni,
-
- output logic ctrl_busy_o, // core is busy processing instrs
-
- // decoder related signals
- input logic illegal_insn_i, // decoder has an invalid instr
- input logic ecall_insn_i, // decoder has ECALL instr
- input logic mret_insn_i, // decoder has MRET instr
- input logic dret_insn_i, // decoder has DRET instr
- input logic wfi_insn_i, // decoder has WFI instr
- input logic ebrk_insn_i, // decoder has EBREAK instr
- input logic csr_pipe_flush_i, // do CSR-related pipeline flush
-
- // instr from IF-ID pipeline stage
- input logic instr_valid_i, // instr is valid
- input logic [31:0] instr_i, // uncompressed instr data for mtval
- input logic [15:0] instr_compressed_i, // instr compressed data for mtval
- input logic instr_is_compressed_i, // instr is compressed
- // input logic instr_bp_taken_i, // instr was predicted taken branch
- input logic instr_fetch_err_i, // instr has error
- input logic instr_fetch_err_plus2_i, // instr error is x32
- input logic [31:0] pc_id_i, // instr address
-
- // to IF-ID pipeline stage
- output logic instr_valid_clear_o, // kill instr in IF-ID reg
- output logic id_in_ready_o, // ID stage is ready for new instr
- output logic controller_run_o, // Controller is in standard instruction
- // run mode
-
- // to prefetcher
- output logic instr_req_o, // start fetching instructions
- output logic pc_set_o, // jump to address set by pc_mux
- output logic pc_set_spec_o, // speculative branch
- output brq_pkg::pc_sel_e pc_mux_o, // IF stage fetch address selector
- // (boot, normal, exception...)
- // output logic nt_branch_mispredict_o, // Not-taken branch in ID/EX was
- // mispredicted (predicted taken)
- output brq_pkg::exc_pc_sel_e exc_pc_mux_o, // IF stage selector for exception PC
- output brq_pkg::exc_cause_e exc_cause_o, // for IF stage, CSRs
-
- // LSU
- input logic [31:0] lsu_addr_last_i, // for mtval
- input logic load_err_i,
- input logic store_err_i,
- output logic wb_exception_o, // Instruction in WB taking an exception
-
- // jump/branch signals
- input logic branch_set_i, // branch set signal (branch definitely
- // taken)
- input logic branch_set_spec_i, // speculative branch signal (branch
- // may be taken)
- // input logic branch_not_set_i, // branch is definitely not taken
- input logic jump_set_i, // jump taken set signal
-
- // interrupt signals
- input logic csr_mstatus_mie_i, // M-mode interrupt enable bit
- input logic irq_pending_i, // interrupt request pending
- input brq_pkg::irqs_t irqs_i, // interrupt requests qualified with
- // mie CSR
- input logic irq_nm_i, // non-maskeable interrupt
- output logic nmi_mode_o, // core executing NMI handler
-
- // debug signals
- input logic debug_req_i,
- output brq_pkg::dbg_cause_e debug_cause_o,
- output logic debug_csr_save_o,
- output logic debug_mode_o,
- input logic debug_single_step_i,
- input logic debug_ebreakm_i,
- input logic debug_ebreaku_i,
- input logic trigger_match_i,
-// input logic instr_bp_taken_i,
- output logic csr_save_if_o,
- output logic csr_save_id_o,
- output logic csr_save_wb_o,
- output logic csr_restore_mret_id_o,
- output logic csr_restore_dret_id_o,
- output logic csr_save_cause_o,
- output logic [31:0] csr_mtval_o,
- input brq_pkg::priv_lvl_e priv_mode_i,
- input logic csr_mstatus_tw_i,
-
- // stall & flush signals
- input logic stall_id_i,
- input logic stall_wb_i,
- output logic flush_id_o,
- input logic ready_wb_i,
-
- // performance monitors
- output logic perf_jump_o, // we are executing a jump
- // instruction (j, jr, jal, jalr)
- output logic perf_tbranch_o, // we are executing a taken branch
- // instruction
- input logic fpu_busy_i
-);
- import brq_pkg::*;
- logic instr_bp_taken_i;
- assign instr_bp_taken_i = '0;
- // FSM state encoding
- typedef enum logic [3:0] {
- RESET, BOOT_SET, WAIT_SLEEP, SLEEP, FIRST_FETCH, DECODE, FLUSH,
- IRQ_TAKEN, DBG_TAKEN_IF, DBG_TAKEN_ID
- } ctrl_fsm_e;
-
- ctrl_fsm_e ctrl_fsm_cs, ctrl_fsm_ns;
-
- logic nmi_mode_q, nmi_mode_d;
- logic debug_mode_q, debug_mode_d;
- logic load_err_q, load_err_d;
- logic store_err_q, store_err_d;
- logic exc_req_q, exc_req_d;
- logic illegal_insn_q, illegal_insn_d;
-
- // Of the various exception/fault signals, which one takes priority in FLUSH and hence controls
- // what happens next (setting exc_cause, csr_mtval etc)
- logic instr_fetch_err_prio;
- logic illegal_insn_prio;
- logic ecall_insn_prio;
- logic ebrk_insn_prio;
- logic store_err_prio;
- logic load_err_prio;
-
- logic stall;
- logic halt_if;
- logic retain_id;
- logic flush_id;
- logic illegal_dret;
- logic illegal_umode;
- logic exc_req_lsu;
- logic special_req_all;
- logic special_req_branch;
- logic enter_debug_mode;
- logic ebreak_into_debug;
- logic handle_irq;
-
- logic [3:0] mfip_id;
- logic unused_irq_timer;
-
- logic ecall_insn;
- logic mret_insn;
- logic dret_insn;
- logic wfi_insn;
- logic ebrk_insn;
- logic csr_pipe_flush;
- logic instr_fetch_err;
-
-`ifndef SYNTHESIS
- // synopsys translate_off
- // make sure we are called later so that we do not generate messages for
- // glitches
- always_ff @(negedge clk_i) begin
- // print warning in case of decoding errors
- if ((ctrl_fsm_cs == DECODE) && instr_valid_i && !instr_fetch_err_i && illegal_insn_d) begin
- $display("%t: Illegal instruction (hart %0x) at PC 0x%h: 0x%h", $time, brq_core.hart_id_i,
- brq_idu.pc_id_i, brq_idu.instr_rdata_i);
- end
- end
- // synopsys translate_on
-`endif
-
- ////////////////
- // Exceptions //
- ////////////////
-
- assign load_err_d = load_err_i;
- assign store_err_d = store_err_i;
-
- // Decoder doesn't take instr_valid into account, factor it in here.
- assign ecall_insn = ecall_insn_i & instr_valid_i;
- assign mret_insn = mret_insn_i & instr_valid_i;
- assign dret_insn = dret_insn_i & instr_valid_i;
- assign wfi_insn = wfi_insn_i & instr_valid_i;
- assign ebrk_insn = ebrk_insn_i & instr_valid_i;
- assign csr_pipe_flush = csr_pipe_flush_i & instr_valid_i;
- assign instr_fetch_err = instr_fetch_err_i & instr_valid_i;
-
- // "Executing DRET outside of Debug Mode causes an illegal instruction exception."
- // [Debug Spec v0.13.2, p.41]
- assign illegal_dret = dret_insn & ~debug_mode_q;
-
- // Some instructions can only be executed in M-Mode
- assign illegal_umode = (priv_mode_i != PRIV_LVL_M) &
- // MRET must be in M-Mode. TW means trap WFI to M-Mode.
- (mret_insn | (csr_mstatus_tw_i & wfi_insn));
-
- // This is recorded in the illegal_insn_q flop to help timing. Specifically
- // it is needed to break the path from brq_cs_registers/illegal_csr_insn_o
- // to pc_set_o. Clear when controller is in FLUSH so it won't remain set
- // once illegal instruction is handled.
- // All terms in this expression are qualified by instr_valid_i
- assign illegal_insn_d = (illegal_insn_i | illegal_dret | illegal_umode) & (ctrl_fsm_cs != FLUSH);
-
- // exception requests
- // requests are flopped in exc_req_q. This is cleared when controller is in
- // the FLUSH state so the cycle following exc_req_q won't remain set for an
- // exception request that has just been handled.
- // All terms in this expression are qualified by instr_valid_i
- assign exc_req_d = (ecall_insn | ebrk_insn | illegal_insn_d | instr_fetch_err) &
- (ctrl_fsm_cs != FLUSH);
-
- // LSU exception requests
- assign exc_req_lsu = store_err_i | load_err_i;
-
-
- // special requests: special instructions, pipeline flushes, exceptions...
-
- // To avoid creating a path from data_err_i -> instr_req_o and to help timing the below
- // special_req_all has a version that only applies to branches. For a branch the controller needs
- // to set pc_set_o but only if there is no special request. If the generic special_req_all signal
- // is used then a variety of signals that will never cause a special request during a branch
- // instruction end up factored into pc_set_o. The special_req_branch only considers the special
- // request reasons that are relevant to a branch.
-
- // generic special request signal, applies to all instructions
- // All terms in this expression are qualified by instr_valid_i except exc_req_lsu which can come
- // from the Writeback stage with no instr_valid_i from the ID stage
- assign special_req_all = mret_insn | dret_insn | wfi_insn | csr_pipe_flush |
- exc_req_d | exc_req_lsu;
-
- // special request that can specifically occur during branch instructions
- // All terms in this expression are qualified by instr_valid_i
- assign special_req_branch = instr_fetch_err & (ctrl_fsm_cs != FLUSH);
-
-
- // Exception/fault prioritisation is taken from Table 3.7 of Priviledged Spec v1.11
- if (WritebackStage) begin : g_wb_exceptions
- always_comb begin
- instr_fetch_err_prio = 0;
- illegal_insn_prio = 0;
- ecall_insn_prio = 0;
- ebrk_insn_prio = 0;
- store_err_prio = 0;
- load_err_prio = 0;
-
- // Note that with the writeback stage store/load errors occur on the instruction in writeback,
- // all other exception/faults occur on the instruction in ID/EX. The faults from writeback
- // must take priority as that instruction is architecurally ordered before the one in ID/EX.
- if (store_err_q) begin
- store_err_prio = 1'b1;
- end else if (load_err_q) begin
- load_err_prio = 1'b1;
- end else if (instr_fetch_err) begin
- instr_fetch_err_prio = 1'b1;
- end else if (illegal_insn_q) begin
- illegal_insn_prio = 1'b1;
- end else if (ecall_insn) begin
- ecall_insn_prio = 1'b1;
- end else if (ebrk_insn) begin
- ebrk_insn_prio = 1'b1;
- end
- end
-
- // Instruction in writeback is generating an exception so instruction in ID must not execute
- assign wb_exception_o = load_err_q | store_err_q | load_err_i | store_err_i;
- end else begin : g_no_wb_exceptions
- always_comb begin
- instr_fetch_err_prio = 0;
- illegal_insn_prio = 0;
- ecall_insn_prio = 0;
- ebrk_insn_prio = 0;
- store_err_prio = 0;
- load_err_prio = 0;
-
- if (instr_fetch_err) begin
- instr_fetch_err_prio = 1'b1;
- end else if (illegal_insn_q) begin
- illegal_insn_prio = 1'b1;
- end else if (ecall_insn) begin
- ecall_insn_prio = 1'b1;
- end else if (ebrk_insn) begin
- ebrk_insn_prio = 1'b1;
- end else if (store_err_q) begin
- store_err_prio = 1'b1;
- end else if (load_err_q) begin
- load_err_prio = 1'b1;
- end
- end
- assign wb_exception_o = 1'b0;
- end
-
-
- ////////////////
- // Interrupts //
- ////////////////
-
- // Enter debug mode due to an external debug_req_i or because the core is in
- // single step mode (dcsr.step == 1). Single step must be qualified with
- // instruction valid otherwise the core will immediately enter debug mode
- // due to a recently flushed IF (or a delay in an instruction returning from
- // memory) before it has had anything to single step.
- // Also enter debug mode on a trigger match (hardware breakpoint)
- assign enter_debug_mode = (debug_req_i | (debug_single_step_i & instr_valid_i) |
- trigger_match_i) & ~debug_mode_q;
-
- // Set when an ebreak should enter debug mode rather than jump to exception
- // handler
- assign ebreak_into_debug = priv_mode_i == PRIV_LVL_M ? debug_ebreakm_i :
- priv_mode_i == PRIV_LVL_U ? debug_ebreaku_i :
- 1'b0;
-
- // Interrupts including NMI are ignored,
- // - while in debug mode [Debug Spec v0.13.2, p.39],
- // - while in NMI mode (nested NMIs are not supported, NMI has highest priority and
- // cannot be interrupted by regular interrupts).
- assign handle_irq = ~debug_mode_q & ~nmi_mode_q &
- (irq_nm_i | (irq_pending_i & csr_mstatus_mie_i));
-
- // generate ID of fast interrupts, highest priority to highest ID
- always_comb begin : gen_mfip_id
- if (irqs_i.irq_fast[14]) mfip_id = 4'd14;
- else if (irqs_i.irq_fast[13]) mfip_id = 4'd13;
- else if (irqs_i.irq_fast[12]) mfip_id = 4'd12;
- else if (irqs_i.irq_fast[11]) mfip_id = 4'd11;
- else if (irqs_i.irq_fast[10]) mfip_id = 4'd10;
- else if (irqs_i.irq_fast[ 9]) mfip_id = 4'd9;
- else if (irqs_i.irq_fast[ 8]) mfip_id = 4'd8;
- else if (irqs_i.irq_fast[ 7]) mfip_id = 4'd7;
- else if (irqs_i.irq_fast[ 6]) mfip_id = 4'd6;
- else if (irqs_i.irq_fast[ 5]) mfip_id = 4'd5;
- else if (irqs_i.irq_fast[ 4]) mfip_id = 4'd4;
- else if (irqs_i.irq_fast[ 3]) mfip_id = 4'd3;
- else if (irqs_i.irq_fast[ 2]) mfip_id = 4'd2;
- else if (irqs_i.irq_fast[ 1]) mfip_id = 4'd1;
- else mfip_id = 4'd0;
- end
-
- assign unused_irq_timer = irqs_i.irq_timer;
-
- /////////////////////
- // Core controller //
- /////////////////////
-
- always_comb begin
- // Default values
- instr_req_o = 1'b1;
-
- csr_save_if_o = 1'b0;
- csr_save_id_o = 1'b0;
- csr_save_wb_o = 1'b0;
- csr_restore_mret_id_o = 1'b0;
- csr_restore_dret_id_o = 1'b0;
- csr_save_cause_o = 1'b0;
- csr_mtval_o = '0;
-
- // The values of pc_mux and exc_pc_mux are only relevant if pc_set is set. Some of the states
- // below always set pc_mux and exc_pc_mux but only set pc_set if certain conditions are met.
- // This avoid having to factor those conditions into the pc_mux and exc_pc_mux select signals
- // helping timing.
- pc_mux_o = PC_BOOT;
- pc_set_o = 1'b0;
- pc_set_spec_o = 1'b0;
- //nt_branch_mispredict_o = 1'b0;
-
- exc_pc_mux_o = EXC_PC_IRQ;
- exc_cause_o = EXC_CAUSE_INSN_ADDR_MISA; // = 6'h00
-
- ctrl_fsm_ns = ctrl_fsm_cs;
-
- ctrl_busy_o = 1'b1;
-
- halt_if = 1'b0;
- retain_id = 1'b0;
- flush_id = 1'b0;
-
- debug_csr_save_o = 1'b0;
- debug_cause_o = DBG_CAUSE_EBREAK;
- debug_mode_d = debug_mode_q;
- nmi_mode_d = nmi_mode_q;
-
- perf_tbranch_o = 1'b0;
- perf_jump_o = 1'b0;
-
- controller_run_o = 1'b0;
-
- unique case (ctrl_fsm_cs)
- RESET: begin
- instr_req_o = 1'b0;
- pc_mux_o = PC_BOOT;
- pc_set_o = 1'b1;
- pc_set_spec_o = 1'b1;
- ctrl_fsm_ns = BOOT_SET;
- end
-
- BOOT_SET: begin
- // copy boot address to instr fetch address
- instr_req_o = 1'b1;
- pc_mux_o = PC_BOOT;
- pc_set_o = 1'b1;
- pc_set_spec_o = 1'b1;
-
- ctrl_fsm_ns = FIRST_FETCH;
- end
-
- WAIT_SLEEP: begin
- ctrl_busy_o = 1'b0;
- instr_req_o = 1'b0;
- halt_if = 1'b1;
- flush_id = 1'b1;
- ctrl_fsm_ns = SLEEP;
- end
-
- SLEEP: begin
- // instruction in IF stage is already valid
- // we begin execution when an interrupt has arrived
- instr_req_o = 1'b0;
- halt_if = 1'b1;
- flush_id = 1'b1;
-
- // normal execution flow
- // in debug mode or single step mode we leave immediately (wfi=nop)
- if (irq_nm_i || irq_pending_i || debug_req_i || debug_mode_q || debug_single_step_i) begin
- ctrl_fsm_ns = FIRST_FETCH;
- end else begin
- // Make sure clock remains disabled.
- ctrl_busy_o = 1'b0;
- end
- end
-
- FIRST_FETCH: begin
- // Stall because of IF miss
- if (id_in_ready_o) begin
- ctrl_fsm_ns = DECODE;
- end
-
- // handle interrupts
- if (handle_irq) begin
- // We are handling an interrupt. Set halt_if to tell IF not to give
- // us any more instructions before it redirects to the handler, but
- // don't set flush_id: we must allow this instruction to complete
- // (since it might have outstanding loads or stores).
- ctrl_fsm_ns = IRQ_TAKEN;
- halt_if = 1'b1;
- end
-
- // enter debug mode
- if (enter_debug_mode) begin
- ctrl_fsm_ns = DBG_TAKEN_IF;
- // Halt IF only for now, ID will be flushed in DBG_TAKEN_IF as the
- // ID state is needed for correct debug mode entry
- halt_if = 1'b1;
- end
- end
-
- DECODE: begin
- // normal operating mode of the ID stage, in case of debug and interrupt requests,
- // priorities are as follows (lower number == higher priority)
- // 1. currently running (multicycle) instructions and exceptions caused by these
- // 2. debug requests
- // 3. interrupt requests
-
- controller_run_o = 1'b1;
-
- // Set PC mux for branch and jump here to ease timing. Value is only relevant if pc_set_o is
- // also set. Setting the mux value here avoids factoring in special_req and instr_valid_i
- // which helps timing.
- pc_mux_o = PC_JUMP;
-
-
- // Get ready for special instructions, exceptions, pipeline flushes
- if (special_req_all) begin
- // Halt IF but don't flush ID. This leaves a valid instruction in
- // ID so controller can determine appropriate action in the
- // FLUSH state.
- retain_id = 1'b1;
-
- // Wait for the writeback stage to either be ready for a new instruction or raise its own
- // exception before going to FLUSH. If the instruction in writeback raises an exception it
- // must take priority over any exception from an instruction in ID/EX. Only once the
- // writeback stage is ready can we be certain that won't happen. Without a writeback
- // stage ready_wb_i == 1 so the FSM will always go directly to FLUSH.
-
- if (ready_wb_i | wb_exception_o) begin
- ctrl_fsm_ns = FLUSH;
- end
- end
-
- if (!special_req_branch) begin
- if (branch_set_i || jump_set_i) begin
- // Only set the PC if the branch predictor hasn't already done the branch for us
- pc_set_o = BranchPredictor ? ~instr_bp_taken_i : 1'b1;
-
- perf_tbranch_o = branch_set_i;
- perf_jump_o = jump_set_i;
- end
-
- // if (BranchPredictor) begin
- // if (instr_bp_taken_i & branch_not_set_i) begin
- // // If the instruction is a branch that was predicted to be taken but was not taken
- // // signal a mispredict.
- // nt_branch_mispredict_o = 1'b1;
- // end
- // end
- end
-
- // pc_set signal excluding branch taken condition
- if ((branch_set_spec_i || jump_set_i) && !special_req_branch) begin
- // Only speculatively set the PC if the branch predictor hasn't already done the branch
- // for us
- pc_set_spec_o = /*BranchPredictor ? ~instr_bp_taken_i : */1'b1;
- end
-
- // If entering debug mode or handling an IRQ the core needs to wait
- // until the current instruction has finished executing. Stall IF
- // during that time.
- if ((enter_debug_mode || handle_irq) && stall) begin
- halt_if = 1'b1;
- end
-
- if (!stall && !special_req_all) begin
- if (enter_debug_mode) begin
- // enter debug mode
- ctrl_fsm_ns = DBG_TAKEN_IF;
- // Halt IF only for now, ID will be flushed in DBG_TAKEN_IF as the
- // ID state is needed for correct debug mode entry
- halt_if = 1'b1;
- end else if (handle_irq) begin
- // handle interrupt (not in debug mode)
- ctrl_fsm_ns = IRQ_TAKEN;
- // We are handling an interrupt (not in debug mode). Set halt_if to
- // tell IF not to give us any more instructions before it redirects
- // to the handler, but don't set flush_id: we must allow this
- // instruction to complete (since it might have outstanding loads
- // or stores).
- halt_if = 1'b1;
- end
- end
-
- end // DECODE
-
- IRQ_TAKEN: begin
- pc_mux_o = PC_EXC;
- exc_pc_mux_o = EXC_PC_IRQ;
-
- if (handle_irq) begin
- pc_set_o = 1'b1;
- pc_set_spec_o = 1'b1;
-
- csr_save_if_o = 1'b1;
- csr_save_cause_o = 1'b1;
-
- // interrupt priorities according to Privileged Spec v1.11 p.31
- if (irq_nm_i && !nmi_mode_q) begin
- exc_cause_o = EXC_CAUSE_IRQ_NM;
- nmi_mode_d = 1'b1; // enter NMI mode
- end else if (irqs_i.irq_fast != 15'b0) begin
- // generate exception cause ID from fast interrupt ID:
- // - first bit distinguishes interrupts from exceptions,
- // - second bit adds 16 to fast interrupt ID
- // for example EXC_CAUSE_IRQ_FAST_0 = {1'b1, 5'd16}
- exc_cause_o = exc_cause_e'({2'b11, mfip_id});
- end else if (irqs_i.irq_external) begin
- exc_cause_o = EXC_CAUSE_IRQ_EXTERNAL_M;
- end else if (irqs_i.irq_software) begin
- exc_cause_o = EXC_CAUSE_IRQ_SOFTWARE_M;
- end else if (irqs_i.irq_timer)begin // irqs_i.irq_timer
- exc_cause_o = EXC_CAUSE_IRQ_TIMER_M;
- end
- end
-
- ctrl_fsm_ns = DECODE;
- end
-
- DBG_TAKEN_IF: begin
- pc_mux_o = PC_EXC;
- exc_pc_mux_o = EXC_PC_DBD;
-
- // enter debug mode and save PC in IF to dpc
- // jump to debug exception handler in debug memory
- if (debug_single_step_i || debug_req_i || trigger_match_i) begin
- flush_id = 1'b1;
- pc_set_o = 1'b1;
- pc_set_spec_o = 1'b1;
-
- csr_save_if_o = 1'b1;
- debug_csr_save_o = 1'b1;
-
- csr_save_cause_o = 1'b1;
- if (trigger_match_i) begin
- debug_cause_o = DBG_CAUSE_TRIGGER;
- end else if (debug_single_step_i) begin
- debug_cause_o = DBG_CAUSE_STEP;
- end else begin
- debug_cause_o = DBG_CAUSE_HALTREQ;
- end
-
- // enter debug mode
- debug_mode_d = 1'b1;
- end
-
- ctrl_fsm_ns = DECODE;
- end
-
- DBG_TAKEN_ID: begin
- // enter debug mode and save PC in ID to dpc, used when encountering
- // 1. EBREAK during debug mode
- // 2. EBREAK with forced entry into debug mode (ebreakm or ebreaku set).
- // regular ebreak's go through FLUSH.
- //
- // for 1. do not update dcsr and dpc, for 2. do so [Debug Spec v0.13.2, p.39]
- // jump to debug exception handler in debug memory
- flush_id = 1'b1;
- pc_mux_o = PC_EXC;
- pc_set_o = 1'b1;
- pc_set_spec_o = 1'b1;
- exc_pc_mux_o = EXC_PC_DBD;
-
- // update dcsr and dpc
- if (ebreak_into_debug && !debug_mode_q) begin // ebreak with forced entry
-
- // dpc (set to the address of the EBREAK, i.e. set to PC in ID stage)
- csr_save_cause_o = 1'b1;
- csr_save_id_o = 1'b1;
-
- // dcsr
- debug_csr_save_o = 1'b1;
- debug_cause_o = DBG_CAUSE_EBREAK;
- end
-
- // enter debug mode
- debug_mode_d = 1'b1;
-
- ctrl_fsm_ns = DECODE;
- end
-
- FLUSH: begin
- // flush the pipeline
- halt_if = 1'b1;
- flush_id = 1'b1;
- ctrl_fsm_ns = DECODE;
-
- // As pc_mux and exc_pc_mux can take various values in this state they aren't set early
- // here.
-
- // exceptions: set exception PC, save PC and exception cause
- // exc_req_lsu is high for one clock cycle only (in DECODE)
- if (exc_req_q || store_err_q || load_err_q) begin
- pc_set_o = 1'b1;
- pc_set_spec_o = 1'b1;
- pc_mux_o = PC_EXC;
- exc_pc_mux_o = debug_mode_q ? EXC_PC_DBG_EXC : EXC_PC_EXC;
-
- if (WritebackStage) begin : g_writeback_mepc_save
- // With the writeback stage present whether an instruction accessing memory will cause
- // an exception is only known when it is in writeback. So when taking such an exception
- // epc must come from writeback.
- csr_save_id_o = ~(store_err_q | load_err_q);
- csr_save_wb_o = store_err_q | load_err_q;
- end else begin : g_no_writeback_mepc_save
- csr_save_id_o = 1'b0;
- end
-
- csr_save_cause_o = 1'b1;
-
- // Exception/fault prioritisation logic will have set exactly 1 X_prio signal
- unique case (1'b1)
- instr_fetch_err_prio: begin
- exc_cause_o = EXC_CAUSE_INSTR_ACCESS_FAULT;
- csr_mtval_o = instr_fetch_err_plus2_i ? (pc_id_i + 32'd2) : pc_id_i;
- end
- illegal_insn_prio: begin
- exc_cause_o = EXC_CAUSE_ILLEGAL_INSN;
- csr_mtval_o = instr_is_compressed_i ? {16'b0, instr_compressed_i} : instr_i;
- end
- ecall_insn_prio: begin
- exc_cause_o = (priv_mode_i == PRIV_LVL_M) ? EXC_CAUSE_ECALL_MMODE :
- EXC_CAUSE_ECALL_UMODE;
- end
- ebrk_insn_prio: begin
- if (debug_mode_q | ebreak_into_debug) begin
- /*
- * EBREAK in debug mode re-enters debug mode
- *
- * "The only exception is EBREAK. When that is executed in Debug
- * Mode, it halts the hart again but without updating dpc or
- * dcsr." [Debug Spec v0.13.2, p.39]
- */
-
- /*
- * dcsr.ebreakm == 1:
- * "EBREAK instructions in M-mode enter Debug Mode."
- * [Debug Spec v0.13.2, p.42]
- */
- pc_set_o = 1'b0;
- pc_set_spec_o = 1'b0;
- csr_save_id_o = 1'b0;
- csr_save_cause_o = 1'b0;
- ctrl_fsm_ns = DBG_TAKEN_ID;
- flush_id = 1'b0;
- end else begin
- /*
- * "The EBREAK instruction is used by debuggers to cause control
- * to be transferred back to a debugging environment. It
- * generates a breakpoint exception and performs no other
- * operation. [...] ECALL and EBREAK cause the receiving
- * privilege mode's epc register to be set to the address of the
- * ECALL or EBREAK instruction itself, not the address of the
- * following instruction." [Privileged Spec v1.11, p.40]
- */
- exc_cause_o = EXC_CAUSE_BREAKPOINT;
- end
- end
- store_err_prio: begin
- exc_cause_o = EXC_CAUSE_STORE_ACCESS_FAULT;
- csr_mtval_o = lsu_addr_last_i;
- end
- load_err_prio: begin
- exc_cause_o = EXC_CAUSE_LOAD_ACCESS_FAULT;
- csr_mtval_o = lsu_addr_last_i;
- end
- default: ;
- endcase
- end else begin
- // special instructions and pipeline flushes
- if (mret_insn) begin
- pc_mux_o = PC_ERET;
- pc_set_o = 1'b1;
- pc_set_spec_o = 1'b1;
- csr_restore_mret_id_o = 1'b1;
- if (nmi_mode_q) begin
- nmi_mode_d = 1'b0; // exit NMI mode
- end
- end else if (dret_insn) begin
- pc_mux_o = PC_DRET;
- pc_set_o = 1'b1;
- pc_set_spec_o = 1'b1;
- debug_mode_d = 1'b0;
- csr_restore_dret_id_o = 1'b1;
- end else if (wfi_insn) begin
- ctrl_fsm_ns = WAIT_SLEEP;
- end else if (csr_pipe_flush && handle_irq) begin
- // start handling IRQs when doing CSR-related pipeline flushes
- ctrl_fsm_ns = IRQ_TAKEN;
- end
- end // exc_req_q
-
- // Entering debug mode due to either single step or debug_req. Ensure
- // registers are set for exception but then enter debug handler rather
- // than exception handler [Debug Spec v0.13.2, p.44]
- // Leave all other signals as is to ensure CSRs and PC get set as if
- // core was entering exception handler, entry to debug mode will then
- // see the appropriate state and setup dpc correctly.
- // If an EBREAK instruction is causing us to enter debug mode on the
- // same cycle as a debug_req or single step, honor the EBREAK and
- // proceed to DBG_TAKEN_ID.
- if (enter_debug_mode && !(ebrk_insn_prio && ebreak_into_debug)) begin
- ctrl_fsm_ns = DBG_TAKEN_IF;
- end
- end // FLUSH
-
- default: begin
- instr_req_o = 1'b0;
- ctrl_fsm_ns = RESET;
- end
- endcase
- end
-
- assign flush_id_o = flush_id;
-
- // signal to CSR when in debug mode
- assign debug_mode_o = debug_mode_q;
-
- // signal to CSR when in an NMI handler (for nested exception handling)
- assign nmi_mode_o = nmi_mode_q;
-
- ///////////////////
- // Stall control //
- ///////////////////
-
- // If high current instruction cannot complete this cycle. Either because it needs more cycles to
- // finish (stall_id_i) or because the writeback stage cannot accept it yet (stall_wb_i). If there
- // is no writeback stage stall_wb_i is a constant 0.
- assign stall = stall_id_i | stall_wb_i | fpu_busy_i;
-
- // signal to IF stage that ID stage is ready for next instr
- assign id_in_ready_o = ~stall & ~halt_if & ~retain_id;
-
- // kill instr in IF-ID pipeline reg that are done, or if a
- // multicycle instr causes an exception for example
- // retain_id is another kind of stall, where the instr_valid bit must remain
- // set (unless flush_id is set also). It cannot be factored directly into
- // stall as this causes a combinational loop.
- assign instr_valid_clear_o = ~(stall | retain_id) | flush_id;
-
- // update registers
- always_ff @(posedge clk_i or negedge rst_ni) begin : update_regs
- if (!rst_ni) begin
- ctrl_fsm_cs <= RESET;
- nmi_mode_q <= 1'b0;
- debug_mode_q <= 1'b0;
- load_err_q <= 1'b0;
- store_err_q <= 1'b0;
- exc_req_q <= 1'b0;
- illegal_insn_q <= 1'b0;
- end else begin
- ctrl_fsm_cs <= ctrl_fsm_ns;
- nmi_mode_q <= nmi_mode_d;
- debug_mode_q <= debug_mode_d;
- load_err_q <= load_err_d;
- store_err_q <= store_err_d;
- exc_req_q <= exc_req_d;
- illegal_insn_q <= illegal_insn_d;
- end
- end
-
-
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/brq_idu_decoder.sv b/verilog/rtl/brq_idu_decoder.sv
deleted file mode 100644
index 1e7c136..0000000
--- a/verilog/rtl/brq_idu_decoder.sv
+++ /dev/null
@@ -1,1718 +0,0 @@
-// Copyright lowRISC contributors.
-// Copyright 2018 ETH Zurich and University of Bologna, see also CREDITS.md.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-/**
- * Instruction decoder
- *
- * This module is fully combinatorial, clock and reset are used for
- * assertions only.
- */
-
-module brq_idu_decoder #(
- parameter bit RV32E = 0,
- parameter brq_pkg::rv32m_e RV32M = brq_pkg::RV32MFast,
- parameter brq_pkg::rv32b_e RV32B = brq_pkg::RV32BNone,
- parameter brq_pkg::rvfloat_e RVF = brq_pkg::RV64FDouble,
- parameter bit BranchTargetALU = 0
-) (
- input logic clk_i,
- input logic rst_ni,
-
- // to/from controller
- output logic illegal_insn_o, // illegal instr encountered
- output logic ebrk_insn_o, // trap instr encountered
- output logic mret_insn_o, // return from exception instr
- // encountered
- output logic dret_insn_o, // return from debug instr encountered
- output logic ecall_insn_o, // syscall instr encountered
- output logic wfi_insn_o, // wait for interrupt instr encountered
- output logic jump_set_o, // jump taken set signal
- input logic branch_taken_i, // registered branch decision
- output logic icache_inval_o,
-
- // from IF-ID pipeline register
- input logic instr_first_cycle_i, // instruction read is in its first cycle
- input logic [31:0] instr_rdata_i, // instruction read from memory/cache
- input logic [31:0] instr_rdata_alu_i, // instruction read from memory/cache
- // replicated to ease fan-out)
-
- input logic illegal_c_insn_i, // compressed instruction decode failed
-
- // immediates
- output brq_pkg::imm_a_sel_e imm_a_mux_sel_o, // immediate selection for operand a
- output brq_pkg::imm_b_sel_e imm_b_mux_sel_o, // immediate selection for operand b
- output brq_pkg::op_a_sel_e bt_a_mux_sel_o, // branch target selection operand a
- output brq_pkg::imm_b_sel_e bt_b_mux_sel_o, // branch target selection operand b
- output logic [31:0] imm_i_type_o,
- output logic [31:0] imm_s_type_o,
- output logic [31:0] imm_b_type_o,
- output logic [31:0] imm_u_type_o,
- output logic [31:0] imm_j_type_o,
- output logic [31:0] zimm_rs1_type_o,
-
- // register file
- output brq_pkg::rf_wd_sel_e rf_wdata_sel_o, // RF write data selection
- output logic rf_we_o, // write enable for regfile
- output logic [4:0] rf_raddr_a_o,
- output logic [4:0] rf_raddr_b_o,
- output logic [4:0] rf_waddr_o,
- output logic rf_ren_a_o, // Instruction reads from RF addr A
- output logic rf_ren_b_o, // Instruction reads from RF addr B
-
- // ALU
- output brq_pkg::alu_op_e alu_operator_o, // ALU operation selection
- output brq_pkg::op_a_sel_e alu_op_a_mux_sel_o, // operand a selection: reg value, PC,
- // immediate or zero
- output brq_pkg::op_b_sel_e alu_op_b_mux_sel_o, // operand b selection: reg value or
- // immediate
- output logic alu_multicycle_o, // ternary bitmanip instruction
-
- // MULT & DIV
- output logic mult_en_o, // perform integer multiplication
- output logic div_en_o, // perform integer division or remainder
- output logic mult_sel_o, // as above but static, for data muxes
- output logic div_sel_o, // as above but static, for data muxes
-
- output brq_pkg::md_op_e multdiv_operator_o,
- output logic [1:0] multdiv_signed_mode_o,
-
- // CSRs
- output logic csr_access_o, // access to CSR
- output brq_pkg::csr_op_e csr_op_o, // operation to perform on CSR
-
- // LSU
- output logic data_req_o, // start transaction to data memory
- output logic data_we_o, // write enable
- output logic [1:0] data_type_o, // size of transaction: byte, half
- // word or word
- output logic data_sign_extension_o, // sign extension for data read from
- // memory
-
- // jump/branches
- output logic jump_in_dec_o, // jump is being calculated in ALU
- output logic branch_in_dec_o,
-
- // Floating point extensions IO
- output fpnew_pkg::roundmode_e fp_rounding_mode_o, // defines the rounding mode
-
- output logic [4:0] fp_rf_raddr_a_o,
- output logic [4:0] fp_rf_raddr_b_o,
- output logic [4:0] fp_rf_raddr_c_o,
-
- output logic [4:0] fp_rf_waddr_o,
- output logic fp_rf_we_o,
-
- output fpnew_pkg::operation_e fp_alu_operator_o,
- output logic fp_alu_op_mod_o,
- output logic fp_rm_dynamic_o,
- output fpnew_pkg::fp_format_e fp_src_fmt_o,
- output fpnew_pkg::fp_format_e fp_dst_fmt_o,
- output logic is_fp_instr_o,
- output logic use_fp_rs1_o,
- output logic use_fp_rs2_o,
- output logic use_fp_rs3_o,
- output logic use_fp_rd_o,
- output logic fp_swap_oprnds_o,
- output logic fp_load_o,
- output logic mv_instr_o
-);
-
- import brq_pkg::*;
- import fpnew_pkg::*;
-
- logic fp_invalid_rm;
-
- logic illegal_insn;
- logic illegal_reg_rv32e;
- logic csr_illegal;
- logic rf_we;
-
- logic [31:0] instr;
- logic [31:0] instr_alu;
- // Source/Destination register instruction index
- logic [4:0] instr_rs1;
- logic [4:0] instr_rs2;
- logic [4:0] instr_rs3;
- logic [4:0] instr_rd;
-
- logic use_rs3_d;
- logic use_rs3_q;
-
- csr_op_e csr_op;
-
- opcode_e opcode;
- opcode_e opcode_alu;
-
- // To help timing the flops containing the current instruction are replicated to reduce fan-out.
- // instr_alu is used to determine the ALU control logic and associated operand/imm select signals
- // as the ALU is often on the more critical timing paths. instr is used for everything else.
- assign instr = instr_rdata_i;
- assign instr_alu = instr_rdata_alu_i;
-
- //////////////////////////////////////
- // Register and immediate selection //
- //////////////////////////////////////
-
- // immediate extraction and sign extension
- assign imm_i_type_o = { {20{instr[31]}}, instr[31:20] };
- assign imm_s_type_o = { {20{instr[31]}}, instr[31:25], instr[11:7] };
- assign imm_b_type_o = { {19{instr[31]}}, instr[31], instr[7], instr[30:25], instr[11:8], 1'b0 };
- assign imm_u_type_o = { instr[31:12], 12'b0 };
- assign imm_j_type_o = { {12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0 };
-
- // immediate for CSR manipulation (zero extended)
- assign zimm_rs1_type_o = { 27'b0, instr_rs1 }; // rs1
-
- // the use of rs3 is known one cycle ahead.
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- use_rs3_q <= 1'b0;
- end else begin
- use_rs3_q <= use_rs3_d;
- end
- end
-
- // source registers
- assign instr_rs1 = instr[19:15];
- assign instr_rs2 = instr[24:20];
- assign instr_rs3 = instr[31:27];
- assign rf_raddr_a_o = (use_rs3_q & ~instr_first_cycle_i) ? instr_rs3 : instr_rs1; // rs3 / rs1
- assign rf_raddr_b_o = instr_rs2; // rs2
-
- // destination register
- assign instr_rd = instr[11:7];
- assign rf_waddr_o = instr_rd; // rd
-
- // fp source registers
- assign fp_rf_raddr_a_o = instr_rs1;
- assign fp_rf_raddr_b_o = instr_rs2;
- assign fp_rf_raddr_c_o = instr_rs3;
-
- // fp destination register
- assign fp_rf_waddr_o = instr_rd;
-
- assign fp_rounding_mode_o = roundmode_e'(instr[14:12]);
- assign fp_invalid_rm = (instr[14:12] == 3'b101) ? 1'b1 :
- (instr[14:12] == 3'b110) ? 1'b1 : 1'b0;
- assign fp_rm_dynamic_o = (instr[14:12] == 3'b111) ? 1'b1 : 1'b0;
-
- assign fp_dst_fmt_o = FP32;
-
- ////////////////////
- // Register check //
- ////////////////////
- if (RV32E) begin : gen_rv32e_reg_check_active
- assign illegal_reg_rv32e = ((rf_raddr_a_o[4] & (alu_op_a_mux_sel_o == OP_A_REG_A)) |
- (rf_raddr_b_o[4] & (alu_op_b_mux_sel_o == OP_B_REG_B)) |
- (rf_waddr_o[4] & rf_we));
- end else begin : gen_rv32e_reg_check_inactive
- assign illegal_reg_rv32e = 1'b0;
- end
-
- ///////////////////////
- // CSR operand check //
- ///////////////////////
- always_comb begin : csr_operand_check
- csr_op_o = csr_op;
-
- // CSRRSI/CSRRCI must not write 0 to CSRs (uimm[4:0]=='0)
- // CSRRS/CSRRC must not write from x0 to CSRs (rs1=='0)
- if ((csr_op == CSR_OP_SET || csr_op == CSR_OP_CLEAR) &&
- instr_rs1 == '0) begin
- csr_op_o = CSR_OP_READ;
- end
- end
-
- /////////////
- // Decoder //
- /////////////
-
- always_comb begin
- jump_in_dec_o = 1'b0;
- jump_set_o = 1'b0;
- branch_in_dec_o = 1'b0;
- icache_inval_o = 1'b0;
-
- multdiv_operator_o = MD_OP_MULL;
- multdiv_signed_mode_o = 2'b00;
-
- rf_wdata_sel_o = RF_WD_EX;
- rf_we = 1'b0;
- rf_ren_a_o = 1'b0;
- rf_ren_b_o = 1'b0;
-
- csr_access_o = 1'b0;
- csr_illegal = 1'b0;
- csr_op = CSR_OP_READ;
-
- data_we_o = 1'b0;
- data_type_o = 2'b00;
- data_sign_extension_o = 1'b0;
- data_req_o = 1'b0;
-
- illegal_insn = 1'b0;
- ebrk_insn_o = 1'b0;
- mret_insn_o = 1'b0;
- dret_insn_o = 1'b0;
- ecall_insn_o = 1'b0;
- wfi_insn_o = 1'b0;
-
- // Floating Point
- fp_rf_we_o = 1'b0;
- is_fp_instr_o = 1'b0;
- use_fp_rs1_o = 1'b0;
- use_fp_rs2_o = 1'b0;
- use_fp_rs3_o = 1'b0;
- use_fp_rd_o = 1'b0;
- fp_load_o = 1'b0;
- fp_src_fmt_o = FP32;
- fp_dst_fmt_o = FP32;
- fp_swap_oprnds_o = 1'b0;
- mv_instr_o = 1'b0;
-
- opcode = opcode_e'(instr[6:0]);
-
- unique case (opcode)
-
- ///////////
- // Jumps //
- ///////////
-
- OPCODE_JAL: begin // Jump and Link
- jump_in_dec_o = 1'b1;
-
- if (instr_first_cycle_i) begin
- // Calculate jump target (and store PC + 4 if BranchTargetALU is configured)
- rf_we = BranchTargetALU;
- jump_set_o = 1'b1;
- end else begin
- // Calculate and store PC+4
- rf_we = 1'b1;
- end
- end
-
- OPCODE_JALR: begin // Jump and Link Register
- jump_in_dec_o = 1'b1;
-
- if (instr_first_cycle_i) begin
- // Calculate jump target (and store PC + 4 if BranchTargetALU is configured)
- rf_we = BranchTargetALU;
- jump_set_o = 1'b1;
- end else begin
- // Calculate and store PC+4
- rf_we = 1'b1;
- end
- if (instr[14:12] != 3'b0) begin
- illegal_insn = 1'b1;
- end
-
- rf_ren_a_o = 1'b1;
- end
-
- OPCODE_BRANCH: begin // Branch
- branch_in_dec_o = 1'b1;
- // Check branch condition selection
- unique case (instr[14:12])
- 3'b000,
- 3'b001,
- 3'b100,
- 3'b101,
- 3'b110,
- 3'b111: illegal_insn = 1'b0;
- default: illegal_insn = 1'b1;
- endcase
- rf_ren_a_o = 1'b1;
- rf_ren_b_o = 1'b1;
- end
-
- ////////////////
- // Load/store //
- ////////////////
-
- OPCODE_STORE: begin
- rf_ren_a_o = 1'b1;
- rf_ren_b_o = 1'b1;
- data_req_o = 1'b1;
- data_we_o = 1'b1;
-
- if (instr[14]) begin
- illegal_insn = 1'b1;
- end
-
- // store size
- unique case (instr[13:12])
- 2'b00: data_type_o = 2'b10; // sb
- 2'b01: data_type_o = 2'b01; // sh
- 2'b10: data_type_o = 2'b00; // sw
- default: illegal_insn = 1'b1;
- endcase
- end
-
- OPCODE_LOAD: begin
- rf_ren_a_o = 1'b1;
- data_req_o = 1'b1;
- data_type_o = 2'b00;
-
- // sign/zero extension
- data_sign_extension_o = ~instr[14];
-
- // load size
- unique case (instr[13:12])
- 2'b00: data_type_o = 2'b10; // lb(u)
- 2'b01: data_type_o = 2'b01; // lh(u)
- 2'b10: begin
- data_type_o = 2'b00; // lw
- if (instr[14]) begin
- illegal_insn = 1'b1; // lwu does not exist
- end
- end
- default: begin
- illegal_insn = 1'b1;
- end
- endcase
- end
-
- /////////
- // ALU //
- /////////
-
- OPCODE_LUI: begin // Load Upper Immediate
- rf_we = 1'b1;
- end
-
- OPCODE_AUIPC: begin // Add Upper Immediate to PC
- rf_we = 1'b1;
- end
-
- OPCODE_OP_IMM: begin // Register-Immediate ALU Operations
- rf_ren_a_o = 1'b1;
- rf_we = 1'b1;
-
- unique case (instr[14:12])
- 3'b000,
- 3'b010,
- 3'b011,
- 3'b100,
- 3'b110,
- 3'b111: illegal_insn = 1'b0;
-
- 3'b001: begin
- unique case (instr[31:27])
- 5'b0_0000: illegal_insn = (instr[26:25] == 2'b00) ? 1'b0 : 1'b1; // slli
- 5'b0_0100, // sloi
- 5'b0_1001, // sbclri
- 5'b0_0101, // sbseti
- 5'b0_1101: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // sbinvi
- 5'b0_0001: if (instr[26] == 1'b0) begin
- illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // shfl
- end else begin
- illegal_insn = 1'b1;
- end
- 5'b0_1100: begin
- unique case(instr[26:20])
- 7'b000_0000, // clz
- 7'b000_0001, // ctz
- 7'b000_0010, // pcnt
- 7'b000_0100, // sext.b
- 7'b000_0101: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // sext.h
- 7'b001_0000, // crc32.b
- 7'b001_0001, // crc32.h
- 7'b001_0010, // crc32.w
- 7'b001_1000, // crc32c.b
- 7'b001_1001, // crc32c.h
- 7'b001_1010: illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // crc32c.w
-
- default: illegal_insn = 1'b1;
- endcase
- end
- default : illegal_insn = 1'b1;
- endcase
- end
-
- 3'b101: begin
- if (instr[26]) begin
- illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // fsri
- end else begin
- unique case (instr[31:27])
- 5'b0_0000, // srli
- 5'b0_1000: illegal_insn = (instr[26:25] == 2'b00) ? 1'b0 : 1'b1; // srai
-
- 5'b0_0100, // sroi
- 5'b0_1100, // rori
- 5'b0_1001: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // sbexti
-
- 5'b0_1101: begin
- if ((RV32B == RV32BFull)) begin
- illegal_insn = 1'b0; // grevi
- end else begin
- unique case (instr[24:20])
- 5'b11111, // rev
- 5'b11000: illegal_insn = (RV32B == RV32BBalanced) ? 1'b0 : 1'b1; // rev8
-
- default: illegal_insn = 1'b1;
- endcase
- end
- end
- 5'b0_0101: begin
- if ((RV32B == RV32BFull)) begin
- illegal_insn = 1'b0; // gorci
- end else if (instr[24:20] == 5'b00111) begin
- illegal_insn = (RV32B == RV32BBalanced) ? 1'b0 : 1'b1; // orc.b
- end
- end
- 5'b0_0001: begin
- if (instr[26] == 1'b0) begin
- illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // unshfl
- end else begin
- illegal_insn = 1'b1;
- end
- end
-
- default: illegal_insn = 1'b1;
- endcase
- end
- end
-
- // default: illegal_insn = 1'b1;
- endcase
- end
-
- OPCODE_OP: begin // Register-Register ALU operation
- rf_ren_a_o = 1'b1;
- rf_ren_b_o = 1'b1;
- rf_we = 1'b1;
- if ({instr[26], instr[13:12]} == {1'b1, 2'b01}) begin
- illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // cmix / cmov / fsl / fsr
- end else begin
- unique case ({instr[31:25], instr[14:12]})
- // RV32I ALU operations
- {7'b000_0000, 3'b000},
- {7'b010_0000, 3'b000},
- {7'b000_0000, 3'b010},
- {7'b000_0000, 3'b011},
- {7'b000_0000, 3'b100},
- {7'b000_0000, 3'b110},
- {7'b000_0000, 3'b111},
- {7'b000_0000, 3'b001},
- {7'b000_0000, 3'b101},
- {7'b010_0000, 3'b101}: illegal_insn = 1'b0;
-
- // RV32B zbb
- {7'b010_0000, 3'b111}, // andn
- {7'b010_0000, 3'b110}, // orn
- {7'b010_0000, 3'b100}, // xnor
- {7'b001_0000, 3'b001}, // slo
- {7'b001_0000, 3'b101}, // sro
- {7'b011_0000, 3'b001}, // rol
- {7'b011_0000, 3'b101}, // ror
- {7'b000_0101, 3'b100}, // min
- {7'b000_0101, 3'b101}, // max
- {7'b000_0101, 3'b110}, // minu
- {7'b000_0101, 3'b111}, // maxu
- {7'b000_0100, 3'b100}, // pack
- {7'b010_0100, 3'b100}, // packu
- {7'b000_0100, 3'b111}, // packh
- // RV32B zbs
- {7'b010_0100, 3'b001}, // sbclr
- {7'b001_0100, 3'b001}, // sbset
- {7'b011_0100, 3'b001}, // sbinv
- {7'b010_0100, 3'b101}, // sbext
- // RV32B zbf
- {7'b010_0100, 3'b111}: illegal_insn = (RV32B != RV32BNone) ? 1'b0 : 1'b1; // bfp
- // RV32B zbe
- {7'b010_0100, 3'b110}, // bdep
- {7'b000_0100, 3'b110}, // bext
- // RV32B zbp
- {7'b011_0100, 3'b101}, // grev
- {7'b001_0100, 3'b101}, // gorc
- {7'b000_0100, 3'b001}, // shfl
- {7'b000_0100, 3'b101}, // unshfl
- // RV32B zbc
- {7'b000_0101, 3'b001}, // clmul
- {7'b000_0101, 3'b010}, // clmulr
- {7'b000_0101, 3'b011}: illegal_insn = (RV32B == RV32BFull) ? 1'b0 : 1'b1; // clmulh
-
- // RV32M instructions
- {7'b000_0001, 3'b000}: begin // mul
- multdiv_operator_o = MD_OP_MULL;
- multdiv_signed_mode_o = 2'b00;
- illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
- end
- {7'b000_0001, 3'b001}: begin // mulh
- multdiv_operator_o = MD_OP_MULH;
- multdiv_signed_mode_o = 2'b11;
- illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
- end
- {7'b000_0001, 3'b010}: begin // mulhsu
- multdiv_operator_o = MD_OP_MULH;
- multdiv_signed_mode_o = 2'b01;
- illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
- end
- {7'b000_0001, 3'b011}: begin // mulhu
- multdiv_operator_o = MD_OP_MULH;
- multdiv_signed_mode_o = 2'b00;
- illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
- end
- {7'b000_0001, 3'b100}: begin // div
- multdiv_operator_o = MD_OP_DIV;
- multdiv_signed_mode_o = 2'b11;
- illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
- end
- {7'b000_0001, 3'b101}: begin // divu
- multdiv_operator_o = MD_OP_DIV;
- multdiv_signed_mode_o = 2'b00;
- illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
- end
- {7'b000_0001, 3'b110}: begin // rem
- multdiv_operator_o = MD_OP_REM;
- multdiv_signed_mode_o = 2'b11;
- illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
- end
- {7'b000_0001, 3'b111}: begin // remu
- multdiv_operator_o = MD_OP_REM;
- multdiv_signed_mode_o = 2'b00;
- illegal_insn = (RV32M == RV32MNone) ? 1'b1 : 1'b0;
- end
- default: begin
- illegal_insn = 1'b1;
- end
- endcase
- end
- end
-
- /////////////
- // Special //
- /////////////
-
- OPCODE_MISC_MEM: begin
- unique case (instr[14:12])
- 3'b000: begin
- // FENCE is treated as a NOP since all memory operations are already strictly ordered.
- rf_we = 1'b0;
- end
- 3'b001: begin
- // FENCE.I is implemented as a jump to the next PC, this gives the required flushing
- // behaviour (iside prefetch buffer flushed and response to any outstanding iside
- // requests will be ignored).
- // If present, the ICache will also be flushed.
- jump_in_dec_o = 1'b1;
-
- rf_we = 1'b0;
-
- if (instr_first_cycle_i) begin
- jump_set_o = 1'b1;
- icache_inval_o = 1'b1;
- end
- end
- default: begin
- illegal_insn = 1'b1;
- end
- endcase
- end
-
- OPCODE_SYSTEM: begin
- if (instr[14:12] == 3'b000) begin
- // non CSR related SYSTEM instructions
- unique case (instr[31:20])
- 12'h000: // ECALL
- // environment (system) call
- ecall_insn_o = 1'b1;
-
- 12'h001: // ebreak
- // debugger trap
- ebrk_insn_o = 1'b1;
-
- 12'h302: // mret
- mret_insn_o = 1'b1;
-
- 12'h7b2: // dret
- dret_insn_o = 1'b1;
-
- 12'h105: // wfi
- wfi_insn_o = 1'b1;
-
- default:
- illegal_insn = 1'b1;
- endcase
-
- // rs1 and rd must be 0
- if (instr_rs1 != 5'b0 || instr_rd != 5'b0) begin
- illegal_insn = 1'b1;
- end
- end else begin
- // instruction to read/modify CSR
- csr_access_o = 1'b1;
- rf_wdata_sel_o = RF_WD_CSR;
- rf_we = 1'b1;
-
- if (~instr[14]) begin
- rf_ren_a_o = 1'b1;
- end
-
- unique case (instr[13:12])
- 2'b01: csr_op = CSR_OP_WRITE;
- 2'b10: csr_op = CSR_OP_SET;
- 2'b11: csr_op = CSR_OP_CLEAR;
- default: csr_illegal = 1'b1;
- endcase
-
- illegal_insn = csr_illegal;
- end
-
- end
-
- //////////////////////////////////////////
- // Floating Point Extension (F and D) //
- //////////////////////////////////////////
-
- OPCODE_STORE_FP: begin
- data_req_o = 1'b1;
- data_we_o = 1'b1;
- data_type_o = 2'b00;
-
- use_fp_rs2_o = 1'b1;
-
- unique case(instr[14:12])
- 3'b011: begin // FSD
- illegal_insn = (RVF == RV64FDouble) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- 3'b010: begin // FSW
- illegal_insn = (RVF == RV32FNone) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- default: illegal_insn = 1'b1;
- endcase
- end
-
- OPCODE_LOAD_FP: begin
- data_req_o = 1'b1;
- data_type_o = 2'b00;
- fp_load_o = 1'b1;
-
- use_fp_rd_o = 1'b1;
-
- unique case(instr[14:12])
- 3'b011: begin // FLD
- illegal_insn = (RVF == RV64FDouble) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- 3'b010: begin // FLW
- illegal_insn = (RVF == RV32FNone) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- default: illegal_insn = 1'b1;
- endcase
- end
-
- OPCODE_MADD_FP, // FMADD.S, FMADD.D
- OPCODE_MSUB_FP, // FMSUB.S, FMSUB.D
- OPCODE_NMSUB_FP, // FNMSUB.S, FNMSUB.D
- OPCODE_NMADD_FP: begin //FNMADD.S, FNMADD.S
- fp_rf_we_o = 1'b1;
- fp_src_fmt_o = FP32;
- is_fp_instr_o = 1'b1;
-
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rs3_o = 1'b1;
- use_fp_rd_o = 1'b1;
-
- unique case (instr[26:25])
- 01: begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- 00: begin
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- default: illegal_insn = 1'b1;
- endcase
- end
-
- OPCODE_OP_FP: begin
- fp_src_fmt_o = FP32;
- is_fp_instr_o = 1'b1;
-
- unique case (instr[31:25])
- 7'b0000001, // FADD.D
- 7'b0000101: begin // FSUB.D
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rd_o = 1'b1;
- fp_swap_oprnds_o = 1'b1;
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- 7'b0001001, // FMUL.D
- 7'b0001101:begin // FDIV.D
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rd_o = 1'b1;
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- 7'b0000000, // FADD.S
- 7'b0000100: begin // FSUB.S
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rd_o = 1'b1;
- fp_swap_oprnds_o = 1'b1;
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- 7'b0001000, // FMUL.S
- 7'b0001100: begin // FDIV.S
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rd_o = 1'b1;
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- 7'b0101101: begin
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~|instr[24:20]) begin //FSQRT.D
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- end
- 7'b0101100: begin // FSQRT.S
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~|instr[24:20]) begin
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- end
- 7'b0010001: begin // FSGNJ.D, FSGNJN.D, FSGNJX.D
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~(instr[14] | (&instr[13:12]))) begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- end
- 7'b0010000: begin // FSGNJ.S, FSGNJN.S, FSGNJX.S
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~(instr[14] | (&instr[13:12]))) begin
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- end
- 7'b0010101: begin // FMIN.D, FMAX.D
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~|instr[14:13]) begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- end
- 7'b0010100: begin // FMIN.S, FMAX.S
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~|instr[14:13]) begin
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- end
- 7'b0100000: begin // FCVT.S.D
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~(|instr[24:21] | (~instr[20]))) begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- end
- 7'b1100000: begin // FCVT.W.S, FCVT.WU.S
- rf_we = 1'b1; // write back in int_regfile
- use_fp_rs1_o = 1'b1;
- if (~|instr[24:21]) begin
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- end
- 7'b0100001: begin // FCVT.D.S
- fp_rf_we_o = 1'b1;
- use_fp_rs1_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~|instr[24:20]) begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- end
- 7'b1110000: begin // FMV.X.W , FCLASS.S
- rf_we = 1'b1; // write back in int_regfile
- unique case ({instr[24:20],instr[14:12]})
- {5'b00000,3'b000}: begin
- use_fp_rs1_o = 1'b1;
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- mv_instr_o = 1'b1;
- end
- {5'b00000,3'b001}: begin
- use_fp_rs1_o = 1'b1;
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- default: begin
- illegal_insn =1'b1;
- end
- endcase
- end
- 7'b1010001: begin // FEQ.D, FLT.D, FLE.D
- rf_we = 1'b1; // write back in int_regfile
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- if (~(instr[14]) | (&instr[13:12])) begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- end
- 7'b1010000: begin // FEQ.S, FLT.S, FLE.S
- rf_we = 1'b1; // write back in int_regfile
- use_fp_rs1_o = 1'b1;
- use_fp_rs2_o = 1'b1;
- if (~(instr[14]) | (&instr[13:12])) begin
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- end
- 7'b1110001: begin // FCLASS.D
- rf_we = 1'b1; // write back in int_regfile
- use_fp_rs1_o = 1'b1;
- unique case ({instr[24:20],instr[14:12]})
- {5'b00000,3'b001}: begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- default: begin
- illegal_insn =1'b1;
- end
- endcase
- end
- 7'b1100001: begin // // FCVT.W.D, FCVT.WU.D
- rf_we = 1'b1; // write back in int_regfile
- use_fp_rs1_o = 1'b1;
- if (~|instr[24:21]) begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- end
- 7'b1101000: begin // FCVT.S.W, FCVT.S.WU
- fp_rf_we_o = 1'b1;
- use_fp_rd_o = 1'b1;
- if (~|instr[24:21]) begin
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- end
- 7'b1111001: begin // FCVT.D.W, FCVT.D.WU
- rf_we = 1'b1; // write back in int_regfile
- use_fp_rd_o = 1'b1;
- if (~|instr[24:21]) begin
- illegal_insn = ((RVF == RV64FDouble) & (fp_invalid_rm)) ? 1'b0 : 1'b1;
- fp_src_fmt_o = FP64;
- end
- end
- 7'b1111000: begin // FMV.W.X
- fp_rf_we_o = 1'b1;
- use_fp_rd_o = 1'b1;
- mv_instr_o = 1'b1;
- if (~(|instr[24:20]) | (|instr[14:12])) begin
- illegal_insn = ((RVF == RV32FNone) & (~fp_invalid_rm)) ? 1'b1 : 1'b0;
- fp_src_fmt_o = FP32;
- end
- end
- default: illegal_insn = 1'b1;
- endcase
- end
- default: begin
- illegal_insn = 1'b1;
- end
- endcase
-
- // make sure illegal compressed instructions cause illegal instruction exceptions
- if (illegal_c_insn_i) begin
- illegal_insn = 1'b1;
- end
-
- // make sure illegal instructions detected in the decoder do not propagate from decoder
- // into register file, LSU, EX, WB, CSRs, PC
- // NOTE: instructions can also be detected to be illegal inside the CSRs (upon accesses with
- // insufficient privileges), or when accessing non-available registers in RV32E,
- // these cases are not handled here
- if (illegal_insn) begin
- rf_we = 1'b0;
- data_req_o = 1'b0;
- data_we_o = 1'b0;
- jump_in_dec_o = 1'b0;
- jump_set_o = 1'b0;
- branch_in_dec_o = 1'b0;
- csr_access_o = 1'b0;
-
- // floating point
- fp_rf_we_o = 1'b0;
- end
- end
-
- /////////////////////////////
- // Decoder for ALU control //
- /////////////////////////////
-
- always_comb begin
- alu_operator_o = ALU_SLTU;
- alu_op_a_mux_sel_o = OP_A_IMM;
- alu_op_b_mux_sel_o = OP_B_IMM;
-
- imm_a_mux_sel_o = IMM_A_ZERO;
- imm_b_mux_sel_o = IMM_B_I;
-
- bt_a_mux_sel_o = OP_A_CURRPC;
- bt_b_mux_sel_o = IMM_B_I;
-
-
- opcode_alu = opcode_e'(instr_alu[6:0]);
-
- use_rs3_d = 1'b0;
- alu_multicycle_o = 1'b0;
- mult_sel_o = 1'b0;
- div_sel_o = 1'b0;
-
- fp_alu_op_mod_o = 1'b0;
- fp_alu_operator_o = FMADD;
-
- unique case (opcode_alu)
-
- ///////////
- // Jumps //
- ///////////
-
- OPCODE_JAL: begin // Jump and Link
- if (BranchTargetALU) begin
- bt_a_mux_sel_o = OP_A_CURRPC;
- bt_b_mux_sel_o = IMM_B_J;
- end
-
- // Jumps take two cycles without the BTALU
- if (instr_first_cycle_i && !BranchTargetALU) begin
- // Calculate jump target
- alu_op_a_mux_sel_o = OP_A_CURRPC;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_J;
- alu_operator_o = ALU_ADD;
- end else begin
- // Calculate and store PC+4
- alu_op_a_mux_sel_o = OP_A_CURRPC;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_INCR_PC;
- alu_operator_o = ALU_ADD;
- end
- end
-
- OPCODE_JALR: begin // Jump and Link Register
- if (BranchTargetALU) begin
- bt_a_mux_sel_o = OP_A_REG_A;
- bt_b_mux_sel_o = IMM_B_I;
- end
-
- // Jumps take two cycles without the BTALU
- if (instr_first_cycle_i && !BranchTargetALU) begin
- // Calculate jump target
- alu_op_a_mux_sel_o = OP_A_REG_A;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_I;
- alu_operator_o = ALU_ADD;
- end else begin
- // Calculate and store PC+4
- alu_op_a_mux_sel_o = OP_A_CURRPC;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_INCR_PC;
- alu_operator_o = ALU_ADD;
- end
- end
-
- OPCODE_BRANCH: begin // Branch
- // Check branch condition selection
- unique case (instr_alu[14:12])
- 3'b000: alu_operator_o = ALU_EQ;
- 3'b001: alu_operator_o = ALU_NE;
- 3'b100: alu_operator_o = ALU_LT;
- 3'b101: alu_operator_o = ALU_GE;
- 3'b110: alu_operator_o = ALU_LTU;
- 3'b111: alu_operator_o = ALU_GEU;
- default: ;
- endcase
-
- if (BranchTargetALU) begin
- bt_a_mux_sel_o = OP_A_CURRPC;
- // Not-taken branch will jump to next instruction (used in secure mode)
- bt_b_mux_sel_o = branch_taken_i ? IMM_B_B : IMM_B_INCR_PC;
- end
-
- // Without branch target ALU, a branch is a two-stage operation using the Main ALU in both
- // stages
- if (instr_first_cycle_i) begin
- // First evaluate the branch condition
- alu_op_a_mux_sel_o = OP_A_REG_A;
- alu_op_b_mux_sel_o = OP_B_REG_B;
- end else begin
- // Then calculate jump target
- alu_op_a_mux_sel_o = OP_A_CURRPC;
- alu_op_b_mux_sel_o = OP_B_IMM;
- // Not-taken branch will jump to next instruction (used in secure mode)
- imm_b_mux_sel_o = branch_taken_i ? IMM_B_B : IMM_B_INCR_PC;
- alu_operator_o = ALU_ADD;
- end
- end
-
- ////////////////
- // Load/store //
- ////////////////
-
- OPCODE_STORE: begin
- alu_op_a_mux_sel_o = OP_A_REG_A;
- alu_op_b_mux_sel_o = OP_B_REG_B;
- alu_operator_o = ALU_ADD;
-
- if (!instr_alu[14]) begin
- // offset from immediate
- imm_b_mux_sel_o = IMM_B_S;
- alu_op_b_mux_sel_o = OP_B_IMM;
- end
- end
-
- OPCODE_LOAD: begin
- alu_op_a_mux_sel_o = OP_A_REG_A;
-
- // offset from immediate
- alu_operator_o = ALU_ADD;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_I;
- end
-
- /////////
- // ALU //
- /////////
-
- OPCODE_LUI: begin // Load Upper Immediate
- alu_op_a_mux_sel_o = OP_A_IMM;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_a_mux_sel_o = IMM_A_ZERO;
- imm_b_mux_sel_o = IMM_B_U;
- alu_operator_o = ALU_ADD;
- end
-
- OPCODE_AUIPC: begin // Add Upper Immediate to PC
- alu_op_a_mux_sel_o = OP_A_CURRPC;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_U;
- alu_operator_o = ALU_ADD;
- end
-
- OPCODE_OP_IMM: begin // Register-Immediate ALU Operations
- alu_op_a_mux_sel_o = OP_A_REG_A;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_I;
-
- unique case (instr_alu[14:12])
- 3'b000: alu_operator_o = ALU_ADD; // Add Immediate
- 3'b010: alu_operator_o = ALU_SLT; // Set to one if Lower Than Immediate
- 3'b011: alu_operator_o = ALU_SLTU; // Set to one if Lower Than Immediate Unsigned
- 3'b100: alu_operator_o = ALU_XOR; // Exclusive Or with Immediate
- 3'b110: alu_operator_o = ALU_OR; // Or with Immediate
- 3'b111: alu_operator_o = ALU_AND; // And with Immediate
-
- 3'b001: begin
- if (RV32B != RV32BNone) begin
- unique case (instr_alu[31:27])
- 5'b0_0000: alu_operator_o = ALU_SLL; // Shift Left Logical by Immediate
- 5'b0_0100: alu_operator_o = ALU_SLO; // Shift Left Ones by Immediate
- 5'b0_1001: alu_operator_o = ALU_SBCLR; // Clear bit specified by immediate
- 5'b0_0101: alu_operator_o = ALU_SBSET; // Set bit specified by immediate
- 5'b0_1101: alu_operator_o = ALU_SBINV; // Invert bit specified by immediate.
- // Shuffle with Immediate Control Value
- 5'b0_0001: if (instr_alu[26] == 0) alu_operator_o = ALU_SHFL;
- 5'b0_1100: begin
- unique case (instr_alu[26:20])
- 7'b000_0000: alu_operator_o = ALU_CLZ; // clz
- 7'b000_0001: alu_operator_o = ALU_CTZ; // ctz
- 7'b000_0010: alu_operator_o = ALU_PCNT; // pcnt
- 7'b000_0100: alu_operator_o = ALU_SEXTB; // sext.b
- 7'b000_0101: alu_operator_o = ALU_SEXTH; // sext.h
- 7'b001_0000: begin
- if (RV32B == RV32BFull) begin
- alu_operator_o = ALU_CRC32_B; // crc32.b
- alu_multicycle_o = 1'b1;
- end
- end
- 7'b001_0001: begin
- if (RV32B == RV32BFull) begin
- alu_operator_o = ALU_CRC32_H; // crc32.h
- alu_multicycle_o = 1'b1;
- end
- end
- 7'b001_0010: begin
- if (RV32B == RV32BFull) begin
- alu_operator_o = ALU_CRC32_W; // crc32.w
- alu_multicycle_o = 1'b1;
- end
- end
- 7'b001_1000: begin
- if (RV32B == RV32BFull) begin
- alu_operator_o = ALU_CRC32C_B; // crc32c.b
- alu_multicycle_o = 1'b1;
- end
- end
- 7'b001_1001: begin
- if (RV32B == RV32BFull) begin
- alu_operator_o = ALU_CRC32C_H; // crc32c.h
- alu_multicycle_o = 1'b1;
- end
- end
- 7'b001_1010: begin
- if (RV32B == RV32BFull) begin
- alu_operator_o = ALU_CRC32C_W; // crc32c.w
- alu_multicycle_o = 1'b1;
- end
- end
- default: ;
- endcase
- end
-
- default: ;
- endcase
- end else begin
- alu_operator_o = ALU_SLL; // Shift Left Logical by Immediate
- end
- end
-
- 3'b101: begin
- if (RV32B != RV32BNone) begin
- if (instr_alu[26] == 1'b1) begin
- alu_operator_o = ALU_FSR;
- alu_multicycle_o = 1'b1;
- if (instr_first_cycle_i) begin
- use_rs3_d = 1'b1;
- end else begin
- use_rs3_d = 1'b0;
- end
- end else begin
- unique case (instr_alu[31:27])
- 5'b0_0000: alu_operator_o = ALU_SRL; // Shift Right Logical by Immediate
- 5'b0_1000: alu_operator_o = ALU_SRA; // Shift Right Arithmetically by Immediate
- 5'b0_0100: alu_operator_o = ALU_SRO; // Shift Right Ones by Immediate
- 5'b0_1001: alu_operator_o = ALU_SBEXT; // Extract bit specified by immediate.
- 5'b0_1100: begin
- alu_operator_o = ALU_ROR; // Rotate Right by Immediate
- alu_multicycle_o = 1'b1;
- end
- 5'b0_1101: alu_operator_o = ALU_GREV; // General Reverse with Imm Control Val
- 5'b0_0101: alu_operator_o = ALU_GORC; // General Or-combine with Imm Control Val
- // Unshuffle with Immediate Control Value
- 5'b0_0001: begin
- if (RV32B == RV32BFull) begin
- if (instr_alu[26] == 1'b0) alu_operator_o = ALU_UNSHFL;
- end
- end
- default: ;
- endcase
- end
-
- end else begin
- if (instr_alu[31:27] == 5'b0_0000) begin
- alu_operator_o = ALU_SRL; // Shift Right Logical by Immediate
- end else if (instr_alu[31:27] == 5'b0_1000) begin
- alu_operator_o = ALU_SRA; // Shift Right Arithmetically by Immediate
- end
- end
- end
-
- // default: ;
- endcase
- end
-
- OPCODE_OP: begin // Register-Register ALU operation
- alu_op_a_mux_sel_o = OP_A_REG_A;
- alu_op_b_mux_sel_o = OP_B_REG_B;
-
- if (instr_alu[26]) begin
- if (RV32B != RV32BNone) begin
- unique case ({instr_alu[26:25], instr_alu[14:12]})
- {2'b11, 3'b001}: begin
- alu_operator_o = ALU_CMIX; // cmix
- alu_multicycle_o = 1'b1;
- if (instr_first_cycle_i) begin
- use_rs3_d = 1'b1;
- end else begin
- use_rs3_d = 1'b0;
- end
- end
- {2'b11, 3'b101}: begin
- alu_operator_o = ALU_CMOV; // cmov
- alu_multicycle_o = 1'b1;
- if (instr_first_cycle_i) begin
- use_rs3_d = 1'b1;
- end else begin
- use_rs3_d = 1'b0;
- end
- end
- {2'b10, 3'b001}: begin
- alu_operator_o = ALU_FSL; // fsl
- alu_multicycle_o = 1'b1;
- if (instr_first_cycle_i) begin
- use_rs3_d = 1'b1;
- end else begin
- use_rs3_d = 1'b0;
- end
- end
- {2'b10, 3'b101}: begin
- alu_operator_o = ALU_FSR; // fsr
- alu_multicycle_o = 1'b1;
- if (instr_first_cycle_i) begin
- use_rs3_d = 1'b1;
- end else begin
- use_rs3_d = 1'b0;
- end
- end
- default: ;
- endcase
- end
- end else begin
- unique case ({instr_alu[31:25], instr_alu[14:12]})
- // RV32I ALU operations
- {7'b000_0000, 3'b000}: alu_operator_o = ALU_ADD; // Add
- {7'b010_0000, 3'b000}: alu_operator_o = ALU_SUB; // Sub
- {7'b000_0000, 3'b010}: alu_operator_o = ALU_SLT; // Set Lower Than
- {7'b000_0000, 3'b011}: alu_operator_o = ALU_SLTU; // Set Lower Than Unsigned
- {7'b000_0000, 3'b100}: alu_operator_o = ALU_XOR; // Xor
- {7'b000_0000, 3'b110}: alu_operator_o = ALU_OR; // Or
- {7'b000_0000, 3'b111}: alu_operator_o = ALU_AND; // And
- {7'b000_0000, 3'b001}: alu_operator_o = ALU_SLL; // Shift Left Logical
- {7'b000_0000, 3'b101}: alu_operator_o = ALU_SRL; // Shift Right Logical
- {7'b010_0000, 3'b101}: alu_operator_o = ALU_SRA; // Shift Right Arithmetic
-
- // RV32B ALU Operations
- {7'b001_0000, 3'b001}: if (RV32B != RV32BNone) alu_operator_o = ALU_SLO; // slo
- {7'b001_0000, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_SRO; // sro
- {7'b011_0000, 3'b001}: begin
- if (RV32B != RV32BNone) begin
- alu_operator_o = ALU_ROL; // rol
- alu_multicycle_o = 1'b1;
- end
- end
- {7'b011_0000, 3'b101}: begin
- if (RV32B != RV32BNone) begin
- alu_operator_o = ALU_ROR; // ror
- alu_multicycle_o = 1'b1;
- end
- end
-
- {7'b000_0101, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_MIN; // min
- {7'b000_0101, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_MAX; // max
- {7'b000_0101, 3'b110}: if (RV32B != RV32BNone) alu_operator_o = ALU_MINU; // minu
- {7'b000_0101, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_MAXU; // maxu
-
- {7'b000_0100, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_PACK; // pack
- {7'b010_0100, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_PACKU; // packu
- {7'b000_0100, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_PACKH; // packh
-
- {7'b010_0000, 3'b100}: if (RV32B != RV32BNone) alu_operator_o = ALU_XNOR; // xnor
- {7'b010_0000, 3'b110}: if (RV32B != RV32BNone) alu_operator_o = ALU_ORN; // orn
- {7'b010_0000, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_ANDN; // andn
-
- // RV32B zbs
- {7'b010_0100, 3'b001}: if (RV32B != RV32BNone) alu_operator_o = ALU_SBCLR; // sbclr
- {7'b001_0100, 3'b001}: if (RV32B != RV32BNone) alu_operator_o = ALU_SBSET; // sbset
- {7'b011_0100, 3'b001}: if (RV32B != RV32BNone) alu_operator_o = ALU_SBINV; // sbinv
- {7'b010_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_SBEXT; // sbext
-
- // RV32B zbf
- {7'b010_0100, 3'b111}: if (RV32B != RV32BNone) alu_operator_o = ALU_BFP; // bfp
-
- // RV32B zbp
- {7'b011_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GREV; // grev
- {7'b001_0100, 3'b101}: if (RV32B != RV32BNone) alu_operator_o = ALU_GORC; // grev
- {7'b000_0100, 3'b001}: if (RV32B == RV32BFull) alu_operator_o = ALU_SHFL; // shfl
- {7'b000_0100, 3'b101}: if (RV32B == RV32BFull) alu_operator_o = ALU_UNSHFL; // unshfl
-
- // RV32B zbc
- {7'b000_0101, 3'b001}: if (RV32B == RV32BFull) alu_operator_o = ALU_CLMUL; // clmul
- {7'b000_0101, 3'b010}: if (RV32B == RV32BFull) alu_operator_o = ALU_CLMULR; // clmulr
- {7'b000_0101, 3'b011}: if (RV32B == RV32BFull) alu_operator_o = ALU_CLMULH; // clmulh
-
- // RV32B zbe
- {7'b010_0100, 3'b110}: begin
- if (RV32B == RV32BFull) begin
- alu_operator_o = ALU_BDEP; // bdep
- alu_multicycle_o = 1'b1;
- end
- end
- {7'b000_0100, 3'b110}: begin
- if (RV32B == RV32BFull) begin
- alu_operator_o = ALU_BEXT; // bext
- alu_multicycle_o = 1'b1;
- end
- end
-
- // RV32M instructions, all use the same ALU operation
- {7'b000_0001, 3'b000}: begin // mul
- alu_operator_o = ALU_ADD;
- mult_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
- end
- {7'b000_0001, 3'b001}: begin // mulh
- alu_operator_o = ALU_ADD;
- mult_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
- end
- {7'b000_0001, 3'b010}: begin // mulhsu
- alu_operator_o = ALU_ADD;
- mult_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
- end
- {7'b000_0001, 3'b011}: begin // mulhu
- alu_operator_o = ALU_ADD;
- mult_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
- end
- {7'b000_0001, 3'b100}: begin // div
- alu_operator_o = ALU_ADD;
- div_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
- end
- {7'b000_0001, 3'b101}: begin // divu
- alu_operator_o = ALU_ADD;
- div_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
- end
- {7'b000_0001, 3'b110}: begin // rem
- alu_operator_o = ALU_ADD;
- div_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
- end
- {7'b000_0001, 3'b111}: begin // remu
- alu_operator_o = ALU_ADD;
- div_sel_o = (RV32M == RV32MNone) ? 1'b0 : 1'b1;
- end
-
- default: ;
- endcase
- end
- end
-
- /////////////
- // Special //
- /////////////
-
- OPCODE_MISC_MEM: begin
- unique case (instr_alu[14:12])
- 3'b000: begin
- // FENCE is treated as a NOP since all memory operations are already strictly ordered.
- alu_operator_o = ALU_ADD; // nop
- alu_op_a_mux_sel_o = OP_A_REG_A;
- alu_op_b_mux_sel_o = OP_B_IMM;
- end
- 3'b001: begin
- // FENCE.I will flush the IF stage, prefetch buffer and ICache if present.
- if (BranchTargetALU) begin
- bt_a_mux_sel_o = OP_A_CURRPC;
- bt_b_mux_sel_o = IMM_B_INCR_PC;
- end else begin
- alu_op_a_mux_sel_o = OP_A_CURRPC;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_INCR_PC;
- alu_operator_o = ALU_ADD;
- end
- end
- default: ;
- endcase
- end
-
- OPCODE_SYSTEM: begin
- if (instr_alu[14:12] == 3'b000) begin
- // non CSR related SYSTEM instructions
- alu_op_a_mux_sel_o = OP_A_REG_A;
- alu_op_b_mux_sel_o = OP_B_IMM;
- end else begin
- // instruction to read/modify CSR
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_a_mux_sel_o = IMM_A_Z;
- imm_b_mux_sel_o = IMM_B_I; // CSR address is encoded in I imm
-
- if (instr_alu[14]) begin
- // rs1 field is used as immediate
- alu_op_a_mux_sel_o = OP_A_IMM;
- end else begin
- alu_op_a_mux_sel_o = OP_A_REG_A;
- end
- end
- end
- //////////////////////////////////////////
- // Floating Point Extension (F and D) //
- //////////////////////////////////////////
-
- OPCODE_STORE_FP: begin
- alu_op_a_mux_sel_o = OP_A_REG_A;
- alu_op_b_mux_sel_o = OP_B_REG_B;
- alu_operator_o = ALU_ADD;
-
- unique case(instr[14:12])
- 3'b011: begin // FSD
- imm_b_mux_sel_o = IMM_B_S;
- alu_op_b_mux_sel_o = OP_B_IMM;
- end
- 3'b010: begin // FSW
- imm_b_mux_sel_o = IMM_B_S;
- alu_op_b_mux_sel_o = OP_B_IMM;
- end
- default: ;
- endcase
- end
-
- OPCODE_LOAD_FP: begin
- unique case(instr[14:12])
- 3'b011: begin // FLD
- alu_op_a_mux_sel_o = OP_A_REG_A;
-
- alu_operator_o = ALU_ADD;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_I;
- end
- 3'b010: begin // FLW
- alu_op_a_mux_sel_o = OP_A_REG_A;
-
- alu_operator_o = ALU_ADD;
- alu_op_b_mux_sel_o = OP_B_IMM;
- imm_b_mux_sel_o = IMM_B_I;
- end
- default: ;
- endcase
- end
-
- OPCODE_MADD_FP: begin // FMADD.S, FMADD.D
- unique case (instr[26:25])
- 01: begin
- fp_alu_operator_o = FMADD;
- fp_alu_op_mod_o = 1'b0;
- end
- 00: begin
- fp_alu_operator_o = FMADD;
- fp_alu_op_mod_o = 1'b0;
- end
- default: ;
- endcase
- end
-
- OPCODE_MSUB_FP: begin // FMSUB.S, FMSUB.D
- unique case (instr[26:25])
- 01: begin
- fp_alu_operator_o = FMADD;
- fp_alu_op_mod_o = 1'b1;
- end
- 00: begin
- fp_alu_operator_o = FMADD;
- fp_alu_op_mod_o = 1'b1;
- end
- default: ;
- endcase
- end
-
- OPCODE_NMSUB_FP: begin // FNMSUB.S, FNMSUB.D
- unique case (instr[26:25])
- 01: begin
- fp_alu_operator_o = FNMSUB;
- end
- 00: begin
- fp_alu_operator_o = FNMSUB;
- end
- default: ;
- endcase
- end
-
- OPCODE_NMADD_FP: begin //FNMADD.S, FNMADD.S
- unique case (instr[26:25])
- 01: begin
- fp_alu_operator_o = FNMSUB;
- fp_alu_op_mod_o = 1'b1;
- end
- 00: begin
- fp_alu_operator_o = FNMSUB;
- fp_alu_op_mod_o = 1'b1;
- end
- default: ;
- endcase
- end
-
- OPCODE_OP_FP: begin
- unique case (instr[31:25])
- 7'b0000001: begin // FADD.D
- fp_alu_operator_o = ADD;
- end
- 7'b0000101: begin // FSUB.D
- fp_alu_operator_o = ADD;
- fp_alu_op_mod_o = 1'b1;
- end
- 7'b0001001: begin // FMUL.D
- fp_alu_operator_o = MUL;
- end
- 7'b0001101:begin // FDIV.S
- fp_alu_operator_o = DIV;
- end
- 7'b0000000: begin // FADD.S
- fp_alu_operator_o = ADD;
- end
- 7'b0000100: begin // FSUB.S
- fp_alu_operator_o = ADD;
- fp_alu_op_mod_o = 1'b1;
- end
- 7'b0001000: begin // FMUL.S
- fp_alu_operator_o = MUL;
- end
- 7'b0001100: begin // FDIV.S
- fp_alu_operator_o = DIV;
- end
- 7'b0101101: begin
- if (~|instr[24:20]) begin // FSQRT.D
- fp_alu_operator_o = SQRT;
- end
- end
- 7'b0101100: begin // FSQRT.S
- if (~|instr[24:20]) begin
- fp_alu_operator_o = SQRT;
- end
- end
- 7'b0010001: begin // FSGNJ.D, FSGNJN.D, FSGNJX.D
- if (~(instr[14] | (&instr[13:12]))) begin
- fp_alu_operator_o = SGNJ;
- end
- end
- 7'b0010000: begin // FSGNJ.S, FSGNJN.S, FSGNJX.S
- if (~(instr[14] | (&instr[13:12]))) begin
- fp_alu_operator_o = SGNJ;
- end
- end
- 7'b0010101: begin // FMIN.D, FMAX.D
- if (~|instr[14:13]) begin
- fp_alu_operator_o = MINMAX;
- end
- end
- 7'b0010100: begin // FMIN.S, FMAX.S
- if (~|instr[14:13]) begin
- fp_alu_operator_o = MINMAX;
- end
- end
- 7'b0100000: begin // FCVT.S.D
- if (~(|instr[24:21] | (~instr[20]))) begin
- fp_alu_operator_o = F2F;
- end
- end
- 7'b1100000: begin // FCVT.W.S, FCVT.WU.S
- if (~|instr[24:21]) begin
- fp_alu_operator_o = F2I;
-
- if (instr[20])
- fp_alu_op_mod_o = 1'b1;
- end
- end
- 7'b0100001: begin // FCVT.D.S
- if (~|instr[24:20]) begin
- fp_alu_operator_o = F2F;
- end
- end
- 7'b1110000: begin // FMV.X.W , FCLASS.S
- unique case ({instr[24:20],instr[14:12]})
- // {3'b0000000,3'b000}: begin
- // fp_alu_operator_o = ADD; // to be decided YET
- // end
- {3'b000,3'b001}: begin
- fp_alu_operator_o = CLASSIFY;
- end
- default: ;
- endcase
- end
- 7'b1010001: begin // FEQ.D, FLT.D, FLE.D
- if ((~instr[14]) | (&instr[13:12])) begin
- fp_alu_operator_o = CMP;
- end
- end
- 7'b1010000: begin // FEQ.S, FLT.S, FLE.S
- if ((~instr[14]) | (&instr[13:12])) begin
- fp_alu_operator_o = CMP;
- end
- end
- 7'b1110001: begin // FCLASS.D
- unique case ({instr[24:20],instr[14:12]})
- {3'b000,3'b001}: begin
- fp_alu_operator_o = CLASSIFY;
- end
- default: ;
- endcase
- end
- 7'b1100001: begin // // FCVT.W.D, FCVT.WU.D
- if (~|instr[24:21]) begin
- fp_alu_operator_o = F2I;
-
- if (instr[20])
- fp_alu_op_mod_o = 1'b1;
- end
- end
- 7'b1101000: begin // FCVT.S.W, FCVT.S.WU
- if (~(|instr[24:21])) begin
- fp_alu_operator_o = I2F;
-
- if (instr[20])
- fp_alu_op_mod_o = 1'b1;
- end
- end
- 7'b1111001: begin // FCVT.D.W, FCVT.D.WU
- if (~|instr[24:21]) begin
- fp_alu_operator_o = I2F;
-
- if (instr[20])
- fp_alu_op_mod_o = 1'b1;
- end
- end
- // 7'b1111000: begin // FMV.W.X
- // if ((|instr[24:20]) | (|instr[14:12])) begin
- // fp_alu_operator_o = FMADD; // to be decided
- // end
- // end
- default: ;
- endcase
- end
- default: ;
- endcase
- end
-
- // do not enable multdiv in case of illegal instruction exceptions
- assign mult_en_o = illegal_insn ? 1'b0 : mult_sel_o;
- assign div_en_o = illegal_insn ? 1'b0 : div_sel_o;
-
- // make sure instructions accessing non-available registers in RV32E cause illegal
- // instruction exceptions
- assign illegal_insn_o = illegal_insn | illegal_reg_rv32e;
-
- // do not propgate regfile write enable if non-available registers are accessed in RV32E
- assign rf_we_o = rf_we & ~illegal_reg_rv32e;
-
- ////////////////
- // Assertions //
- ////////////////
-
-// // Selectors must be known/valid.
-// `ASSERT(buraqRegImmAluOpKnown, (opcode == OPCODE_OP_IMM) |->
-// !$isunknown(instr[14:12]))
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/brq_ifu.sv b/verilog/rtl/brq_ifu.sv
deleted file mode 100644
index d44024c..0000000
--- a/verilog/rtl/brq_ifu.sv
+++ /dev/null
@@ -1,273 +0,0 @@
-
-
-/**
- * Instruction Fetch Stage
- *
- * Instruction fetch unit: Selection of the next PC, and buffering (sampling) of
- * the read instruction.
- */
-
-
-
-module brq_ifu #(
- parameter int unsigned DmHaltAddr = 32'h1A110800,
- parameter int unsigned DmExceptionAddr = 32'h1A110808,
- parameter bit DummyInstructions = 1'b0,
- parameter bit ICache = 1'b0,
- parameter bit ICacheECC = 1'b0,
- parameter bit PCIncrCheck = 1'b0,
- parameter bit BranchPredictor = 1'b0
-) (
- input logic clk_i,
- input logic rst_ni,
-
- input logic [31:0] boot_addr_i, // also used for mtvec
- input logic req_i, // instruction request control
-
- // instruction cache interface
- output logic instr_req_o,
- output logic [31:0] instr_addr_o,
- input logic instr_gnt_i,
- input logic instr_rvalid_i,
- input logic [31:0] instr_rdata_i,
- input logic instr_err_i,
- input logic instr_pmp_err_i,
-
- // output of ID stage
- output logic instr_valid_id_o, // instr in IF-ID is valid
- output logic instr_new_id_o, // instr in IF-ID is new
- output logic [31:0] instr_rdata_id_o, // instr for ID stage
- output logic [31:0] instr_rdata_alu_id_o, // replicated instr for ID stage
- // to reduce fan-out
- output logic [15:0] instr_rdata_c_id_o, // compressed instr for ID stage
- // (mtval), meaningful only if
- // instr_is_compressed_id_o = 1'b1
- output logic instr_is_compressed_id_o, // compressed decoder thinks this
- // is a compressed instr
- // output logic instr_bp_taken_o, // instruction was predicted to be
- // a taken branch
- output logic instr_fetch_err_o, // bus error on fetch
- output logic instr_fetch_err_plus2_o, // bus error misaligned
- output logic illegal_c_insn_id_o, // compressed decoder thinks this
- // is an invalid instr
- // output logic dummy_instr_id_o, // Instruction is a dummy
- output logic [31:0] pc_if_o,
- output logic [31:0] pc_id_o,
-
- // control signals
- input logic instr_valid_clear_i, // clear instr valid bit in IF-ID
- input logic pc_set_i, // set the PC to a new value
- input logic pc_set_spec_i,
- input brq_pkg::pc_sel_e pc_mux_i, // selector for PC multiplexer
- // input logic nt_branch_mispredict_i, // Not-taken branch in ID/EX was
- // mispredicted (predicted taken)
- input brq_pkg::exc_pc_sel_e exc_pc_mux_i, // selects ISR address
-
- // jump and branch target
- input logic [31:0] branch_target_ex_i, // branch/jump target address
-
- // CSRs
- input logic [31:0] csr_mepc_i, // PC to restore after handling
- // the interrupt/exception
- input logic [31:0] csr_depc_i, // PC to restore after handling
- // the debug request
- input logic [31:0] csr_mtvec_i, // base PC to jump to on exception
- output logic csr_mtvec_init_o, // tell CS regfile to init mtvec
-
- // pipeline stall
- input logic id_in_ready_i, // ID stage is ready for new instr
-
- // misc signals
- output logic pc_mismatch_alert_o,
- output logic if_busy_o // IF stage is busy fetching instr
-);
-
- import brq_pkg::*;
-
- logic instr_valid_id_d, instr_valid_id_q;
- logic instr_new_id_d, instr_new_id_q;
-
- // prefetch buffer related signals
- logic prefetch_busy;
- logic branch_req;
- logic branch_spec;
- logic predicted_branch;
- logic [31:0] fetch_addr_n;
-
- logic fetch_valid;
- logic fetch_ready;
- logic [31:0] fetch_rdata;
- logic [31:0] fetch_addr;
- logic fetch_err;
- logic fetch_err_plus2;
-
- logic if_instr_valid;
- logic [31:0] if_instr_rdata;
- logic [31:0] if_instr_addr;
- logic if_instr_err;
-
- logic [31:0] exc_pc;
-
-
- logic if_id_pipe_reg_we; // IF-ID pipeline reg write enable
-
- logic [31:0] instr_out;
- logic instr_is_compressed_out;
- logic illegal_c_instr_out;
- logic instr_err_out;
-
- logic predict_branch_taken;
- logic [31:0] predict_branch_pc;
-
- brq_pkg::pc_sel_e pc_mux_internal;
-
- // exception PC selection mux
- always_comb begin : exc_pc_mux
- unique case (exc_pc_mux_i)
- EXC_PC_EXC: exc_pc = { csr_mtvec_i[31:2], 2'b00 };
- EXC_PC_IRQ: exc_pc = { csr_mtvec_i[31:2], 2'b00 };
- EXC_PC_DBD: exc_pc = DmHaltAddr;
- EXC_PC_DBG_EXC: exc_pc = DmExceptionAddr;
- // default: exc_pc = { csr_mtvec_i[31:8], 8'h00 };
- endcase
- end
-
- // The Branch predictor can provide a new PC which is internal to ifu. Only override the mux
- // select to choose this if the core isn't already trying to set a PC.
- assign pc_mux_internal =
- (BranchPredictor && predict_branch_taken && !pc_set_i) ? PC_BP : pc_mux_i;
-
- // fetch address selection mux
- always_comb begin : fetch_addr_mux
- unique case (pc_mux_internal)
- PC_BOOT: fetch_addr_n = { boot_addr_i[31:2], 2'b00 };
- PC_JUMP: fetch_addr_n = branch_target_ex_i;
- PC_EXC: fetch_addr_n = exc_pc; // set PC to exception handler
- PC_ERET: fetch_addr_n = csr_mepc_i; // restore PC when returning from EXC
- PC_DRET: fetch_addr_n = csr_depc_i;
- // Without branch predictor will never get pc_mux_internal == PC_BP. We still handle no branch
- // predictor case here to ensure redundant mux logic isn't synthesised.
- PC_BP: fetch_addr_n = BranchPredictor ? predict_branch_pc : { boot_addr_i[31:2], 2'b00 };
- default: fetch_addr_n = { boot_addr_i[31:2], 2'b00 };
- endcase
- end
-
- // tell CS register file to initialize mtvec on boot
- assign csr_mtvec_init_o = (pc_mux_i == PC_BOOT) & pc_set_i;
-
- // prefetch buffer, caches a fixed number of instructions
- brq_ifu_prefetch_buffer #(
- .BranchPredictor (BranchPredictor)
- ) ifu_prefetch_buffer_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
-
- .req_i ( req_i ),
-
- .branch_i ( branch_req ),
- .branch_spec_i ( branch_spec ),
- .predicted_branch_i ( predicted_branch ),
- // .branch_mispredict_i ( nt_branch_mispredict_i ),
- .addr_i ( {fetch_addr_n[31:1], 1'b0} ),
-
- .ready_i ( fetch_ready ),
- .valid_o ( fetch_valid ),
- .rdata_o ( fetch_rdata ),
- .addr_o ( fetch_addr ),
- .err_o ( fetch_err ),
- .err_plus2_o ( fetch_err_plus2 ),
-
- .instr_req_o ( instr_req_o ),
- .instr_addr_o ( instr_addr_o ),
- .instr_gnt_i ( instr_gnt_i ),
- .instr_rvalid_i ( instr_rvalid_i ),
- .instr_rdata_i ( instr_rdata_i ),
- .instr_err_i ( instr_err_i ),
- .instr_pmp_err_i ( instr_pmp_err_i ),
-
- .busy_o ( prefetch_busy )
- );
-
-
- assign branch_req = pc_set_i | predict_branch_taken;
- assign branch_spec = pc_set_spec_i | predict_branch_taken;
-
- assign pc_if_o = if_instr_addr;
- assign if_busy_o = prefetch_busy;
-
- // compressed instruction decoding, or more precisely compressed instruction
- // expander
- //
- // since it does not matter where we decompress instructions, we do it here
- // to ease timing closure
- logic [31:0] instr_decompressed;
- logic illegal_c_insn;
- logic instr_is_compressed;
-
- brq_ifu_compressed_decoder ifu_compressed_decoder_i (
- .instr_i ( if_instr_rdata ),
- .instr_o ( instr_decompressed ),
- .is_compressed_o ( instr_is_compressed ),
- .illegal_instr_o ( illegal_c_insn )
- );
-
- assign instr_out = instr_decompressed;
- assign instr_is_compressed_out = instr_is_compressed;
- assign illegal_c_instr_out = illegal_c_insn;
- assign instr_err_out = if_instr_err;
-
- // The ID stage becomes valid as soon as any instruction is registered in the ID stage flops.
- // Note that the current instruction is squashed by the incoming pc_set_i signal.
- // Valid is held until it is explicitly cleared (due to an instruction completing or an exception)
- assign instr_valid_id_d = (if_instr_valid & id_in_ready_i & ~pc_set_i) |
- (instr_valid_id_q & ~instr_valid_clear_i);
- assign instr_new_id_d = if_instr_valid & id_in_ready_i;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- instr_valid_id_q <= 1'b0;
- instr_new_id_q <= 1'b0;
- end else begin
- instr_valid_id_q <= instr_valid_id_d;
- instr_new_id_q <= instr_new_id_d;
- end
- end
-
- assign instr_valid_id_o = instr_valid_id_q;
- // Signal when a new instruction enters the ID stage (only used for RVFI signalling).
- assign instr_new_id_o = instr_new_id_q;
-
- // IF-ID pipeline registers, frozen when the ID stage is stalled
- assign if_id_pipe_reg_we = instr_new_id_d;
-
- always_ff @(posedge clk_i) begin
- if (if_id_pipe_reg_we) begin
- instr_rdata_id_o <= instr_out;
- // To reduce fan-out and help timing from the instr_rdata_id flops they are replicated.
- instr_rdata_alu_id_o <= instr_out;
- instr_fetch_err_o <= instr_err_out;
- instr_fetch_err_plus2_o <= fetch_err_plus2;
- instr_rdata_c_id_o <= if_instr_rdata[15:0];
- instr_is_compressed_id_o <= instr_is_compressed_out;
- illegal_c_insn_id_o <= illegal_c_instr_out;
- pc_id_o <= pc_if_o;
- end
- end
-
-
- assign pc_mismatch_alert_o = 1'b0;
-
- // end else begin : g_no_ifu_branch_predictor
- // assign instr_bp_taken_o = 1'b0;
- assign predict_branch_taken = 1'b0;
- assign predicted_branch = 1'b0;
- assign predict_branch_pc = 32'b0;
-
- assign if_instr_valid = fetch_valid;
- assign if_instr_rdata = fetch_rdata;
- assign if_instr_addr = fetch_addr;
- assign if_instr_err = fetch_err;
- assign fetch_ready = id_in_ready_i; //& ~stall_dummy_instr;
- // end
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/brq_ifu_compressed_decoder.sv b/verilog/rtl/brq_ifu_compressed_decoder.sv
deleted file mode 100644
index b615e9a..0000000
--- a/verilog/rtl/brq_ifu_compressed_decoder.sv
+++ /dev/null
@@ -1,271 +0,0 @@
-
-/**
- * Compressed instruction decoder
- *
- * Decodes RISC-V compressed instructions into their RV32 equivalent.
- * This module is fully combinatorial, clock and reset are used for
- * assertions only.
- */
-
-
-module brq_ifu_compressed_decoder (
- input logic [31:0] instr_i,
- output logic [31:0] instr_o,
- output logic is_compressed_o,
- output logic illegal_instr_o
-);
- import brq_pkg::*;
-
- // valid_i indicates if instr_i is valid and is used for assertions only.
- // The following signal is used to avoid possible lint errors.
-
- ////////////////////////
- // Compressed decoder //
- ////////////////////////
-
- always_comb begin
- // By default, forward incoming instruction, mark it as legal.
- instr_o = instr_i;
- illegal_instr_o = 1'b0;
-
- // Check if incoming instruction is compressed.
- unique case (instr_i[1:0])
- // C0
- 2'b00: begin
- unique case (instr_i[15:13])
- 3'b000: begin
- // c.addi4spn -> addi rd', x2, imm
- instr_o = {2'b0, instr_i[10:7], instr_i[12:11], instr_i[5],
- instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], {OPCODE_OP_IMM}};
- if (instr_i[12:5] == 8'b0) illegal_instr_o = 1'b1;
- end
-
- 3'b010: begin
- // c.lw -> lw rd', imm(rs1')
- instr_o = {5'b0, instr_i[5], instr_i[12:10], instr_i[6],
- 2'b00, 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[4:2], {OPCODE_LOAD}};
- end
-
- 3'b110: begin
- // c.sw -> sw rs2', imm(rs1')
- instr_o = {5'b0, instr_i[5], instr_i[12], 2'b01, instr_i[4:2],
- 2'b01, instr_i[9:7], 3'b010, instr_i[11:10], instr_i[6],
- 2'b00, {OPCODE_STORE}};
- end
-
- 3'b001,
- 3'b011,
- 3'b100,
- 3'b101,
- 3'b111: begin
- illegal_instr_o = 1'b1;
- end
-
- //default: begin
- // illegal_instr_o = 1'b1;
- //end
- endcase
- end
-
- // C1
- //
- // Register address checks for RV32E are performed in the regular instruction decoder.
- // If this check fails, an illegal instruction exception is triggered and the controller
- // writes the actual faulting instruction to mtval.
- 2'b01: begin
- unique case (instr_i[15:13])
- 3'b000: begin
- // c.addi -> addi rd, rd, nzimm
- // c.nop
- instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2],
- instr_i[11:7], 3'b0, instr_i[11:7], {OPCODE_OP_IMM}};
- end
-
- 3'b001, 3'b101: begin
- // 001: c.jal -> jal x1, imm
- // 101: c.j -> jal x0, imm
- instr_o = {instr_i[12], instr_i[8], instr_i[10:9], instr_i[6],
- instr_i[7], instr_i[2], instr_i[11], instr_i[5:3],
- {9 {instr_i[12]}}, 4'b0, ~instr_i[15], {OPCODE_JAL}};
- end
-
- 3'b010: begin
- // c.li -> addi rd, x0, nzimm
- // (c.li hints are translated into an addi hint)
- instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b0,
- 3'b0, instr_i[11:7], {OPCODE_OP_IMM}};
- end
-
- 3'b011: begin
- // c.lui -> lui rd, imm
- // (c.lui hints are translated into a lui hint)
- instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], {OPCODE_LUI}};
-
- if (instr_i[11:7] == 5'h02) begin
- // c.addi16sp -> addi x2, x2, nzimm
- instr_o = {{3 {instr_i[12]}}, instr_i[4:3], instr_i[5], instr_i[2],
- instr_i[6], 4'b0, 5'h02, 3'b000, 5'h02, {OPCODE_OP_IMM}};
- end
-
- if ({instr_i[12], instr_i[6:2]} == 6'b0) illegal_instr_o = 1'b1;
- end
-
- 3'b100: begin
- unique case (instr_i[11:10])
- 2'b00,
- 2'b01: begin
- // 00: c.srli -> srli rd, rd, shamt
- // 01: c.srai -> srai rd, rd, shamt
- // (c.srli/c.srai hints are translated into a srli/srai hint)
- instr_o = {1'b0, instr_i[10], 5'b0, instr_i[6:2], 2'b01, instr_i[9:7],
- 3'b101, 2'b01, instr_i[9:7], {OPCODE_OP_IMM}};
- if (instr_i[12] == 1'b1) illegal_instr_o = 1'b1;
- end
-
- 2'b10: begin
- // c.andi -> andi rd, rd, imm
- instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 2'b01, instr_i[9:7],
- 3'b111, 2'b01, instr_i[9:7], {OPCODE_OP_IMM}};
- end
-
- 2'b11: begin
- unique case ({instr_i[12], instr_i[6:5]})
- 3'b000: begin
- // c.sub -> sub rd', rd', rs2'
- instr_o = {2'b01, 5'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7],
- 3'b000, 2'b01, instr_i[9:7], {OPCODE_OP}};
- end
-
- 3'b001: begin
- // c.xor -> xor rd', rd', rs2'
- instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100,
- 2'b01, instr_i[9:7], {OPCODE_OP}};
- end
-
- 3'b010: begin
- // c.or -> or rd', rd', rs2'
- instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110,
- 2'b01, instr_i[9:7], {OPCODE_OP}};
- end
-
- 3'b011: begin
- // c.and -> and rd', rd', rs2'
- instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111,
- 2'b01, instr_i[9:7], {OPCODE_OP}};
- end
-
- 3'b100,
- 3'b101,
- 3'b110,
- 3'b111: begin
- // 100: c.subw
- // 101: c.addw
- illegal_instr_o = 1'b1;
- end
-
- // default: begin
- // illegal_instr_o = 1'b1;
- // end
- endcase
- end
-
- // default: begin
- // illegal_instr_o = 1'b1;
- // end
- endcase
- end
-
- 3'b110, 3'b111: begin
- // 0: c.beqz -> beq rs1', x0, imm
- // 1: c.bnez -> bne rs1', x0, imm
- instr_o = {{4 {instr_i[12]}}, instr_i[6:5], instr_i[2], 5'b0, 2'b01,
- instr_i[9:7], 2'b00, instr_i[13], instr_i[11:10], instr_i[4:3],
- instr_i[12], {OPCODE_BRANCH}};
- end
-
- // default: begin
- // illegal_instr_o = 1'b1;
- // end
- endcase
- end
-
- // C2
- //
- // Register address checks for RV32E are performed in the regular instruction decoder.
- // If this check fails, an illegal instruction exception is triggered and the controller
- // writes the actual faulting instruction to mtval.
- 2'b10: begin
- unique case (instr_i[15:13])
- 3'b000: begin
- // c.slli -> slli rd, rd, shamt
- // (c.ssli hints are translated into a slli hint)
- instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b001, instr_i[11:7], {OPCODE_OP_IMM}};
- if (instr_i[12] == 1'b1) illegal_instr_o = 1'b1; // reserved for custom extensions
- end
-
- 3'b010: begin
- // c.lwsp -> lw rd, imm(x2)
- instr_o = {4'b0, instr_i[3:2], instr_i[12], instr_i[6:4], 2'b00, 5'h02,
- 3'b010, instr_i[11:7], OPCODE_LOAD};
- if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
- end
-
- 3'b100: begin
- if (instr_i[12] == 1'b0) begin
- if (instr_i[6:2] != 5'b0) begin
- // c.mv -> add rd/rs1, x0, rs2
- // (c.mv hints are translated into an add hint)
- instr_o = {7'b0, instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], {OPCODE_OP}};
- end else begin
- // c.jr -> jalr x0, rd/rs1, 0
- instr_o = {12'b0, instr_i[11:7], 3'b0, 5'b0, {OPCODE_JALR}};
- if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
- end
- end else begin
- if (instr_i[6:2] != 5'b0) begin
- // c.add -> add rd, rd, rs2
- // (c.add hints are translated into an add hint)
- instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], {OPCODE_OP}};
- end else begin
- if (instr_i[11:7] == 5'b0) begin
- // c.ebreak -> ebreak
- instr_o = {32'h00_10_00_73};
- end else begin
- // c.jalr -> jalr x1, rs1, 0
- instr_o = {12'b0, instr_i[11:7], 3'b000, 5'b00001, {OPCODE_JALR}};
- end
- end
- end
- end
-
- 3'b110: begin
- // c.swsp -> sw rs2, imm(x2)
- instr_o = {4'b0, instr_i[8:7], instr_i[12], instr_i[6:2], 5'h02, 3'b010,
- instr_i[11:9], 2'b00, {OPCODE_STORE}};
- end
-
- 3'b001,
- 3'b011,
- 3'b101,
- 3'b111: begin
- illegal_instr_o = 1'b1;
- end
-
- // default: begin
- // illegal_instr_o = 1'b1;
- // end
- endcase
- end
-
- // Incoming instruction is not compressed.
- 2'b11:;
-
- // default: begin
- // illegal_instr_o = 1'b1;
- // end
- endcase
- end
-
- assign is_compressed_o = (instr_i[1:0] != 2'b11);
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/brq_ifu_dummy_instr.sv b/verilog/rtl/brq_ifu_dummy_instr.sv
deleted file mode 100644
index 91bec36..0000000
--- a/verilog/rtl/brq_ifu_dummy_instr.sv
+++ /dev/null
@@ -1,141 +0,0 @@
-
-
-/**
- * Dummy instruction module
- *
- * Provides pseudo-randomly inserted fake instructions for secure code obfuscation
- */
-
-module brq_ifu_dummy_instr (
- // Clock and reset
- input logic clk_i,
- input logic rst_ni,
-
- // Interface to CSRs
- input logic dummy_instr_en_i,
- input logic [2:0] dummy_instr_mask_i,
- input logic dummy_instr_seed_en_i,
- input logic [31:0] dummy_instr_seed_i,
-
- // Interface to IF stage
- input logic fetch_valid_i,
- input logic id_in_ready_i,
- output logic insert_dummy_instr_o,
- output logic [31:0] dummy_instr_data_o
-);
-
- localparam int unsigned TIMEOUT_CNT_W = 5;
- localparam int unsigned OP_W = 5;
-
- typedef enum logic [1:0] {
- DUMMY_ADD = 2'b00,
- DUMMY_MUL = 2'b01,
- DUMMY_DIV = 2'b10,
- DUMMY_AND = 2'b11
- } dummy_instr_e;
-
- typedef struct packed {
- dummy_instr_e instr_type;
- logic [OP_W-1:0] op_b;
- logic [OP_W-1:0] op_a;
- logic [TIMEOUT_CNT_W-1:0] cnt;
- } lfsr_data_t;
- localparam int unsigned LFSR_OUT_W = $bits(lfsr_data_t);
-
- lfsr_data_t lfsr_data;
- logic [TIMEOUT_CNT_W-1:0] dummy_cnt_incr, dummy_cnt_threshold;
- logic [TIMEOUT_CNT_W-1:0] dummy_cnt_d, dummy_cnt_q;
- logic dummy_cnt_en;
- logic lfsr_en;
- logic [LFSR_OUT_W-1:0] lfsr_state;
- logic insert_dummy_instr;
- logic [6:0] dummy_set;
- logic [2:0] dummy_opcode;
- logic [31:0] dummy_instr;
- logic [31:0] dummy_instr_seed_q, dummy_instr_seed_d;
-
- // Shift the LFSR every time we insert an instruction
- assign lfsr_en = insert_dummy_instr & id_in_ready_i;
-
- assign dummy_instr_seed_d = dummy_instr_seed_q ^ dummy_instr_seed_i;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- dummy_instr_seed_q <= '0;
- end else if (dummy_instr_seed_en_i) begin
- dummy_instr_seed_q <= dummy_instr_seed_d;
- end
- end
-
- prim_lfsr #(
- .LfsrDw ( 32 ),
- .StateOutDw ( LFSR_OUT_W )
- ) lfsr_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
- .seed_en_i ( dummy_instr_seed_en_i ),
- .seed_i ( dummy_instr_seed_d ),
- .lfsr_en_i ( lfsr_en ),
- .entropy_i ( '0 ),
- .state_o ( lfsr_state )
- );
-
- // Extract fields from LFSR
- assign lfsr_data = lfsr_data_t'(lfsr_state);
-
- // Set count threshold for inserting a new instruction. This is the pseudo-random value from the
- // LFSR with a mask applied (based on CSR config data) to shorten the period if required.
- assign dummy_cnt_threshold = lfsr_data.cnt & {dummy_instr_mask_i,{TIMEOUT_CNT_W-3{1'b1}}};
- assign dummy_cnt_incr = dummy_cnt_q + {{TIMEOUT_CNT_W-1{1'b0}},1'b1};
- // Clear the counter everytime a new instruction is inserted
- assign dummy_cnt_d = insert_dummy_instr ? '0 : dummy_cnt_incr;
- // Increment the counter for each executed instruction while dummy instuctions are
- // enabled.
- assign dummy_cnt_en = dummy_instr_en_i & id_in_ready_i &
- (fetch_valid_i | insert_dummy_instr);
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- dummy_cnt_q <= '0;
- end else if (dummy_cnt_en) begin
- dummy_cnt_q <= dummy_cnt_d;
- end
- end
-
- // Insert a dummy instruction each time the counter hits the threshold
- assign insert_dummy_instr = dummy_instr_en_i & (dummy_cnt_q == dummy_cnt_threshold);
-
- // Encode instruction
- always_comb begin
- unique case (lfsr_data.instr_type)
- DUMMY_ADD : begin
- dummy_set = 7'b0000000;
- dummy_opcode = 3'b000;
- end
- DUMMY_MUL : begin
- dummy_set = 7'b0000001;
- dummy_opcode = 3'b000;
- end
- DUMMY_DIV : begin
- dummy_set = 7'b0000001;
- dummy_opcode = 3'b100;
- end
- DUMMY_AND : begin
- dummy_set = 7'b0000000;
- dummy_opcode = 3'b111;
- end
- default : begin
- dummy_set = 7'b0000000;
- dummy_opcode = 3'b000;
- end
- endcase
- end
-
- // SET RS2 RS1 OP RD
- assign dummy_instr = {dummy_set,lfsr_data.op_b,lfsr_data.op_a,dummy_opcode,5'h00,7'h33};
-
- // Assign outputs
- assign insert_dummy_instr_o = insert_dummy_instr;
- assign dummy_instr_data_o = dummy_instr;
-
-endmodule
diff --git a/verilog/rtl/brq_ifu_fifo.sv b/verilog/rtl/brq_ifu_fifo.sv
deleted file mode 100644
index 09bb06c..0000000
--- a/verilog/rtl/brq_ifu_fifo.sv
+++ /dev/null
@@ -1,237 +0,0 @@
-
-
-/**
- * Fetch Fifo for 32 bit memory interface
- *
- * input port: send address and data to the FIFO
- * clear_i clears the FIFO for the following cycle, including any new request
- */
-
-
-
-module brq_ifu_fifo #(
- parameter int unsigned NUM_REQS = 2
-) (
- input logic clk_i,
- input logic rst_ni,
-
- // control signals
- input logic clear_i, // clears the contents of the FIFO
- output logic [NUM_REQS-1:0] busy_o,
-
- // input port
- input logic in_valid_i,
- input logic [31:0] in_addr_i,
- input logic [31:0] in_rdata_i,
- input logic in_err_i,
-
- // output port
- output logic out_valid_o,
- input logic out_ready_i,
- output logic [31:0] out_addr_o,
- output logic [31:0] out_addr_next_o,
- output logic [31:0] out_rdata_o,
- output logic out_err_o,
- output logic out_err_plus2_o
-);
-
- localparam int unsigned DEPTH = NUM_REQS+1;
-
- // index 0 is used for output
- logic [DEPTH-1:0] [31:0] rdata_d, rdata_q;
- logic [DEPTH-1:0] err_d, err_q;
- logic [DEPTH-1:0] valid_d, valid_q;
- logic [DEPTH-1:0] lowest_free_entry;
- logic [DEPTH-1:0] valid_pushed, valid_popped;
- logic [DEPTH-1:0] entry_en;
-
- logic pop_fifo;
- logic [31:0] rdata, rdata_unaligned;
- logic err, err_unaligned, err_plus2;
- logic valid, valid_unaligned;
-
- logic aligned_is_compressed, unaligned_is_compressed;
-
- logic addr_incr_two;
- logic [31:1] instr_addr_next;
- logic [31:1] instr_addr_d, instr_addr_q;
- logic instr_addr_en;
- logic unused_addr_in;
-
- /////////////////
- // Output port //
- /////////////////
-
- assign rdata = valid_q[0] ? rdata_q[0] : in_rdata_i;
- assign err = valid_q[0] ? err_q[0] : in_err_i;
- assign valid = valid_q[0] | in_valid_i;
-
- // The FIFO contains word aligned memory fetches, but the instructions contained in each entry
- // might be half-word aligned (due to compressed instructions)
- // e.g.
- // | 31 16 | 15 0 |
- // FIFO entry 0 | Instr 1 [15:0] | Instr 0 [15:0] |
- // FIFO entry 1 | Instr 2 [15:0] | Instr 1 [31:16] |
- //
- // The FIFO also has a direct bypass path, so a complete instruction might be made up of data
- // from the FIFO and new incoming data.
- //
-
- // Construct the output data for an unaligned instruction
- assign rdata_unaligned = valid_q[1] ? {rdata_q[1][15:0], rdata[31:16]} :
- {in_rdata_i[15:0], rdata[31:16]};
-
- // If entry[1] is valid, an error can come from entry[0] or entry[1], unless the
- // instruction in entry[0] is compressed (entry[1] is a new instruction)
- // If entry[1] is not valid, and entry[0] is, an error can come from entry[0] or the incoming
- // data, unless the instruction in entry[0] is compressed
- // If entry[0] is not valid, the error must come from the incoming data
- assign err_unaligned = valid_q[1] ? ((err_q[1] & ~unaligned_is_compressed) | err_q[0]) :
- ((valid_q[0] & err_q[0]) |
- (in_err_i & (~valid_q[0] | ~unaligned_is_compressed)));
-
- // Record when an error is caused by the second half of an unaligned 32bit instruction.
- // Only needs to be correct when unaligned and if err_unaligned is set
- assign err_plus2 = valid_q[1] ? (err_q[1] & ~err_q[0]) :
- (in_err_i & valid_q[0] & ~err_q[0]);
-
- // An uncompressed unaligned instruction is only valid if both parts are available
- assign valid_unaligned = valid_q[1] ? 1'b1 :
- (valid_q[0] & in_valid_i);
-
- // If there is an error, rdata is unknown
- assign unaligned_is_compressed = (rdata[17:16] != 2'b11) & ~err;
- assign aligned_is_compressed = (rdata[ 1: 0] != 2'b11) & ~err;
-
- ////////////////////////////////////////
- // Instruction aligner (if unaligned) //
- ////////////////////////////////////////
-
- always_comb begin
- if (out_addr_o[1]) begin
- // unaligned case
- out_rdata_o = rdata_unaligned;
- out_err_o = err_unaligned;
- out_err_plus2_o = err_plus2;
-
- if (unaligned_is_compressed) begin
- out_valid_o = valid;
- end else begin
- out_valid_o = valid_unaligned;
- end
- end else begin
- // aligned case
- out_rdata_o = rdata;
- out_err_o = err;
- out_err_plus2_o = 1'b0;
- out_valid_o = valid;
- end
- end
-
- /////////////////////////
- // Instruction address //
- /////////////////////////
-
- // Update the address on branches and every time an instruction is driven
- assign instr_addr_en = clear_i | (out_ready_i & out_valid_o);
-
- // Increment the address by two every time a compressed instruction is popped
- assign addr_incr_two = instr_addr_q[1] ? unaligned_is_compressed :
- aligned_is_compressed;
-
- assign instr_addr_next = (instr_addr_q[31:1] +
- // Increment address by 4 or 2
- {29'd0,~addr_incr_two,addr_incr_two});
-
- assign instr_addr_d = clear_i ? in_addr_i[31:1] :
- instr_addr_next;
-
- always_ff @(posedge clk_i) begin
- if (instr_addr_en) begin
- instr_addr_q <= instr_addr_d;
- end
- end
-
- // Output both PC of current instruction and instruction following. PC of instruction following is
- // required for the branch predictor. It's used to fetch the instruction following a branch that
- // was not-taken but (mis)predicted taken.
- assign out_addr_next_o = {instr_addr_next, 1'b0};
- assign out_addr_o = {instr_addr_q, 1'b0};
-
- // The LSB of the address is unused, since all addresses are halfword aligned
- assign unused_addr_in = in_addr_i[0];
-
- /////////////////
- // FIFO status //
- /////////////////
-
- // Indicate the fill level of fifo-entries. This is used to determine when a new request can be
- // made on the bus. The prefetch buffer only needs to know about the upper entries which overlap
- // with NUM_REQS.
- assign busy_o = valid_q[DEPTH-1:DEPTH-NUM_REQS];
-
- /////////////////////
- // FIFO management //
- /////////////////////
-
- // Since an entry can contain unaligned instructions, popping an entry can leave the entry valid
- assign pop_fifo = out_ready_i & out_valid_o & (~aligned_is_compressed | out_addr_o[1]);
-
- for (genvar i = 0; i < (DEPTH - 1); i++) begin : g_fifo_next
- // Calculate lowest free entry (write pointer)
- if (i == 0) begin : g_ent0
- assign lowest_free_entry[i] = ~valid_q[i];
- end else begin : g_ent_others
- assign lowest_free_entry[i] = ~valid_q[i] & valid_q[i-1];
- end
-
- // An entry is set when an incoming request chooses the lowest available entry
- assign valid_pushed[i] = (in_valid_i & lowest_free_entry[i]) |
- valid_q[i];
- // Popping the FIFO shifts all entries down
- assign valid_popped[i] = pop_fifo ? valid_pushed[i+1] : valid_pushed[i];
- // All entries are wiped out on a clear
- assign valid_d[i] = valid_popped[i] & ~clear_i;
-
- // data flops are enabled if there is new data to shift into it, or
- assign entry_en[i] = (valid_pushed[i+1] & pop_fifo) |
- // a new request is incoming and this is the lowest free entry
- (in_valid_i & lowest_free_entry[i] & ~pop_fifo);
-
- // take the next entry or the incoming data
- assign rdata_d[i] = valid_q[i+1] ? rdata_q[i+1] : in_rdata_i;
- assign err_d [i] = valid_q[i+1] ? err_q [i+1] : in_err_i;
- end
- // The top entry is similar but with simpler muxing
- assign lowest_free_entry[DEPTH-1] = ~valid_q[DEPTH-1] & valid_q[DEPTH-2];
- assign valid_pushed [DEPTH-1] = valid_q[DEPTH-1] | (in_valid_i & lowest_free_entry[DEPTH-1]);
- assign valid_popped [DEPTH-1] = pop_fifo ? 1'b0 : valid_pushed[DEPTH-1];
- assign valid_d [DEPTH-1] = valid_popped[DEPTH-1] & ~clear_i;
- assign entry_en[DEPTH-1] = in_valid_i & lowest_free_entry[DEPTH-1];
- assign rdata_d [DEPTH-1] = in_rdata_i;
- assign err_d [DEPTH-1] = in_err_i;
-
- ////////////////////
- // FIFO registers //
- ////////////////////
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- valid_q <= '0;
- end else begin
- valid_q <= valid_d;
- end
- end
-
- for (genvar i = 0; i < DEPTH; i++) begin : g_fifo_regs
- always_ff @(posedge clk_i) begin
- if (entry_en[i]) begin
- rdata_q[i] <= rdata_d[i];
- err_q[i] <= err_d[i];
- end
- end
- end
-
-
-
-endmodule
diff --git a/verilog/rtl/brq_ifu_icache.sv b/verilog/rtl/brq_ifu_icache.sv
deleted file mode 100644
index 51a998c..0000000
--- a/verilog/rtl/brq_ifu_icache.sv
+++ /dev/null
@@ -1,1052 +0,0 @@
-
-
-/**
- * Instruction cache
- *
- * Provides an instruction cache along with cache management, instruction buffering and prefetching
- */
-
-module brq_ifu_icache #(
- parameter bit BranchPredictor = 1'b0,
- // Cache arrangement parameters
- parameter int unsigned BusWidth = 32,
- parameter int unsigned CacheSizeBytes = 4*1024,
- parameter bit ICacheECC = 1'b0,
- parameter int unsigned LineSize = 64,
- parameter int unsigned NumWays = 2,
- // Only cache branch targets
- parameter bit BranchCache = 1'b0
-) (
- // Clock and reset
- input logic clk_i,
- input logic rst_ni,
-
- // Signal that the core would like instructions
- input logic req_i,
-
- // Set the cache's address counter
- input logic branch_i,
- input logic branch_spec_i,
- input logic predicted_branch_i,
- input logic branch_mispredict_i,
- input logic [31:0] addr_i,
-
- // IF stage interface: Pass fetched instructions to the core
- input logic ready_i,
- output logic valid_o,
- output logic [31:0] rdata_o,
- output logic [31:0] addr_o,
- output logic err_o,
- output logic err_plus2_o,
-
- // Instruction memory / interconnect interface: Fetch instruction data from memory
- output logic instr_req_o,
- input logic instr_gnt_i,
- output logic [31:0] instr_addr_o,
- input logic [BusWidth-1:0] instr_rdata_i,
- input logic instr_err_i,
- input logic instr_pmp_err_i,
- input logic instr_rvalid_i,
-
- // Cache status
- input logic icache_enable_i,
- input logic icache_inval_i,
- output logic busy_o
-);
- // Local constants
- localparam int unsigned ADDR_W = 32;
- // Number of fill buffers (must be >= 2)
- localparam int unsigned NUM_FB = 4;
- // Request throttling threshold
- localparam int unsigned FB_THRESHOLD = NUM_FB - 2;
- // Derived parameters
- localparam int unsigned LINE_SIZE_ECC = ICacheECC ? (LineSize + 8) : LineSize;
- localparam int unsigned LINE_SIZE_BYTES = LineSize/8;
- localparam int unsigned LINE_W = $clog2(LINE_SIZE_BYTES);
- localparam int unsigned BUS_BYTES = BusWidth/8;
- localparam int unsigned BUS_W = $clog2(BUS_BYTES);
- localparam int unsigned LINE_BEATS = LINE_SIZE_BYTES / BUS_BYTES;
- localparam int unsigned LINE_BEATS_W = $clog2(LINE_BEATS);
- localparam int unsigned NUM_LINES = CacheSizeBytes / NumWays / LINE_SIZE_BYTES;
- localparam int unsigned INDEX_W = $clog2(NUM_LINES);
- localparam int unsigned INDEX_HI = INDEX_W + LINE_W - 1;
- localparam int unsigned TAG_SIZE = ADDR_W - INDEX_W - LINE_W + 1; // 1 valid bit
- localparam int unsigned TAG_SIZE_ECC = ICacheECC ? (TAG_SIZE + 6) : TAG_SIZE;
- localparam int unsigned OUTPUT_BEATS = (BUS_BYTES / 2); // number of halfwords
-
- // Prefetch signals
- logic [ADDR_W-1:0] lookup_addr_aligned;
- logic [ADDR_W-1:0] branch_mispredict_addr;
- logic [ADDR_W-1:0] prefetch_addr_d, prefetch_addr_q;
- logic prefetch_addr_en;
- logic branch_or_mispredict;
- // Cache pipelipe IC0 signals
- logic branch_suppress;
- logic lookup_throttle;
- logic lookup_req_ic0;
- logic [ADDR_W-1:0] lookup_addr_ic0;
- logic [INDEX_W-1:0] lookup_index_ic0;
- logic fill_req_ic0;
- logic [INDEX_W-1:0] fill_index_ic0;
- logic [TAG_SIZE-1:0] fill_tag_ic0;
- logic [LineSize-1:0] fill_wdata_ic0;
- logic lookup_grant_ic0;
- logic lookup_actual_ic0;
- logic fill_grant_ic0;
- logic tag_req_ic0;
- logic [INDEX_W-1:0] tag_index_ic0;
- logic [NumWays-1:0] tag_banks_ic0;
- logic tag_write_ic0;
- logic [TAG_SIZE_ECC-1:0] tag_wdata_ic0;
- logic data_req_ic0;
- logic [INDEX_W-1:0] data_index_ic0;
- logic [NumWays-1:0] data_banks_ic0;
- logic data_write_ic0;
- logic [LINE_SIZE_ECC-1:0] data_wdata_ic0;
- // Cache pipelipe IC1 signals
- logic [TAG_SIZE_ECC-1:0] tag_rdata_ic1 [NumWays];
- logic [LINE_SIZE_ECC-1:0] data_rdata_ic1 [NumWays];
- logic [LINE_SIZE_ECC-1:0] hit_data_ic1;
- logic lookup_valid_ic1;
- logic [ADDR_W-1:INDEX_HI+1] lookup_addr_ic1;
- logic [NumWays-1:0] tag_match_ic1;
- logic tag_hit_ic1;
- logic [NumWays-1:0] tag_invalid_ic1;
- logic [NumWays-1:0] lowest_invalid_way_ic1;
- logic [NumWays-1:0] round_robin_way_ic1, round_robin_way_q;
- logic [NumWays-1:0] sel_way_ic1;
- logic ecc_err_ic1;
- logic ecc_write_req;
- logic [NumWays-1:0] ecc_write_ways;
- logic [INDEX_W-1:0] ecc_write_index;
- // Fill buffer signals
- logic gnt_or_pmp_err, gnt_not_pmp_err;
- logic [$clog2(NUM_FB)-1:0] fb_fill_level;
- logic fill_cache_new;
- logic fill_new_alloc;
- logic fill_spec_req, fill_spec_done, fill_spec_hold;
- logic [NUM_FB-1:0][NUM_FB-1:0] fill_older_d, fill_older_q;
- logic [NUM_FB-1:0] fill_alloc_sel, fill_alloc;
- logic [NUM_FB-1:0] fill_busy_d, fill_busy_q;
- logic [NUM_FB-1:0] fill_done;
- logic [NUM_FB-1:0] fill_in_ic1;
- logic [NUM_FB-1:0] fill_stale_d, fill_stale_q;
- logic [NUM_FB-1:0] fill_cache_d, fill_cache_q;
- logic [NUM_FB-1:0] fill_hit_ic1, fill_hit_d, fill_hit_q;
- logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_ext_cnt_d, fill_ext_cnt_q;
- logic [NUM_FB-1:0] fill_ext_hold_d, fill_ext_hold_q;
- logic [NUM_FB-1:0] fill_ext_done_d, fill_ext_done_q;
- logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_rvd_cnt_d, fill_rvd_cnt_q;
- logic [NUM_FB-1:0] fill_rvd_done;
- logic [NUM_FB-1:0] fill_ram_done_d, fill_ram_done_q;
- logic [NUM_FB-1:0] fill_out_grant;
- logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_out_cnt_d, fill_out_cnt_q;
- logic [NUM_FB-1:0] fill_out_done;
- logic [NUM_FB-1:0] fill_ext_req, fill_rvd_exp, fill_ram_req, fill_out_req;
- logic [NUM_FB-1:0] fill_data_sel, fill_data_reg, fill_data_hit, fill_data_rvd;
- logic [NUM_FB-1:0][LINE_BEATS_W-1:0] fill_ext_off, fill_rvd_off;
- logic [NUM_FB-1:0][LINE_BEATS_W:0] fill_ext_beat, fill_rvd_beat;
- logic [NUM_FB-1:0] fill_ext_arb, fill_ram_arb, fill_out_arb;
- logic [NUM_FB-1:0] fill_rvd_arb;
- logic [NUM_FB-1:0] fill_entry_en;
- logic [NUM_FB-1:0] fill_addr_en;
- logic [NUM_FB-1:0] fill_way_en;
- logic [NUM_FB-1:0][LINE_BEATS-1:0] fill_data_en;
- logic [NUM_FB-1:0][LINE_BEATS-1:0] fill_err_d, fill_err_q;
- logic [ADDR_W-1:0] fill_addr_q [NUM_FB];
- logic [NumWays-1:0] fill_way_q [NUM_FB];
- logic [LineSize-1:0] fill_data_d [NUM_FB];
- logic [LineSize-1:0] fill_data_q [NUM_FB];
- logic [ADDR_W-1:BUS_W] fill_ext_req_addr;
- logic [ADDR_W-1:0] fill_ram_req_addr;
- logic [NumWays-1:0] fill_ram_req_way;
- logic [LineSize-1:0] fill_ram_req_data;
- logic [LineSize-1:0] fill_out_data;
- logic [LINE_BEATS-1:0] fill_out_err;
- // External req signals
- logic instr_req;
- logic [ADDR_W-1:BUS_W] instr_addr;
- // Data output signals
- logic skid_complete_instr;
- logic skid_ready;
- logic output_compressed;
- logic skid_valid_d, skid_valid_q, skid_en;
- logic [15:0] skid_data_d, skid_data_q;
- logic skid_err_q;
- logic output_valid;
- logic addr_incr_two;
- logic output_addr_en;
- logic [ADDR_W-1:1] output_addr_incr;
- logic [ADDR_W-1:1] output_addr_d, output_addr_q;
- logic [15:0] output_data_lo, output_data_hi;
- logic data_valid, output_ready;
- logic [LineSize-1:0] line_data;
- logic [LINE_BEATS-1:0] line_err;
- logic [31:0] line_data_muxed;
- logic line_err_muxed;
- logic [31:0] output_data;
- logic output_err;
- // Invalidations
- logic start_inval, inval_done;
- logic reset_inval_q;
- logic inval_prog_d, inval_prog_q;
- logic [INDEX_W-1:0] inval_index_d, inval_index_q;
-
- //////////////////////////
- // Instruction prefetch //
- //////////////////////////
-
- if (BranchPredictor) begin : g_branch_predictor
- // Where the branch predictor is present record what address followed a predicted branch. If
- // that branch is predicted taken but mispredicted (so not-taken) this is used to resume on
- // the not-taken code path.
- logic [31:0] branch_mispredict_addr_q;
- logic branch_mispredict_addr_en;
-
- assign branch_mispredict_addr_en = branch_i & predicted_branch_i;
-
- always_ff @(posedge clk_i) begin
- if (branch_mispredict_addr_en) begin
- branch_mispredict_addr_q <= {output_addr_incr, 1'b0};
- end
- end
-
- assign branch_mispredict_addr = branch_mispredict_addr_q;
-
- end else begin : g_no_branch_predictor
- logic unused_predicted_branch;
-
- assign unused_predicted_branch = predicted_branch_i;
-
- assign branch_mispredict_addr = '0;
- end
-
- assign branch_or_mispredict = branch_i | branch_mispredict_i;
-
- assign lookup_addr_aligned = {lookup_addr_ic0[ADDR_W-1:LINE_W],{LINE_W{1'b0}}};
-
- // The prefetch address increments by one cache line for each granted request.
- // This address is also updated if there is a branch that is not granted, since the target
- // address (addr_i) is only valid for one cycle while branch_i is high.
-
- // The captured branch target address is not forced to be aligned since the offset in the cache
- // line must also be recorded for later use by the fill buffers.
- assign prefetch_addr_d =
- lookup_grant_ic0 ? (lookup_addr_aligned + {{ADDR_W-LINE_W-1{1'b0}},1'b1,{LINE_W{1'b0}}}) :
- branch_i ? addr_i :
- branch_mispredict_addr;
-
- assign prefetch_addr_en = branch_or_mispredict | lookup_grant_ic0;
-
- always_ff @(posedge clk_i) begin
- if (prefetch_addr_en) begin
- prefetch_addr_q <= prefetch_addr_d;
- end
- end
-
- ////////////////////////
- // Pipeline stage IC0 //
- ////////////////////////
-
- // Cache lookup
- assign lookup_throttle = (fb_fill_level > FB_THRESHOLD[$clog2(NUM_FB)-1:0]);
-
- assign lookup_req_ic0 = req_i & ~&fill_busy_q & (branch_or_mispredict | ~lookup_throttle) &
- ~ecc_write_req;
- assign lookup_addr_ic0 = branch_spec_i ? addr_i :
- branch_mispredict_i ? branch_mispredict_addr :
- prefetch_addr_q;
- assign lookup_index_ic0 = lookup_addr_ic0[INDEX_HI:LINE_W];
-
- // Cache write
- assign fill_req_ic0 = (|fill_ram_req);
- assign fill_index_ic0 = fill_ram_req_addr[INDEX_HI:LINE_W];
- assign fill_tag_ic0 = {(~inval_prog_q & ~ecc_write_req),fill_ram_req_addr[ADDR_W-1:INDEX_HI+1]};
- assign fill_wdata_ic0 = fill_ram_req_data;
-
- // Suppress a new lookup on a not-taken branch (as the address will be incorrect)
- assign branch_suppress = branch_spec_i & ~branch_i;
-
- // Arbitrated signals - lookups have highest priority
- assign lookup_grant_ic0 = lookup_req_ic0 & ~branch_suppress;
- assign fill_grant_ic0 = fill_req_ic0 & (~lookup_req_ic0 | branch_suppress) & ~inval_prog_q &
- ~ecc_write_req;
- // Qualified lookup grant to mask ram signals in IC1 if access was not made
- assign lookup_actual_ic0 = lookup_grant_ic0 & icache_enable_i & ~inval_prog_q & ~start_inval;
-
- // Tagram
- assign tag_req_ic0 = lookup_req_ic0 | fill_req_ic0 | inval_prog_q | ecc_write_req;
- assign tag_index_ic0 = inval_prog_q ? inval_index_q :
- ecc_write_req ? ecc_write_index :
- fill_grant_ic0 ? fill_index_ic0 :
- lookup_index_ic0;
- assign tag_banks_ic0 = ecc_write_req ? ecc_write_ways :
- fill_grant_ic0 ? fill_ram_req_way :
- {NumWays{1'b1}};
- assign tag_write_ic0 = fill_grant_ic0 | inval_prog_q | ecc_write_req;
-
- // Dataram
- assign data_req_ic0 = lookup_req_ic0 | fill_req_ic0;
- assign data_index_ic0 = tag_index_ic0;
- assign data_banks_ic0 = tag_banks_ic0;
- assign data_write_ic0 = tag_write_ic0;
-
- // Append ECC checkbits to write data if required
- if (ICacheECC) begin : gen_ecc_wdata
-
- // Tagram ECC
- // Reuse the same ecc encoding module for larger cache sizes by padding with zeros
- logic [21:0] tag_ecc_input_padded;
- logic [27:0] tag_ecc_output_padded;
- logic [22-TAG_SIZE:0] tag_ecc_output_unused;
-
- assign tag_ecc_input_padded = {{22-TAG_SIZE{1'b0}},fill_tag_ic0};
- assign tag_ecc_output_unused = tag_ecc_output_padded[21:TAG_SIZE-1];
-
- prim_secded_28_22_enc tag_ecc_enc (
- .in (tag_ecc_input_padded),
- .out (tag_ecc_output_padded)
- );
-
- assign tag_wdata_ic0 = {tag_ecc_output_padded[27:22],tag_ecc_output_padded[TAG_SIZE-1:0]};
-
- // Dataram ECC
- prim_secded_72_64_enc data_ecc_enc (
- .in (fill_wdata_ic0),
- .out (data_wdata_ic0)
- );
-
- end else begin : gen_noecc_wdata
- assign tag_wdata_ic0 = fill_tag_ic0;
- assign data_wdata_ic0 = fill_wdata_ic0;
- end
-
- ////////////////
- // IC0 -> IC1 //
- ////////////////
-
- for (genvar way = 0; way < NumWays; way++) begin : gen_rams
- // Tag RAM instantiation
- prim_ram_1p #(
- .Width (TAG_SIZE_ECC),
- .Depth (NUM_LINES),
- .DataBitsPerMask (TAG_SIZE_ECC)
- ) tag_bank (
- .clk_i (clk_i),
- .req_i (tag_req_ic0 & tag_banks_ic0[way]),
- .write_i (tag_write_ic0),
- .wmask_i ({TAG_SIZE_ECC{1'b1}}),
- .addr_i (tag_index_ic0),
- .wdata_i (tag_wdata_ic0),
- .rdata_o (tag_rdata_ic1[way])
- );
- // Data RAM instantiation
- prim_ram_1p #(
- .Width (LINE_SIZE_ECC),
- .Depth (NUM_LINES),
- .DataBitsPerMask (LINE_SIZE_ECC)
- ) data_bank (
- .clk_i (clk_i),
- .req_i (data_req_ic0 & data_banks_ic0[way]),
- .write_i (data_write_ic0),
- .wmask_i ({LINE_SIZE_ECC{1'b1}}),
- .addr_i (data_index_ic0),
- .wdata_i (data_wdata_ic0),
- .rdata_o (data_rdata_ic1[way])
- );
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- lookup_valid_ic1 <= 1'b0;
- end else begin
- lookup_valid_ic1 <= lookup_actual_ic0;
- end
- end
-
- always_ff @(posedge clk_i) begin
- if (lookup_grant_ic0) begin
- lookup_addr_ic1 <= lookup_addr_ic0[ADDR_W-1:INDEX_HI+1];
- fill_in_ic1 <= fill_alloc_sel;
- end
- end
-
- ////////////////////////
- // Pipeline stage IC1 //
- ////////////////////////
-
- // Tag matching
- for (genvar way = 0; way < NumWays; way++) begin : gen_tag_match
- assign tag_match_ic1[way] = (tag_rdata_ic1[way][TAG_SIZE-1:0] ==
- {1'b1,lookup_addr_ic1[ADDR_W-1:INDEX_HI+1]});
- assign tag_invalid_ic1[way] = ~tag_rdata_ic1[way][TAG_SIZE-1];
- end
-
- assign tag_hit_ic1 = |tag_match_ic1;
-
- // Hit data mux
- always_comb begin
- hit_data_ic1 = 'b0;
- for (int way = 0; way < NumWays; way++) begin
- if (tag_match_ic1[way]) begin
- hit_data_ic1 |= data_rdata_ic1[way];
- end
- end
- end
-
- // Way selection for allocations to the cache (onehot signals)
- // 1 first invalid way
- // 2 global round-robin (pseudorandom) way
- assign lowest_invalid_way_ic1[0] = tag_invalid_ic1[0];
- assign round_robin_way_ic1[0] = round_robin_way_q[NumWays-1];
- for (genvar way = 1; way < NumWays; way++) begin : gen_lowest_way
- assign lowest_invalid_way_ic1[way] = tag_invalid_ic1[way] & ~|tag_invalid_ic1[way-1:0];
- assign round_robin_way_ic1[way] = round_robin_way_q[way-1];
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- round_robin_way_q <= {{NumWays-1{1'b0}},1'b1};
- end else if (lookup_valid_ic1) begin
- round_robin_way_q <= round_robin_way_ic1;
- end
- end
-
- assign sel_way_ic1 = |tag_invalid_ic1 ? lowest_invalid_way_ic1 :
- round_robin_way_q;
-
- // ECC checking logic
- if (ICacheECC) begin : gen_data_ecc_checking
- logic [NumWays-1:0] tag_err_ic1;
- logic [1:0] data_err_ic1;
- logic ecc_correction_write_d, ecc_correction_write_q;
- logic [NumWays-1:0] ecc_correction_ways_d, ecc_correction_ways_q;
- logic [INDEX_W-1:0] lookup_index_ic1, ecc_correction_index_q;
-
- // Tag ECC checking
- for (genvar way = 0; way < NumWays; way++) begin : gen_tag_ecc
- logic [1:0] tag_err_bank_ic1;
- logic [27:0] tag_rdata_padded_ic1;
-
- // Expand the tag rdata with extra padding if the tag size is less than the maximum
- assign tag_rdata_padded_ic1 = {tag_rdata_ic1[way][TAG_SIZE_ECC-1-:6],
- {22-TAG_SIZE{1'b0}},
- tag_rdata_ic1[way][TAG_SIZE-1:0]};
-
- prim_secded_28_22_dec data_ecc_dec (
- .in (tag_rdata_padded_ic1),
- .d_o (),
- .syndrome_o (),
- .err_o (tag_err_bank_ic1)
- );
- assign tag_err_ic1[way] = |tag_err_bank_ic1;
- end
-
- // Data ECC checking
- // Note - could generate for all ways and mux after
- prim_secded_72_64_dec data_ecc_dec (
- .in (hit_data_ic1),
- .d_o (),
- .syndrome_o (),
- .err_o (data_err_ic1)
- );
-
- assign ecc_err_ic1 = lookup_valid_ic1 & ((|data_err_ic1) | (|tag_err_ic1));
-
- // Error correction
- // All ways will be invalidated on a tag error to prevent X-propagation from data_err_ic1 on
- // spurious hits. Also prevents the same line being allocated twice when there was a true
- // hit and a spurious hit.
- assign ecc_correction_ways_d = {NumWays{|tag_err_ic1}} |
- (tag_match_ic1 & {NumWays{|data_err_ic1}});
- assign ecc_correction_write_d = ecc_err_ic1;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- ecc_correction_write_q <= 1'b0;
- end else begin
- ecc_correction_write_q <= ecc_correction_write_d;
- end
- end
-
- // The index is required in IC1 only when ECC is configured so is registered here
- always_ff @(posedge clk_i) begin
- if (lookup_grant_ic0) begin
- lookup_index_ic1 <= lookup_addr_ic0[INDEX_HI-:INDEX_W];
- end
- end
-
- // Store the ways with errors to be invalidated
- always_ff @(posedge clk_i) begin
- if (ecc_err_ic1) begin
- ecc_correction_ways_q <= ecc_correction_ways_d;
- ecc_correction_index_q <= lookup_index_ic1;
- end
- end
-
- assign ecc_write_req = ecc_correction_write_q;
- assign ecc_write_ways = ecc_correction_ways_q;
- assign ecc_write_index = ecc_correction_index_q;
-
- end else begin : gen_no_data_ecc
- assign ecc_err_ic1 = 1'b0;
- assign ecc_write_req = 1'b0;
- assign ecc_write_ways = '0;
- assign ecc_write_index = '0;
- end
-
- ///////////////////////////////
- // Cache allocation decision //
- ///////////////////////////////
-
- if (BranchCache) begin : gen_caching_logic
-
- // Cache branch target + a number of subsequent lines
- localparam int unsigned CACHE_AHEAD = 2;
- localparam int unsigned CACHE_CNT_W = (CACHE_AHEAD == 1) ? 1 : $clog2(CACHE_AHEAD) + 1;
- logic cache_cnt_dec;
- logic [CACHE_CNT_W-1:0] cache_cnt_d, cache_cnt_q;
-
- assign cache_cnt_dec = lookup_grant_ic0 & (|cache_cnt_q);
- assign cache_cnt_d = branch_i ? CACHE_AHEAD[CACHE_CNT_W-1:0] :
- (cache_cnt_q - {{CACHE_CNT_W-1{1'b0}},cache_cnt_dec});
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- cache_cnt_q <= '0;
- end else begin
- cache_cnt_q <= cache_cnt_d;
- end
- end
-
- assign fill_cache_new = (branch_i | (|cache_cnt_q)) & icache_enable_i &
- ~icache_inval_i & ~inval_prog_q;
-
- end else begin : gen_cache_all
-
- // Cache all missing fetches
- assign fill_cache_new = icache_enable_i & ~start_inval & ~inval_prog_q;
- end
-
- //////////////////////////
- // Fill buffer tracking //
- //////////////////////////
-
- always_comb begin
- fb_fill_level = '0;
- for (int i = 0; i < NUM_FB; i++) begin
- if (fill_busy_q[i] & ~fill_stale_q[i]) begin
- fb_fill_level += {{$clog2(NUM_FB)-1{1'b0}},1'b1};
- end
- end
- end
-
- // PMP errors might not / don't need to be granted (since the external request is masked)
- assign gnt_or_pmp_err = instr_gnt_i | instr_pmp_err_i;
- assign gnt_not_pmp_err = instr_gnt_i & ~instr_pmp_err_i;
- // Allocate a new buffer for every granted lookup
- assign fill_new_alloc = lookup_grant_ic0;
- // Track whether a speculative external request was made from IC0, and whether it was granted
- // Speculative requests are only made for branches, or if the cache is disabled
- assign fill_spec_req = (~icache_enable_i | branch_or_mispredict) & ~|fill_ext_req;
- assign fill_spec_done = fill_spec_req & gnt_not_pmp_err;
- assign fill_spec_hold = fill_spec_req & ~gnt_or_pmp_err;
-
- for (genvar fb = 0; fb < NUM_FB; fb++) begin : gen_fbs
-
- /////////////////////////////
- // Fill buffer allocations //
- /////////////////////////////
-
- // Allocate the lowest available buffer
- if (fb == 0) begin : gen_fb_zero
- assign fill_alloc_sel[fb] = ~fill_busy_q[fb];
- end else begin : gen_fb_rest
- assign fill_alloc_sel[fb] = ~fill_busy_q[fb] & (&fill_busy_q[fb-1:0]);
- end
-
- assign fill_alloc[fb] = fill_alloc_sel[fb] & fill_new_alloc;
- assign fill_busy_d[fb] = fill_alloc[fb] | (fill_busy_q[fb] & ~fill_done[fb]);
-
- // Track which other fill buffers are older than this one (for age-based arbitration)
- // TODO sparsify
- assign fill_older_d[fb] = (fill_alloc[fb] ? fill_busy_q : fill_older_q[fb]) & ~fill_done;
-
- // A fill buffer can release once all its actions are completed
- // all data written to the cache (unless hit or error)
- assign fill_done[fb] = (fill_ram_done_q[fb] | fill_hit_q[fb] | ~fill_cache_q[fb] |
- (|fill_err_q[fb])) &
- // all data output unless stale due to intervening branch
- (fill_out_done[fb] | fill_stale_q[fb] | branch_or_mispredict) &
- // all external requests completed
- fill_rvd_done[fb];
-
- /////////////////////////////////
- // Fill buffer status tracking //
- /////////////////////////////////
-
- // Track staleness (requests become stale when a branch intervenes)
- assign fill_stale_d[fb] = fill_busy_q[fb] & (branch_or_mispredict | fill_stale_q[fb]);
- // Track whether or not this request should allocate to the cache
- // Any invalidation or disabling of the cache while the buffer is busy will stop allocation
- assign fill_cache_d[fb] = (fill_alloc[fb] & fill_cache_new) |
- (fill_cache_q[fb] & fill_busy_q[fb] &
- icache_enable_i & ~icache_inval_i);
- // Record whether the request hit in the cache
- assign fill_hit_ic1[fb] = lookup_valid_ic1 & fill_in_ic1[fb] & tag_hit_ic1 & ~ecc_err_ic1;
- assign fill_hit_d[fb] = fill_hit_ic1[fb] | (fill_hit_q[fb] & fill_busy_q[fb]);
-
- ///////////////////////////////////////////
- // Fill buffer external request tracking //
- ///////////////////////////////////////////
-
- // Make an external request
- assign fill_ext_req[fb] = fill_busy_q[fb] & ~fill_ext_done_d[fb];
-
- // Count the number of completed external requests (each line requires LINE_BEATS requests)
- // Don't count fake PMP error grants here since they will never receive an rvalid response
- assign fill_ext_cnt_d[fb] = fill_alloc[fb] ?
- {{LINE_BEATS_W{1'b0}},fill_spec_done} :
- (fill_ext_cnt_q[fb] + {{LINE_BEATS_W{1'b0}},
- fill_ext_arb[fb] & gnt_not_pmp_err});
- // External request must be held until granted
- assign fill_ext_hold_d[fb] = (fill_alloc[fb] & fill_spec_hold) |
- (fill_ext_arb[fb] & ~gnt_or_pmp_err);
- // External requests are completed when the counter is filled or when the request is cancelled
- assign fill_ext_done_d[fb] = (fill_ext_cnt_q[fb][LINE_BEATS_W] |
- // external requests are considered complete if the request hit
- fill_hit_ic1[fb] | fill_hit_q[fb] |
- // external requests will stop once any PMP error is received
- fill_err_q[fb][fill_ext_off[fb]] |
- // cancel if the line won't be cached and, it is stale
- (~fill_cache_q[fb] & (branch_or_mispredict | fill_stale_q[fb] |
- // or we're already at the end of the line
- fill_ext_beat[fb][LINE_BEATS_W]))) &
- // can't cancel while we are waiting for a grant on the bus
- ~fill_ext_hold_q[fb] & fill_busy_q[fb];
- // Track whether this fill buffer expects to receive beats of data
- assign fill_rvd_exp[fb] = fill_busy_q[fb] & ~fill_rvd_done[fb];
- // Count the number of rvalid beats received
- assign fill_rvd_cnt_d[fb] = fill_alloc[fb] ? '0 :
- (fill_rvd_cnt_q[fb] +
- {{LINE_BEATS_W{1'b0}},fill_rvd_arb[fb]});
- // External data is complete when all issued external requests have received their data
- assign fill_rvd_done[fb] = (fill_ext_done_q[fb] & ~fill_ext_hold_q[fb]) &
- (fill_rvd_cnt_q[fb] == fill_ext_cnt_q[fb]);
-
- //////////////////////////////////////
- // Fill buffer data output tracking //
- //////////////////////////////////////
-
- // Send data to the IF stage for requests that are not stale, have not completed their
- // data output, and have data available to send.
- // Data is available if:
- // - The request hit in the cache
- // - The current beat is an error (since a PMP error might not actually receive any data)
- // - Buffered data is available (fill_rvd_cnt_q is ahead of fill_out_cnt_q)
- // - Data is available from the bus this cycle (fill_rvd_arb)
- assign fill_out_req[fb] = fill_busy_q[fb] & ~fill_stale_q[fb] & ~fill_out_done[fb] &
- (fill_hit_ic1[fb] | fill_hit_q[fb] |
- (fill_err_q[fb][fill_out_cnt_q[fb][LINE_BEATS_W-1:0]]) |
- (fill_rvd_beat[fb] > fill_out_cnt_q[fb]) | fill_rvd_arb[fb]);
-
- // Calculate when a beat of data is output. Any ECC error squashes the output that cycle.
- assign fill_out_grant[fb] = fill_out_arb[fb] & output_ready;
-
- // Count the beats of data output to the IF stage
- assign fill_out_cnt_d[fb] = fill_alloc[fb] ? {1'b0,lookup_addr_ic0[LINE_W-1:BUS_W]} :
- (fill_out_cnt_q[fb] +
- {{LINE_BEATS_W{1'b0}},fill_out_grant[fb]});
- // Data output complete when the counter fills
- assign fill_out_done[fb] = fill_out_cnt_q[fb][LINE_BEATS_W];
-
- //////////////////////////////////////
- // Fill buffer ram request tracking //
- //////////////////////////////////////
-
- // make a fill request once all data beats received
- assign fill_ram_req[fb] = fill_busy_q[fb] & fill_rvd_cnt_q[fb][LINE_BEATS_W] &
- // unless the request hit, was non-allocating or got an error
- ~fill_hit_q[fb] & fill_cache_q[fb] & ~|fill_err_q[fb] &
- // or the request was already completed
- ~fill_ram_done_q[fb];
-
- // Record when a cache allocation request has been completed
- assign fill_ram_done_d[fb] = fill_ram_arb[fb] | (fill_ram_done_q[fb] & fill_busy_q[fb]);
-
- //////////////////////////////
- // Fill buffer line offsets //
- //////////////////////////////
-
- // When we branch into the middle of a line, the output count will not start from zero. This
- // beat count is used to know which incoming rdata beats are relevant.
- assign fill_ext_beat[fb] = {1'b0,fill_addr_q[fb][LINE_W-1:BUS_W]} +
- fill_ext_cnt_q[fb][LINE_BEATS_W:0];
- assign fill_ext_off[fb] = fill_ext_beat[fb][LINE_BEATS_W-1:0];
- assign fill_rvd_beat[fb] = {1'b0,fill_addr_q[fb][LINE_W-1:BUS_W]} +
- fill_rvd_cnt_q[fb][LINE_BEATS_W:0];
- assign fill_rvd_off[fb] = fill_rvd_beat[fb][LINE_BEATS_W-1:0];
-
- /////////////////////////////
- // Fill buffer arbitration //
- /////////////////////////////
-
- // Age based arbitration - all these signals are one-hot
- assign fill_ext_arb[fb] = fill_ext_req[fb] & ~|(fill_ext_req & fill_older_q[fb]);
- assign fill_ram_arb[fb] = fill_ram_req[fb] & fill_grant_ic0 & ~|(fill_ram_req & fill_older_q[fb]);
- // Calculate which fill buffer is the oldest one which still needs to output data to IF
- assign fill_data_sel[fb] = ~|(fill_busy_q & ~fill_out_done & ~fill_stale_q &
- fill_older_q[fb]);
- // Arbitrate the request which has data available to send, and is the oldest outstanding
- assign fill_out_arb[fb] = fill_out_req[fb] & fill_data_sel[fb];
- // Assign incoming rvalid data to the oldest fill buffer expecting it
- assign fill_rvd_arb[fb] = instr_rvalid_i & fill_rvd_exp[fb] & ~|(fill_rvd_exp & fill_older_q[fb]);
-
- /////////////////////////////
- // Fill buffer data muxing //
- /////////////////////////////
-
- // Output data muxing controls
- // 1. Select data from the fill buffer data register
- assign fill_data_reg[fb] = fill_busy_q[fb] & ~fill_stale_q[fb] &
- ~fill_out_done[fb] & fill_data_sel[fb] &
- // The incoming data is already ahead of the output count
- ((fill_rvd_beat[fb] > fill_out_cnt_q[fb]) | fill_hit_q[fb] |
- (|fill_err_q[fb]));
- // 2. Select IC1 hit data
- assign fill_data_hit[fb] = fill_busy_q[fb] & fill_hit_ic1[fb] & fill_data_sel[fb];
- // 3. Select incoming instr_rdata_i
- assign fill_data_rvd[fb] = fill_busy_q[fb] & fill_rvd_arb[fb] & ~fill_hit_q[fb] &
- ~fill_hit_ic1[fb] & ~fill_stale_q[fb] & ~fill_out_done[fb] &
- // The incoming data lines up with the output count
- (fill_rvd_beat[fb] == fill_out_cnt_q[fb]) & fill_data_sel[fb];
-
-
- ///////////////////////////
- // Fill buffer registers //
- ///////////////////////////
-
- // Fill buffer general enable
- assign fill_entry_en[fb] = fill_alloc[fb] | fill_busy_q[fb];
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- fill_busy_q[fb] <= 1'b0;
- fill_older_q[fb] <= '0;
- fill_stale_q[fb] <= 1'b0;
- fill_cache_q[fb] <= 1'b0;
- fill_hit_q[fb] <= 1'b0;
- fill_ext_cnt_q[fb] <= '0;
- fill_ext_hold_q[fb] <= 1'b0;
- fill_ext_done_q[fb] <= 1'b0;
- fill_rvd_cnt_q[fb] <= '0;
- fill_ram_done_q[fb] <= 1'b0;
- fill_out_cnt_q[fb] <= '0;
- end else if (fill_entry_en[fb]) begin
- fill_busy_q[fb] <= fill_busy_d[fb];
- fill_older_q[fb] <= fill_older_d[fb];
- fill_stale_q[fb] <= fill_stale_d[fb];
- fill_cache_q[fb] <= fill_cache_d[fb];
- fill_hit_q[fb] <= fill_hit_d[fb];
- fill_ext_cnt_q[fb] <= fill_ext_cnt_d[fb];
- fill_ext_hold_q[fb] <= fill_ext_hold_d[fb];
- fill_ext_done_q[fb] <= fill_ext_done_d[fb];
- fill_rvd_cnt_q[fb] <= fill_rvd_cnt_d[fb];
- fill_ram_done_q[fb] <= fill_ram_done_d[fb];
- fill_out_cnt_q[fb] <= fill_out_cnt_d[fb];
- end
- end
-
- ////////////////////////////////////////
- // Fill buffer address / data storage //
- ////////////////////////////////////////
-
- assign fill_addr_en[fb] = fill_alloc[fb];
- assign fill_way_en[fb] = (lookup_valid_ic1 & fill_in_ic1[fb]);
-
- always_ff @(posedge clk_i) begin
- if (fill_addr_en[fb]) begin
- fill_addr_q[fb] <= lookup_addr_ic0;
- end
- end
-
- always_ff @(posedge clk_i) begin
- if (fill_way_en[fb]) begin
- fill_way_q[fb] <= sel_way_ic1;
- end
- end
-
- // Data either comes from the cache or the bus. If there was an ECC error, we must take
- // the incoming bus data since the cache hit data is corrupted.
- assign fill_data_d[fb] = fill_hit_ic1[fb] ? hit_data_ic1[LineSize-1:0] :
- {LINE_BEATS{instr_rdata_i}};
-
- for (genvar b = 0; b < LINE_BEATS; b++) begin : gen_data_buf
- // Error tracking (per beat)
- // Either a PMP error on a speculative request,
- assign fill_err_d[fb][b] = (instr_pmp_err_i & fill_alloc[fb] & fill_spec_req &
- (lookup_addr_ic0[LINE_W-1:BUS_W] == b[LINE_BEATS_W-1:0])) |
- // a PMP error on a fill buffer ext req
- (instr_pmp_err_i & fill_ext_arb[fb] &
- (fill_ext_off[fb] == b[LINE_BEATS_W-1:0])) |
- // Or a data error with instr_rvalid_i
- (fill_rvd_arb[fb] & instr_err_i &
- (fill_rvd_off[fb] == b[LINE_BEATS_W-1:0])) |
- // Hold the error once recorded
- (fill_busy_q[fb] & fill_err_q[fb][b]);
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- fill_err_q[fb][b] <= '0;
- end else if (fill_entry_en[fb]) begin
- fill_err_q[fb][b] <= fill_err_d[fb][b];
- end
- end
-
- // Enable the relevant part of the data register (or all for cache hits)
- // Ignore incoming rvalid data when we already have cache hit data
- assign fill_data_en[fb][b] = fill_hit_ic1[fb] |
- (fill_rvd_arb[fb] & ~fill_hit_q[fb] &
- (fill_rvd_off[fb] == b[LINE_BEATS_W-1:0]));
-
- always_ff @(posedge clk_i) begin
- if (fill_data_en[fb][b]) begin
- fill_data_q[fb][b*BusWidth+:BusWidth] <= fill_data_d[fb][b*BusWidth+:BusWidth];
- end
- end
-
- end
- end
-
- ////////////////////////////////
- // Fill buffer one-hot muxing //
- ////////////////////////////////
-
- // External req info
- always_comb begin
- fill_ext_req_addr = '0;
- for (int i = 0; i < NUM_FB; i++) begin
- if (fill_ext_arb[i]) begin
- fill_ext_req_addr |= {fill_addr_q[i][ADDR_W-1:LINE_W], fill_ext_off[i]};
- end
- end
- end
-
- // Cache req info
- always_comb begin
- fill_ram_req_addr = '0;
- fill_ram_req_way = '0;
- fill_ram_req_data = '0;
- for (int i = 0; i < NUM_FB; i++) begin
- if (fill_ram_arb[i]) begin
- fill_ram_req_addr |= fill_addr_q[i];
- fill_ram_req_way |= fill_way_q[i];
- fill_ram_req_data |= fill_data_q[i];
- end
- end
- end
-
- // IF stage output data
- always_comb begin
- fill_out_data = '0;
- fill_out_err = '0;
- for (int i = 0; i < NUM_FB; i++) begin
- if (fill_data_reg[i]) begin
- fill_out_data |= fill_data_q[i];
- // Ignore any speculative errors accumulated on cache hits
- fill_out_err |= (fill_err_q[i] & ~{LINE_BEATS{fill_hit_q[i]}});
- end
- end
- end
-
- ///////////////////////
- // External requests //
- ///////////////////////
-
- assign instr_req = ((~icache_enable_i | branch_or_mispredict) & lookup_grant_ic0) |
- (|fill_ext_req);
-
- assign instr_addr = |fill_ext_req ? fill_ext_req_addr :
- lookup_addr_ic0[ADDR_W-1:BUS_W];
-
- assign instr_req_o = instr_req;
- assign instr_addr_o = {instr_addr[ADDR_W-1:BUS_W],{BUS_W{1'b0}}};
-
- ////////////////////////
- // Output data muxing //
- ////////////////////////
-
- // Mux between line-width data sources
- assign line_data = |fill_data_hit ? hit_data_ic1[LineSize-1:0] : fill_out_data;
- assign line_err = |fill_data_hit ? {LINE_BEATS{1'b0}} : fill_out_err;
-
- // Mux the relevant beat of line data, based on the output address
- always_comb begin
- line_data_muxed = '0;
- line_err_muxed = 1'b0;
- for (int i = 0; i < LINE_BEATS; i++) begin
- // When data has been skidded, the output address is behind by one
- if ((output_addr_q[LINE_W-1:BUS_W] + {{LINE_BEATS_W-1{1'b0}},skid_valid_q}) ==
- i[LINE_BEATS_W-1:0]) begin
- line_data_muxed |= line_data[i*32+:32];
- line_err_muxed |= line_err[i];
- end
- end
- end
-
- // Mux between incoming rdata and the muxed line data
- assign output_data = |fill_data_rvd ? instr_rdata_i : line_data_muxed;
- assign output_err = |fill_data_rvd ? instr_err_i : line_err_muxed;
-
- // Output data is valid (from any of the three possible sources). Note that fill_out_arb
- // must be used here rather than fill_out_req because data can become valid out of order
- // (e.g. cache hit data can become available ahead of an older outstanding miss).
- assign data_valid = |fill_out_arb;
-
- // Skid buffer data
- assign skid_data_d = output_data[31:16];
-
- assign skid_en = data_valid & (ready_i | skid_ready);
-
- always_ff @(posedge clk_i) begin
- if (skid_en) begin
- skid_data_q <= skid_data_d;
- skid_err_q <= output_err;
- end
- end
-
- // The data in the skid buffer is ready if it's a complete compressed instruction or if there's
- // an error (no need to wait for the second half)
- assign skid_complete_instr = skid_valid_q & ((skid_data_q[1:0] != 2'b11) | skid_err_q);
-
- // Data can be loaded into the skid buffer for an unaligned uncompressed instruction
- assign skid_ready = output_addr_q[1] & ~skid_valid_q & (~output_compressed | output_err);
-
- assign output_ready = (ready_i | skid_ready) & ~skid_complete_instr;
-
- assign output_compressed = (rdata_o[1:0] != 2'b11);
-
- assign skid_valid_d =
- // Branches invalidate the skid buffer
- branch_or_mispredict ? 1'b0 :
- // Once valid, the skid buffer stays valid until a compressed instruction realigns the stream
- (skid_valid_q ? ~(ready_i & ((skid_data_q[1:0] != 2'b11) | skid_err_q)) :
- // The skid buffer becomes valid when:
- // - we branch to an unaligned uncompressed instruction
- (((output_addr_q[1] & (~output_compressed | output_err)) |
- // - a compressed instruction misaligns the stream
- (~output_addr_q[1] & output_compressed & ~output_err & ready_i)) & data_valid));
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- skid_valid_q <= 1'b0;
- end else begin
- skid_valid_q <= skid_valid_d;
- end
- end
-
- // Signal that valid data is available to the IF stage
- // Note that if the first half of an unaligned instruction reports an error, we do not need
- // to wait for the second half (and for PMP errors we might not have fetched the second half)
- // Compressed instruction completely satisfied by skid buffer
- assign output_valid = skid_complete_instr |
- // Output data available and, output stream aligned, or skid data available,
- (data_valid & (~output_addr_q[1] | skid_valid_q |
- // or this is an error or an unaligned compressed instruction
- output_err | (output_data[17:16] != 2'b11)));
-
- // Update the address on branches and every time an instruction is driven
- assign output_addr_en = branch_or_mispredict | (ready_i & valid_o);
-
- // Increment the address by two every time a compressed instruction is popped
- assign addr_incr_two = output_compressed & ~err_o;
-
- // Next IF stage PC
- assign output_addr_incr = (output_addr_q[31:1] +
- // Increment address by 4 or 2
- {29'd0, ~addr_incr_two, addr_incr_two});
-
- // Redirect the address on branches or mispredicts
- assign output_addr_d = branch_i ? addr_i[31:1] :
- branch_mispredict_i ? branch_mispredict_addr[31:1] :
- output_addr_incr;
-
- always_ff @(posedge clk_i) begin
- if (output_addr_en) begin
- output_addr_q <= output_addr_d;
- end
- end
-
- // Mux the data from BusWidth to halfword
- // This muxing realigns data when instruction words are split across BUS_W e.g.
- // word 1 |----|*h1*|
- // word 0 |*h0*|----| --> |*h1*|*h0*|
- // 31 15 0 31 15 0
- always_comb begin
- output_data_lo = '0;
- for (int i = 0; i < OUTPUT_BEATS; i++) begin
- if (output_addr_q[BUS_W-1:1] == i[BUS_W-2:0]) begin
- output_data_lo |= output_data[i*16+:16];
- end
- end
- end
-
- always_comb begin
- output_data_hi = '0;
- for (int i = 0; i < OUTPUT_BEATS-1; i++) begin
- if (output_addr_q[BUS_W-1:1] == i[BUS_W-2:0]) begin
- output_data_hi |= output_data[(i+1)*16+:16];
- end
- end
- if (&output_addr_q[BUS_W-1:1]) begin
- output_data_hi |= output_data[15:0];
- end
- end
-
- assign valid_o = output_valid & ~branch_mispredict_i;
- assign rdata_o = {output_data_hi, (skid_valid_q ? skid_data_q : output_data_lo)};
- assign addr_o = {output_addr_q, 1'b0};
- assign err_o = (skid_valid_q & skid_err_q) | (~skid_complete_instr & output_err);
- // Error caused by the second half of a misaligned uncompressed instruction
- // (only relevant when err_o is set)
- assign err_plus2_o = skid_valid_q & ~skid_err_q;
-
- ///////////////////
- // Invalidations //
- ///////////////////
-
- // Invalidate on reset, or when instructed. If an invalidation request is received while a
- // previous invalidation is ongoing, it does not need to be restarted.
- assign start_inval = (~reset_inval_q | icache_inval_i) & ~inval_prog_q;
- assign inval_prog_d = start_inval | (inval_prog_q & ~inval_done);
- assign inval_done = &inval_index_q;
- assign inval_index_d = start_inval ? '0 :
- (inval_index_q + {{INDEX_W-1{1'b0}},1'b1});
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- inval_prog_q <= 1'b0;
- reset_inval_q <= 1'b0;
- end else begin
- inval_prog_q <= inval_prog_d;
- reset_inval_q <= 1'b1;
- end
- end
-
- always_ff @(posedge clk_i) begin
- if (inval_prog_d) begin
- inval_index_q <= inval_index_d;
- end
- end
-
- /////////////////
- // Busy status //
- /////////////////
-
- // Only busy (for WFI purposes) while an invalidation is in-progress, or external requests are
- // outstanding.
- assign busy_o = inval_prog_q | (|(fill_busy_q & ~fill_rvd_done));
-
-
-
-endmodule
diff --git a/verilog/rtl/brq_ifu_prefetch_buffer.sv b/verilog/rtl/brq_ifu_prefetch_buffer.sv
deleted file mode 100644
index cfcc050..0000000
--- a/verilog/rtl/brq_ifu_prefetch_buffer.sv
+++ /dev/null
@@ -1,318 +0,0 @@
-
-/**
- * Prefetcher Buffer for 32 bit memory interface
- *
- * Prefetch Buffer that caches instructions. This cuts overly long critical
- * paths to the instruction cache.
- */
-module brq_ifu_prefetch_buffer #(
- parameter bit BranchPredictor = 1'b0
-) (
- input logic clk_i,
- input logic rst_ni,
-
- input logic req_i,
-
- input logic branch_i,
- input logic branch_spec_i,
- input logic predicted_branch_i,
- // input logic branch_mispredict_i,
- input logic [31:0] addr_i,
-
-
- input logic ready_i,
- output logic valid_o,
- output logic [31:0] rdata_o,
- output logic [31:0] addr_o,
- output logic err_o,
- output logic err_plus2_o,
-
-
- // goes to instruction memory / instruction cache
- output logic instr_req_o,
- input logic instr_gnt_i,
- output logic [31:0] instr_addr_o,
- input logic [31:0] instr_rdata_i,
- input logic instr_err_i,
- input logic instr_pmp_err_i,
- input logic instr_rvalid_i,
-
- // Prefetch Buffer Status
- output logic busy_o
-);
-
- logic branch_mispredict_i;
- assign branch_mispredict_i = '0;
- localparam int unsigned NUM_REQS = 2;
-
- logic branch_suppress;
- logic valid_new_req, valid_req;
- logic valid_req_d, valid_req_q;
- logic discard_req_d, discard_req_q;
- logic gnt_or_pmp_err, rvalid_or_pmp_err;
- logic [NUM_REQS-1:0] rdata_outstanding_n, rdata_outstanding_s, rdata_outstanding_q;
- logic [NUM_REQS-1:0] branch_discard_n, branch_discard_s, branch_discard_q;
- logic [NUM_REQS-1:0] rdata_pmp_err_n, rdata_pmp_err_s, rdata_pmp_err_q;
- logic [NUM_REQS-1:0] rdata_outstanding_rev;
-
- logic [31:0] stored_addr_d, stored_addr_q;
- logic stored_addr_en;
- logic [31:0] fetch_addr_d, fetch_addr_q;
- logic fetch_addr_en;
- logic [31:0] branch_mispredict_addr;
- logic [31:0] instr_addr, instr_addr_w_aligned;
- logic instr_or_pmp_err;
-
- logic fifo_valid;
- logic [31:0] fifo_addr;
- logic fifo_ready;
- logic fifo_clear;
- logic [NUM_REQS-1:0] fifo_busy;
-
- logic valid_raw;
-
- logic [31:0] addr_next;
-
- logic branch_or_mispredict;
-
- ////////////////////////////
- // Prefetch buffer status //
- ////////////////////////////
-
- assign busy_o = (|rdata_outstanding_q) | instr_req_o;
-
- assign branch_or_mispredict = branch_i | branch_mispredict_i;
-
- //////////////////////////////////////////////
- // Fetch fifo - consumes addresses and data //
- //////////////////////////////////////////////
-
- // Instruction fetch errors are valid on the data phase of a request
- // PMP errors are generated in the address phase, and registered into a fake data phase
- assign instr_or_pmp_err = instr_err_i | rdata_pmp_err_q[0];
-
- // A branch will invalidate any previously fetched instructions.
- // Note that the FENCE.I instruction relies on this flushing behaviour on branch. If it is
- // altered the FENCE.I implementation may require changes.
- assign fifo_clear = branch_or_mispredict;
-
- // Reversed version of rdata_outstanding_q which can be overlaid with fifo fill state
- for (genvar i = 0; i < NUM_REQS; i++) begin : gen_rd_rev
- assign rdata_outstanding_rev[i] = rdata_outstanding_q[NUM_REQS-1-i];
- end
-
- // The fifo is ready to accept a new request if it is not full - including space reserved for
- // requests already outstanding.
- // Overlay the fifo fill state with the outstanding requests to see if there is space.
- assign fifo_ready = ~&(fifo_busy | rdata_outstanding_rev);
-
- brq_ifu_fifo #(
- .NUM_REQS (NUM_REQS)
- ) fifo_i (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
-
- .clear_i ( fifo_clear ),
- .busy_o ( fifo_busy ),
-
- .in_valid_i ( fifo_valid ),
- .in_addr_i ( fifo_addr ),
- .in_rdata_i ( instr_rdata_i ),
- .in_err_i ( instr_or_pmp_err ),
-
- .out_valid_o ( valid_raw ),
- .out_ready_i ( ready_i ),
- .out_rdata_o ( rdata_o ),
- .out_addr_o ( addr_o ),
- .out_addr_next_o ( addr_next ),
- .out_err_o ( err_o ),
- .out_err_plus2_o ( err_plus2_o )
- );
-
- //////////////
- // Requests //
- //////////////
-
- // Suppress a new request on a not-taken branch (as the external address will be incorrect)
- assign branch_suppress = branch_spec_i & ~branch_i;
-
- // Make a new request any time there is space in the FIFO, and space in the request queue
- assign valid_new_req = ~branch_suppress & req_i & (fifo_ready | branch_or_mispredict) &
- ~rdata_outstanding_q[NUM_REQS-1];
-
- assign valid_req = valid_req_q | valid_new_req;
-
- // If a request address triggers a PMP error, the external bus request is suppressed. We might
- // therefore never receive a grant for such a request. The grant is faked in this case to make
- // sure the request proceeds and the error is pushed to the FIFO.
- assign gnt_or_pmp_err = instr_gnt_i | instr_pmp_err_i;
-
- // As with the grant, the rvalid must be faked for a PMP error, since the request was suppressed.
- assign rvalid_or_pmp_err = rdata_outstanding_q[0] & (instr_rvalid_i | rdata_pmp_err_q[0]);
-
- // Hold the request stable for requests that didn't get granted
- assign valid_req_d = valid_req & ~gnt_or_pmp_err;
-
- // Record whether an outstanding bus request is cancelled by a branch
- assign discard_req_d = valid_req_q & (branch_or_mispredict | discard_req_q);
-
- ////////////////
- // Fetch addr //
- ////////////////
-
- // Two addresses are tracked in the prefetch buffer:
- // 1. stored_addr_q - This is the address issued on the bus. It stays stable until
- // the request is granted.
- // 2. fetch_addr_q - This is our next address to fetch from. It is updated on branches to
- // capture the new address, and then for each new request issued.
- // A third address is tracked in the fetch FIFO itself:
- // 3. instr_addr_q - This is the address at the head of the FIFO, efectively our oldest fetched
- // address. This address is updated on branches, and does its own increment
- // each time the FIFO is popped.
-
- // 1. stored_addr_q
-
- // Only update stored_addr_q for new ungranted requests
- assign stored_addr_en = valid_new_req & ~valid_req_q & ~gnt_or_pmp_err;
-
- // Store whatever address was issued on the bus
- assign stored_addr_d = instr_addr;
-
- // CPU resets with a branch, so no need to reset these addresses
- always_ff @(posedge clk_i) begin
- if (stored_addr_en) begin
- stored_addr_q <= stored_addr_d;
- end
- end
-
- if (BranchPredictor) begin : g_branch_predictor
- // Where the branch predictor is present record what address followed a predicted branch. If
- // that branch is predicted taken but mispredicted (so not-taken) this is used to resume on
- // the not-taken code path.
- logic [31:0] branch_mispredict_addr_q;
- logic branch_mispredict_addr_en;
-
- assign branch_mispredict_addr_en = branch_i & predicted_branch_i;
-
- always_ff @(posedge clk_i) begin
- if (branch_mispredict_addr_en) begin
- branch_mispredict_addr_q <= addr_next;
- end
- end
-
- assign branch_mispredict_addr = branch_mispredict_addr_q;
- end else begin : g_no_branch_predictor
- logic unused_predicted_branch;
- logic [31:0] unused_addr_next;
-
- assign unused_predicted_branch = predicted_branch_i;
- assign unused_addr_next = addr_next;
-
- assign branch_mispredict_addr = '0;
- end
-
- // 2. fetch_addr_q
-
- // Update on a branch or as soon as a request is issued
- assign fetch_addr_en = branch_or_mispredict | (valid_new_req & ~valid_req_q);
-
- assign fetch_addr_d = (branch_i ? addr_i :
- branch_mispredict_i ? {branch_mispredict_addr[31:2], 2'b00} :
- {fetch_addr_q[31:2], 2'b00}) +
- // Current address + 4
- {{29{1'b0}},(valid_new_req & ~valid_req_q),2'b00};
-
- always_ff @(posedge clk_i) begin
- if (fetch_addr_en) begin
- fetch_addr_q <= fetch_addr_d;
- end
- end
-
- // Address mux
- assign instr_addr = valid_req_q ? stored_addr_q :
- branch_spec_i ? addr_i :
- branch_mispredict_i ? branch_mispredict_addr :
- fetch_addr_q;
-
- assign instr_addr_w_aligned = {instr_addr[31:2], 2'b00};
-
- ///////////////////////////////
- // Request outstanding queue //
- ///////////////////////////////
-
- for (genvar i = 0; i < NUM_REQS; i++) begin : g_outstanding_reqs
- // Request 0 (always the oldest outstanding request)
- if (i == 0) begin : g_req0
- // A request becomes outstanding once granted, and is cleared once the rvalid is received.
- // Outstanding requests shift down the queue towards entry 0.
- assign rdata_outstanding_n[i] = (valid_req & gnt_or_pmp_err) |
- rdata_outstanding_q[i];
- // If a branch is received at any point while a request is outstanding, it must be tracked
- // to ensure we discard the data once received
- assign branch_discard_n[i] = (valid_req & gnt_or_pmp_err & discard_req_d) |
- (branch_or_mispredict & rdata_outstanding_q[i]) |
- branch_discard_q[i];
- // Record whether this request received a PMP error
- assign rdata_pmp_err_n[i] = (valid_req & ~rdata_outstanding_q[i] & instr_pmp_err_i) |
- rdata_pmp_err_q[i];
-
- end else begin : g_reqtop
- // Entries > 0 consider the FIFO fill state to calculate their next state (by checking
- // whether the previous entry is valid)
-
- assign rdata_outstanding_n[i] = (valid_req & gnt_or_pmp_err &
- rdata_outstanding_q[i-1]) |
- rdata_outstanding_q[i];
- assign branch_discard_n[i] = (valid_req & gnt_or_pmp_err & discard_req_d &
- rdata_outstanding_q[i-1]) |
- (branch_or_mispredict & rdata_outstanding_q[i]) |
- branch_discard_q[i];
- assign rdata_pmp_err_n[i] = (valid_req & ~rdata_outstanding_q[i] & instr_pmp_err_i &
- rdata_outstanding_q[i-1]) |
- rdata_pmp_err_q[i];
- end
- end
-
- // Shift the entries down on each instr_rvalid_i
- assign rdata_outstanding_s = rvalid_or_pmp_err ? {1'b0,rdata_outstanding_n[NUM_REQS-1:1]} :
- rdata_outstanding_n;
- assign branch_discard_s = rvalid_or_pmp_err ? {1'b0,branch_discard_n[NUM_REQS-1:1]} :
- branch_discard_n;
- assign rdata_pmp_err_s = rvalid_or_pmp_err ? {1'b0,rdata_pmp_err_n[NUM_REQS-1:1]} :
- rdata_pmp_err_n;
-
- // Push a new entry to the FIFO once complete (and not cancelled by a branch)
- assign fifo_valid = rvalid_or_pmp_err & ~branch_discard_q[0];
-
- assign fifo_addr = branch_i ? addr_i : branch_mispredict_addr;
-
- ///////////////
- // Registers //
- ///////////////
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- valid_req_q <= 1'b0;
- discard_req_q <= 1'b0;
- rdata_outstanding_q <= 'b0;
- branch_discard_q <= 'b0;
- rdata_pmp_err_q <= 'b0;
- end else begin
- valid_req_q <= valid_req_d;
- discard_req_q <= discard_req_d;
- rdata_outstanding_q <= rdata_outstanding_s;
- branch_discard_q <= branch_discard_s;
- rdata_pmp_err_q <= rdata_pmp_err_s;
- end
- end
-
- /////////////
- // Outputs //
- /////////////
-
- assign instr_req_o = valid_req;
- assign instr_addr_o = instr_addr_w_aligned;
-
- assign valid_o = valid_raw & ~branch_mispredict_i;
-
-endmodule
diff --git a/verilog/rtl/brq_lsu.sv b/verilog/rtl/brq_lsu.sv
deleted file mode 100644
index a87191a..0000000
--- a/verilog/rtl/brq_lsu.sv
+++ /dev/null
@@ -1,489 +0,0 @@
-/**
- * Load Store Unit
- *
- * Load Store Unit, used to eliminate multiple access during processor stalls,
- * and to align bytes and halfwords.
- */
-
-module brq_lsu
-(
- input logic clk_i,
- input logic rst_ni,
-
- // data interface
- output logic data_req_o,
- input logic data_gnt_i,
- input logic data_rvalid_i,
- input logic data_err_i,
- input logic data_pmp_err_i,
-
- output logic [31:0] data_addr_o,
- output logic data_we_o,
- output logic [3:0] data_be_o,
- output logic [31:0] data_wdata_o,
- input logic [31:0] data_rdata_i,
-
- // signals to/from ID/EX stage
- input logic lsu_we_i, // write enable -> from ID/EX
- input logic [1:0] lsu_type_i, // data type: word, half word, byte -> from ID/EX
- input logic [31:0] lsu_wdata_i, // data to write to memory -> from ID/EX
- input logic lsu_sign_ext_i, // sign extension -> from ID/EX
-
- output logic [31:0] lsu_rdata_o, // requested data -> to ID/EX
- output logic lsu_rdata_valid_o,
- input logic lsu_req_i, // data request -> from ID/EX
-
- input logic [31:0] adder_result_ex_i, // address computed in ALU -> from ID/EX
-
- output logic addr_incr_req_o, // request address increment for
- // misaligned accesses -> to ID/EX
- output logic [31:0] addr_last_o, // address of last transaction -> to controller
- // -> mtval
- // -> AGU for misaligned accesses
-
- output logic lsu_req_done_o, // Signals that data request is complete
- // (only need to await final data
- // response) -> to ID/EX
-
- output logic lsu_resp_valid_o, // LSU has response from transaction -> to ID/EX
-
- // exception signals
- output logic load_err_o,
- output logic store_err_o,
-
- output logic busy_o,
-
- output logic perf_load_o,
- output logic perf_store_o
-);
-
- logic [31:0] data_addr;
- logic [31:0] data_addr_w_aligned;
- logic [31:0] addr_last_q;
-
- logic addr_update;
- logic ctrl_update;
- logic rdata_update;
- logic [31:8] rdata_q;
- logic [1:0] rdata_offset_q;
- logic [1:0] data_type_q;
- logic data_sign_ext_q;
- logic data_we_q;
-
- logic [1:0] data_offset; // mux control for data to be written to memory
-
- logic [3:0] data_be;
- logic [31:0] data_wdata;
-
- logic [31:0] data_rdata_ext;
-
- logic [31:0] rdata_w_ext; // word realignment for misaligned loads
- logic [31:0] rdata_h_ext; // sign extension for half words
- logic [31:0] rdata_b_ext; // sign extension for bytes
-
- logic split_misaligned_access;
- logic handle_misaligned_q, handle_misaligned_d; // high after receiving grant for first
- // part of a misaligned access
- logic pmp_err_q, pmp_err_d;
- logic lsu_err_q, lsu_err_d;
- logic data_or_pmp_err;
-
- typedef enum logic [2:0] {
- IDLE, WAIT_GNT_MIS, WAIT_RVALID_MIS, WAIT_GNT,
- WAIT_RVALID_MIS_GNTS_DONE
- } ls_fsm_e;
-
- ls_fsm_e ls_fsm_cs, ls_fsm_ns;
-
- assign data_addr = adder_result_ex_i;
- assign data_offset = data_addr[1:0];
-
- ///////////////////
- // BE generation //
- ///////////////////
-
- always_comb begin
- unique case (lsu_type_i) // Data type 00 Word, 01 Half word, 11,10 byte
- 2'b00: begin // Writing a word
- if (!handle_misaligned_q) begin // first part of potentially misaligned transaction
- unique case (data_offset)
- 2'b00: data_be = 4'b1111;
- 2'b01: data_be = 4'b1110;
- 2'b10: data_be = 4'b1100;
- 2'b11: data_be = 4'b1000;
- // default: data_be = 4'b1111;
- endcase // case (data_offset)
- end else begin // second part of misaligned transaction
- unique case (data_offset)
- 2'b00: data_be = 4'b0000; // this is not used, but included for completeness
- 2'b01: data_be = 4'b0001;
- 2'b10: data_be = 4'b0011;
- 2'b11: data_be = 4'b0111;
- // default: data_be = 4'b1111;
- endcase // case (data_offset)
- end
- end
-
- 2'b01: begin // Writing a half word
- if (!handle_misaligned_q) begin // first part of potentially misaligned transaction
- unique case (data_offset)
- 2'b00: data_be = 4'b0011;
- 2'b01: data_be = 4'b0110;
- 2'b10: data_be = 4'b1100;
- 2'b11: data_be = 4'b1000;
- // default: data_be = 4'b1111;
- endcase // case (data_offset)
- end else begin // second part of misaligned transaction
- data_be = 4'b0001;
- end
- end
-
- 2'b10,
- 2'b11: begin // Writing a byte
- unique case (data_offset)
- 2'b00: data_be = 4'b0001;
- 2'b01: data_be = 4'b0010;
- 2'b10: data_be = 4'b0100;
- 2'b11: data_be = 4'b1000;
- // default: data_be = 4'b1111;
- endcase // case (data_offset)
- end
-
- // default: data_be = 4'b1111;
- endcase // case (lsu_type_i)
- end
-
- /////////////////////
- // WData alignment //
- /////////////////////
-
- // prepare data to be written to the memory
- // we handle misaligned accesses, half word and byte accesses here
- always_comb begin
- unique case (data_offset)
- 2'b00: data_wdata = lsu_wdata_i[31:0];
- 2'b01: data_wdata = {lsu_wdata_i[23:0], lsu_wdata_i[31:24]};
- 2'b10: data_wdata = {lsu_wdata_i[15:0], lsu_wdata_i[31:16]};
- 2'b11: data_wdata = {lsu_wdata_i[ 7:0], lsu_wdata_i[31: 8]};
- // default: data_wdata = lsu_wdata_i[31:0];
- endcase // case (data_offset)
- end
-
- /////////////////////
- // RData alignment //
- /////////////////////
-
- // register for unaligned rdata
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rdata_q <= '0;
- end else if (rdata_update) begin
- rdata_q <= data_rdata_i[31:8];
- end
- end
-
- // registers for transaction control
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rdata_offset_q <= 2'h0;
- data_type_q <= 2'h0;
- data_sign_ext_q <= 1'b0;
- data_we_q <= 1'b0;
- end else if (ctrl_update) begin
- rdata_offset_q <= data_offset;
- data_type_q <= lsu_type_i;
- data_sign_ext_q <= lsu_sign_ext_i;
- data_we_q <= lsu_we_i;
- end
- end
-
- // Store last address for mtval + AGU for misaligned transactions.
- // Do not update in case of errors, mtval needs the (first) failing address
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- addr_last_q <= '0;
- end else if (addr_update) begin
- addr_last_q <= data_addr;
- end
- end
-
- // take care of misaligned words
- always_comb begin
- unique case (rdata_offset_q)
- 2'b00: rdata_w_ext = data_rdata_i[31:0];
- 2'b01: rdata_w_ext = {data_rdata_i[ 7:0], rdata_q[31:8]};
- 2'b10: rdata_w_ext = {data_rdata_i[15:0], rdata_q[31:16]};
- 2'b11: rdata_w_ext = {data_rdata_i[23:0], rdata_q[31:24]};
- // default: rdata_w_ext = data_rdata_i[31:0];
- endcase
- end
-
- ////////////////////
- // Sign extension //
- ////////////////////
-
- // sign extension for half words
- always_comb begin
- unique case (rdata_offset_q)
- 2'b00: begin
- if (!data_sign_ext_q) begin
- rdata_h_ext = {16'h0000, data_rdata_i[15:0]};
- end else begin
- rdata_h_ext = {{16{data_rdata_i[15]}}, data_rdata_i[15:0]};
- end
- end
-
- 2'b01: begin
- if (!data_sign_ext_q) begin
- rdata_h_ext = {16'h0000, data_rdata_i[23:8]};
- end else begin
- rdata_h_ext = {{16{data_rdata_i[23]}}, data_rdata_i[23:8]};
- end
- end
-
- 2'b10: begin
- if (!data_sign_ext_q) begin
- rdata_h_ext = {16'h0000, data_rdata_i[31:16]};
- end else begin
- rdata_h_ext = {{16{data_rdata_i[31]}}, data_rdata_i[31:16]};
- end
- end
-
- 2'b11: begin
- if (!data_sign_ext_q) begin
- rdata_h_ext = {16'h0000, data_rdata_i[7:0], rdata_q[31:24]};
- end else begin
- rdata_h_ext = {{16{data_rdata_i[7]}}, data_rdata_i[7:0], rdata_q[31:24]};
- end
- end
-
- // default: rdata_h_ext = {16'h0000, data_rdata_i[15:0]};
- endcase // case (rdata_offset_q)
- end
-
- // sign extension for bytes
- always_comb begin
- unique case (rdata_offset_q)
- 2'b00: begin
- if (!data_sign_ext_q) begin
- rdata_b_ext = {24'h00_0000, data_rdata_i[7:0]};
- end else begin
- rdata_b_ext = {{24{data_rdata_i[7]}}, data_rdata_i[7:0]};
- end
- end
-
- 2'b01: begin
- if (!data_sign_ext_q) begin
- rdata_b_ext = {24'h00_0000, data_rdata_i[15:8]};
- end else begin
- rdata_b_ext = {{24{data_rdata_i[15]}}, data_rdata_i[15:8]};
- end
- end
-
- 2'b10: begin
- if (!data_sign_ext_q) begin
- rdata_b_ext = {24'h00_0000, data_rdata_i[23:16]};
- end else begin
- rdata_b_ext = {{24{data_rdata_i[23]}}, data_rdata_i[23:16]};
- end
- end
-
- 2'b11: begin
- if (!data_sign_ext_q) begin
- rdata_b_ext = {24'h00_0000, data_rdata_i[31:24]};
- end else begin
- rdata_b_ext = {{24{data_rdata_i[31]}}, data_rdata_i[31:24]};
- end
- end
-
- // default: rdata_b_ext = {24'h00_0000, data_rdata_i[7:0]};
- endcase // case (rdata_offset_q)
- end
-
- // select word, half word or byte sign extended version
- always_comb begin
- unique case (data_type_q)
- 2'b00: data_rdata_ext = rdata_w_ext;
- 2'b01: data_rdata_ext = rdata_h_ext;
- 2'b10,2'b11: data_rdata_ext = rdata_b_ext;
- // default: data_rdata_ext = rdata_w_ext;
- endcase // case (data_type_q)
- end
-
- /////////////
- // LSU FSM //
- /////////////
-
- // check for misaligned accesses that need to be split into two word-aligned accesses
- assign split_misaligned_access =
- ((lsu_type_i == 2'b00) && (data_offset != 2'b00)) || // misaligned word access
- ((lsu_type_i == 2'b01) && (data_offset == 2'b11)); // misaligned half-word access
-
- // FSM
- always_comb begin
- ls_fsm_ns = ls_fsm_cs;
-
- data_req_o = 1'b0;
- addr_incr_req_o = 1'b0;
- handle_misaligned_d = handle_misaligned_q;
- pmp_err_d = pmp_err_q;
- lsu_err_d = lsu_err_q;
-
- addr_update = 1'b0;
- ctrl_update = 1'b0;
- rdata_update = 1'b0;
-
- perf_load_o = 1'b0;
- perf_store_o = 1'b0;
-
- unique case (ls_fsm_cs)
-
- IDLE: begin
- pmp_err_d = 1'b0;
- if (lsu_req_i) begin
- data_req_o = 1'b1;
- pmp_err_d = data_pmp_err_i;
- lsu_err_d = 1'b0;
- perf_load_o = ~lsu_we_i;
- perf_store_o = lsu_we_i;
-
- if (data_gnt_i) begin
- ctrl_update = 1'b1;
- addr_update = 1'b1;
- handle_misaligned_d = split_misaligned_access;
- ls_fsm_ns = split_misaligned_access ? WAIT_RVALID_MIS : IDLE;
- end else begin
- ls_fsm_ns = split_misaligned_access ? WAIT_GNT_MIS : WAIT_GNT;
- end
- end
- end
-
- WAIT_GNT_MIS: begin
- data_req_o = 1'b1;
- // data_pmp_err_i is valid during the address phase of a request. An error will block the
- // external request and so a data_gnt_i might never be signalled. The registered version
- // pmp_err_q is only updated for new address phases and so can be used in WAIT_GNT* and
- // WAIT_RVALID* states
- if (data_gnt_i || pmp_err_q) begin
- addr_update = 1'b1;
- ctrl_update = 1'b1;
- handle_misaligned_d = 1'b1;
- ls_fsm_ns = WAIT_RVALID_MIS;
- end
- end
-
- WAIT_RVALID_MIS: begin
- // push out second request
- data_req_o = 1'b1;
- // tell ID/EX stage to update the address
- addr_incr_req_o = 1'b1;
-
- // first part rvalid is received, or gets a PMP error
- if (data_rvalid_i || pmp_err_q) begin
- // Update the PMP error for the second part
- pmp_err_d = data_pmp_err_i;
- // Record the error status of the first part
- lsu_err_d = data_err_i | pmp_err_q;
- // Capture the first rdata for loads
- rdata_update = ~data_we_q;
- // If already granted, wait for second rvalid
- ls_fsm_ns = data_gnt_i ? IDLE : WAIT_GNT;
- // Update the address for the second part, if no error
- addr_update = data_gnt_i & ~(data_err_i | pmp_err_q);
- // clear handle_misaligned if second request is granted
- handle_misaligned_d = ~data_gnt_i;
- end else begin
- // first part rvalid is NOT received
- if (data_gnt_i) begin
- // second grant is received
- ls_fsm_ns = WAIT_RVALID_MIS_GNTS_DONE;
- handle_misaligned_d = 1'b0;
- end
- end
- end
-
- WAIT_GNT: begin
- // tell ID/EX stage to update the address
- addr_incr_req_o = handle_misaligned_q;
- data_req_o = 1'b1;
- if (data_gnt_i || pmp_err_q) begin
- ctrl_update = 1'b1;
- // Update the address, unless there was an error
- addr_update = ~lsu_err_q;
- ls_fsm_ns = IDLE;
- handle_misaligned_d = 1'b0;
- end
- end
-
- WAIT_RVALID_MIS_GNTS_DONE: begin
- // tell ID/EX stage to update the address (to make sure the
- // second address can be captured correctly for mtval and PMP checking)
- addr_incr_req_o = 1'b1;
- // Wait for the first rvalid, second request is already granted
- if (data_rvalid_i) begin
- // Update the pmp error for the second part
- pmp_err_d = data_pmp_err_i;
- // The first part cannot see a PMP error in this state
- lsu_err_d = data_err_i;
- // Now we can update the address for the second part if no error
- addr_update = ~data_err_i;
- // Capture the first rdata for loads
- rdata_update = ~data_we_q;
- // Wait for second rvalid
- ls_fsm_ns = IDLE;
- end
- end
-
- default: begin
- ls_fsm_ns = IDLE;
- end
- endcase
- end
-
- assign lsu_req_done_o = (lsu_req_i | (ls_fsm_cs != IDLE)) & (ls_fsm_ns == IDLE);
-
- // registers for FSM
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- ls_fsm_cs <= IDLE;
- handle_misaligned_q <= '0;
- pmp_err_q <= '0;
- lsu_err_q <= '0;
- end else begin
- ls_fsm_cs <= ls_fsm_ns;
- handle_misaligned_q <= handle_misaligned_d;
- pmp_err_q <= pmp_err_d;
- lsu_err_q <= lsu_err_d;
- end
- end
-
- /////////////
- // Outputs //
- /////////////
-
- assign data_or_pmp_err = lsu_err_q | data_err_i | pmp_err_q;
- assign lsu_resp_valid_o = (data_rvalid_i | pmp_err_q) & (ls_fsm_cs == IDLE);
- assign lsu_rdata_valid_o = (ls_fsm_cs == IDLE) & data_rvalid_i & ~data_or_pmp_err & ~data_we_q;
-
- // output to register file
- assign lsu_rdata_o = data_rdata_ext;
-
- // output data address must be word aligned
- assign data_addr_w_aligned = {data_addr[31:2], 2'b00};
-
- // output to data interface
- assign data_addr_o = data_addr_w_aligned;
- assign data_wdata_o = data_wdata;
- assign data_we_o = lsu_we_i;
- assign data_be_o = data_be;
-
- // output to ID stage: mtval + AGU for misaligned transactions
- assign addr_last_o = addr_last_q;
-
- // Signal a load or store error depending on the transaction type outstanding
- assign load_err_o = data_or_pmp_err & ~data_we_q & lsu_resp_valid_o;
- assign store_err_o = data_or_pmp_err & data_we_q & lsu_resp_valid_o;
-
- assign busy_o = (ls_fsm_cs != IDLE);
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/brq_pkg.sv b/verilog/rtl/brq_pkg.sv
deleted file mode 100644
index fa44b1d..0000000
--- a/verilog/rtl/brq_pkg.sv
+++ /dev/null
@@ -1,535 +0,0 @@
-// Copyright lowRISC contributors.
-// Copyright 2017 ETH Zurich and University of Bologna, see also CREDITS.md.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-/**
- * Package with constants used by Ibex
- */
-package brq_pkg;
-
-/////////////////////
-// Parameter Enums //
-/////////////////////
-
-typedef enum integer {
- RegFileFF = 0,
- RegFileFPGA = 1,
- RegFileLatch = 2
-} regfile_e;
-
-typedef enum integer {
- RV32MNone = 0,
- RV32MSlow = 1,
- RV32MFast = 2,
- RV32MSingleCycle = 3
-} rv32m_e;
-
-typedef enum integer {
- RV32BNone = 0,
- RV32BBalanced = 1,
- RV32BFull = 2
-} rv32b_e;
-
-// floatig point
-typedef enum integer {
- RV32FNone = 0,
- RV32FSingle = 1,
- RV64FDouble = 2
- // RV32FQuad = 3
-} rvfloat_e;
-
-/////////////
-// Opcodes //
-/////////////
-
-typedef enum logic [6:0] {
- OPCODE_LOAD = 7'h03,
- OPCODE_MISC_MEM = 7'h0f,
- OPCODE_OP_IMM = 7'h13,
- OPCODE_AUIPC = 7'h17,
- OPCODE_STORE = 7'h23,
- OPCODE_OP = 7'h33,
- OPCODE_LUI = 7'h37,
- OPCODE_BRANCH = 7'h63,
- OPCODE_JALR = 7'h67,
- OPCODE_JAL = 7'h6f,
- OPCODE_SYSTEM = 7'h73,
- // Floating Point
- OPCODE_LOAD_FP = 7'h07,
- OPCODE_STORE_FP = 7'h27,
- OPCODE_MADD_FP = 7'h43,
- OPCODE_MSUB_FP = 7'h47,
- OPCODE_NMSUB_FP = 7'h4b,
- OPCODE_NMADD_FP = 7'h4f,
- OPCODE_OP_FP = 7'h53
-} opcode_e;
-
-
-////////////////////
-// ALU operations //
-////////////////////
-
-typedef enum logic [5:0] {
- // Arithmetics
- ALU_ADD,
- ALU_SUB,
-
- // Logics
- ALU_XOR,
- ALU_OR,
- ALU_AND,
- // RV32B
- ALU_XNOR,
- ALU_ORN,
- ALU_ANDN,
-
- // Shifts
- ALU_SRA,
- ALU_SRL,
- ALU_SLL,
- // RV32B
- ALU_SRO,
- ALU_SLO,
- ALU_ROR,
- ALU_ROL,
- ALU_GREV,
- ALU_GORC,
- ALU_SHFL,
- ALU_UNSHFL,
-
- // Comparisons
- ALU_LT,
- ALU_LTU,
- ALU_GE,
- ALU_GEU,
- ALU_EQ,
- ALU_NE,
- // RV32B
- ALU_MIN,
- ALU_MINU,
- ALU_MAX,
- ALU_MAXU,
-
- // Pack
- // RV32B
- ALU_PACK,
- ALU_PACKU,
- ALU_PACKH,
-
- // Sign-Extend
- // RV32B
- ALU_SEXTB,
- ALU_SEXTH,
-
- // Bitcounting
- // RV32B
- ALU_CLZ,
- ALU_CTZ,
- ALU_PCNT,
-
- // Set lower than
- ALU_SLT,
- ALU_SLTU,
-
- // Ternary Bitmanip Operations
- // RV32B
- ALU_CMOV,
- ALU_CMIX,
- ALU_FSL,
- ALU_FSR,
-
- // Single-Bit Operations
- // RV32B
- ALU_SBSET,
- ALU_SBCLR,
- ALU_SBINV,
- ALU_SBEXT,
-
- // Bit Extract / Deposit
- // RV32B
- ALU_BEXT,
- ALU_BDEP,
-
- // Bit Field Place
- // RV32B
- ALU_BFP,
-
- // Carry-less Multiply
- // RV32B
- ALU_CLMUL,
- ALU_CLMULR,
- ALU_CLMULH,
-
- // Cyclic Redundancy Check
- ALU_CRC32_B,
- ALU_CRC32C_B,
- ALU_CRC32_H,
- ALU_CRC32C_H,
- ALU_CRC32_W,
- ALU_CRC32C_W
-} alu_op_e;
-
-typedef enum logic [1:0] {
- // Multiplier/divider
- MD_OP_MULL,
- MD_OP_MULH,
- MD_OP_DIV,
- MD_OP_REM
-} md_op_e;
-
-// define which type instruction
-// is catered
-typedef enum logic {
- SINGLE_FP,
- DOUBLE_FP
-} fp_type_e;
-
-//////////////////////////////////
-// Control and status registers //
-//////////////////////////////////
-
-// CSR operations
-typedef enum logic [1:0] {
- CSR_OP_READ,
- CSR_OP_WRITE,
- CSR_OP_SET,
- CSR_OP_CLEAR
-} csr_op_e;
-
-// Privileged mode
-typedef enum logic[1:0] {
- PRIV_LVL_M = 2'b11,
- PRIV_LVL_H = 2'b10,
- PRIV_LVL_S = 2'b01,
- PRIV_LVL_U = 2'b00
-} priv_lvl_e;
-
-// Constants for the dcsr.xdebugver fields
-typedef enum logic[3:0] {
- XDEBUGVER_NO = 4'd0, // no external debug support
- XDEBUGVER_STD = 4'd4, // external debug according to RISC-V debug spec
- XDEBUGVER_NONSTD = 4'd15 // debug not conforming to RISC-V debug spec
-} x_debug_ver_e;
-
-//////////////
-// WB stage //
-//////////////
-
-// Type of instruction present in writeback stage
-typedef enum logic[1:0] {
- WB_INSTR_LOAD, // Instruction is awaiting load data
- WB_INSTR_STORE, // Instruction is awaiting store response
- WB_INSTR_OTHER // Instruction doesn't fit into above categories
-} wb_instr_type_e;
-
-//////////////
-// ID stage //
-//////////////
-
-// Operand a selection
-typedef enum logic[1:0] {
- OP_A_REG_A,
- OP_A_FWD,
- OP_A_CURRPC,
- OP_A_IMM
-} op_a_sel_e;
-
-// Immediate a selection
-typedef enum logic {
- IMM_A_Z,
- IMM_A_ZERO
-} imm_a_sel_e;
-
-// Operand b selection
-typedef enum logic {
- OP_B_REG_B,
- OP_B_IMM
-} op_b_sel_e;
-
-// Immediate b selection
-typedef enum logic [2:0] {
- IMM_B_I,
- IMM_B_S,
- IMM_B_B,
- IMM_B_U,
- IMM_B_J,
- IMM_B_INCR_PC,
- IMM_B_INCR_ADDR
-} imm_b_sel_e;
-
-// Regfile write data selection
-typedef enum logic {
- RF_WD_EX,
- RF_WD_CSR
-} rf_wd_sel_e;
-
-//////////////
-// IF stage //
-//////////////
-
-// PC mux selection
-typedef enum logic [2:0] {
- PC_BOOT,
- PC_JUMP,
- PC_EXC,
- PC_ERET,
- PC_DRET,
- PC_BP
-} pc_sel_e;
-
-// Exception PC mux selection
-typedef enum logic [1:0] {
- EXC_PC_EXC,
- EXC_PC_IRQ,
- EXC_PC_DBD,
- EXC_PC_DBG_EXC // Exception while in debug mode
-} exc_pc_sel_e;
-
-// Interrupt requests
-typedef struct packed {
- logic irq_software;
- logic irq_timer;
- logic irq_external;
- logic [14:0] irq_fast; // 15 fast interrupts,
- // one interrupt is reserved for NMI (not visible through mip/mie)
-} irqs_t;
-
-// Exception cause
-typedef enum logic [5:0] {
- EXC_CAUSE_IRQ_SOFTWARE_M = {1'b1, 5'd03},
- EXC_CAUSE_IRQ_TIMER_M = {1'b1, 5'd07},
- EXC_CAUSE_IRQ_EXTERNAL_M = {1'b1, 5'd11},
- // EXC_CAUSE_IRQ_FAST_0 = {1'b1, 5'd16},
- // EXC_CAUSE_IRQ_FAST_14 = {1'b1, 5'd30},
- EXC_CAUSE_IRQ_NM = {1'b1, 5'd31}, // == EXC_CAUSE_IRQ_FAST_15
- EXC_CAUSE_INSN_ADDR_MISA = {1'b0, 5'd00},
- EXC_CAUSE_INSTR_ACCESS_FAULT = {1'b0, 5'd01},
- EXC_CAUSE_ILLEGAL_INSN = {1'b0, 5'd02},
- EXC_CAUSE_BREAKPOINT = {1'b0, 5'd03},
- EXC_CAUSE_LOAD_ACCESS_FAULT = {1'b0, 5'd05},
- EXC_CAUSE_STORE_ACCESS_FAULT = {1'b0, 5'd07},
- EXC_CAUSE_ECALL_UMODE = {1'b0, 5'd08},
- EXC_CAUSE_ECALL_MMODE = {1'b0, 5'd11}
-} exc_cause_e;
-
-// Debug cause
-typedef enum logic [2:0] {
- DBG_CAUSE_NONE = 3'h0,
- DBG_CAUSE_EBREAK = 3'h1,
- DBG_CAUSE_TRIGGER = 3'h2,
- DBG_CAUSE_HALTREQ = 3'h3,
- DBG_CAUSE_STEP = 3'h4
-} dbg_cause_e;
-
-// PMP constants
-parameter int unsigned PMP_MAX_REGIONS = 16;
-parameter int unsigned PMP_CFG_W = 8;
-
-// PMP acces type
-parameter int unsigned PMP_I = 0;
-parameter int unsigned PMP_D = 1;
-
-typedef enum logic [1:0] {
- PMP_ACC_EXEC = 2'b00,
- PMP_ACC_WRITE = 2'b01,
- PMP_ACC_READ = 2'b10
-} pmp_req_e;
-
-// PMP cfg structures
-typedef enum logic [1:0] {
- PMP_MODE_OFF = 2'b00,
- PMP_MODE_TOR = 2'b01,
- PMP_MODE_NA4 = 2'b10,
- PMP_MODE_NAPOT = 2'b11
-} pmp_cfg_mode_e;
-
-typedef struct packed {
- logic lock;
- pmp_cfg_mode_e mode;
- logic exec;
- logic write;
- logic read;
-} pmp_cfg_t;
-
-// CSRs
-typedef enum logic[11:0] {
- // Machine information
- CSR_MHARTID = 12'hF14,
-
- // Machine trap setup
- CSR_MSTATUS = 12'h300,
- CSR_MISA = 12'h301,
- CSR_MIE = 12'h304,
- CSR_MTVEC = 12'h305,
-
- // Machine trap handling
- CSR_MSCRATCH = 12'h340,
- CSR_MEPC = 12'h341,
- CSR_MCAUSE = 12'h342,
- CSR_MTVAL = 12'h343,
- CSR_MIP = 12'h344,
-
- // Physical memory protection
- CSR_PMPCFG0 = 12'h3A0,
- CSR_PMPCFG1 = 12'h3A1,
- CSR_PMPCFG2 = 12'h3A2,
- CSR_PMPCFG3 = 12'h3A3,
- CSR_PMPADDR0 = 12'h3B0,
- CSR_PMPADDR1 = 12'h3B1,
- CSR_PMPADDR2 = 12'h3B2,
- CSR_PMPADDR3 = 12'h3B3,
- CSR_PMPADDR4 = 12'h3B4,
- CSR_PMPADDR5 = 12'h3B5,
- CSR_PMPADDR6 = 12'h3B6,
- CSR_PMPADDR7 = 12'h3B7,
- CSR_PMPADDR8 = 12'h3B8,
- CSR_PMPADDR9 = 12'h3B9,
- CSR_PMPADDR10 = 12'h3BA,
- CSR_PMPADDR11 = 12'h3BB,
- CSR_PMPADDR12 = 12'h3BC,
- CSR_PMPADDR13 = 12'h3BD,
- CSR_PMPADDR14 = 12'h3BE,
- CSR_PMPADDR15 = 12'h3BF,
-
- // Debug trigger
- CSR_TSELECT = 12'h7A0,
- CSR_TDATA1 = 12'h7A1,
- CSR_TDATA2 = 12'h7A2,
- CSR_TDATA3 = 12'h7A3,
- CSR_MCONTEXT = 12'h7A8,
- CSR_SCONTEXT = 12'h7AA,
-
- // Debug/trace
- CSR_DCSR = 12'h7b0,
- CSR_DPC = 12'h7b1,
-
- // Debug
- CSR_DSCRATCH0 = 12'h7b2, // optional
- CSR_DSCRATCH1 = 12'h7b3, // optional
-
- // Machine Counter/Timers
- CSR_MCOUNTINHIBIT = 12'h320,
- CSR_MHPMEVENT3 = 12'h323,
- CSR_MHPMEVENT4 = 12'h324,
- CSR_MHPMEVENT5 = 12'h325,
- CSR_MHPMEVENT6 = 12'h326,
- CSR_MHPMEVENT7 = 12'h327,
- CSR_MHPMEVENT8 = 12'h328,
- CSR_MHPMEVENT9 = 12'h329,
- CSR_MHPMEVENT10 = 12'h32A,
- CSR_MHPMEVENT11 = 12'h32B,
- CSR_MHPMEVENT12 = 12'h32C,
- CSR_MHPMEVENT13 = 12'h32D,
- CSR_MHPMEVENT14 = 12'h32E,
- CSR_MHPMEVENT15 = 12'h32F,
- CSR_MHPMEVENT16 = 12'h330,
- CSR_MHPMEVENT17 = 12'h331,
- CSR_MHPMEVENT18 = 12'h332,
- CSR_MHPMEVENT19 = 12'h333,
- CSR_MHPMEVENT20 = 12'h334,
- CSR_MHPMEVENT21 = 12'h335,
- CSR_MHPMEVENT22 = 12'h336,
- CSR_MHPMEVENT23 = 12'h337,
- CSR_MHPMEVENT24 = 12'h338,
- CSR_MHPMEVENT25 = 12'h339,
- CSR_MHPMEVENT26 = 12'h33A,
- CSR_MHPMEVENT27 = 12'h33B,
- CSR_MHPMEVENT28 = 12'h33C,
- CSR_MHPMEVENT29 = 12'h33D,
- CSR_MHPMEVENT30 = 12'h33E,
- CSR_MHPMEVENT31 = 12'h33F,
- CSR_MCYCLE = 12'hB00,
- CSR_MINSTRET = 12'hB02,
- CSR_MHPMCOUNTER3 = 12'hB03,
- CSR_MHPMCOUNTER4 = 12'hB04,
- CSR_MHPMCOUNTER5 = 12'hB05,
- CSR_MHPMCOUNTER6 = 12'hB06,
- CSR_MHPMCOUNTER7 = 12'hB07,
- CSR_MHPMCOUNTER8 = 12'hB08,
- CSR_MHPMCOUNTER9 = 12'hB09,
- CSR_MHPMCOUNTER10 = 12'hB0A,
- CSR_MHPMCOUNTER11 = 12'hB0B,
- CSR_MHPMCOUNTER12 = 12'hB0C,
- CSR_MHPMCOUNTER13 = 12'hB0D,
- CSR_MHPMCOUNTER14 = 12'hB0E,
- CSR_MHPMCOUNTER15 = 12'hB0F,
- CSR_MHPMCOUNTER16 = 12'hB10,
- CSR_MHPMCOUNTER17 = 12'hB11,
- CSR_MHPMCOUNTER18 = 12'hB12,
- CSR_MHPMCOUNTER19 = 12'hB13,
- CSR_MHPMCOUNTER20 = 12'hB14,
- CSR_MHPMCOUNTER21 = 12'hB15,
- CSR_MHPMCOUNTER22 = 12'hB16,
- CSR_MHPMCOUNTER23 = 12'hB17,
- CSR_MHPMCOUNTER24 = 12'hB18,
- CSR_MHPMCOUNTER25 = 12'hB19,
- CSR_MHPMCOUNTER26 = 12'hB1A,
- CSR_MHPMCOUNTER27 = 12'hB1B,
- CSR_MHPMCOUNTER28 = 12'hB1C,
- CSR_MHPMCOUNTER29 = 12'hB1D,
- CSR_MHPMCOUNTER30 = 12'hB1E,
- CSR_MHPMCOUNTER31 = 12'hB1F,
- CSR_MCYCLEH = 12'hB80,
- CSR_MINSTRETH = 12'hB82,
- CSR_MHPMCOUNTER3H = 12'hB83,
- CSR_MHPMCOUNTER4H = 12'hB84,
- CSR_MHPMCOUNTER5H = 12'hB85,
- CSR_MHPMCOUNTER6H = 12'hB86,
- CSR_MHPMCOUNTER7H = 12'hB87,
- CSR_MHPMCOUNTER8H = 12'hB88,
- CSR_MHPMCOUNTER9H = 12'hB89,
- CSR_MHPMCOUNTER10H = 12'hB8A,
- CSR_MHPMCOUNTER11H = 12'hB8B,
- CSR_MHPMCOUNTER12H = 12'hB8C,
- CSR_MHPMCOUNTER13H = 12'hB8D,
- CSR_MHPMCOUNTER14H = 12'hB8E,
- CSR_MHPMCOUNTER15H = 12'hB8F,
- CSR_MHPMCOUNTER16H = 12'hB90,
- CSR_MHPMCOUNTER17H = 12'hB91,
- CSR_MHPMCOUNTER18H = 12'hB92,
- CSR_MHPMCOUNTER19H = 12'hB93,
- CSR_MHPMCOUNTER20H = 12'hB94,
- CSR_MHPMCOUNTER21H = 12'hB95,
- CSR_MHPMCOUNTER22H = 12'hB96,
- CSR_MHPMCOUNTER23H = 12'hB97,
- CSR_MHPMCOUNTER24H = 12'hB98,
- CSR_MHPMCOUNTER25H = 12'hB99,
- CSR_MHPMCOUNTER26H = 12'hB9A,
- CSR_MHPMCOUNTER27H = 12'hB9B,
- CSR_MHPMCOUNTER28H = 12'hB9C,
- CSR_MHPMCOUNTER29H = 12'hB9D,
- CSR_MHPMCOUNTER30H = 12'hB9E,
- CSR_MHPMCOUNTER31H = 12'hB9F,
- CSR_CPUCTRL = 12'h7C0,
- CSR_SECURESEED = 12'h7C1,
-
- // Floating point fcsr
- CSR_FCSR = 12'h003,
- CSR_FRM = 12'h002,
- CSR_FFLAG = 12'h001
-} csr_num_e;
-
-// CSR pmp-related offsets
-parameter logic [11:0] CSR_OFF_PMP_CFG = 12'h3A0; // pmp_cfg @ 12'h3a0 - 12'h3a3
-parameter logic [11:0] CSR_OFF_PMP_ADDR = 12'h3B0; // pmp_addr @ 12'h3b0 - 12'h3bf
-
-// CSR status bits
-parameter int unsigned CSR_MSTATUS_MIE_BIT = 3;
-parameter int unsigned CSR_MSTATUS_MPIE_BIT = 7;
-parameter int unsigned CSR_MSTATUS_MPP_BIT_LOW = 11;
-parameter int unsigned CSR_MSTATUS_MPP_BIT_HIGH = 12;
-parameter int unsigned CSR_MSTATUS_MPRV_BIT = 17;
-parameter int unsigned CSR_MSTATUS_TW_BIT = 21;
-
-// CSR machine ISA
-parameter logic [1:0] CSR_MISA_MXL = 2'd1; // M-XLEN: XLEN in M-Mode for RV32
-
-// CSR interrupt pending/enable bits
-parameter int unsigned CSR_MSIX_BIT = 3;
-parameter int unsigned CSR_MTIX_BIT = 7;
-parameter int unsigned CSR_MEIX_BIT = 11;
-parameter int unsigned CSR_MFIX_BIT_LOW = 16;
-parameter int unsigned CSR_MFIX_BIT_HIGH = 30;
-
-endpackage
diff --git a/verilog/rtl/brq_pmp.sv b/verilog/rtl/brq_pmp.sv
deleted file mode 100644
index 0a5e800..0000000
--- a/verilog/rtl/brq_pmp.sv
+++ /dev/null
@@ -1,125 +0,0 @@
-
-module brq_pmp #(
- // Granularity of NAPOT access,
- // 0 = No restriction, 1 = 8 byte, 2 = 16 byte, 3 = 32 byte, etc.
- parameter int unsigned PMPGranularity = 0,
- // Number of access channels (e.g. i-side + d-side)
- parameter int unsigned PMPNumChan = 2,
- // Number of implemented regions
- parameter int unsigned PMPNumRegions = 4
-) (
- // Clock and Reset
- input logic clk_i,
- input logic rst_ni,
-
- // Interface to CSRs
- input brq_pkg::pmp_cfg_t csr_pmp_cfg_i [PMPNumRegions],
- input logic [33:0] csr_pmp_addr_i [PMPNumRegions],
-
- input brq_pkg::priv_lvl_e priv_mode_i [PMPNumChan],
- // Access checking channels
- input logic [33:0] pmp_req_addr_i [PMPNumChan],
- input brq_pkg::pmp_req_e pmp_req_type_i [PMPNumChan],
- output logic pmp_req_err_o [PMPNumChan]
-
-);
-
- import brq_pkg::*;
-
- // Access Checking Signals
- logic [33:0] region_start_addr [PMPNumRegions];
- logic [33:PMPGranularity+2] region_addr_mask [PMPNumRegions];
- logic [PMPNumChan-1:0][PMPNumRegions-1:0] region_match_gt;
- logic [PMPNumChan-1:0][PMPNumRegions-1:0] region_match_lt;
- logic [PMPNumChan-1:0][PMPNumRegions-1:0] region_match_eq;
- logic [PMPNumChan-1:0][PMPNumRegions-1:0] region_match_all;
- logic [PMPNumChan-1:0][PMPNumRegions-1:0] region_perm_check;
- logic [PMPNumChan-1:0] access_fault;
-
-
- // ---------------
- // Access checking
- // ---------------
-
- for (genvar r = 0; r < PMPNumRegions; r++) begin : g_addr_exp
- // Start address for TOR matching
- if (r == 0) begin : g_entry0
- assign region_start_addr[r] = (csr_pmp_cfg_i[r].mode == PMP_MODE_TOR) ? 34'h000000000 :
- csr_pmp_addr_i[r];
- end else begin : g_oth
- assign region_start_addr[r] = (csr_pmp_cfg_i[r].mode == PMP_MODE_TOR) ? csr_pmp_addr_i[r-1] :
- csr_pmp_addr_i[r];
- end
- // Address mask for NA matching
- for (genvar b = PMPGranularity+2; b < 34; b++) begin : g_bitmask
- if (b == 2) begin : g_bit0
- // Always mask bit 2 for NAPOT
- assign region_addr_mask[r][b] = (csr_pmp_cfg_i[r].mode != PMP_MODE_NAPOT);
- end else begin : g_others
- // We will mask this bit if it is within the programmed granule
- // i.e. addr = yyyy 0111
- // ^
- // | This bit pos is the top of the mask, all lower bits set
- // thus mask = 1111 0000
- assign region_addr_mask[r][b] = (csr_pmp_cfg_i[r].mode != PMP_MODE_NAPOT) |
- ~&csr_pmp_addr_i[r][b-1:PMPGranularity+1];
- end
- end
- end
-
- for (genvar c = 0; c < PMPNumChan; c++) begin : g_access_check
- for (genvar r = 0; r < PMPNumRegions; r++) begin : g_regions
- // Comparators are sized according to granularity
- assign region_match_eq[c][r] = (pmp_req_addr_i[c][33:PMPGranularity+2] &
- region_addr_mask[r]) ==
- (region_start_addr[r][33:PMPGranularity+2] &
- region_addr_mask[r]);
- assign region_match_gt[c][r] = pmp_req_addr_i[c][33:PMPGranularity+2] >
- region_start_addr[r][33:PMPGranularity+2];
- assign region_match_lt[c][r] = pmp_req_addr_i[c][33:PMPGranularity+2] <
- csr_pmp_addr_i[r][33:PMPGranularity+2];
-
- always_comb begin
- region_match_all[c][r] = 1'b0;
- unique case (csr_pmp_cfg_i[r].mode)
- PMP_MODE_OFF : region_match_all[c][r] = 1'b0;
- PMP_MODE_NA4 : region_match_all[c][r] = region_match_eq[c][r];
- PMP_MODE_NAPOT : region_match_all[c][r] = region_match_eq[c][r];
- PMP_MODE_TOR : begin
- region_match_all[c][r] = (region_match_eq[c][r] | region_match_gt[c][r]) &
- region_match_lt[c][r];
- end
- default : region_match_all[c][r] = 1'b0;
- endcase
- end
-
- // Check specific required permissions
- assign region_perm_check[c][r] =
- ((pmp_req_type_i[c] == PMP_ACC_EXEC) & csr_pmp_cfg_i[r].exec) |
- ((pmp_req_type_i[c] == PMP_ACC_WRITE) & csr_pmp_cfg_i[r].write) |
- ((pmp_req_type_i[c] == PMP_ACC_READ) & csr_pmp_cfg_i[r].read);
- end
-
- // Access fault determination / prioritization
- always_comb begin
- // Default is allow for M-mode, deny for other modes
- access_fault[c] = (priv_mode_i[c] != PRIV_LVL_M);
-
- // PMP entries are statically prioritized, from 0 to N-1
- // The lowest-numbered PMP entry which matches an address determines accessability
- for (int r = PMPNumRegions-1; r >= 0; r--) begin
- if (region_match_all[c][r]) begin
- access_fault[c] = (priv_mode_i[c] == PRIV_LVL_M) ?
- // For M-mode, any region which matches with the L-bit clear, or with sufficient
- // access permissions will be allowed
- (csr_pmp_cfg_i[r].lock & ~region_perm_check[c][r]) :
- // For other modes, the lock bit doesn't matter
- ~region_perm_check[c][r];
- end
- end
- end
-
- assign pmp_req_err_o[c] = access_fault[c];
- end
-
-endmodule
diff --git a/verilog/rtl/brq_register_file_ff.sv b/verilog/rtl/brq_register_file_ff.sv
deleted file mode 100644
index ce7dbbd..0000000
--- a/verilog/rtl/brq_register_file_ff.sv
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/**
- * RISC-V register file
- *
- * Register file with 31 or 15x 32 bit wide registers. Register 0 is fixed to 0.
- * This register file is based on flip flops. Use this register file when
- * targeting FPGA synthesis or Verilator simulation.
- */
-module brq_register_file_ff #(
- parameter bit RV32E = 0,
- parameter int unsigned DataWidth = 32,
- parameter bit DummyInstructions = 0
-) (
- // Clock and Reset
- input logic clk_i,
- input logic rst_ni,
-
- // input logic test_en_i,
- input logic dummy_instr_id_i,
-
- //Read port R1
- input logic [4:0] raddr_a_i,
- output logic [DataWidth-1:0] rdata_a_o,
-
- //Read port R2
- input logic [4:0] raddr_b_i,
- output logic [DataWidth-1:0] rdata_b_o,
-
-
- // Write port W1
- input logic [4:0] waddr_a_i,
- input logic [DataWidth-1:0] wdata_a_i,
- input logic we_a_i
-
-);
-
- localparam int unsigned ADDR_WIDTH = RV32E ? 4 : 5;
- localparam int unsigned NUM_WORDS = 2**ADDR_WIDTH;
-
- logic [NUM_WORDS-1:0][DataWidth-1:0] rf_reg;
- logic [NUM_WORDS-1:1][DataWidth-1:0] rf_reg_q;
- logic [NUM_WORDS-1:1] we_a_dec;
-
- always_comb begin : we_a_decoder
- for (int unsigned i = 1; i < NUM_WORDS; i++) begin
- we_a_dec[i] = (waddr_a_i == 5'(i)) ? we_a_i : 1'b0;
- end
- end
-
- // No flops for R0 as it's hard-wired to 0
- for (genvar i = 1; i < NUM_WORDS; i++) begin : g_rf_flops
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rf_reg_q[i] <= '0;
- end else if(we_a_dec[i]) begin
- rf_reg_q[i] <= wdata_a_i;
- end
- end
- end
-
- // With dummy instructions enabled, R0 behaves as a real register but will always return 0 for
- // real instructions.
- if (DummyInstructions) begin : g_dummy_r0
- logic we_r0_dummy;
- logic [DataWidth-1:0] rf_r0_q;
-
- // Write enable for dummy R0 register (waddr_a_i will always be 0 for dummy instructions)
- assign we_r0_dummy = we_a_i & dummy_instr_id_i;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rf_r0_q <= '0;
- end else if (we_r0_dummy) begin
- rf_r0_q <= wdata_a_i;
- end
- end
-
- // Output the dummy data for dummy instructions, otherwise R0 reads as zero
- assign rf_reg[0] = dummy_instr_id_i ? rf_r0_q : '0;
-
- end else begin : g_normal_r0
- logic unused_dummy_instr_id;
- assign unused_dummy_instr_id = dummy_instr_id_i;
-
- // R0 is nil
- assign rf_reg[0] = '0;
- end
-
- assign rf_reg[NUM_WORDS-1:1] = rf_reg_q[NUM_WORDS-1:1];
-
- assign rdata_a_o = rf_reg[raddr_a_i];
- assign rdata_b_o = rf_reg[raddr_b_i];
-
- // Signal not used in FF register file
- // logic unused_test_en;
- // assign unused_test_en = test_en_i;
-
-endmodule
diff --git a/verilog/rtl/brq_wbu.sv b/verilog/rtl/brq_wbu.sv
deleted file mode 100644
index 54fa901..0000000
--- a/verilog/rtl/brq_wbu.sv
+++ /dev/null
@@ -1,214 +0,0 @@
-
-/**
- * Writeback Stage
- *
- * Writeback is an optional third pipeline stage. It writes data back to the register file that was
- * produced in the ID/EX stage or awaits a response to a load/store (LSU writes direct to register
- * file for load data). If the writeback stage is not present (WritebackStage == 0) this acts as
- * a simple passthrough to write data direct to the register file.
- */
-
-
-module brq_wbu #(
- parameter bit WritebackStage = 1'b0
-) (
- input logic clk_i,
- input logic rst_ni,
-
- input logic en_wb_i,
- input brq_pkg::wb_instr_type_e instr_type_wb_i,
- input logic [31:0] pc_id_i,
- input logic instr_is_compressed_id_i,
- input logic instr_perf_count_id_i,
-
- output logic ready_wb_o,
- output logic rf_write_wb_o,
- output logic outstanding_load_wb_o,
- output logic outstanding_store_wb_o,
- output logic [31:0] pc_wb_o,
- output logic perf_instr_ret_wb_o,
- output logic perf_instr_ret_compressed_wb_o,
-
- input logic [4:0] rf_waddr_id_i,
- input logic [31:0] rf_wdata_id_i,
- input logic rf_we_id_i,
-
- input logic [31:0] rf_wdata_lsu_i,
- input logic rf_we_lsu_i,
-
- output logic [31:0] rf_wdata_fwd_wb_o,
-
- output logic [4:0] rf_waddr_wb_o,
- output logic [31:0] rf_wdata_wb_o,
- output logic rf_we_wb_o,
-
- input logic lsu_resp_valid_i,
- input logic lsu_resp_err_i,
-
- output logic instr_done_wb_o,
-
- // floating point
- output logic fp_rf_write_wb_o,
- output logic fp_rf_wen_wb_o,
- output logic [4:0] fp_rf_waddr_wb_o,
- input logic [4:0] fp_rf_waddr_id_i,
- input logic fp_rf_wen_id_i,
- output logic [31:0] fp_rf_wdata_wb_o,
- input logic fp_load_i
-);
-
- import brq_pkg::*;
-
- // 0 == RF write from ID
- // 1 == RF write from LSU
- logic [31:0] rf_wdata_wb_mux[2];
- logic [1:0] rf_wdata_wb_mux_we;
-
- logic [31:0] fp_rf_wdata_wb_mux[2];
- logic [1:0] fp_rf_wdata_wb_mux_we;
-
- if(WritebackStage) begin : g_writeback_stage
- logic [31:0] rf_wdata_wb_q;
- logic rf_we_wb_q;
- logic [4:0] rf_waddr_wb_q;
-
- logic wb_done;
-
- logic wb_valid_q;
- logic [31:0] wb_pc_q;
- logic wb_compressed_q;
- logic wb_count_q;
- wb_instr_type_e wb_instr_type_q;
-
- logic wb_valid_d;
-
- logic fp_rf_we_wb_q;
- logic fp_load_q;
-
- // Stage becomes valid if an instruction enters for ID/EX and valid is cleared when instruction
- // is done
- assign wb_valid_d = (en_wb_i & ready_wb_o) | (wb_valid_q & ~wb_done);
-
- // Writeback for non load/store instructions always completes in a cycle (so instantly done)
- // Writeback for load/store must wait for response to be received by the LSU
- // Signal only relevant if wb_valid_q set
- assign wb_done = (wb_instr_type_q == WB_INSTR_OTHER) | lsu_resp_valid_i;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if(~rst_ni) begin
- wb_valid_q <= 1'b0;
- end else begin
- wb_valid_q <= wb_valid_d;
- end
- end
-
- always_ff @(posedge clk_i) begin
- if(en_wb_i) begin
- rf_we_wb_q <= rf_we_id_i;
- rf_waddr_wb_q <= rf_waddr_id_i;
- rf_wdata_wb_q <= rf_wdata_id_i;
- wb_instr_type_q <= instr_type_wb_i;
- wb_pc_q <= pc_id_i;
- wb_compressed_q <= instr_is_compressed_id_i;
- wb_count_q <= instr_perf_count_id_i;
-
- // added for floating point registers for wb stage
- fp_rf_we_wb_q <= fp_rf_wen_id_i;
- fp_load_q <= fp_load_i;
- end
- end
-
- assign rf_waddr_wb_o = rf_waddr_wb_q;
- assign rf_wdata_wb_mux[0] = rf_wdata_wb_q;
- assign rf_wdata_wb_mux_we[0] = rf_we_wb_q & wb_valid_q;
-
- assign fp_rf_waddr_wb_o = rf_waddr_wb_q; // no seperate datapath for rd address
- assign fp_rf_wdata_wb_mux[0] = rf_wdata_wb_q; // no seperate datapath for data bus
- assign fp_rf_wdata_wb_mux_we[0] = fp_rf_we_wb_q & wb_valid_q;
-
- assign ready_wb_o = ~wb_valid_q | wb_done;
-
- // Instruction in writeback will be writing to register file if either rf_we is set or writeback
- // is awaiting load data. This is used for determining RF read hazards in ID/EX
- assign rf_write_wb_o = wb_valid_q & (rf_we_wb_q | (wb_instr_type_q == WB_INSTR_LOAD));
- assign fp_rf_write_wb_o = wb_valid_q & (fp_rf_we_wb_q | (wb_instr_type_q == WB_INSTR_LOAD));
-
- assign outstanding_load_wb_o = wb_valid_q & (wb_instr_type_q == WB_INSTR_LOAD);
- assign outstanding_store_wb_o = wb_valid_q & (wb_instr_type_q == WB_INSTR_STORE);
-
- assign pc_wb_o = wb_pc_q;
-
- assign instr_done_wb_o = wb_valid_q & wb_done;
-
- // Increment instruction retire counters for valid instructions which are not lsu errors
- assign perf_instr_ret_wb_o = instr_done_wb_o & wb_count_q &
- ~(lsu_resp_valid_i & lsu_resp_err_i);
- assign perf_instr_ret_compressed_wb_o = perf_instr_ret_wb_o & wb_compressed_q;
-
- // Forward data that will be written to the RF back to ID to resolve data hazards. The flopped
- // rf_wdata_wb_q is used rather than rf_wdata_wb_o as the latter includes read data from memory
- // that returns too late to be used on the forwarding path.
- assign rf_wdata_fwd_wb_o = rf_wdata_wb_q;
-
- assign rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
- assign rf_wdata_wb_mux_we[1] = rf_we_lsu_i & ~fp_load_q;
-
- assign fp_rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
- assign fp_rf_wdata_wb_mux_we[1] = rf_we_lsu_i & fp_load_q;
- end else begin : g_bypass_wb
- // without writeback stage just pass through register write signals
- assign rf_waddr_wb_o = rf_waddr_id_i;
- assign rf_wdata_wb_mux[0] = rf_wdata_id_i;
- assign rf_wdata_wb_mux_we[0] = rf_we_id_i;
-
- // for floating point unit
- assign fp_rf_waddr_wb_o = rf_waddr_id_i; // no seperate datapath for rd address
- assign fp_rf_wdata_wb_mux[0] = rf_wdata_id_i; // no seperate datapath for data bus
- assign fp_rf_wdata_wb_mux_we[0] = fp_rf_wen_id_i;
-
- // Increment instruction retire counters for valid instructions which are not lsu errors
- assign perf_instr_ret_wb_o = instr_perf_count_id_i & en_wb_i &
- ~(lsu_resp_valid_i & lsu_resp_err_i);
- assign perf_instr_ret_compressed_wb_o = perf_instr_ret_wb_o & instr_is_compressed_id_i;
-
- // ready needs to be constant 1 without writeback stage (otherwise ID/EX stage will stall)
- assign ready_wb_o = 1'b1;
-
- // Unused Writeback stage only IO & wiring
- // Assign inputs and internal wiring to unused signals to satisfy lint checks
- // Tie-off outputs to constant values
- logic unused_clk;
- logic unused_rst;
- wb_instr_type_e unused_instr_type_wb;
- logic [31:0] unused_pc_id;
-
- assign unused_clk = clk_i;
- assign unused_rst = rst_ni;
- assign unused_instr_type_wb = instr_type_wb_i;
- assign unused_pc_id = pc_id_i;
-
- assign outstanding_load_wb_o = 1'b0;
- assign outstanding_store_wb_o = 1'b0;
- assign pc_wb_o = '0;
- assign rf_write_wb_o = 1'b0;
- assign rf_wdata_fwd_wb_o = 32'b0;
- assign instr_done_wb_o = 1'b0;
-
- assign rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
- assign rf_wdata_wb_mux_we[1] = rf_we_lsu_i & ~fp_load_i;
-
- assign fp_rf_wdata_wb_mux[1] = rf_wdata_lsu_i;
- assign fp_rf_wdata_wb_mux_we[1] = rf_we_lsu_i & fp_load_i;
- end
-
- // RF write data can come from ID results (all RF writes that aren't because of loads will come
- // from here) or the LSU (RF writes for load data)
- assign rf_wdata_wb_o = (rf_wdata_wb_mux_we[0]) ? rf_wdata_wb_mux[0] :
- rf_wdata_wb_mux[1];
- assign rf_we_wb_o = |rf_wdata_wb_mux_we;
-
- assign fp_rf_wdata_wb_o = fp_rf_wdata_wb_mux_we[0] ? fp_rf_wdata_wb_mux[0] :
- fp_rf_wdata_wb_mux[1];
- assign fp_rf_wen_wb_o = |fp_rf_wdata_wb_mux_we;
-
-endmodule
diff --git a/verilog/rtl/cf_math_pkg.sv b/verilog/rtl/cf_math_pkg.sv
deleted file mode 100644
index 9f35a44..0000000
--- a/verilog/rtl/cf_math_pkg.sv
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 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.
-
-/// cf_math_pkg: Constant Function Implementations of Mathematical Functions for HDL Elaboration
-///
-/// This package contains a collection of mathematical functions that are commonly used when defining
-/// the value of constants in HDL code. These functions are implemented as Verilog constants
-/// functions. Introduced in Verilog 2001 (IEEE Std 1364-2001), a constant function (§ 10.3.5) is a
-/// function whose value can be evaluated at compile time or during elaboration. A constant function
-/// must be called with arguments that are constants.
-package cf_math_pkg;
-
- /// Ceiled Division of Two Natural Numbers
- ///
- /// Returns the quotient of two natural numbers, rounded towards plus infinity.
- function automatic integer ceil_div (input longint dividend, input longint divisor);
- automatic longint remainder;
-
- // pragma translate_off
- `ifndef VERILATOR
- if (dividend < 0) begin
- $fatal(1, "Dividend %0d is not a natural number!", dividend);
- end
-
- if (divisor < 0) begin
- $fatal(1, "Divisor %0d is not a natural number!", divisor);
- end
-
- if (divisor == 0) begin
- $fatal(1, "Division by zero!");
- end
- `endif
- // pragma translate_on
-
- remainder = dividend;
- for (ceil_div = 0; remainder > 0; ceil_div++) begin
- remainder = remainder - divisor;
- end
- endfunction
-
- /// Index width required to be able to represent up to `num_idx` indices as a binary
- /// encoded signal.
- /// Ensures that the minimum width if an index signal is `1`, regardless of parametrization.
- ///
- /// Sample usage in type definition:
- /// As parameter:
- /// `parameter type idx_t = logic[cf_math_pkg::idx_width(NumIdx)-1:0]`
- /// As typedef:
- /// `typedef logic [cf_math_pkg::idx_width(NumIdx)-1:0] idx_t`
- function automatic integer unsigned idx_width (input integer unsigned num_idx);
- return (num_idx > 32'd1) ? unsigned'($clog2(num_idx)) : 32'd1;
- endfunction
-
-endpackage
diff --git a/verilog/rtl/control_mvp.sv b/verilog/rtl/control_mvp.sv
deleted file mode 100644
index 4c5364d..0000000
--- a/verilog/rtl/control_mvp.sv
+++ /dev/null
@@ -1,3413 +0,0 @@
-// Copyright 2018 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.
-
-////////////////////////////////////////////////////////////////////////////////
-// Company: IIS @ ETHZ - Federal Institute of Technology //
-// //
-// Engineers: Lei Li lile@iis.ee.ethz.ch //
-// //
-// Additional contributions by: //
-// //
-// //
-// //
-// Create Date: 04/03/2018 //
-// Design Name: FPU //
-// Module Name: control_mvp.sv //
-// Project Name: Private FPU //
-// Language: SystemVerilog //
-// //
-// Description: the control logic of div and sqrt //
-// //
-// Revision Date: 12/04/2018 //
-// Lei Li //
-// To address some requirements by Stefan and add low power //
-// control for special cases //
-// Revision Date: 13/04/2018 //
-// Lei Li //
-// To fix some bug found in Control FSM //
-// when Iteration_unit_num_S = 2'b10 //
-// //
-// //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-import defs_div_sqrt_mvp::*;
-
-module control_mvp
-
- (//Input
- input logic Clk_CI,
- input logic Rst_RBI,
- input logic Div_start_SI ,
- input logic Sqrt_start_SI,
- input logic Start_SI,
- input logic Kill_SI,
- input logic Special_case_SBI,
- input logic Special_case_dly_SBI,
- input logic [C_PC-1:0] Precision_ctl_SI,
- input logic [1:0] Format_sel_SI,
- input logic [C_MANT_FP64:0] Numerator_DI,
- input logic [C_EXP_FP64:0] Exp_num_DI,
- input logic [C_MANT_FP64:0] Denominator_DI,
- input logic [C_EXP_FP64:0] Exp_den_DI,
-
-
- output logic Div_start_dly_SO ,
- output logic Sqrt_start_dly_SO,
- output logic Div_enable_SO,
- output logic Sqrt_enable_SO,
-
-
- //To next stage
- output logic Full_precision_SO,
- output logic FP32_SO,
- output logic FP64_SO,
- output logic FP16_SO,
- output logic FP16ALT_SO,
-
- output logic Ready_SO,
- output logic Done_SO,
-
- output logic [C_MANT_FP64+4:0] Mant_result_prenorm_DO,
- // output logic [3:0] Round_bit_DO,
- output logic [C_EXP_FP64+1:0] Exp_result_prenorm_DO
- );
-
- logic [C_MANT_FP64+1+4:0] Partial_remainder_DN,Partial_remainder_DP; //58bits,r=q+2
- logic [C_MANT_FP64+4:0] Quotient_DP; //57bits
- /////////////////////////////////////////////////////////////////////////////
- // Assign Inputs //
- /////////////////////////////////////////////////////////////////////////////
- logic [C_MANT_FP64+1:0] Numerator_se_D; //sign extension and hidden bit
- logic [C_MANT_FP64+1:0] Denominator_se_D; //signa extension and hidden bit
- logic [C_MANT_FP64+1:0] Denominator_se_DB; //1's complement
-
- assign Numerator_se_D={1'b0,Numerator_DI};
-
- assign Denominator_se_D={1'b0,Denominator_DI};
-
- always_comb
- begin
- if(FP32_SO)
- begin
- Denominator_se_DB={~Denominator_se_D[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP32], {(C_MANT_FP64-C_MANT_FP32){1'b0}} };
- end
- else if(FP64_SO) begin
- Denominator_se_DB=~Denominator_se_D;
- end
- else if(FP16_SO) begin
- Denominator_se_DB={~Denominator_se_D[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP16], {(C_MANT_FP64-C_MANT_FP16){1'b0}} };
- end
- else begin
- Denominator_se_DB={~Denominator_se_D[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP16ALT], {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} };
- end
- end
-
-
- logic [C_MANT_FP64+1:0] Mant_D_sqrt_Norm;
-
- assign Mant_D_sqrt_Norm=Exp_num_DI[0]?{1'b0,Numerator_DI}:{Numerator_DI,1'b0}; //for sqrt
-
- /////////////////////////////////////////////////////////////////////////////
- // Format Selection //
- /////////////////////////////////////////////////////////////////////////////
- logic [1:0] Format_sel_S;
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Format_sel_S<='b0;
- end
- else if(Start_SI&&Ready_SO)
- begin
- Format_sel_S<=Format_sel_SI;
- end
- else
- begin
- Format_sel_S<=Format_sel_S;
- end
- end
-
- assign FP32_SO = (Format_sel_S==2'b00);
- assign FP64_SO = (Format_sel_S==2'b01);
- assign FP16_SO = (Format_sel_S==2'b10);
- assign FP16ALT_SO = (Format_sel_S==2'b11);
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Precision Control //
- /////////////////////////////////////////////////////////////////////////////
-
- logic [C_PC-1:0] Precision_ctl_S;
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Precision_ctl_S<='b0;
- end
- else if(Start_SI&&Ready_SO)
- begin
- Precision_ctl_S<=Precision_ctl_SI;
- end
- else
- begin
- Precision_ctl_S<=Precision_ctl_S;
- end
- end
- assign Full_precision_SO = (Precision_ctl_S==6'h00);
-
-
-
- logic [5:0] State_ctl_S;
- logic [5:0] State_Two_iteration_unit_S;
- logic [5:0] State_Four_iteration_unit_S;
-
- assign State_Two_iteration_unit_S = Precision_ctl_S[C_PC-1:1]; //Two iteration units
- assign State_Four_iteration_unit_S = Precision_ctl_S[C_PC-1:2]; //Four iteration units
- always_comb
- begin
- case(Iteration_unit_num_S)
-//////////////////////one iteration unit, start///////////////////////////////////////
- 2'b00: //one iteration unit
- begin
- case(Format_sel_S)
- 2'b00: //FP32
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h1b; //24+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = Precision_ctl_S;
- end
- end
- 2'b01: //FP64
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h38; //53+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = Precision_ctl_S;
- end
- end
- 2'b10: //FP16
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h0e; //11+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = Precision_ctl_S;
- end
- end
- 2'b11: //FP16ALT
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h0b; //8+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = Precision_ctl_S;
- end
- end
- endcase
- end
-//////////////////////one iteration unit, end///////////////////////////////////////
-
-//////////////////////two iteration units, start///////////////////////////////////////
- 2'b01: //two iteration units
- begin
- case(Format_sel_S)
- 2'b00: //FP32
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h0d; //24+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = State_Two_iteration_unit_S;
- end
- end
- 2'b01: //FP64
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h1b; //53+3 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = State_Two_iteration_unit_S;
- end
- end
- 2'b10: //FP16
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h06; //11+3 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = State_Two_iteration_unit_S;
- end
- end
- 2'b11: //FP16ALT
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h05; //8+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = State_Two_iteration_unit_S;
- end
- end
- endcase
- end
-//////////////////////two iteration units, end///////////////////////////////////////
-
-//////////////////////three iteration units, start///////////////////////////////////////
- 2'b10: //three iteration units
- begin
- case(Format_sel_S)
- 2'b00: //FP32
- begin
- case(Precision_ctl_S)
- 6'h00:
- begin
- State_ctl_S = 6'h08; //24+3 more iterations for rounding bits
- end
- 6'h06,6'h07,6'h08:
- begin
- State_ctl_S = 6'h02;
- end
- 6'h09,6'h0a,6'h0b:
- begin
- State_ctl_S = 6'h03;
- end
- 6'h0c,6'h0d,6'h0e:
- begin
- State_ctl_S = 6'h04;
- end
- 6'h0f,6'h10,6'h11:
- begin
- State_ctl_S = 6'h05;
- end
- 6'h12,6'h13,6'h14:
- begin
- State_ctl_S = 6'h06;
- end
- 6'h15,6'h16,6'h17:
- begin
- State_ctl_S = 6'h07;
- end
- default:
- begin
- State_ctl_S = 6'h08; //24+3 more iterations for rounding bits
- end
- endcase
- end
- 2'b01: //FP64
- begin
- case(Precision_ctl_S)
- 6'h00:
- begin
- State_ctl_S = 6'h12; //53+4 more iterations for rounding bits
- end
- 6'h06,6'h07,6'h08:
- begin
- State_ctl_S = 6'h02;
- end
- 6'h09,6'h0a,6'h0b:
- begin
- State_ctl_S = 6'h03;
- end
- 6'h0c,6'h0d,6'h0e:
- begin
- State_ctl_S = 6'h04;
- end
- 6'h0f,6'h10,6'h11:
- begin
- State_ctl_S = 6'h05;
- end
- 6'h12,6'h13,6'h14:
- begin
- State_ctl_S = 6'h06;
- end
- 6'h15,6'h16,6'h17:
- begin
- State_ctl_S = 6'h07;
- end
- 6'h18,6'h19,6'h1a:
- begin
- State_ctl_S = 6'h08;
- end
- 6'h1b,6'h1c,6'h1d:
- begin
- State_ctl_S = 6'h09;
- end
- 6'h1e,6'h1f,6'h20:
- begin
- State_ctl_S = 6'h0a;
- end
- 6'h21,6'h22,6'h23:
- begin
- State_ctl_S = 6'h0b;
- end
- 6'h24,6'h25,6'h26:
- begin
- State_ctl_S = 6'h0c;
- end
- 6'h27,6'h28,6'h29:
- begin
- State_ctl_S = 6'h0d;
- end
- 6'h2a,6'h2b,6'h2c:
- begin
- State_ctl_S = 6'h0e;
- end
- 6'h2d,6'h2e,6'h2f:
- begin
- State_ctl_S = 6'h0f;
- end
- 6'h30,6'h31,6'h32:
- begin
- State_ctl_S = 6'h10;
- end
- 6'h33,6'h34,6'h35:
- begin
- State_ctl_S = 6'h11;
- end
- default:
- begin
- State_ctl_S = 6'h12; //53+4 more iterations for rounding bits
- end
- endcase
- end
- 2'b10: //FP16
- begin
- case(Precision_ctl_S)
- 6'h00:
- begin
- State_ctl_S = 6'h04; //12+3 more iterations for rounding bits
- end
- 6'h06,6'h07,6'h08:
- begin
- State_ctl_S = 6'h02;
- end
- 6'h09,6'h0a,6'h0b:
- begin
- State_ctl_S = 6'h03;
- end
- default:
- begin
- State_ctl_S = 6'h04; //12+3 more iterations for rounding bits
- end
- endcase
- end
- 2'b11: //FP16ALT
- begin
- case(Precision_ctl_S)
- 6'h00:
- begin
- State_ctl_S = 6'h03; //8+4 more iterations for rounding bits
- end
- 6'h06,6'h07,6'h08:
- begin
- State_ctl_S = 6'h02;
- end
- default:
- begin
- State_ctl_S = 6'h03; //8+4 more iterations for rounding bits
- end
- endcase
- end
- endcase
- end
-//////////////////////three iteration units, end///////////////////////////////////////
-
-//////////////////////four iteration units, start///////////////////////////////////////
- 2'b11: //four iteration units
- begin
- case(Format_sel_S)
- 2'b00: //FP32
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h06; //24+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = State_Four_iteration_unit_S;
- end
- end
- 2'b01: //FP64
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h0d; //53+3 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = State_Four_iteration_unit_S;
- end
- end
- 2'b10: //FP16
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h03; //11+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = State_Four_iteration_unit_S;
- end
- end
- 2'b11: //FP16ALT
- begin
- if(Full_precision_SO)
- begin
- State_ctl_S = 6'h02; //8+4 more iterations for rounding bits
- end
- else
- begin
- State_ctl_S = State_Four_iteration_unit_S;
- end
- end
- endcase
- end
-//////////////////////four iteration units, end///////////////////////////////////////
-
- endcase
- end
-
-
- /////////////////////////////////////////////////////////////////////////////
- // control logic //
- /////////////////////////////////////////////////////////////////////////////
-
- logic Div_start_dly_S;
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) // generate Div_start_dly_S signal
- begin
- if(~Rst_RBI)
- begin
- Div_start_dly_S<=1'b0;
- end
- else if(Div_start_SI&&Ready_SO)
- begin
- Div_start_dly_S<=1'b1;
- end
- else
- begin
- Div_start_dly_S<=1'b0;
- end
- end
-
- assign Div_start_dly_SO=Div_start_dly_S;
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) begin // generate Div_enable_SO signal
- if(~Rst_RBI)
- Div_enable_SO<=1'b0;
- // Synchronous rst_ni with Flush
- else if (Kill_SI)
- Div_enable_SO <= 1'b0;
- else if(Div_start_SI&&Ready_SO)
- Div_enable_SO<=1'b1;
- else if(Done_SO)
- Div_enable_SO<=1'b0;
- else
- Div_enable_SO<=Div_enable_SO;
- end
-
- logic Sqrt_start_dly_S;
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) // generate Sqrt_start_dly_SI signal
- begin
- if(~Rst_RBI)
- begin
- Sqrt_start_dly_S<=1'b0;
- end
- else if(Sqrt_start_SI&&Ready_SO)
- begin
- Sqrt_start_dly_S<=1'b1;
- end
- else
- begin
- Sqrt_start_dly_S<=1'b0;
- end
- end
- assign Sqrt_start_dly_SO=Sqrt_start_dly_S;
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) begin // generate Sqrt_enable_SO signal
- if(~Rst_RBI)
- Sqrt_enable_SO<=1'b0;
- else if (Kill_SI)
- Sqrt_enable_SO <= 1'b0;
- else if(Sqrt_start_SI&&Ready_SO)
- Sqrt_enable_SO<=1'b1;
- else if(Done_SO)
- Sqrt_enable_SO<=1'b0;
- else
- Sqrt_enable_SO<=Sqrt_enable_SO;
- end
-
- logic [5:0] Crtl_cnt_S;
- logic Start_dly_S;
-
- assign Start_dly_S=Div_start_dly_S |Sqrt_start_dly_S;
-
- logic Fsm_enable_S;
- assign Fsm_enable_S=( (Start_dly_S | (| Crtl_cnt_S)) && (~Kill_SI) && Special_case_dly_SBI);
-
- logic Final_state_S;
- assign Final_state_S= (Crtl_cnt_S==State_ctl_S);
-
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) //control_FSM
- begin
- if (~Rst_RBI)
- begin
- Crtl_cnt_S <= '0;
- end
- else if (Final_state_S | Kill_SI)
- begin
- Crtl_cnt_S <= '0;
- end
- else if(Fsm_enable_S) // one cycle Start_SI
- begin
- Crtl_cnt_S <= Crtl_cnt_S+1;
- end
- else
- begin
- Crtl_cnt_S <= '0;
- end
- end // always_ff
-
-
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) //Generate Done_SO, they can share this Done_SO.
- begin
- if(~Rst_RBI)
- begin
- Done_SO<=1'b0;
- end
- else if(Start_SI&&Ready_SO)
- begin
- if(~Special_case_SBI)
- begin
- Done_SO<=1'b1;
- end
- else
- begin
- Done_SO<=1'b0;
- end
- end
- else if(Final_state_S)
- begin
- Done_SO<=1'b1;
- end
- else
- begin
- Done_SO<=1'b0;
- end
- end
-
-
-
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) //Generate Ready_SO
- begin
- if(~Rst_RBI)
- begin
- Ready_SO<=1'b1;
- end
-
- else if(Start_SI&&Ready_SO)
- begin
- if(~Special_case_SBI)
- begin
- Ready_SO<=1'b1;
- end
- else
- begin
- Ready_SO<=1'b0;
- end
- end
- else if(Final_state_S | Kill_SI)
- begin
- Ready_SO<=1'b1;
- end
- else
- begin
- Ready_SO<=Ready_SO;
- end
- end
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Declarations for square root when Iteration_unit_num_S = 2'b00, start //
- ////////////////////////////////////////////////////////////////////////////
-
- logic Qcnt_one_0;
- logic Qcnt_one_1;
- logic [1:0] Qcnt_one_2;
- logic [2:0] Qcnt_one_3;
- logic [3:0] Qcnt_one_4;
- logic [4:0] Qcnt_one_5;
- logic [5:0] Qcnt_one_6;
- logic [6:0] Qcnt_one_7;
- logic [7:0] Qcnt_one_8;
- logic [8:0] Qcnt_one_9;
- logic [9:0] Qcnt_one_10;
- logic [10:0] Qcnt_one_11;
- logic [11:0] Qcnt_one_12;
- logic [12:0] Qcnt_one_13;
- logic [13:0] Qcnt_one_14;
- logic [14:0] Qcnt_one_15;
- logic [15:0] Qcnt_one_16;
- logic [16:0] Qcnt_one_17;
- logic [17:0] Qcnt_one_18;
- logic [18:0] Qcnt_one_19;
- logic [19:0] Qcnt_one_20;
- logic [20:0] Qcnt_one_21;
- logic [21:0] Qcnt_one_22;
- logic [22:0] Qcnt_one_23;
- logic [23:0] Qcnt_one_24;
- logic [24:0] Qcnt_one_25;
- logic [25:0] Qcnt_one_26;
- logic [26:0] Qcnt_one_27;
- logic [27:0] Qcnt_one_28;
- logic [28:0] Qcnt_one_29;
- logic [29:0] Qcnt_one_30;
- logic [30:0] Qcnt_one_31;
- logic [31:0] Qcnt_one_32;
- logic [32:0] Qcnt_one_33;
- logic [33:0] Qcnt_one_34;
- logic [34:0] Qcnt_one_35;
- logic [35:0] Qcnt_one_36;
- logic [36:0] Qcnt_one_37;
- logic [37:0] Qcnt_one_38;
- logic [38:0] Qcnt_one_39;
- logic [39:0] Qcnt_one_40;
- logic [40:0] Qcnt_one_41;
- logic [41:0] Qcnt_one_42;
- logic [42:0] Qcnt_one_43;
- logic [43:0] Qcnt_one_44;
- logic [44:0] Qcnt_one_45;
- logic [45:0] Qcnt_one_46;
- logic [46:0] Qcnt_one_47;
- logic [47:0] Qcnt_one_48;
- logic [48:0] Qcnt_one_49;
- logic [49:0] Qcnt_one_50;
- logic [50:0] Qcnt_one_51;
- logic [51:0] Qcnt_one_52;
- logic [52:0] Qcnt_one_53;
- logic [53:0] Qcnt_one_54;
- logic [54:0] Qcnt_one_55;
- logic [55:0] Qcnt_one_56;
- logic [56:0] Qcnt_one_57;
- logic [57:0] Qcnt_one_58;
- logic [58:0] Qcnt_one_59;
- logic [59:0] Qcnt_one_60;
-
- /////////////////////////////////////////////////////////////////////////////
- // Declarations for square root when Iteration_unit_num_S = 2'b00, end //
- ////////////////////////////////////////////////////////////////////////////
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Declarations for square root when Iteration_unit_num_S = 2'b01, start //
- ////////////////////////////////////////////////////////////////////////////
- logic [1:0] Qcnt_two_0;
- logic [2:0] Qcnt_two_1;
- logic [4:0] Qcnt_two_2;
- logic [6:0] Qcnt_two_3;
- logic [8:0] Qcnt_two_4;
- logic [10:0] Qcnt_two_5;
- logic [12:0] Qcnt_two_6;
- logic [14:0] Qcnt_two_7;
- logic [16:0] Qcnt_two_8;
- logic [18:0] Qcnt_two_9;
- logic [20:0] Qcnt_two_10;
- logic [22:0] Qcnt_two_11;
- logic [24:0] Qcnt_two_12;
- logic [26:0] Qcnt_two_13;
- logic [28:0] Qcnt_two_14;
- logic [30:0] Qcnt_two_15;
- logic [32:0] Qcnt_two_16;
- logic [34:0] Qcnt_two_17;
- logic [36:0] Qcnt_two_18;
- logic [38:0] Qcnt_two_19;
- logic [40:0] Qcnt_two_20;
- logic [42:0] Qcnt_two_21;
- logic [44:0] Qcnt_two_22;
- logic [46:0] Qcnt_two_23;
- logic [48:0] Qcnt_two_24;
- logic [50:0] Qcnt_two_25;
- logic [52:0] Qcnt_two_26;
- logic [54:0] Qcnt_two_27;
- logic [56:0] Qcnt_two_28;
- /////////////////////////////////////////////////////////////////////////////
- // Declarations for square root when Iteration_unit_num_S = 2'b01, end //
- ////////////////////////////////////////////////////////////////////////////
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Declarations for square root when Iteration_unit_num_S = 2'b10, start //
- ////////////////////////////////////////////////////////////////////////////
- logic [2:0] Qcnt_three_0;
- logic [4:0] Qcnt_three_1;
- logic [7:0] Qcnt_three_2;
- logic [10:0] Qcnt_three_3;
- logic [13:0] Qcnt_three_4;
- logic [16:0] Qcnt_three_5;
- logic [19:0] Qcnt_three_6;
- logic [22:0] Qcnt_three_7;
- logic [25:0] Qcnt_three_8;
- logic [28:0] Qcnt_three_9;
- logic [31:0] Qcnt_three_10;
- logic [34:0] Qcnt_three_11;
- logic [37:0] Qcnt_three_12;
- logic [40:0] Qcnt_three_13;
- logic [43:0] Qcnt_three_14;
- logic [46:0] Qcnt_three_15;
- logic [49:0] Qcnt_three_16;
- logic [52:0] Qcnt_three_17;
- logic [55:0] Qcnt_three_18;
- logic [58:0] Qcnt_three_19;
- logic [61:0] Qcnt_three_20;
- /////////////////////////////////////////////////////////////////////////////
- // Declarations for square root when Iteration_unit_num_S = 2'b10, end //
- ////////////////////////////////////////////////////////////////////////////
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Declarations for square root when Iteration_unit_num_S = 2'b11, start //
- ////////////////////////////////////////////////////////////////////////////
- logic [3:0] Qcnt_four_0;
- logic [6:0] Qcnt_four_1;
- logic [10:0] Qcnt_four_2;
- logic [14:0] Qcnt_four_3;
- logic [18:0] Qcnt_four_4;
- logic [22:0] Qcnt_four_5;
- logic [26:0] Qcnt_four_6;
- logic [30:0] Qcnt_four_7;
- logic [34:0] Qcnt_four_8;
- logic [38:0] Qcnt_four_9;
- logic [42:0] Qcnt_four_10;
- logic [46:0] Qcnt_four_11;
- logic [50:0] Qcnt_four_12;
- logic [54:0] Qcnt_four_13;
- logic [58:0] Qcnt_four_14;
-
- /////////////////////////////////////////////////////////////////////////////
- // Declarations for square root when Iteration_unit_num_S = 2'b11, end //
- ////////////////////////////////////////////////////////////////////////////
-
-
-
- logic [C_MANT_FP64+1+4:0] Sqrt_R0,Sqrt_Q0,Q_sqrt0,Q_sqrt_com_0;
- logic [C_MANT_FP64+1+4:0] Sqrt_R1,Sqrt_Q1,Q_sqrt1,Q_sqrt_com_1;
- logic [C_MANT_FP64+1+4:0] Sqrt_R2,Sqrt_Q2,Q_sqrt2,Q_sqrt_com_2;
- logic [C_MANT_FP64+1+4:0] Sqrt_R3,Sqrt_Q3,Q_sqrt3,Q_sqrt_com_3,Sqrt_R4; //Sqrt_Q4;
-
-
- logic [1:0] Sqrt_DI [3:0];
- logic [1:0] Sqrt_DO [3:0];
- logic Sqrt_carry_DO;
-
-
- logic [C_MANT_FP64+1+4:0] Iteration_cell_a_D [3:0];
- logic [C_MANT_FP64+1+4:0] Iteration_cell_b_D [3:0];
- logic [C_MANT_FP64+1+4:0] Iteration_cell_a_BMASK_D [3:0];
- logic [C_MANT_FP64+1+4:0] Iteration_cell_b_BMASK_D [3:0];
- logic Iteration_cell_carry_D [3:0];
- logic [C_MANT_FP64+1+4:0] Iteration_cell_sum_D [3:0];
- logic [C_MANT_FP64+1+4:0] Iteration_cell_sum_AMASK_D [3:0];
-
-
- logic [3:0] Sqrt_quotinent_S;
-
-
- always_comb
- begin //
- case (Format_sel_S)
- 2'b00:
- begin
- Sqrt_quotinent_S = {(~Iteration_cell_sum_AMASK_D[0][C_MANT_FP32+5]),(~Iteration_cell_sum_AMASK_D[1][C_MANT_FP32+5]),(~Iteration_cell_sum_AMASK_D[2][C_MANT_FP32+5]),(~Iteration_cell_sum_AMASK_D[3][C_MANT_FP32+5])};
- Q_sqrt_com_0 ={ {(C_MANT_FP64-C_MANT_FP32){1'b0}},~Q_sqrt0[C_MANT_FP32+5:0] };
- Q_sqrt_com_1 ={ {(C_MANT_FP64-C_MANT_FP32){1'b0}},~Q_sqrt1[C_MANT_FP32+5:0] };
- Q_sqrt_com_2 ={ {(C_MANT_FP64-C_MANT_FP32){1'b0}},~Q_sqrt2[C_MANT_FP32+5:0] };
- Q_sqrt_com_3 ={ {(C_MANT_FP64-C_MANT_FP32){1'b0}},~Q_sqrt3[C_MANT_FP32+5:0] };
- end
- 2'b01:
- begin
- Sqrt_quotinent_S = {Iteration_cell_carry_D[0],Iteration_cell_carry_D[1],Iteration_cell_carry_D[2],Iteration_cell_carry_D[3]};
- Q_sqrt_com_0=~Q_sqrt0;
- Q_sqrt_com_1=~Q_sqrt1;
- Q_sqrt_com_2=~Q_sqrt2;
- Q_sqrt_com_3=~Q_sqrt3;
- end
- 2'b10:
- begin
- Sqrt_quotinent_S = {(~Iteration_cell_sum_AMASK_D[0][C_MANT_FP16+5]),(~Iteration_cell_sum_AMASK_D[1][C_MANT_FP16+5]),(~Iteration_cell_sum_AMASK_D[2][C_MANT_FP16+5]),(~Iteration_cell_sum_AMASK_D[3][C_MANT_FP16+5])};
- Q_sqrt_com_0 ={ {(C_MANT_FP64-C_MANT_FP16){1'b0}},~Q_sqrt0[C_MANT_FP16+5:0] };
- Q_sqrt_com_1 ={ {(C_MANT_FP64-C_MANT_FP16){1'b0}},~Q_sqrt1[C_MANT_FP16+5:0] };
- Q_sqrt_com_2 ={ {(C_MANT_FP64-C_MANT_FP16){1'b0}},~Q_sqrt2[C_MANT_FP16+5:0] };
- Q_sqrt_com_3 ={ {(C_MANT_FP64-C_MANT_FP16){1'b0}},~Q_sqrt3[C_MANT_FP16+5:0] };
- end
- 2'b11:
- begin
- Sqrt_quotinent_S = {(~Iteration_cell_sum_AMASK_D[0][C_MANT_FP16ALT+5]),(~Iteration_cell_sum_AMASK_D[1][C_MANT_FP16ALT+5]),(~Iteration_cell_sum_AMASK_D[2][C_MANT_FP16ALT+5]),(~Iteration_cell_sum_AMASK_D[3][C_MANT_FP16ALT+5])};
- Q_sqrt_com_0 ={ {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}},~Q_sqrt0[C_MANT_FP16ALT+5:0] };
- Q_sqrt_com_1 ={ {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}},~Q_sqrt1[C_MANT_FP16ALT+5:0] };
- Q_sqrt_com_2 ={ {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}},~Q_sqrt2[C_MANT_FP16ALT+5:0] };
- Q_sqrt_com_3 ={ {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}},~Q_sqrt3[C_MANT_FP16ALT+5:0] };
- end
- endcase
- end
-
-
-
- assign Qcnt_one_0= {1'b0}; //qk for each feedback
- assign Qcnt_one_1= {Quotient_DP[0]};
- assign Qcnt_one_2= {Quotient_DP[1:0]};
- assign Qcnt_one_3= {Quotient_DP[2:0]};
- assign Qcnt_one_4= {Quotient_DP[3:0]};
- assign Qcnt_one_5= {Quotient_DP[4:0]};
- assign Qcnt_one_6= {Quotient_DP[5:0]};
- assign Qcnt_one_7= {Quotient_DP[6:0]};
- assign Qcnt_one_8= {Quotient_DP[7:0]};
- assign Qcnt_one_9= {Quotient_DP[8:0]};
- assign Qcnt_one_10= {Quotient_DP[9:0]};
- assign Qcnt_one_11= {Quotient_DP[10:0]};
- assign Qcnt_one_12= {Quotient_DP[11:0]};
- assign Qcnt_one_13= {Quotient_DP[12:0]};
- assign Qcnt_one_14= {Quotient_DP[13:0]};
- assign Qcnt_one_15= {Quotient_DP[14:0]};
- assign Qcnt_one_16= {Quotient_DP[15:0]};
- assign Qcnt_one_17= {Quotient_DP[16:0]};
- assign Qcnt_one_18= {Quotient_DP[17:0]};
- assign Qcnt_one_19= {Quotient_DP[18:0]};
- assign Qcnt_one_20= {Quotient_DP[19:0]};
- assign Qcnt_one_21= {Quotient_DP[20:0]};
- assign Qcnt_one_22= {Quotient_DP[21:0]};
- assign Qcnt_one_23= {Quotient_DP[22:0]};
- assign Qcnt_one_24= {Quotient_DP[23:0]};
- assign Qcnt_one_25= {Quotient_DP[24:0]};
- assign Qcnt_one_26= {Quotient_DP[25:0]};
- assign Qcnt_one_27= {Quotient_DP[26:0]};
- assign Qcnt_one_28= {Quotient_DP[27:0]};
- assign Qcnt_one_29= {Quotient_DP[28:0]};
- assign Qcnt_one_30= {Quotient_DP[29:0]};
- assign Qcnt_one_31= {Quotient_DP[30:0]};
- assign Qcnt_one_32= {Quotient_DP[31:0]};
- assign Qcnt_one_33= {Quotient_DP[32:0]};
- assign Qcnt_one_34= {Quotient_DP[33:0]};
- assign Qcnt_one_35= {Quotient_DP[34:0]};
- assign Qcnt_one_36= {Quotient_DP[35:0]};
- assign Qcnt_one_37= {Quotient_DP[36:0]};
- assign Qcnt_one_38= {Quotient_DP[37:0]};
- assign Qcnt_one_39= {Quotient_DP[38:0]};
- assign Qcnt_one_40= {Quotient_DP[39:0]};
- assign Qcnt_one_41= {Quotient_DP[40:0]};
- assign Qcnt_one_42= {Quotient_DP[41:0]};
- assign Qcnt_one_43= {Quotient_DP[42:0]};
- assign Qcnt_one_44= {Quotient_DP[43:0]};
- assign Qcnt_one_45= {Quotient_DP[44:0]};
- assign Qcnt_one_46= {Quotient_DP[45:0]};
- assign Qcnt_one_47= {Quotient_DP[46:0]};
- assign Qcnt_one_48= {Quotient_DP[47:0]};
- assign Qcnt_one_49= {Quotient_DP[48:0]};
- assign Qcnt_one_50= {Quotient_DP[49:0]};
- assign Qcnt_one_51= {Quotient_DP[50:0]};
- assign Qcnt_one_52= {Quotient_DP[51:0]};
- assign Qcnt_one_53= {Quotient_DP[52:0]};
- assign Qcnt_one_54= {Quotient_DP[53:0]};
- assign Qcnt_one_55= {Quotient_DP[54:0]};
- assign Qcnt_one_56= {Quotient_DP[55:0]};
- assign Qcnt_one_57= {Quotient_DP[56:0]};
-
-
- assign Qcnt_two_0 = {1'b0, Sqrt_quotinent_S[3]}; //qk for each feedback
- assign Qcnt_two_1 = {Quotient_DP[1:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_2 = {Quotient_DP[3:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_3 = {Quotient_DP[5:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_4 = {Quotient_DP[7:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_5 = {Quotient_DP[9:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_6 = {Quotient_DP[11:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_7 = {Quotient_DP[13:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_8 = {Quotient_DP[15:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_9 = {Quotient_DP[17:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_10 = {Quotient_DP[19:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_11 = {Quotient_DP[21:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_12 = {Quotient_DP[23:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_13 = {Quotient_DP[25:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_14 = {Quotient_DP[27:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_15 = {Quotient_DP[29:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_16 = {Quotient_DP[31:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_17 = {Quotient_DP[33:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_18 = {Quotient_DP[35:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_19 = {Quotient_DP[37:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_20 = {Quotient_DP[39:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_21 = {Quotient_DP[41:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_22 = {Quotient_DP[43:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_23 = {Quotient_DP[45:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_24 = {Quotient_DP[47:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_25 = {Quotient_DP[49:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_26 = {Quotient_DP[51:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_27 = {Quotient_DP[53:0],Sqrt_quotinent_S[3]};
- assign Qcnt_two_28 = {Quotient_DP[55:0],Sqrt_quotinent_S[3]};
-
-
- assign Qcnt_three_0 = {1'b0, Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]}; //qk for each feedback
- assign Qcnt_three_1 = {Quotient_DP[2:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_2 = {Quotient_DP[5:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_3 = {Quotient_DP[8:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_4 = {Quotient_DP[11:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_5 = {Quotient_DP[14:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_6 = {Quotient_DP[17:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_7 = {Quotient_DP[20:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_8 = {Quotient_DP[23:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_9 = {Quotient_DP[26:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_10 = {Quotient_DP[29:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_11 = {Quotient_DP[32:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_12 = {Quotient_DP[35:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_13 = {Quotient_DP[38:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_14 = {Quotient_DP[41:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_15 = {Quotient_DP[44:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_16 = {Quotient_DP[47:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_17 = {Quotient_DP[50:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_18 = {Quotient_DP[53:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
- assign Qcnt_three_19 = {Quotient_DP[56:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2]};
-
-
- assign Qcnt_four_0 = {1'b0, Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_1 = {Quotient_DP[3:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_2 = {Quotient_DP[7:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_3 = {Quotient_DP[11:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_4 = {Quotient_DP[15:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_5 = {Quotient_DP[19:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_6 = {Quotient_DP[23:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_7 = {Quotient_DP[27:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_8 = {Quotient_DP[31:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_9 = {Quotient_DP[35:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_10 = {Quotient_DP[39:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_11 = {Quotient_DP[43:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_12 = {Quotient_DP[47:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_13 = {Quotient_DP[51:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
- assign Qcnt_four_14 = {Quotient_DP[55:0],Sqrt_quotinent_S[3],Sqrt_quotinent_S[2],Sqrt_quotinent_S[1]};
-
-
-
-
- always_comb begin // the intermediate operands for sqrt
-
- case(Iteration_unit_num_S)
- 2'b00:
- begin
-
- /////////////////////////////////////////////////////////////////////////////
- // Operands for square root when Iteration_unit_num_S = 2'b00, start //
- /////////////////////////////////////////////////////////////////////////////
-
-
-
-
- case(Crtl_cnt_S)
-
- 6'b000000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64];
- Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_one_0};
- Sqrt_Q0=Q_sqrt_com_0;
- end
- 6'b000001:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2];
- Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_one_1};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b000010:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4];
- Q_sqrt0={{(C_MANT_FP64+4){1'b0}},Qcnt_one_2};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b000011:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6];
- Q_sqrt0={{(C_MANT_FP64+3){1'b0}},Qcnt_one_3};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b000100:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-7:C_MANT_FP64-8];
- Q_sqrt0={{(C_MANT_FP64+2){1'b0}},Qcnt_one_4};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b000101:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-9:C_MANT_FP64-10];
- Q_sqrt0={{(C_MANT_FP64+1){1'b0}},Qcnt_one_5};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b000110:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-11:C_MANT_FP64-12];
- Q_sqrt0={{(C_MANT_FP64){1'b0}},Qcnt_one_6};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b000111:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-13:C_MANT_FP64-14];
- Q_sqrt0={{(C_MANT_FP64-1){1'b0}},Qcnt_one_7};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b001000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-15:C_MANT_FP64-16];
- Q_sqrt0={{(C_MANT_FP64-2){1'b0}},Qcnt_one_8};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b001001:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-17:C_MANT_FP64-18];
- Q_sqrt0={{(C_MANT_FP64-3){1'b0}},Qcnt_one_9};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b001010:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-19:C_MANT_FP64-20];
- Q_sqrt0={{(C_MANT_FP64-4){1'b0}},Qcnt_one_10};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b001011:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-21:C_MANT_FP64-22];
- Q_sqrt0={{(C_MANT_FP64-5){1'b0}},Qcnt_one_11};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b001100:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-23:C_MANT_FP64-24];
- Q_sqrt0={{(C_MANT_FP64-6){1'b0}},Qcnt_one_12};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b001101:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-25:C_MANT_FP64-26];
- Q_sqrt0={{(C_MANT_FP64-7){1'b0}},Qcnt_one_13};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b001110:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-27:C_MANT_FP64-28];
- Q_sqrt0={{(C_MANT_FP64-8){1'b0}},Qcnt_one_14};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b001111:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-29:C_MANT_FP64-30];
- Q_sqrt0={{(C_MANT_FP64-9){1'b0}},Qcnt_one_15};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b010000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-31:C_MANT_FP64-32];
- Q_sqrt0={{(C_MANT_FP64-10){1'b0}},Qcnt_one_16};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b010001:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-33:C_MANT_FP64-34];
- Q_sqrt0={{(C_MANT_FP64-11){1'b0}},Qcnt_one_17};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b010010:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-35:C_MANT_FP64-36];
- Q_sqrt0={{(C_MANT_FP64-12){1'b0}},Qcnt_one_18};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b010011:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-37:C_MANT_FP64-38];
- Q_sqrt0={{(C_MANT_FP64-13){1'b0}},Qcnt_one_19};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b010100:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-39:C_MANT_FP64-40];
- Q_sqrt0={{(C_MANT_FP64-14){1'b0}},Qcnt_one_20};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b010101:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-41:C_MANT_FP64-42];
- Q_sqrt0={{(C_MANT_FP64-15){1'b0}},Qcnt_one_21};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b010110:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-43:C_MANT_FP64-44];
- Q_sqrt0={{(C_MANT_FP64-16){1'b0}},Qcnt_one_22};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b010111:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-45:C_MANT_FP64-46];
- Q_sqrt0={{(C_MANT_FP64-17){1'b0}},Qcnt_one_23};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b011000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-47:C_MANT_FP64-48];
- Q_sqrt0={{(C_MANT_FP64-18){1'b0}},Qcnt_one_24};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b011001:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-49:C_MANT_FP64-50];
- Q_sqrt0={{(C_MANT_FP64-19){1'b0}},Qcnt_one_25};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b011010:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-51:C_MANT_FP64-52];
- Q_sqrt0={{(C_MANT_FP64-20){1'b0}},Qcnt_one_26};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b011011:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-21){1'b0}},Qcnt_one_27};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b011100:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-22){1'b0}},Qcnt_one_28};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b011101:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-23){1'b0}},Qcnt_one_29};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b011110:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-24){1'b0}},Qcnt_one_30};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b011111:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-25){1'b0}},Qcnt_one_31};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b100000:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-26){1'b0}},Qcnt_one_32};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b100001:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-27){1'b0}},Qcnt_one_33};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b100010:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-28){1'b0}},Qcnt_one_34};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b100011:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-29){1'b0}},Qcnt_one_35};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b100100:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-30){1'b0}},Qcnt_one_36};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b100101:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-31){1'b0}},Qcnt_one_37};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b100110:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-32){1'b0}},Qcnt_one_38};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b100111:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-33){1'b0}},Qcnt_one_39};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b101000:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-34){1'b0}},Qcnt_one_40};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b101001:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-35){1'b0}},Qcnt_one_41};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b101010:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-36){1'b0}},Qcnt_one_42};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b101011:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-37){1'b0}},Qcnt_one_43};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b101100:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-38){1'b0}},Qcnt_one_44};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b101101:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-39){1'b0}},Qcnt_one_45};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b101110:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-40){1'b0}},Qcnt_one_46};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b101111:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-41){1'b0}},Qcnt_one_47};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b110000:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-42){1'b0}},Qcnt_one_48};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b110001:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-43){1'b0}},Qcnt_one_49};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b110010:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-44){1'b0}},Qcnt_one_50};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b110011:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-45){1'b0}},Qcnt_one_51};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b110100:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-46){1'b0}},Qcnt_one_52};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b110101:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-47){1'b0}},Qcnt_one_53};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b110110:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-48){1'b0}},Qcnt_one_54};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b110111:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-49){1'b0}},Qcnt_one_55};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
- 6'b111000:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-50){1'b0}},Qcnt_one_56};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- end
-
- default:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0='0;
- Sqrt_Q0='0;
- end
- endcase
- end
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Operands for square root when Iteration_unit_num_S = 2'b00, end //
- /////////////////////////////////////////////////////////////////////////////
-
-
- 2'b01:
- begin
- /////////////////////////////////////////////////////////////////////////////
- // Operands for square root when Iteration_unit_num_S = 2'b01, start //
- /////////////////////////////////////////////////////////////////////////////
- case(Crtl_cnt_S)
-
- 6'b000000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64];
- Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_two_0[1]};
- Sqrt_Q0=Q_sqrt_com_0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2];
- Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_two_0[1:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b000001:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4];
- Q_sqrt0={{(C_MANT_FP64+4){1'b0}},Qcnt_two_1[2:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6];
- Q_sqrt1={{(C_MANT_FP64+3){1'b0}},Qcnt_two_1[2:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b000010:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-7:C_MANT_FP64-8];
- Q_sqrt0={{(C_MANT_FP64+2){1'b0}},Qcnt_two_2[4:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-9:C_MANT_FP64-10];
- Q_sqrt1={{(C_MANT_FP64+1){1'b0}},Qcnt_two_2[4:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b000011:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-11:C_MANT_FP64-12];
- Q_sqrt0={{(C_MANT_FP64){1'b0}},Qcnt_two_3[6:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-13:C_MANT_FP64-14];
- Q_sqrt1={{(C_MANT_FP64-1){1'b0}},Qcnt_two_3[6:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b000100:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-15:C_MANT_FP64-16];
- Q_sqrt0={{(C_MANT_FP64-2){1'b0}},Qcnt_two_4[8:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-17:C_MANT_FP64-18];
- Q_sqrt1={{(C_MANT_FP64-3){1'b0}},Qcnt_two_4[8:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b000101:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-19:C_MANT_FP64-20];
- Q_sqrt0={{(C_MANT_FP64-4){1'b0}},Qcnt_two_5[10:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-21:C_MANT_FP64-22];
- Q_sqrt1={{(C_MANT_FP64-5){1'b0}},Qcnt_two_5[10:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b000110:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-23:C_MANT_FP64-24];
- Q_sqrt0={{(C_MANT_FP64-6){1'b0}},Qcnt_two_6[12:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-25:C_MANT_FP64-26];
- Q_sqrt1={{(C_MANT_FP64-7){1'b0}},Qcnt_two_6[12:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b000111:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-27:C_MANT_FP64-28];
- Q_sqrt0={{(C_MANT_FP64-8){1'b0}},Qcnt_two_7[14:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-29:C_MANT_FP64-30];
- Q_sqrt1={{(C_MANT_FP64-9){1'b0}},Qcnt_two_7[14:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b001000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-31:C_MANT_FP64-32];
- Q_sqrt0={{(C_MANT_FP64-10){1'b0}},Qcnt_two_8[16:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-33:C_MANT_FP64-34];
- Q_sqrt1={{(C_MANT_FP64-11){1'b0}},Qcnt_two_8[16:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b001001:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-35:C_MANT_FP64-36];
- Q_sqrt0={{(C_MANT_FP64-12){1'b0}},Qcnt_two_9[18:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-37:C_MANT_FP64-38];
- Q_sqrt1={{(C_MANT_FP64-13){1'b0}},Qcnt_two_9[18:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b001010:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-39:C_MANT_FP64-40];
- Q_sqrt0={{(C_MANT_FP64-14){1'b0}},Qcnt_two_10[20:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-41:C_MANT_FP64-42];
- Q_sqrt1={{(C_MANT_FP64-15){1'b0}},Qcnt_two_10[20:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b001011:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-43:C_MANT_FP64-44];
- Q_sqrt0={{(C_MANT_FP64-16){1'b0}},Qcnt_two_11[22:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-45:C_MANT_FP64-46];
- Q_sqrt1={{(C_MANT_FP64-17){1'b0}},Qcnt_two_11[22:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b001100:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-47:C_MANT_FP64-48];
- Q_sqrt0={{(C_MANT_FP64-18){1'b0}},Qcnt_two_12[24:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-49:C_MANT_FP64-50];
- Q_sqrt1={{(C_MANT_FP64-19){1'b0}},Qcnt_two_12[24:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b001101:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-51:C_MANT_FP64-52];
- Q_sqrt0={{(C_MANT_FP64-20){1'b0}},Qcnt_two_13[26:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-21){1'b0}},Qcnt_two_13[26:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b001110:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-22){1'b0}},Qcnt_two_14[28:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-23){1'b0}},Qcnt_two_14[28:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b001111:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-24){1'b0}},Qcnt_two_15[30:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-25){1'b0}},Qcnt_two_15[30:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b010000:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-26){1'b0}},Qcnt_two_16[32:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-27){1'b0}},Qcnt_two_16[32:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b010001:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-28){1'b0}},Qcnt_two_17[34:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-29){1'b0}},Qcnt_two_17[34:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b010010:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-30){1'b0}},Qcnt_two_18[36:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-31){1'b0}},Qcnt_two_18[36:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b010011:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-32){1'b0}},Qcnt_two_19[38:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-33){1'b0}},Qcnt_two_19[38:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b010100:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-34){1'b0}},Qcnt_two_20[40:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-35){1'b0}},Qcnt_two_20[40:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b010101:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-36){1'b0}},Qcnt_two_21[42:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-37){1'b0}},Qcnt_two_21[42:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b010110:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-38){1'b0}},Qcnt_two_22[44:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-39){1'b0}},Qcnt_two_22[44:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b010111:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-40){1'b0}},Qcnt_two_23[46:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-41){1'b0}},Qcnt_two_23[46:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b011000:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-42){1'b0}},Qcnt_two_24[48:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-43){1'b0}},Qcnt_two_24[48:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b011001:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-44){1'b0}},Qcnt_two_25[50:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-45){1'b0}},Qcnt_two_25[50:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b011010:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-46){1'b0}},Qcnt_two_26[52:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-47){1'b0}},Qcnt_two_26[52:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b011011:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-48){1'b0}},Qcnt_two_27[54:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-49){1'b0}},Qcnt_two_27[54:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- 6'b011100:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-50){1'b0}},Qcnt_two_28[56:1]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-51){1'b0}},Qcnt_two_28[56:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- default:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64];
- Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_two_0[1]};
- Sqrt_Q0=Q_sqrt_com_0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2];
- Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_two_0[1:0]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- end
-
- endcase
- end
-
- /////////////////////////////////////////////////////////////////////////////
- // Operands for square root when Iteration_unit_num_S = 2'b01, end //
- /////////////////////////////////////////////////////////////////////////////
-
-
- 2'b10:
- begin
- /////////////////////////////////////////////////////////////////////////////
- // Operands for square root when Iteration_unit_num_S = 2'b10, start //
- /////////////////////////////////////////////////////////////////////////////
-
- case(Crtl_cnt_S)
- 6'b000000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64];
- Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_three_0[2]};
- Sqrt_Q0=Q_sqrt_com_0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2];
- Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_three_0[2:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4];
- Q_sqrt2={{(C_MANT_FP64+3){1'b0}},Qcnt_three_0[2:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b000001:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6];
- Q_sqrt0={{(C_MANT_FP64+2){1'b0}},Qcnt_three_1[4:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-7:C_MANT_FP64-8];
- Q_sqrt1={{(C_MANT_FP64+1){1'b0}},Qcnt_three_1[4:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-9:C_MANT_FP64-10];
- Q_sqrt2={{(C_MANT_FP64){1'b0}},Qcnt_three_1[4:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b000010:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-11:C_MANT_FP64-12];
- Q_sqrt0={{(C_MANT_FP64-1){1'b0}},Qcnt_three_2[7:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-13:C_MANT_FP64-14];
- Q_sqrt1={{(C_MANT_FP64-2){1'b0}},Qcnt_three_2[7:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-15:C_MANT_FP64-16];
- Q_sqrt2={{(C_MANT_FP64-3){1'b0}},Qcnt_three_2[7:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b000011:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-17:C_MANT_FP64-18];
- Q_sqrt0={{(C_MANT_FP64-4){1'b0}},Qcnt_three_3[10:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-19:C_MANT_FP64-20];
- Q_sqrt1={{(C_MANT_FP64-5){1'b0}},Qcnt_three_3[10:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-21:C_MANT_FP64-22];
- Q_sqrt2={{(C_MANT_FP64-6){1'b0}},Qcnt_three_3[10:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b000100:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-23:C_MANT_FP64-24];
- Q_sqrt0={{(C_MANT_FP64-7){1'b0}},Qcnt_three_4[13:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-25:C_MANT_FP64-26];
- Q_sqrt1={{(C_MANT_FP64-8){1'b0}},Qcnt_three_4[13:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-27:C_MANT_FP64-28];
- Q_sqrt2={{(C_MANT_FP64-9){1'b0}},Qcnt_three_4[13:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b000101:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-29:C_MANT_FP64-30];
- Q_sqrt0={{(C_MANT_FP64-10){1'b0}},Qcnt_three_5[16:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-31:C_MANT_FP64-32];
- Q_sqrt1={{(C_MANT_FP64-11){1'b0}},Qcnt_three_5[16:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-33:C_MANT_FP64-34];
- Q_sqrt2={{(C_MANT_FP64-12){1'b0}},Qcnt_three_5[16:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b000110:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-35:C_MANT_FP64-36];
- Q_sqrt0={{(C_MANT_FP64-13){1'b0}},Qcnt_three_6[19:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-37:C_MANT_FP64-38];
- Q_sqrt1={{(C_MANT_FP64-14){1'b0}},Qcnt_three_6[19:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-39:C_MANT_FP64-40];
- Q_sqrt2={{(C_MANT_FP64-15){1'b0}},Qcnt_three_6[19:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b000111:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-41:C_MANT_FP64-42];
- Q_sqrt0={{(C_MANT_FP64-16){1'b0}},Qcnt_three_7[22:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-43:C_MANT_FP64-44];
- Q_sqrt1={{(C_MANT_FP64-17){1'b0}},Qcnt_three_7[22:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-45:C_MANT_FP64-46];
- Q_sqrt2={{(C_MANT_FP64-18){1'b0}},Qcnt_three_7[22:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b001000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-47:C_MANT_FP64-48];
- Q_sqrt0={{(C_MANT_FP64-19){1'b0}},Qcnt_three_8[25:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-49:C_MANT_FP64-50];
- Q_sqrt1={{(C_MANT_FP64-20){1'b0}},Qcnt_three_8[25:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-51:C_MANT_FP64-52];
- Q_sqrt2={{(C_MANT_FP64-21){1'b0}},Qcnt_three_8[25:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b001001:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-22){1'b0}},Qcnt_three_9[28:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-23){1'b0}},Qcnt_three_9[28:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-24){1'b0}},Qcnt_three_9[28:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b001010:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-25){1'b0}},Qcnt_three_10[31:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-26){1'b0}},Qcnt_three_10[31:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-27){1'b0}},Qcnt_three_10[31:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b001011:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-28){1'b0}},Qcnt_three_11[34:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-29){1'b0}},Qcnt_three_11[34:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-30){1'b0}},Qcnt_three_11[34:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b001100:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-31){1'b0}},Qcnt_three_12[37:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-32){1'b0}},Qcnt_three_12[37:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-33){1'b0}},Qcnt_three_12[37:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b001101:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-34){1'b0}},Qcnt_three_13[40:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-35){1'b0}},Qcnt_three_13[40:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-36){1'b0}},Qcnt_three_13[40:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b001110:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-37){1'b0}},Qcnt_three_14[43:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-38){1'b0}},Qcnt_three_14[43:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-39){1'b0}},Qcnt_three_14[43:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b001111:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-40){1'b0}},Qcnt_three_15[46:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-41){1'b0}},Qcnt_three_15[46:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-42){1'b0}},Qcnt_three_15[46:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b010000:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-43){1'b0}},Qcnt_three_16[49:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-44){1'b0}},Qcnt_three_16[49:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-45){1'b0}},Qcnt_three_16[49:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b010001:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-46){1'b0}},Qcnt_three_17[52:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-47){1'b0}},Qcnt_three_17[52:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-48){1'b0}},Qcnt_three_17[52:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- 6'b010010:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-49){1'b0}},Qcnt_three_18[55:2]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-50){1'b0}},Qcnt_three_18[55:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-51){1'b0}},Qcnt_three_18[55:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
-
- default :
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64];
- Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_three_0[2]};
- Sqrt_Q0=Q_sqrt_com_0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2];
- Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_three_0[2:1]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4];
- Q_sqrt2={{(C_MANT_FP64+3){1'b0}},Qcnt_three_0[2:0]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- end
- endcase
-
- end
- /////////////////////////////////////////////////////////////////////////////
- // Operands for square root when Iteration_unit_num_S = 2'b10, end //
- /////////////////////////////////////////////////////////////////////////////
-
-
- 2'b11:
- begin
- /////////////////////////////////////////////////////////////////////////////
- // Operands for square root when Iteration_unit_num_S = 2'b11, start //
- /////////////////////////////////////////////////////////////////////////////
-
- case(Crtl_cnt_S)
-
- 6'b000000:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64];
- Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_four_0[3]};
- Sqrt_Q0=Q_sqrt_com_0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2];
- Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_four_0[3:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4];
- Q_sqrt2={{(C_MANT_FP64+3){1'b0}},Qcnt_four_0[3:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6];
- Q_sqrt3={{(C_MANT_FP64+2){1'b0}},Qcnt_four_0[3:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b000001:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-7:C_MANT_FP64-8];
- Q_sqrt0={{(C_MANT_FP64+1){1'b0}},Qcnt_four_1[6:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-9:C_MANT_FP64-10];
- Q_sqrt1={{(C_MANT_FP64){1'b0}},Qcnt_four_1[6:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-11:C_MANT_FP64-12];
- Q_sqrt2={{(C_MANT_FP64-1){1'b0}},Qcnt_four_1[6:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-13:C_MANT_FP64-14];
- Q_sqrt3={{(C_MANT_FP64-2){1'b0}},Qcnt_four_1[6:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b000010:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-15:C_MANT_FP64-16];
- Q_sqrt0={{(C_MANT_FP64-3){1'b0}},Qcnt_four_2[10:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-17:C_MANT_FP64-18];
- Q_sqrt1={{(C_MANT_FP64-4){1'b0}},Qcnt_four_2[10:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-19:C_MANT_FP64-20];
- Q_sqrt2={{(C_MANT_FP64-5){1'b0}},Qcnt_four_2[10:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-21:C_MANT_FP64-22];
- Q_sqrt3={{(C_MANT_FP64-6){1'b0}},Qcnt_four_2[10:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b000011:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-23:C_MANT_FP64-24];
- Q_sqrt0={{(C_MANT_FP64-7){1'b0}},Qcnt_four_3[14:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-25:C_MANT_FP64-26];
- Q_sqrt1={{(C_MANT_FP64-8){1'b0}},Qcnt_four_3[14:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-27:C_MANT_FP64-28];
- Q_sqrt2={{(C_MANT_FP64-9){1'b0}},Qcnt_four_3[14:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-29:C_MANT_FP64-30];
- Q_sqrt3={{(C_MANT_FP64-10){1'b0}},Qcnt_four_3[14:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b000100:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-31:C_MANT_FP64-32];
- Q_sqrt0={{(C_MANT_FP64-11){1'b0}},Qcnt_four_4[18:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-33:C_MANT_FP64-34];
- Q_sqrt1={{(C_MANT_FP64-12){1'b0}},Qcnt_four_4[18:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-35:C_MANT_FP64-36];
- Q_sqrt2={{(C_MANT_FP64-13){1'b0}},Qcnt_four_4[18:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-37:C_MANT_FP64-38];
- Q_sqrt3={{(C_MANT_FP64-14){1'b0}},Qcnt_four_4[18:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b000101:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-39:C_MANT_FP64-40];
- Q_sqrt0={{(C_MANT_FP64-15){1'b0}},Qcnt_four_5[22:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-41:C_MANT_FP64-42];
- Q_sqrt1={{(C_MANT_FP64-16){1'b0}},Qcnt_four_5[22:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-43:C_MANT_FP64-44];
- Q_sqrt2={{(C_MANT_FP64-17){1'b0}},Qcnt_four_5[22:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-45:C_MANT_FP64-46];
- Q_sqrt3={{(C_MANT_FP64-18){1'b0}},Qcnt_four_5[22:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b000110:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64-47:C_MANT_FP64-48];
- Q_sqrt0={{(C_MANT_FP64-19){1'b0}},Qcnt_four_6[26:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-49:C_MANT_FP64-50];
- Q_sqrt1={{(C_MANT_FP64-20){1'b0}},Qcnt_four_6[26:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-51:C_MANT_FP64-52];
- Q_sqrt2={{(C_MANT_FP64-21){1'b0}},Qcnt_four_6[26:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=2'b00;
- Q_sqrt3={{(C_MANT_FP64-22){1'b0}},Qcnt_four_6[26:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b000111:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-23){1'b0}},Qcnt_four_7[30:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-24){1'b0}},Qcnt_four_7[30:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-25){1'b0}},Qcnt_four_7[30:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=2'b00;
- Q_sqrt3={{(C_MANT_FP64-26){1'b0}},Qcnt_four_7[30:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b001000:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-27){1'b0}},Qcnt_four_8[34:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-28){1'b0}},Qcnt_four_8[34:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-29){1'b0}},Qcnt_four_8[34:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=2'b00;
- Q_sqrt3={{(C_MANT_FP64-30){1'b0}},Qcnt_four_8[34:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b001001:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-31){1'b0}},Qcnt_four_9[38:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-32){1'b0}},Qcnt_four_9[38:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-33){1'b0}},Qcnt_four_9[38:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=2'b00;
- Q_sqrt3={{(C_MANT_FP64-34){1'b0}},Qcnt_four_9[38:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b001010:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-35){1'b0}},Qcnt_four_10[42:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-36){1'b0}},Qcnt_four_10[42:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-37){1'b0}},Qcnt_four_10[42:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=2'b00;
- Q_sqrt3={{(C_MANT_FP64-38){1'b0}},Qcnt_four_10[42:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b001011:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-39){1'b0}},Qcnt_four_11[46:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-40){1'b0}},Qcnt_four_11[46:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-41){1'b0}},Qcnt_four_11[46:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=2'b00;
- Q_sqrt3={{(C_MANT_FP64-42){1'b0}},Qcnt_four_11[46:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b001100:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-43){1'b0}},Qcnt_four_12[50:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-44){1'b0}},Qcnt_four_12[50:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-45){1'b0}},Qcnt_four_12[50:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=2'b00;
- Q_sqrt3={{(C_MANT_FP64-46){1'b0}},Qcnt_four_12[50:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- 6'b001101:
- begin
- Sqrt_DI[0]=2'b00;
- Q_sqrt0={{(C_MANT_FP64-47){1'b0}},Qcnt_four_13[54:3]};
- Sqrt_Q0=Quotient_DP[0]?Q_sqrt_com_0:Q_sqrt0;
- Sqrt_DI[1]=2'b00;
- Q_sqrt1={{(C_MANT_FP64-48){1'b0}},Qcnt_four_13[54:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=2'b00;
- Q_sqrt2={{(C_MANT_FP64-49){1'b0}},Qcnt_four_13[54:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=2'b00;
- Q_sqrt3={{(C_MANT_FP64-50){1'b0}},Qcnt_four_13[54:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
-
- default:
- begin
- Sqrt_DI[0]=Mant_D_sqrt_Norm[C_MANT_FP64+1:C_MANT_FP64];
- Q_sqrt0={{(C_MANT_FP64+5){1'b0}},Qcnt_four_0[3]};
- Sqrt_Q0=Q_sqrt_com_0;
- Sqrt_DI[1]=Mant_D_sqrt_Norm[C_MANT_FP64-1:C_MANT_FP64-2];
- Q_sqrt1={{(C_MANT_FP64+4){1'b0}},Qcnt_four_0[3:2]};
- Sqrt_Q1=Sqrt_quotinent_S[3]?Q_sqrt_com_1:Q_sqrt1;
- Sqrt_DI[2]=Mant_D_sqrt_Norm[C_MANT_FP64-3:C_MANT_FP64-4];
- Q_sqrt2={{(C_MANT_FP64+3){1'b0}},Qcnt_four_0[3:1]};
- Sqrt_Q2=Sqrt_quotinent_S[2]?Q_sqrt_com_2:Q_sqrt2;
- Sqrt_DI[3]=Mant_D_sqrt_Norm[C_MANT_FP64-5:C_MANT_FP64-6];
- Q_sqrt3={{(C_MANT_FP64+2){1'b0}},Qcnt_four_0[3:0]};
- Sqrt_Q3=Sqrt_quotinent_S[1]?Q_sqrt_com_3:Q_sqrt3;
- end
- endcase
- end
- endcase
- /////////////////////////////////////////////////////////////////////////////
- // Operands for square root when Iteration_unit_num_S = 2'b11, end //
- /////////////////////////////////////////////////////////////////////////////
- end
-
-
-
- assign Sqrt_R0= ((Sqrt_start_dly_S)?'0:{Partial_remainder_DP[C_MANT_FP64+5:0]});
- assign Sqrt_R1= {Iteration_cell_sum_AMASK_D[0][C_MANT_FP64+5],Iteration_cell_sum_AMASK_D[0][C_MANT_FP64+2:0],Sqrt_DO[0]} ;
- assign Sqrt_R2= {Iteration_cell_sum_AMASK_D[1][C_MANT_FP64+5],Iteration_cell_sum_AMASK_D[1][C_MANT_FP64+2:0],Sqrt_DO[1]};
- assign Sqrt_R3= {Iteration_cell_sum_AMASK_D[2][C_MANT_FP64+5],Iteration_cell_sum_AMASK_D[2][C_MANT_FP64+2:0],Sqrt_DO[2]};
- assign Sqrt_R4= {Iteration_cell_sum_AMASK_D[3][C_MANT_FP64+5],Iteration_cell_sum_AMASK_D[3][C_MANT_FP64+2:0],Sqrt_DO[3]};
-
- logic [C_MANT_FP64+5:0] Denominator_se_format_DB; //
-
- assign Denominator_se_format_DB={Denominator_se_DB[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP16ALT],{FP16ALT_SO?FP16ALT_SO:Denominator_se_DB[C_MANT_FP64-C_MANT_FP16ALT-1]},
- Denominator_se_DB[C_MANT_FP64-C_MANT_FP16ALT-2:C_MANT_FP64-C_MANT_FP16],{FP16_SO?FP16_SO:Denominator_se_DB[C_MANT_FP64-C_MANT_FP16-1]},
- Denominator_se_DB[C_MANT_FP64-C_MANT_FP16-2:C_MANT_FP64-C_MANT_FP32],{FP32_SO?FP32_SO:Denominator_se_DB[C_MANT_FP64-C_MANT_FP32-1]},
- Denominator_se_DB[C_MANT_FP64-C_MANT_FP32-2:C_MANT_FP64-C_MANT_FP64],FP64_SO,3'b0} ;
- // for iteration cell_U0
- logic [C_MANT_FP64+5:0] First_iteration_cell_div_a_D,First_iteration_cell_div_b_D;
- logic Sel_b_for_first_S;
-
-
- assign First_iteration_cell_div_a_D=(Div_start_dly_S)?{Numerator_se_D[C_MANT_FP64+1:C_MANT_FP64-C_MANT_FP16ALT],{FP16ALT_SO?FP16ALT_SO:Numerator_se_D[C_MANT_FP64-C_MANT_FP16ALT-1]},
- Numerator_se_D[C_MANT_FP64-C_MANT_FP16ALT-2:C_MANT_FP64-C_MANT_FP16],{FP16_SO?FP16_SO:Numerator_se_D[C_MANT_FP64-C_MANT_FP16-1]},
- Numerator_se_D[C_MANT_FP64-C_MANT_FP16-2:C_MANT_FP64-C_MANT_FP32],{FP32_SO?FP32_SO:Numerator_se_D[C_MANT_FP64-C_MANT_FP32-1]},
- Numerator_se_D[C_MANT_FP64-C_MANT_FP32-2:C_MANT_FP64-C_MANT_FP64],FP64_SO,3'b0}
- :{Partial_remainder_DP[C_MANT_FP64+4:C_MANT_FP64-C_MANT_FP16ALT+3],{FP16ALT_SO?Quotient_DP[0]:Partial_remainder_DP[C_MANT_FP64-C_MANT_FP16ALT+2]},
- Partial_remainder_DP[C_MANT_FP64-C_MANT_FP16ALT+1:C_MANT_FP64-C_MANT_FP16+3],{FP16_SO?Quotient_DP[0]:Partial_remainder_DP[C_MANT_FP64-C_MANT_FP16+2]},
- Partial_remainder_DP[C_MANT_FP64-C_MANT_FP16+1:C_MANT_FP64-C_MANT_FP32+3],{FP32_SO?Quotient_DP[0]:Partial_remainder_DP[C_MANT_FP64-C_MANT_FP32+2]},
- Partial_remainder_DP[C_MANT_FP64-C_MANT_FP32+1:C_MANT_FP64-C_MANT_FP64+3],FP64_SO&&Quotient_DP[0],3'b0};
- assign Sel_b_for_first_S=(Div_start_dly_S)?1:Quotient_DP[0];
- assign First_iteration_cell_div_b_D=Sel_b_for_first_S?Denominator_se_format_DB:{Denominator_se_D,4'b0};
- assign Iteration_cell_a_BMASK_D[0]=Sqrt_enable_SO?Sqrt_R0:{First_iteration_cell_div_a_D};
- assign Iteration_cell_b_BMASK_D[0]=Sqrt_enable_SO?Sqrt_Q0:{First_iteration_cell_div_b_D};
-
-
-
- // for iteration cell_U1
- logic [C_MANT_FP64+5:0] Sec_iteration_cell_div_a_D,Sec_iteration_cell_div_b_D;
- logic Sel_b_for_sec_S;
- generate
- if(|Iteration_unit_num_S)
- begin
- assign Sel_b_for_sec_S=~Iteration_cell_sum_AMASK_D[0][C_MANT_FP64+5];
- assign Sec_iteration_cell_div_a_D={Iteration_cell_sum_AMASK_D[0][C_MANT_FP64+4:C_MANT_FP64-C_MANT_FP16ALT+3],{FP16ALT_SO?Sel_b_for_sec_S:Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP16ALT+2]},
- Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP16ALT+1:C_MANT_FP64-C_MANT_FP16+3],{FP16_SO?Sel_b_for_sec_S:Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP16+2]},
- Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP16+1:C_MANT_FP64-C_MANT_FP32+3],{FP32_SO?Sel_b_for_sec_S:Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP32+2]},
- Iteration_cell_sum_AMASK_D[0][C_MANT_FP64-C_MANT_FP32+1:C_MANT_FP64-C_MANT_FP64+3],FP64_SO&&Sel_b_for_sec_S,3'b0};
- assign Sec_iteration_cell_div_b_D=Sel_b_for_sec_S?Denominator_se_format_DB:{Denominator_se_D,4'b0};
- assign Iteration_cell_a_BMASK_D[1]=Sqrt_enable_SO?Sqrt_R1:{Sec_iteration_cell_div_a_D};
- assign Iteration_cell_b_BMASK_D[1]=Sqrt_enable_SO?Sqrt_Q1:{Sec_iteration_cell_div_b_D};
- end
- endgenerate
-
- // for iteration cell_U2
- logic [C_MANT_FP64+5:0] Thi_iteration_cell_div_a_D,Thi_iteration_cell_div_b_D;
- logic Sel_b_for_thi_S;
- generate
- if((Iteration_unit_num_S==2'b10) | (Iteration_unit_num_S==2'b11))
- begin
- assign Sel_b_for_thi_S=~Iteration_cell_sum_AMASK_D[1][C_MANT_FP64+5];
- assign Thi_iteration_cell_div_a_D={Iteration_cell_sum_AMASK_D[1][C_MANT_FP64+4:C_MANT_FP64-C_MANT_FP16ALT+3],{FP16ALT_SO?Sel_b_for_thi_S:Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP16ALT+2]},
- Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP16ALT+1:C_MANT_FP64-C_MANT_FP16+3],{FP16_SO?Sel_b_for_thi_S:Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP16+2]},
- Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP16+1:C_MANT_FP64-C_MANT_FP32+3],{FP32_SO?Sel_b_for_thi_S:Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP32+2]},
- Iteration_cell_sum_AMASK_D[1][C_MANT_FP64-C_MANT_FP32+1:C_MANT_FP64-C_MANT_FP64+3],FP64_SO&&Sel_b_for_thi_S,3'b0};
- assign Thi_iteration_cell_div_b_D=Sel_b_for_thi_S?Denominator_se_format_DB:{Denominator_se_D,4'b0};
- assign Iteration_cell_a_BMASK_D[2]=Sqrt_enable_SO?Sqrt_R2:{Thi_iteration_cell_div_a_D};
- assign Iteration_cell_b_BMASK_D[2]=Sqrt_enable_SO?Sqrt_Q2:{Thi_iteration_cell_div_b_D};
- end
- endgenerate
-
- // for iteration cell_U3
- logic [C_MANT_FP64+5:0] Fou_iteration_cell_div_a_D,Fou_iteration_cell_div_b_D;
- logic Sel_b_for_fou_S;
-
- generate
- if(Iteration_unit_num_S==2'b11)
- begin
- assign Sel_b_for_fou_S=~Iteration_cell_sum_AMASK_D[2][C_MANT_FP64+5];
- assign Fou_iteration_cell_div_a_D={Iteration_cell_sum_AMASK_D[2][C_MANT_FP64+4:C_MANT_FP64-C_MANT_FP16ALT+3],{FP16ALT_SO?Sel_b_for_fou_S:Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP16ALT+2]},
- Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP16ALT+1:C_MANT_FP64-C_MANT_FP16+3],{FP16_SO?Sel_b_for_fou_S:Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP16+2]},
- Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP16+1:C_MANT_FP64-C_MANT_FP32+3],{FP32_SO?Sel_b_for_fou_S:Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP32+2]},
- Iteration_cell_sum_AMASK_D[2][C_MANT_FP64-C_MANT_FP32+1:C_MANT_FP64-C_MANT_FP64+3],FP64_SO&&Sel_b_for_fou_S,3'b0};
- assign Fou_iteration_cell_div_b_D=Sel_b_for_fou_S?Denominator_se_format_DB:{Denominator_se_D,4'b0};
- assign Iteration_cell_a_BMASK_D[3]=Sqrt_enable_SO?Sqrt_R3:{Fou_iteration_cell_div_a_D};
- assign Iteration_cell_b_BMASK_D[3]=Sqrt_enable_SO?Sqrt_Q3:{Fou_iteration_cell_div_b_D};
- end
- endgenerate
-
- /////////////////////////////////////////////////////////////////////////////
- // Masking Contrl //
- /////////////////////////////////////////////////////////////////////////////
-
-
- logic [C_MANT_FP64+1+4:0] Mask_bits_ctl_S; //For extension
-
- assign Mask_bits_ctl_S =58'h3ff_ffff_ffff_ffff; //It is not needed. The corresponding process is handled the above codes
-
- /////////////////////////////////////////////////////////////////////////////
- // Iteration Instances with masking control //
- /////////////////////////////////////////////////////////////////////////////
-
-
- logic Div_enable_SI [3:0];
- logic Div_start_dly_SI [3:0];
- logic Sqrt_enable_SI [3:0];
- generate
- genvar i,j;
- for (i=0; i <= Iteration_unit_num_S ; i++)
- begin
- for (j = 0; j <= C_MANT_FP64+5; j++) begin
- assign Iteration_cell_a_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_a_BMASK_D[i][j];
- assign Iteration_cell_b_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_b_BMASK_D[i][j];
- assign Iteration_cell_sum_AMASK_D[i][j] = Mask_bits_ctl_S[j] && Iteration_cell_sum_D[i][j];
- end
-
- assign Div_enable_SI[i] = Div_enable_SO;
- assign Div_start_dly_SI[i] = Div_start_dly_S;
- assign Sqrt_enable_SI[i] = Sqrt_enable_SO;
- iteration_div_sqrt_mvp #(C_MANT_FP64+6) iteration_div_sqrt
- (
- .A_DI (Iteration_cell_a_D[i] ),
- .B_DI (Iteration_cell_b_D[i] ),
- .Div_enable_SI (Div_enable_SI[i] ),
- .Div_start_dly_SI (Div_start_dly_SI[i] ),
- .Sqrt_enable_SI (Sqrt_enable_SI[i] ),
- .D_DI (Sqrt_DI[i] ),
- .D_DO (Sqrt_DO[i] ),
- .Sum_DO (Iteration_cell_sum_D[i] ),
- .Carry_out_DO (Iteration_cell_carry_D[i] )
- );
-
- end
-
- endgenerate
-
-
-
- always_comb
- begin
- case (Iteration_unit_num_S)
- 2'b00:
- begin
- if(Fsm_enable_S)
- Partial_remainder_DN = Sqrt_enable_SO?Sqrt_R1:Iteration_cell_sum_AMASK_D[0];
- else
- Partial_remainder_DN = Partial_remainder_DP;
- end
- 2'b01:
- begin
- if(Fsm_enable_S)
- Partial_remainder_DN = Sqrt_enable_SO?Sqrt_R2:Iteration_cell_sum_AMASK_D[1];
- else
- Partial_remainder_DN = Partial_remainder_DP;
- end
- 2'b10:
- begin
- if(Fsm_enable_S)
- Partial_remainder_DN = Sqrt_enable_SO?Sqrt_R3:Iteration_cell_sum_AMASK_D[2];
- else
- Partial_remainder_DN = Partial_remainder_DP;
- end
- 2'b11:
- begin
- if(Fsm_enable_S)
- Partial_remainder_DN = Sqrt_enable_SO?Sqrt_R4:Iteration_cell_sum_AMASK_D[3];
- else
- Partial_remainder_DN = Partial_remainder_DP;
- end
- endcase
- end
-
-
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) // partial_remainder
- begin
- if(~Rst_RBI)
- begin
- Partial_remainder_DP <= '0;
- end
- else
- begin
- Partial_remainder_DP <= Partial_remainder_DN;
- end
- end
-
- logic [C_MANT_FP64+4:0] Quotient_DN;
-
- always_comb // Can choosen the different carry-outs based on different operations
- begin
- case (Iteration_unit_num_S)
- 2'b00:
- begin
- if(Fsm_enable_S)
- Quotient_DN= Sqrt_enable_SO ? {Quotient_DP[C_MANT_FP64+3:0],Sqrt_quotinent_S[3]} :{Quotient_DP[C_MANT_FP64+3:0],Iteration_cell_carry_D[0]};
- else
- Quotient_DN= Quotient_DP;
- end
- 2'b01:
- begin
- if(Fsm_enable_S)
- Quotient_DN= Sqrt_enable_SO ? {Quotient_DP[C_MANT_FP64+2:0],Sqrt_quotinent_S[3:2]} :{Quotient_DP[C_MANT_FP64+2:0],Iteration_cell_carry_D[0],Iteration_cell_carry_D[1]};
- else
- Quotient_DN= Quotient_DP;
- end
- 2'b10:
- begin
- if(Fsm_enable_S)
- Quotient_DN= Sqrt_enable_SO ? {Quotient_DP[C_MANT_FP64+1:0],Sqrt_quotinent_S[3:1]} : {Quotient_DP[C_MANT_FP64+1:0],Iteration_cell_carry_D[0],Iteration_cell_carry_D[1],Iteration_cell_carry_D[2]};
- else
- Quotient_DN= Quotient_DP;
- end
- 2'b11:
- begin
- if(Fsm_enable_S)
- Quotient_DN= Sqrt_enable_SO ? {Quotient_DP[C_MANT_FP64:0],Sqrt_quotinent_S } : {Quotient_DP[C_MANT_FP64:0],Iteration_cell_carry_D[0],Iteration_cell_carry_D[1],Iteration_cell_carry_D[2],Iteration_cell_carry_D[3]};
- else
- Quotient_DN= Quotient_DP;
- end
- endcase
- end
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI) // Quotient
- begin
- if(~Rst_RBI)
- begin
- Quotient_DP <= '0;
- end
- else
- Quotient_DP <= Quotient_DN;
- end
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Precision Control for outputs //
- /////////////////////////////////////////////////////////////////////////////
-
-
-//////////////////////one iteration unit, start///////////////////////////////////////
- generate
- if(Iteration_unit_num_S==2'b00)
- begin
- always_comb
- begin
- case (Format_sel_S)
- 2'b00:
- begin
- case (Precision_ctl_S)
- 6'h00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4
- end
- 6'h17:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32:0],{(C_MANT_FP64-C_MANT_FP32+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h16:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-1:0],{(C_MANT_FP64-C_MANT_FP32+4+1){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h15:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-2:0],{(C_MANT_FP64-C_MANT_FP32+4+2){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h14:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-3:0],{(C_MANT_FP64-C_MANT_FP32+4+3){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h13:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-4:0],{(C_MANT_FP64-C_MANT_FP32+4+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h12:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-5:0],{(C_MANT_FP64-C_MANT_FP32+4+5){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h11:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-6:0],{(C_MANT_FP64-C_MANT_FP32+4+6){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h10:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-7:0],{(C_MANT_FP64-C_MANT_FP32+4+7){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0f:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-8:0],{(C_MANT_FP64-C_MANT_FP32+4+8){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-9:0],{(C_MANT_FP64-C_MANT_FP32+4+9){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0d:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-10:0],{(C_MANT_FP64-C_MANT_FP32+4+10){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-11:0],{(C_MANT_FP64-C_MANT_FP32+4+11){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0b:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-12:0],{(C_MANT_FP64-C_MANT_FP32+4+12){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-13:0],{(C_MANT_FP64-C_MANT_FP32+4+13){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h09:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-14:0],{(C_MANT_FP64-C_MANT_FP32+4+14){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-15:0],{(C_MANT_FP64-C_MANT_FP32+4+15){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h07:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-16:0],{(C_MANT_FP64-C_MANT_FP32+4+16){1'b0}}}; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4
- end
- endcase
- end
-
- 2'b01:
- begin
- case (Precision_ctl_S)
- 6'h00:
- begin
- Mant_result_prenorm_DO = Quotient_DP[C_MANT_FP64+4:0]; //+4
- end
- 6'h34:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64:0],{(4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h33:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-1:0],{(4+1){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h32:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-2:0],{(4+2){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h31:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-3:0],{(4+3){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h30:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-4:0],{(4+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h2f:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-5:0],{(4+5){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h2e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-6:0],{(4+6){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h2d:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-7:0],{(4+7){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h2c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-8:0],{(4+8){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h2b:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-9:0],{(4+9){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h2a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-10:0],{(4+10){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h29:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-11:0],{(4+11){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h28:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-12:0],{(4+12){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h27:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-13:0],{(4+13){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h26:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-14:0],{(4+14){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h25:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-15:0],{(4+15){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h24:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-16:0],{(4+16){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h23:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-17:0],{(4+17){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h22:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-18:0],{(4+18){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h21:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-19:0],{(4+19){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h20:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-20:0],{(4+20){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h1f:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-21:0],{(4+21){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h1e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-22:0],{(4+22){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h1d:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-23:0],{(4+23){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h1c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-24:0],{(4+24){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h1b:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-25:0],{(4+25){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h1a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-26:0],{(4+26){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h19:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-27:0],{(4+27){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h18:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-28:0],{(4+28){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h17:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-29:0],{(4+29){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h16:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-30:0],{(4+30){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h15:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-31:0],{(4+31){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h14:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-32:0],{(4+32){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h13:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-33:0],{(4+33){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h12:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-34:0],{(4+34){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h11:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-35:0],{(4+35){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h10:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-36:0],{(4+36){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0f:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-37:0],{(4+37){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-38:0],{(4+38){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0d:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-39:0],{(4+39){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-40:0],{(4+40){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0b:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-41:0],{(4+41){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-42:0],{(4+42){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h09:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-43:0],{(4+43){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-44:0],{(4+44){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h07:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-45:0],{(4+45){1'b0}}}; //Precision_ctl_S+1
- end
- default:
- begin
- Mant_result_prenorm_DO = Quotient_DP[C_MANT_FP64+4:0]; //+4
- end
- endcase
- end
-
- 2'b10:
- begin
- case (Precision_ctl_S)
- 6'b00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}}}; //+4
- end
- 6'h0a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16:0],{(C_MANT_FP64-C_MANT_FP16+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h09:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-1:0],{(C_MANT_FP64-C_MANT_FP16+4+1){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-2:0],{(C_MANT_FP64-C_MANT_FP16+4+2){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h07:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-3:0],{(C_MANT_FP64-C_MANT_FP16+4+3){1'b0}}}; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}}}; //+4
- end
- endcase
- end
-
- 2'b11:
- begin
-
- case (Precision_ctl_S)
- 6'b00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}}}; //+4
- end
- 6'h07:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT:0],{(C_MANT_FP64-C_MANT_FP16ALT+4){1'b0}}}; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}}}; //+4
- end
- endcase
- end
- endcase
- end
- end
- endgenerate
-//////////////////////one iteration unit, end//////////////////////////////////////////
-
-//////////////////////two iteration units, start///////////////////////////////////////
- generate
- if(Iteration_unit_num_S==2'b01)
- begin
- always_comb
- begin
- case (Format_sel_S)
- 2'b00:
- begin
- case (Precision_ctl_S)
- 6'h00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4
- end
- 6'h17,6'h16:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32:0],{(C_MANT_FP64-C_MANT_FP32+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h15,6'h14:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-2:0],{(C_MANT_FP64-C_MANT_FP32+4+2){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h13,6'h12:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-4:0],{(C_MANT_FP64-C_MANT_FP32+4+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h11,6'h10:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-6:0],{(C_MANT_FP64-C_MANT_FP32+4+6){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0f,6'h0e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-8:0],{(C_MANT_FP64-C_MANT_FP32+4+8){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0d,6'h0c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-10:0],{(C_MANT_FP64-C_MANT_FP32+4+10){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0b,6'h0a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-12:0],{(C_MANT_FP64-C_MANT_FP32+4+12){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h09,6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-14:0],{(C_MANT_FP64-C_MANT_FP32+4+14){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-16:0],{(C_MANT_FP64-C_MANT_FP32+4+16){1'b0}}}; //Precision_ctl_S+1
- end
- default:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4
- end
- endcase
- end
- 2'b01:
- begin
- case (Precision_ctl_S)
- 6'h00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],1'b0}; //+3
- end
- 6'h34:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+1:1],{(4){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h33,6'h32:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-1:0],{(4+1){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h31,6'h30:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-3:0],{(4+3){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h2f,6'h2e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-5:0],{(4+5){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h2d,6'h2c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-7:0],{(4+7){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h2b,6'h2a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-9:0],{(4+9){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h29,6'h28:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-11:0],{(4+11){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h27,6'h26:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-13:0],{(4+13){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h25,6'h24:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-15:0],{(4+15){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h23,6'h22:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-17:0],{(4+17){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h21,6'h20:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-19:0],{(4+19){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h1f,6'h1e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-21:0],{(4+21){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h1d,6'h1c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-23:0],{(4+23){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h1b,6'h1a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-25:0],{(4+25){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h19,6'h18:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-27:0],{(4+27){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h17,6'h16:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-29:0],{(4+29){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h15,6'h14:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-31:0],{(4+31){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h13,6'h12:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-33:0],{(4+33){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h11,6'h10:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-35:0],{(4+35){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h0f,6'h0e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-37:0],{(4+37){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h0d,6'h0c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-39:0],{(4+39){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h0b,6'h0a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-41:0],{(4+41){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h09,6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-43:0],{(4+43){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h07:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-45:0],{(4+45){1'b0}} }; //Precision_ctl_S+1
- end
- default:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],1'b0}; //+3
- end
- endcase
- end
-
- 2'b10:
- begin
- case (Precision_ctl_S)
- 6'b00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+3:0],{(C_MANT_FP64-C_MANT_FP16+1){1'b0}} }; //+3
- end
- 6'h0a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+1:1],{(C_MANT_FP64-C_MANT_FP16+4){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h09,6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-1:0],{(C_MANT_FP64-C_MANT_FP16+4+1){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h07:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-3:0],{(C_MANT_FP64-C_MANT_FP16+4+3){1'b0}} }; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}} }; //+4
- end
- endcase
- end
-
- 2'b11:
- begin
-
- case (Precision_ctl_S)
- 6'b00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4
- end
- 6'h07:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT:0],{(C_MANT_FP64-C_MANT_FP16ALT+4){1'b0}} }; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4
- end
- endcase
- end
- endcase
- end
- end
- endgenerate
-//////////////////////two iteration units, end//////////////////////////////////////////
-
-//////////////////////three iteration units, start///////////////////////////////////////
- generate
- if(Iteration_unit_num_S==2'b10)
- begin
- always_comb
- begin
- case (Format_sel_S)
- 2'b00:
- begin
- case (Precision_ctl_S)
- 6'h00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+3:0],{(C_MANT_FP64-C_MANT_FP32+1){1'b0}}}; //+3
- end
- 6'h17,6'h16,6'h15:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32:0],{(C_MANT_FP64-C_MANT_FP32+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h14,6'h13,6'h12:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-3:0],{(C_MANT_FP64-C_MANT_FP32+4+3){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h11,6'h10,6'h0f:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-6:0],{(C_MANT_FP64-C_MANT_FP32+4+6){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0e,6'h0d,6'h0c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-9:0],{(C_MANT_FP64-C_MANT_FP32+4+9){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0b,6'h0a,6'h09:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-12:0],{(C_MANT_FP64-C_MANT_FP32+4+12){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h08,6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-15:0],{(C_MANT_FP64-C_MANT_FP32+4+15){1'b0}}}; //Precision_ctl_S+1
- end
- default:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+3:0],{(C_MANT_FP64-C_MANT_FP32+1){1'b0}}}; //+3
- end
- endcase
- end
-
- 2'b01:
- begin
- case (Precision_ctl_S)
- 6'h00:
- begin
- Mant_result_prenorm_DO = Quotient_DP[C_MANT_FP64+4:0]; //+4
- end
- 6'h34,6'h33:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+1:1],{(4){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h32,6'h31,6'h30:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-2:0],{(4+2){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h2f,6'h2e,6'h2d:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-5:0],{(4+5){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h2c,6'h2b,6'h2a:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-8:0],{(4+8){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h29,6'h28,6'h27:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-11:0],{(4+11){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h26,6'h25,6'h24:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-14:0],{(4+14){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h23,6'h22,6'h21:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-17:0],{(4+17){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h20,6'h1f,6'h1e:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-20:0],{(4+20){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h1d,6'h1c,6'h1b:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-23:0],{(4+23){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h1a,6'h19,6'h18:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-26:0],{(4+26){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h17,6'h16,6'h15:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-29:0],{(4+29){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h14,6'h13,6'h12:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-32:0],{(4+32){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h11,6'h10,6'h0f:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-35:0],{(4+35){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h0e,6'h0d,6'h0c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-38:0],{(4+38){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h0b,6'h0a,6'h09:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-41:0],{(4+41){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h08,6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-44:0],{(4+44){1'b0}} }; //Precision_ctl_S+1
- end
- default:
- begin
- Mant_result_prenorm_DO = Quotient_DP[C_MANT_FP64+4:0]; //+4
- end
- endcase
- end
-
- 2'b10:
- begin
- case (Precision_ctl_S)
- 6'b00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}} }; //+4
- end
- 6'h0a,6'h09:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+1:1],{(C_MANT_FP64-C_MANT_FP16+4){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h08,6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16-2:0],{(C_MANT_FP64-C_MANT_FP16+4+2){1'b0}} }; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+4:0],{(C_MANT_FP64-C_MANT_FP16){1'b0}} }; //+4
- end
- endcase
- end
-
- 2'b11:
- begin
-
- case (Precision_ctl_S)
- 6'b00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4
- end
- 6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+1:1],{(C_MANT_FP64-C_MANT_FP16ALT+4){1'b0}} }; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4
- end
- endcase
- end
- endcase
- end
- end
- endgenerate
-//////////////////////three iteration units, end//////////////////////////////////////////
-
-//////////////////////four iteration units, start///////////////////////////////////////
- generate
- if(Iteration_unit_num_S==2'b11)
- begin
- always_comb
- begin
- case (Format_sel_S)
- 2'b00:
- begin
- case (Precision_ctl_S)
- 6'h00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4
- end
- 6'h17,6'h16,6'h15,6'h14:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32:0],{(C_MANT_FP64-C_MANT_FP32+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h13,6'h12,6'h11,6'h10:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-4:0],{(C_MANT_FP64-C_MANT_FP32+4+4){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0f,6'h0e,6'h0d,6'h0c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-8:0],{(C_MANT_FP64-C_MANT_FP32+4+8){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h0b,6'h0a,6'h09,6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-12:0],{(C_MANT_FP64-C_MANT_FP32+4+12){1'b0}}}; //Precision_ctl_S+1
- end
- 6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32-16:0],{(C_MANT_FP64-C_MANT_FP32+4+16){1'b0}}}; //Precision_ctl_S+1
- end
- default:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP32+4:0],{(C_MANT_FP64-C_MANT_FP32){1'b0}}}; //+4
- end
- endcase
- end
-
- 2'b01:
- begin
- case (Precision_ctl_S)
- 6'h00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],{(1){1'b0}}}; //+3
- end
- 6'h34:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],{(1){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h33,6'h32,6'h31,6'h30:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-1:0],{(5){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h2f,6'h2e,6'h2d,6'h2c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-5:0],{(9){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h2b,6'h2a,6'h29,6'h28:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-9:0],{(13){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h27,6'h26,6'h25,6'h24:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-13:0],{(17){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h23,6'h22,6'h21,6'h20:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-17:0],{(21){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h1f,6'h1e,6'h1d,6'h1c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-21:0],{(25){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h1b,6'h1a,6'h19,6'h18:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-25:0],{(29){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h17,6'h16,6'h15,6'h14:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-29:0],{(33){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h13,6'h12,6'h11,6'h10:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-33:0],{(37){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h0f,6'h0e,6'h0d,6'h0c:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-37:0],{(41){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h0b,6'h0a,6'h09,6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-41:0],{(45){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64-45:0],{(49){1'b0}} }; //Precision_ctl_S+1
- end
- default:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP64+3:0],{(1){1'b0}}}; //+3
- end
- endcase
- end
-
- 2'b10:
- begin
- case (Precision_ctl_S)
- 6'b00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+5:0],{(C_MANT_FP64-C_MANT_FP16-1){1'b0}} }; //+5
- end
- 6'h0a,6'h09,6'h08:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+1:1],{(C_MANT_FP64-C_MANT_FP16+4){1'b0}} }; //Precision_ctl_S+1
- end
- 6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+1-4:0],{(C_MANT_FP64-C_MANT_FP16+4+3){1'b0}} }; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16+5:0],{(C_MANT_FP64-C_MANT_FP16-1){1'b0}} }; //+5
- end
- endcase
- end
-
- 2'b11:
- begin
-
- case (Precision_ctl_S)
- 6'b00:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4
- end
- 6'h07,6'h06:
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT:0],{(C_MANT_FP64-C_MANT_FP16ALT+4){1'b0}} }; //Precision_ctl_S+1
- end
- default :
- begin
- Mant_result_prenorm_DO = {Quotient_DP[C_MANT_FP16ALT+4:0],{(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} }; //+4
- end
- endcase
- end
- endcase
- end
- end
- endgenerate
-//////////////////////four iteration units, end///////////////////////////////////////
-
-
-
-
-
-// resultant exponent
- logic [C_EXP_FP64+1:0] Exp_result_prenorm_DN,Exp_result_prenorm_DP;
-
- logic [C_EXP_FP64+1:0] Exp_add_a_D;
- logic [C_EXP_FP64+1:0] Exp_add_b_D;
- logic [C_EXP_FP64+1:0] Exp_add_c_D;
-
- integer C_BIAS_AONE, C_HALF_BIAS;
- always_comb
- begin //
- case (Format_sel_S)
- 2'b00:
- begin
- C_BIAS_AONE =C_BIAS_AONE_FP32;
- C_HALF_BIAS =C_HALF_BIAS_FP32;
- end
- 2'b01:
- begin
- C_BIAS_AONE =C_BIAS_AONE_FP64;
- C_HALF_BIAS =C_HALF_BIAS_FP64;
- end
- 2'b10:
- begin
- C_BIAS_AONE =C_BIAS_AONE_FP16;
- C_HALF_BIAS =C_HALF_BIAS_FP16;
- end
- 2'b11:
- begin
- C_BIAS_AONE =C_BIAS_AONE_FP16ALT;
- C_HALF_BIAS =C_HALF_BIAS_FP16ALT;
- end
- endcase
- end
-
-//For division, exponent=(Exp_a_D-LZ1)-(Exp_b_D-LZ2)+BIAS
-//For square root, exponent=(Exp_a_D-LZ1)/2+(Exp_a_D-LZ1)%2+C_HALF_BIAS
-//For exponent, in preprorces module, (Exp_a_D-LZ1) and (Exp_b_D-LZ2) have been processed with the corresponding process for denormal numbers.
-
- assign Exp_add_a_D = {Sqrt_start_dly_S?{Exp_num_DI[C_EXP_FP64],Exp_num_DI[C_EXP_FP64],Exp_num_DI[C_EXP_FP64],Exp_num_DI[C_EXP_FP64:1]}:{Exp_num_DI[C_EXP_FP64],Exp_num_DI[C_EXP_FP64],Exp_num_DI}};
- assign Exp_add_b_D = {Sqrt_start_dly_S?{1'b0,{C_EXP_ZERO_FP64},Exp_num_DI[0]}:{~Exp_den_DI[C_EXP_FP64],~Exp_den_DI[C_EXP_FP64],~Exp_den_DI}};
- assign Exp_add_c_D = {Div_start_dly_S?{{C_BIAS_AONE}}:{{C_HALF_BIAS}}};
- assign Exp_result_prenorm_DN = (Start_dly_S)?{Exp_add_a_D + Exp_add_b_D + Exp_add_c_D}:Exp_result_prenorm_DP;
-
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Exp_result_prenorm_DP <= '0;
- end
- else
- begin
- Exp_result_prenorm_DP<= Exp_result_prenorm_DN;
- end
- end
-
- assign Exp_result_prenorm_DO = Exp_result_prenorm_DP;
-
-endmodule
diff --git a/verilog/rtl/data_mem_top.sv b/verilog/rtl/data_mem_top.sv
deleted file mode 100644
index 19fb93e..0000000
--- a/verilog/rtl/data_mem_top.sv
+++ /dev/null
@@ -1,67 +0,0 @@
-module data_mem_top
-(
- input clk_i,
- input rst_ni,
-
-// tl-ul insterface
- input tlul_pkg::tl_h2d_t tl_d_i,
- output tlul_pkg::tl_d2h_t tl_d_o,
-
-// sram interface
- output logic csb,
- output logic [11:0] addr_o,
- output logic [31:0] wdata_o,
- output logic [3:0] wmask_o,
- output logic we_o,
- input logic [31:0] rdata_i
-);
-
- logic tl_req;
- logic [31:0] tl_wmask;
- logic we_i;
- logic rvalid_o;
-
- assign wmask_o[0] = (tl_wmask[7:0] != 8'b0) ? 1'b1: 1'b0;
- assign wmask_o[1] = (tl_wmask[15:8] != 8'b0) ? 1'b1: 1'b0;
- assign wmask_o[2] = (tl_wmask[23:16] != 8'b0) ? 1'b1: 2'b0;
- assign wmask_o[3] = (tl_wmask[31:24] != 8'b0) ? 1'b1: 2'b0;
-
- assign we_o = ~we_i;
- assign csb = ~tl_req;
-
-tlul_sram_adapter #(
- .SramAw (12),
- .SramDw (32),
- .Outstanding (4),
- .ByteAccess (1),
- .ErrOnWrite (0), // 1: Writes not allowed, automatically error
- .ErrOnRead (0)
-
-) data_mem (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_i (tl_d_i),
- .tl_o (tl_d_o),
- .req_o (tl_req),
- .gnt_i (1'b1),
- .we_o (we_i),
- .addr_o (addr_o),
- .wdata_o (wdata_o),
- .wmask_o (tl_wmask),
- .rdata_i (rst_ni? rdata_i: '0), // (reset) ? rdata_o: '0
- .rvalid_i (rvalid_o),
- .rerror_i (2'b0)
-
-);
-
- always_ff @(posedge clk_i) begin
- if (!rst_ni) begin
- rvalid_o <= 1'b0;
- end else if (we_i) begin
- rvalid_o <= 1'b0;
- end else begin
- rvalid_o <= tl_req;
- end
- end
-
-endmodule
diff --git a/verilog/rtl/debug_rom.sv b/verilog/rtl/debug_rom.sv
deleted file mode 100644
index a0e0208..0000000
--- a/verilog/rtl/debug_rom.sv
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright 2018 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.
- *
- * File: $filename.v
- *
- * Description: Auto-generated bootrom
- */
-
-// Auto-generated code
-module debug_rom (
- input logic clk_i,
- input logic req_i,
- input logic [63:0] addr_i,
- output logic [63:0] rdata_o
-);
-
- localparam int unsigned RomSize = 19;
-
- const logic [RomSize-1:0][63:0] mem = {
- 64'h00000000_7b200073,
- 64'h7b202473_7b302573,
- 64'h10852423_f1402473,
- 64'ha85ff06f_7b202473,
- 64'h7b302573_10052223,
- 64'h00100073_7b202473,
- 64'h7b302573_10052623,
- 64'h00c51513_00c55513,
- 64'h00000517_fd5ff06f,
- 64'hfa041ce3_00247413,
- 64'h40044403_00a40433,
- 64'hf1402473_02041c63,
- 64'h00147413_40044403,
- 64'h00a40433_10852023,
- 64'hf1402473_00c51513,
- 64'h00c55513_00000517,
- 64'h7b351073_7b241073,
- 64'h0ff0000f_04c0006f,
- 64'h07c0006f_00c0006f
- };
-
- logic [$clog2(RomSize)-1:0] addr_q;
-
- always_ff @(posedge clk_i) begin
- if (req_i) begin
- addr_q <= addr_i[$clog2(RomSize)-1+3:3];
- end
- end
-
- // this prevents spurious Xes from propagating into
- // the speculative fetch stage of the core
- always_comb begin : p_outmux
- rdata_o = '0;
- if (addr_q < $clog2(RomSize)'(RomSize)) begin
- rdata_o = mem[addr_q];
- end
- end
-
-endmodule
diff --git a/verilog/rtl/debug_rom_one_scratch.sv b/verilog/rtl/debug_rom_one_scratch.sv
deleted file mode 100644
index 78d47be..0000000
--- a/verilog/rtl/debug_rom_one_scratch.sv
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright 2018 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.
- *
- * File: $filename.v
- *
- * Description: Auto-generated bootrom
- */
-
-// Auto-generated code
-module debug_rom_one_scratch (
- input logic clk_i,
- input logic req_i,
- input logic [63:0] addr_i,
- output logic [63:0] rdata_o
-);
-
- localparam int unsigned RomSize = 13;
-
- const logic [RomSize-1:0][63:0] mem = {
- 64'h00000000_7b200073,
- 64'h7b202473_10802423,
- 64'hf1402473_ab1ff06f,
- 64'h7b202473_10002223,
- 64'h00100073_7b202473,
- 64'h10002623_fddff06f,
- 64'hfc0418e3_00247413,
- 64'h40044403_f1402473,
- 64'h02041263_00147413,
- 64'h40044403_10802023,
- 64'hf1402473_7b241073,
- 64'h0ff0000f_0340006f,
- 64'h0500006f_00c0006f
- };
-
- logic [$clog2(RomSize)-1:0] addr_q;
-
- always_ff @(posedge clk_i) begin
- if (req_i) begin
- addr_q <= addr_i[$clog2(RomSize)-1+3:3];
- end
- end
-
- // this prevents spurious Xes from propagating into
- // the speculative fetch stage of the core
- always_comb begin : p_outmux
- rdata_o = '0;
- if (addr_q < $clog2(RomSize)'(RomSize)) begin
- rdata_o = mem[addr_q];
- end
- end
-
-endmodule
diff --git a/verilog/rtl/defs_div_sqrt_mvp.sv b/verilog/rtl/defs_div_sqrt_mvp.sv
deleted file mode 100644
index b3f41fe..0000000
--- a/verilog/rtl/defs_div_sqrt_mvp.sv
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2018 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.
-//
-// This file contains all div_sqrt_top_mvp parameters
-// Authors : Lei Li (lile@iis.ee.ethz.ch)
-
-package defs_div_sqrt_mvp;
-
- // op command
- localparam C_RM = 3;
- localparam C_RM_NEAREST = 3'h0;
- localparam C_RM_TRUNC = 3'h1;
- localparam C_RM_PLUSINF = 3'h2;
- localparam C_RM_MINUSINF = 3'h3;
- localparam C_PC = 6; // Precision Control
- localparam C_FS = 2; // Format Selection
- localparam C_IUNC = 2; // Iteration Unit Number Control
- localparam Iteration_unit_num_S = 2'b10;
-
- // FP64
- localparam C_OP_FP64 = 64;
- localparam C_MANT_FP64 = 52;
- localparam C_EXP_FP64 = 11;
- localparam C_BIAS_FP64 = 1023;
- localparam C_BIAS_AONE_FP64 = 11'h400;
- localparam C_HALF_BIAS_FP64 = 511;
- localparam C_EXP_ZERO_FP64 = 11'h000;
- localparam C_EXP_ONE_FP64 = 13'h001; // Bit width is in agreement with in norm
- localparam C_EXP_INF_FP64 = 11'h7FF;
- localparam C_MANT_ZERO_FP64 = 52'h0;
- localparam C_MANT_NAN_FP64 = 52'h8_0000_0000_0000;
- localparam C_PZERO_FP64 = 64'h0000_0000_0000_0000;
- localparam C_MZERO_FP64 = 64'h8000_0000_0000_0000;
- localparam C_QNAN_FP64 = 64'h7FF8_0000_0000_0000;
-
- // FP32
- localparam C_OP_FP32 = 32;
- localparam C_MANT_FP32 = 23;
- localparam C_EXP_FP32 = 8;
- localparam C_BIAS_FP32 = 127;
- localparam C_BIAS_AONE_FP32 = 8'h80;
- localparam C_HALF_BIAS_FP32 = 63;
- localparam C_EXP_ZERO_FP32 = 8'h00;
- localparam C_EXP_INF_FP32 = 8'hFF;
- localparam C_MANT_ZERO_FP32 = 23'h0;
- localparam C_PZERO_FP32 = 32'h0000_0000;
- localparam C_MZERO_FP32 = 32'h8000_0000;
- localparam C_QNAN_FP32 = 32'h7FC0_0000;
-
- // FP16
- localparam C_OP_FP16 = 16;
- localparam C_MANT_FP16 = 10;
- localparam C_EXP_FP16 = 5;
- localparam C_BIAS_FP16 = 15;
- localparam C_BIAS_AONE_FP16 = 5'h10;
- localparam C_HALF_BIAS_FP16 = 7;
- localparam C_EXP_ZERO_FP16 = 5'h00;
- localparam C_EXP_INF_FP16 = 5'h1F;
- localparam C_MANT_ZERO_FP16 = 10'h0;
- localparam C_PZERO_FP16 = 16'h0000;
- localparam C_MZERO_FP16 = 16'h8000;
- localparam C_QNAN_FP16 = 16'h7E00;
-
- // FP16alt
- localparam C_OP_FP16ALT = 16;
- localparam C_MANT_FP16ALT = 7;
- localparam C_EXP_FP16ALT = 8;
- localparam C_BIAS_FP16ALT = 127;
- localparam C_BIAS_AONE_FP16ALT = 8'h80;
- localparam C_HALF_BIAS_FP16ALT = 63;
- localparam C_EXP_ZERO_FP16ALT = 8'h00;
- localparam C_EXP_INF_FP16ALT = 8'hFF;
- localparam C_MANT_ZERO_FP16ALT = 7'h0;
- localparam C_QNAN_FP16ALT = 16'h7FC0;
-
-endpackage : defs_div_sqrt_mvp
diff --git a/verilog/rtl/div_sqrt_top_mvp.sv b/verilog/rtl/div_sqrt_top_mvp.sv
deleted file mode 100644
index 3af6081..0000000
--- a/verilog/rtl/div_sqrt_top_mvp.sv
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2018 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.
-
-////////////////////////////////////////////////////////////////////////////////
-// Company: IIS @ ETHZ - Federal Institute of Technology //
-// //
-// Engineers: Lei Li -- lile@iis.ee.ethz.ch //
-// //
-// Additional contributions by: //
-// //
-// //
-// //
-// Create Date: 03/03/2018 //
-// Design Name: div_sqrt_top_mvp //
-// Module Name: div_sqrt_top_mvp.sv //
-// Project Name: The shared divisor and square root //
-// Language: SystemVerilog //
-// //
-// Description: The top of div and sqrt //
-// //
-// //
-// Revision Date: 12/04/2018 //
-// Lei Li //
-// To address some requirements by Stefan and add low power //
-// control for special cases //
-////////////////////////////////////////////////////////////////////////////////
-
-import defs_div_sqrt_mvp::*;
-
-module div_sqrt_top_mvp
-
- (//Input
- input logic Clk_CI,
- input logic Rst_RBI,
- input logic Div_start_SI,
- input logic Sqrt_start_SI,
-
- //Input Operands
- input logic [C_OP_FP64-1:0] Operand_a_DI,
- input logic [C_OP_FP64-1:0] Operand_b_DI,
-
- // Input Control
- input logic [C_RM-1:0] RM_SI, //Rounding Mode
- input logic [C_PC-1:0] Precision_ctl_SI, // Precision Control
- input logic [C_FS-1:0] Format_sel_SI, // Format Selection,
- input logic Kill_SI,
-
- //Output Result
- output logic [C_OP_FP64-1:0] Result_DO,
-
- //Output-Flags
- output logic [4:0] Fflags_SO,
- output logic Ready_SO,
- output logic Done_SO
- );
-
-
-
-
-
- //Operand components
- logic [C_EXP_FP64:0] Exp_a_D;
- logic [C_EXP_FP64:0] Exp_b_D;
- logic [C_MANT_FP64:0] Mant_a_D;
- logic [C_MANT_FP64:0] Mant_b_D;
-
- logic [C_EXP_FP64+1:0] Exp_z_D;
- logic [C_MANT_FP64+4:0] Mant_z_D;
- logic Sign_z_D;
- logic Start_S;
- logic [C_RM-1:0] RM_dly_S;
- logic Div_enable_S;
- logic Sqrt_enable_S;
- logic Inf_a_S;
- logic Inf_b_S;
- logic Zero_a_S;
- logic Zero_b_S;
- logic NaN_a_S;
- logic NaN_b_S;
- logic SNaN_S;
- logic Special_case_SB,Special_case_dly_SB;
-
- logic Full_precision_S;
- logic FP32_S;
- logic FP64_S;
- logic FP16_S;
- logic FP16ALT_S;
-
-
- preprocess_mvp preprocess_U0
- (
- .Clk_CI (Clk_CI ),
- .Rst_RBI (Rst_RBI ),
- .Div_start_SI (Div_start_SI ),
- .Sqrt_start_SI (Sqrt_start_SI ),
- .Ready_SI (Ready_SO ),
- .Operand_a_DI (Operand_a_DI ),
- .Operand_b_DI (Operand_b_DI ),
- .RM_SI (RM_SI ),
- .Format_sel_SI (Format_sel_SI ),
- .Start_SO (Start_S ),
- .Exp_a_DO_norm (Exp_a_D ),
- .Exp_b_DO_norm (Exp_b_D ),
- .Mant_a_DO_norm (Mant_a_D ),
- .Mant_b_DO_norm (Mant_b_D ),
- .RM_dly_SO (RM_dly_S ),
- .Sign_z_DO (Sign_z_D ),
- .Inf_a_SO (Inf_a_S ),
- .Inf_b_SO (Inf_b_S ),
- .Zero_a_SO (Zero_a_S ),
- .Zero_b_SO (Zero_b_S ),
- .NaN_a_SO (NaN_a_S ),
- .NaN_b_SO (NaN_b_S ),
- .SNaN_SO (SNaN_S ),
- .Special_case_SBO (Special_case_SB ),
- .Special_case_dly_SBO (Special_case_dly_SB)
- );
-
- nrbd_nrsc_mvp nrbd_nrsc_U0
- (
- .Clk_CI (Clk_CI ),
- .Rst_RBI (Rst_RBI ),
- .Div_start_SI (Div_start_SI ) ,
- .Sqrt_start_SI (Sqrt_start_SI ),
- .Start_SI (Start_S ),
- .Kill_SI (Kill_SI ),
- .Special_case_SBI (Special_case_SB ),
- .Special_case_dly_SBI (Special_case_dly_SB),
- .Div_enable_SO (Div_enable_S ),
- .Sqrt_enable_SO (Sqrt_enable_S ),
- .Precision_ctl_SI (Precision_ctl_SI ),
- .Format_sel_SI (Format_sel_SI ),
- .Exp_a_DI (Exp_a_D ),
- .Exp_b_DI (Exp_b_D ),
- .Mant_a_DI (Mant_a_D ),
- .Mant_b_DI (Mant_b_D ),
- .Full_precision_SO (Full_precision_S ),
- .FP32_SO (FP32_S ),
- .FP64_SO (FP64_S ),
- .FP16_SO (FP16_S ),
- .FP16ALT_SO (FP16ALT_S ),
- .Ready_SO (Ready_SO ),
- .Done_SO (Done_SO ),
- .Exp_z_DO (Exp_z_D ),
- .Mant_z_DO (Mant_z_D )
- );
-
-
- norm_div_sqrt_mvp fpu_norm_U0
- (
- .Mant_in_DI (Mant_z_D ),
- .Exp_in_DI (Exp_z_D ),
- .Sign_in_DI (Sign_z_D ),
- .Div_enable_SI (Div_enable_S ),
- .Sqrt_enable_SI (Sqrt_enable_S ),
- .Inf_a_SI (Inf_a_S ),
- .Inf_b_SI (Inf_b_S ),
- .Zero_a_SI (Zero_a_S ),
- .Zero_b_SI (Zero_b_S ),
- .NaN_a_SI (NaN_a_S ),
- .NaN_b_SI (NaN_b_S ),
- .SNaN_SI (SNaN_S ),
- .RM_SI (RM_dly_S ),
- .Full_precision_SI (Full_precision_S ),
- .FP32_SI (FP32_S ),
- .FP64_SI (FP64_S ),
- .FP16_SI (FP16_S ),
- .FP16ALT_SI (FP16ALT_S ),
- .Result_DO (Result_DO ),
- .Fflags_SO (Fflags_SO ) //{NV,DZ,OF,UF,NX}
- );
-
-endmodule
diff --git a/verilog/rtl/dm_csrs.sv b/verilog/rtl/dm_csrs.sv
deleted file mode 100644
index e74d320..0000000
--- a/verilog/rtl/dm_csrs.sv
+++ /dev/null
@@ -1,630 +0,0 @@
-/* Copyright 2018 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.
- *
- * File: dm_csrs.sv
- * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
- * Date: 30.6.2018
- *
- * Description: Debug CSRs. Communication over Debug Transport Module (DTM)
- */
-
-module dm_csrs #(
- parameter int unsigned NrHarts = 1,
- parameter int unsigned BusWidth = 32,
- parameter logic [NrHarts-1:0] SelectableHarts = {NrHarts{1'b1}}
-) (
- input logic clk_i, // Clock
- input logic rst_ni, // Asynchronous reset active low
- input logic testmode_i,
- input logic dmi_rst_ni, // Debug Module Intf reset active-low
- input logic dmi_req_valid_i,
- output logic dmi_req_ready_o,
- input dm::dmi_req_t dmi_req_i,
- // every request needs a response one cycle later
- output logic dmi_resp_valid_o,
- input logic dmi_resp_ready_i,
- output dm::dmi_resp_t dmi_resp_o,
- // global ctrl
- output logic ndmreset_o, // non-debug module reset active-high
- output logic dmactive_o, // 1 -> debug-module is active,
- // 0 -> synchronous re-set
- // hart status
- input dm::hartinfo_t [NrHarts-1:0] hartinfo_i, // static hartinfo
- input logic [NrHarts-1:0] halted_i, // hart is halted
- input logic [NrHarts-1:0] unavailable_i, // e.g.: powered down
- input logic [NrHarts-1:0] resumeack_i, // hart acknowledged resume request
- // hart control
- output logic [19:0] hartsel_o, // hartselect to ctrl module
- output logic [NrHarts-1:0] haltreq_o, // request to halt a hart
- output logic [NrHarts-1:0] resumereq_o, // request hart to resume
- output logic clear_resumeack_o,
-
- output logic cmd_valid_o, // debugger writing to cmd field
- output dm::command_t cmd_o, // abstract command
- input logic cmderror_valid_i, // an error occurred
- input dm::cmderr_e cmderror_i, // this error occurred
- input logic cmdbusy_i, // cmd is currently busy executing
-
- output logic [dm::ProgBufSize-1:0][31:0] progbuf_o, // to system bus
- output logic [dm::DataCount-1:0][31:0] data_o,
-
- input logic [dm::DataCount-1:0][31:0] data_i,
- input logic data_valid_i,
- // system bus access module (SBA)
- output logic [BusWidth-1:0] sbaddress_o,
- input logic [BusWidth-1:0] sbaddress_i,
- output logic sbaddress_write_valid_o,
- // control signals in
- output logic sbreadonaddr_o,
- output logic sbautoincrement_o,
- output logic [2:0] sbaccess_o,
- // data out
- output logic sbreadondata_o,
- output logic [BusWidth-1:0] sbdata_o,
- output logic sbdata_read_valid_o,
- output logic sbdata_write_valid_o,
- // read data in
- input logic [BusWidth-1:0] sbdata_i,
- input logic sbdata_valid_i,
- // control signals
- input logic sbbusy_i,
- input logic sberror_valid_i, // bus error occurred
- input logic [2:0] sberror_i // bus error occurred
-);
-
- // the amount of bits we need to represent all harts
- localparam int unsigned HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
- localparam int unsigned NrHartsAligned = 2**HartSelLen;
-
- dm::dtm_op_e dtm_op;
- assign dtm_op = dm::dtm_op_e'(dmi_req_i.op);
-
- logic [31:0] resp_queue_data;
-
- localparam dm::dm_csr_e DataEnd = dm::dm_csr_e'(dm::Data0 + {4'b0, dm::DataCount} - 8'h1);
- localparam dm::dm_csr_e ProgBufEnd = dm::dm_csr_e'(dm::ProgBuf0 + {4'b0, dm::ProgBufSize} - 8'h1);
-
- logic [31:0] haltsum0, haltsum1, haltsum2, haltsum3;
- logic [((NrHarts-1)/2**5 + 1) * 32 - 1 : 0] halted;
- logic [(NrHarts-1)/2**5:0][31:0] halted_reshaped0;
- logic [(NrHarts-1)/2**10:0][31:0] halted_reshaped1;
- logic [(NrHarts-1)/2**15:0][31:0] halted_reshaped2;
- logic [((NrHarts-1)/2**10+1)*32-1:0] halted_flat1;
- logic [((NrHarts-1)/2**15+1)*32-1:0] halted_flat2;
- logic [31:0] halted_flat3;
-
- // haltsum0
- logic [14:0] hartsel_idx0;
- always_comb begin : p_haltsum0
- halted = '0;
- haltsum0 = '0;
- hartsel_idx0 = hartsel_o[19:5];
- halted[NrHarts-1:0] = halted_i;
- halted_reshaped0 = halted;
- if (hartsel_idx0 < 15'((NrHarts-1)/2**5+1)) begin
- haltsum0 = halted_reshaped0[hartsel_idx0];
- end
- end
-
- // haltsum1
- logic [9:0] hartsel_idx1;
- always_comb begin : p_reduction1
- halted_flat1 = '0;
- haltsum1 = '0;
- hartsel_idx1 = hartsel_o[19:10];
-
- for (int unsigned k = 0; k < (NrHarts-1)/2**5+1; k++) begin
- halted_flat1[k] = |halted_reshaped0[k];
- end
- halted_reshaped1 = halted_flat1;
-
- if (hartsel_idx1 < 10'(((NrHarts-1)/2**10+1))) begin
- haltsum1 = halted_reshaped1[hartsel_idx1];
- end
- end
-
- // haltsum2
- logic [4:0] hartsel_idx2;
- always_comb begin : p_reduction2
- halted_flat2 = '0;
- haltsum2 = '0;
- hartsel_idx2 = hartsel_o[19:15];
-
- for (int unsigned k = 0; k < (NrHarts-1)/2**10+1; k++) begin
- halted_flat2[k] = |halted_reshaped1[k];
- end
- halted_reshaped2 = halted_flat2;
-
- if (hartsel_idx2 < 5'(((NrHarts-1)/2**15+1))) begin
- haltsum2 = halted_reshaped2[hartsel_idx2];
- end
- end
-
- // haltsum3
- always_comb begin : p_reduction3
- halted_flat3 = '0;
- for (int unsigned k = 0; k < NrHarts/2**15+1; k++) begin
- halted_flat3[k] = |halted_reshaped2[k];
- end
- haltsum3 = halted_flat3;
- end
-
-
- dm::dmstatus_t dmstatus;
- dm::dmcontrol_t dmcontrol_d, dmcontrol_q;
- dm::abstractcs_t abstractcs;
- dm::cmderr_e cmderr_d, cmderr_q;
- dm::command_t command_d, command_q;
- logic cmd_valid_d, cmd_valid_q;
- dm::abstractauto_t abstractauto_d, abstractauto_q;
- dm::sbcs_t sbcs_d, sbcs_q;
- logic [63:0] sbaddr_d, sbaddr_q;
- logic [63:0] sbdata_d, sbdata_q;
-
- logic [NrHarts-1:0] havereset_d, havereset_q;
- // program buffer
- logic [dm::ProgBufSize-1:0][31:0] progbuf_d, progbuf_q;
- logic [dm::DataCount-1:0][31:0] data_d, data_q;
-
- logic [HartSelLen-1:0] selected_hart;
-
- // a successful response returns zero
- assign dmi_resp_o.resp = dm::DTM_SUCCESS;
- // SBA
- assign sbautoincrement_o = sbcs_q.sbautoincrement;
- assign sbreadonaddr_o = sbcs_q.sbreadonaddr;
- assign sbreadondata_o = sbcs_q.sbreadondata;
- assign sbaccess_o = sbcs_q.sbaccess;
- assign sbdata_o = sbdata_q[BusWidth-1:0];
- assign sbaddress_o = sbaddr_q[BusWidth-1:0];
-
- assign hartsel_o = {dmcontrol_q.hartselhi, dmcontrol_q.hartsello};
-
- // needed to avoid lint warnings
- logic [NrHartsAligned-1:0] havereset_d_aligned, havereset_q_aligned,
- resumeack_aligned, unavailable_aligned,
- halted_aligned;
- assign resumeack_aligned = NrHartsAligned'(resumeack_i);
- assign unavailable_aligned = NrHartsAligned'(unavailable_i);
- assign halted_aligned = NrHartsAligned'(halted_i);
-
- assign havereset_d = NrHarts'(havereset_d_aligned);
- assign havereset_q_aligned = NrHartsAligned'(havereset_q);
-
- dm::hartinfo_t [NrHartsAligned-1:0] hartinfo_aligned;
- always_comb begin : p_hartinfo_align
- hartinfo_aligned = '0;
- hartinfo_aligned[NrHarts-1:0] = hartinfo_i;
- end
-
- // helper variables
- dm::sbcs_t sbcs;
- dm::dmcontrol_t dmcontrol;
- dm::abstractcs_t a_abstractcs;
- logic [4:0] autoexecdata_idx;
- always_comb begin : csr_read_write
- // --------------------
- // Static Values (R/O)
- // --------------------
- // dmstatus
- dmstatus = '0;
- dmstatus.version = dm::DbgVersion013;
- // no authentication implemented
- dmstatus.authenticated = 1'b1;
- // we do not support halt-on-reset sequence
- dmstatus.hasresethaltreq = 1'b0;
- // TODO(zarubaf) things need to change here if we implement the array mask
- dmstatus.allhavereset = havereset_q_aligned[selected_hart];
- dmstatus.anyhavereset = havereset_q_aligned[selected_hart];
-
- dmstatus.allresumeack = resumeack_aligned[selected_hart];
- dmstatus.anyresumeack = resumeack_aligned[selected_hart];
-
- dmstatus.allunavail = unavailable_aligned[selected_hart];
- dmstatus.anyunavail = unavailable_aligned[selected_hart];
-
- // as soon as we are out of the legal Hart region tell the debugger
- // that there are only non-existent harts
- dmstatus.allnonexistent = logic'(32'(hartsel_o) > (NrHarts - 1));
- dmstatus.anynonexistent = logic'(32'(hartsel_o) > (NrHarts - 1));
-
- // We are not allowed to be in multiple states at once. This is a to
- // make the running/halted and unavailable states exclusive.
- dmstatus.allhalted = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
- dmstatus.anyhalted = halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
-
- dmstatus.allrunning = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
- dmstatus.anyrunning = ~halted_aligned[selected_hart] & ~unavailable_aligned[selected_hart];
-
- // abstractcs
- abstractcs = '0;
- abstractcs.datacount = dm::DataCount;
- abstractcs.progbufsize = dm::ProgBufSize;
- abstractcs.busy = cmdbusy_i;
- abstractcs.cmderr = cmderr_q;
-
- // abstractautoexec
- abstractauto_d = abstractauto_q;
- abstractauto_d.zero0 = '0;
-
- // default assignments
- havereset_d_aligned = NrHartsAligned'(havereset_q);
- dmcontrol_d = dmcontrol_q;
- cmderr_d = cmderr_q;
- command_d = command_q;
- progbuf_d = progbuf_q;
- data_d = data_q;
- sbcs_d = sbcs_q;
- sbaddr_d = 64'(sbaddress_i);
- sbdata_d = sbdata_q;
-
- resp_queue_data = 32'b0;
- cmd_valid_d = 1'b0;
- sbaddress_write_valid_o = 1'b0;
- sbdata_read_valid_o = 1'b0;
- sbdata_write_valid_o = 1'b0;
- clear_resumeack_o = 1'b0;
-
- // helper variables
- sbcs = '0;
- dmcontrol = '0;
- a_abstractcs = '0;
-
- autoexecdata_idx = dmi_req_i.addr[4:0] - 5'(dm::Data0);
-
- // localparam int unsigned DataCountAlign = $clog2(dm::DataCount);
- // reads
- if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin
- unique case ({1'b0, dmi_req_i.addr}) inside
- [(dm::Data0):DataEnd]: begin
- // logic [$clog2(dm::DataCount)-1:0] resp_queue_idx;
- // resp_queue_idx = dmi_req_i.addr[4:0] - int'(dm::Data0);
- resp_queue_data = data_q[$clog2(dm::DataCount)'(autoexecdata_idx)];
- if (!cmdbusy_i) begin
- // check whether we need to re-execute the command (just give a cmd_valid)
- if (autoexecdata_idx < $bits(abstractauto_q.autoexecdata)) begin
- cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
- end
- end
- end
- dm::DMControl: resp_queue_data = dmcontrol_q;
- dm::DMStatus: resp_queue_data = dmstatus;
- dm::Hartinfo: resp_queue_data = hartinfo_aligned[selected_hart];
- dm::AbstractCS: resp_queue_data = abstractcs;
- dm::AbstractAuto: resp_queue_data = abstractauto_q;
- // command is read-only
- dm::Command: resp_queue_data = '0;
- [(dm::ProgBuf0):ProgBufEnd]: begin
- resp_queue_data = progbuf_q[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]];
- if (!cmdbusy_i) begin
- // check whether we need to re-execute the command (just give a cmd_valid)
- // range of autoexecprogbuf is 31:16
- cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
- end
- end
- dm::HaltSum0: resp_queue_data = haltsum0;
- dm::HaltSum1: resp_queue_data = haltsum1;
- dm::HaltSum2: resp_queue_data = haltsum2;
- dm::HaltSum3: resp_queue_data = haltsum3;
- dm::SBCS: begin
- resp_queue_data = sbcs_q;
- end
- dm::SBAddress0: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- resp_queue_data = sbaddr_q[31:0];
- end
- end
- dm::SBAddress1: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- resp_queue_data = sbaddr_q[63:32];
- end
- end
- dm::SBData0: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- sbdata_read_valid_o = (sbcs_q.sberror == '0);
- resp_queue_data = sbdata_q[31:0];
- end
- end
- dm::SBData1: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- resp_queue_data = sbdata_q[63:32];
- end
- end
- default:;
- endcase
- end
-
- // write
- if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin
- unique case (dm::dm_csr_e'({1'b0, dmi_req_i.addr})) inside
- [(dm::Data0):DataEnd]: begin
- // attempts to write them while busy is set does not change their value
- if (!cmdbusy_i && dm::DataCount > 0) begin
- data_d[dmi_req_i.addr[$clog2(dm::DataCount)-1:0]] = dmi_req_i.data;
- // check whether we need to re-execute the command (just give a cmd_valid)
- if (autoexecdata_idx < $bits(abstractauto_q.autoexecdata)) begin
- cmd_valid_d = abstractauto_q.autoexecdata[autoexecdata_idx];
- end
- end
- end
- dm::DMControl: begin
- dmcontrol = dm::dmcontrol_t'(dmi_req_i.data);
- // clear the havreset of the selected hart
- if (dmcontrol.ackhavereset) begin
- havereset_d_aligned[selected_hart] = 1'b0;
- end
- dmcontrol_d = dmi_req_i.data;
- end
- dm::DMStatus:; // write are ignored to R/O register
- dm::Hartinfo:; // hartinfo is R/O
- // only command error is write-able
- dm::AbstractCS: begin // W1C
- // Gets set if an abstract command fails. The bits in this
- // field remain set until they are cleared by writing 1 to
- // them. No abstract command is started until the value is
- // reset to 0.
- a_abstractcs = dm::abstractcs_t'(dmi_req_i.data);
- // reads during abstract command execution are not allowed
- if (!cmdbusy_i) begin
- cmderr_d = dm::cmderr_e'(~a_abstractcs.cmderr & cmderr_q);
- end else if (cmderr_q == dm::CmdErrNone) begin
- cmderr_d = dm::CmdErrBusy;
- end
- end
- dm::Command: begin
- // writes are ignored if a command is already busy
- if (!cmdbusy_i) begin
- cmd_valid_d = 1'b1;
- command_d = dm::command_t'(dmi_req_i.data);
- // if there was an attempted to write during a busy execution
- // and the cmderror field is zero set the busy error
- end else if (cmderr_q == dm::CmdErrNone) begin
- cmderr_d = dm::CmdErrBusy;
- end
- end
- dm::AbstractAuto: begin
- // this field can only be written legally when there is no command executing
- if (!cmdbusy_i) begin
- abstractauto_d = 32'b0;
- abstractauto_d.autoexecdata = 12'(dmi_req_i.data[dm::DataCount-1:0]);
- abstractauto_d.autoexecprogbuf = 16'(dmi_req_i.data[dm::ProgBufSize-1+16:16]);
- end else if (cmderr_q == dm::CmdErrNone) begin
- cmderr_d = dm::CmdErrBusy;
- end
- end
- [(dm::ProgBuf0):ProgBufEnd]: begin
- // attempts to write them while busy is set does not change their value
- if (!cmdbusy_i) begin
- progbuf_d[dmi_req_i.addr[$clog2(dm::ProgBufSize)-1:0]] = dmi_req_i.data;
- // check whether we need to re-execute the command (just give a cmd_valid)
- // this should probably throw an error if executed during another command
- // was busy
- // range of autoexecprogbuf is 31:16
- cmd_valid_d = abstractauto_q.autoexecprogbuf[{1'b1, dmi_req_i.addr[3:0]}];
- end
- end
- dm::SBCS: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- sbcs = dm::sbcs_t'(dmi_req_i.data);
- sbcs_d = sbcs;
- // R/W1C
- sbcs_d.sbbusyerror = sbcs_q.sbbusyerror & (~sbcs.sbbusyerror);
- sbcs_d.sberror = sbcs_q.sberror & (~sbcs.sberror);
- end
- end
- dm::SBAddress0: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- sbaddr_d[31:0] = dmi_req_i.data;
- sbaddress_write_valid_o = (sbcs_q.sberror == '0);
- end
- end
- dm::SBAddress1: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- sbaddr_d[63:32] = dmi_req_i.data;
- end
- end
- dm::SBData0: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- sbdata_d[31:0] = dmi_req_i.data;
- sbdata_write_valid_o = (sbcs_q.sberror == '0);
- end
- end
- dm::SBData1: begin
- // access while the SBA was busy
- if (sbbusy_i) begin
- sbcs_d.sbbusyerror = 1'b1;
- end else begin
- sbdata_d[63:32] = dmi_req_i.data;
- end
- end
- default:;
- endcase
- end
- // hart threw a command error and has precedence over bus writes
- if (cmderror_valid_i) begin
- cmderr_d = cmderror_i;
- end
-
- // update data registers
- if (data_valid_i) begin
- data_d = data_i;
- end
-
- // set the havereset flag when we did a ndmreset
- if (ndmreset_o) begin
- havereset_d_aligned[NrHarts-1:0] = '1;
- end
- // -------------
- // System Bus
- // -------------
- // set bus error
- if (sberror_valid_i) begin
- sbcs_d.sberror = sberror_i;
- end
- // update read data
- if (sbdata_valid_i) begin
- sbdata_d = 64'(sbdata_i);
- end
-
- // dmcontrol
- // TODO(zarubaf) we currently do not implement the hartarry mask
- dmcontrol_d.hasel = 1'b0;
- // we do not support resetting an individual hart
- dmcontrol_d.hartreset = 1'b0;
- dmcontrol_d.setresethaltreq = 1'b0;
- dmcontrol_d.clrresethaltreq = 1'b0;
- dmcontrol_d.zero1 = '0;
- dmcontrol_d.zero0 = '0;
- // Non-writeable, clear only
- dmcontrol_d.ackhavereset = 1'b0;
- if (!dmcontrol_q.resumereq && dmcontrol_d.resumereq) begin
- clear_resumeack_o = 1'b1;
- end
- if (dmcontrol_q.resumereq && resumeack_i) begin
- dmcontrol_d.resumereq = 1'b0;
- end
- // static values for dcsr
- sbcs_d.sbversion = 3'd1;
- sbcs_d.sbbusy = sbbusy_i;
- sbcs_d.sbasize = $bits(sbcs_d.sbasize)'(BusWidth);
- sbcs_d.sbaccess128 = 1'b0;
- sbcs_d.sbaccess64 = logic'(BusWidth == 32'd64);
- sbcs_d.sbaccess32 = logic'(BusWidth == 32'd32);
- sbcs_d.sbaccess16 = 1'b0;
- sbcs_d.sbaccess8 = 1'b0;
- sbcs_d.sbaccess = (BusWidth == 32'd64) ? 3'd3 : 3'd2;
- end
-
- // output multiplexer
- always_comb begin : p_outmux
- selected_hart = hartsel_o[HartSelLen-1:0];
- // default assignment
- haltreq_o = '0;
- resumereq_o = '0;
- if (selected_hart < (HartSelLen+1)'(NrHarts)) begin
- haltreq_o[selected_hart] = dmcontrol_q.haltreq;
- resumereq_o[selected_hart] = dmcontrol_q.resumereq;
- end
- end
-
- assign dmactive_o = dmcontrol_q.dmactive;
- assign cmd_o = command_q;
- assign cmd_valid_o = cmd_valid_q;
- assign progbuf_o = progbuf_q;
- assign data_o = data_q;
-
- assign ndmreset_o = dmcontrol_q.ndmreset;
-
- logic unused_testmode;
- assign unused_testmode = testmode_i;
-
- // response FIFO
- fifo_sync #(
- .Width (32),
- .Pass (1'b0),
- .Depth (2)
- ) i_fifo (
- .clk_i ( clk_i ),
- .rst_ni ( dmi_rst_ni ), // reset only when system is re-set
- .clr_i ( 1'b0 ),
- .wdata_i ( resp_queue_data ),
- .wvalid_i( dmi_req_valid_i ),
- .wready_o( dmi_req_ready_o ),
- .rdata_o ( dmi_resp_o.data ),
- .rvalid_o( dmi_resp_valid_o ),
- .rready_i( dmi_resp_ready_i ),
- .depth_o ( ) // Doesn't use
- );
-
- always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
- // PoR
- if (!rst_ni) begin
- dmcontrol_q <= '0;
- // this is the only write-able bit during reset
- cmderr_q <= dm::CmdErrNone;
- command_q <= '0;
- cmd_valid_q <= '0;
- abstractauto_q <= '0;
- progbuf_q <= '0;
- data_q <= '0;
- sbcs_q <= '0;
- sbaddr_q <= '0;
- sbdata_q <= '0;
- havereset_q <= '1;
- end else begin
- havereset_q <= SelectableHarts & havereset_d;
- // synchronous re-set of debug module, active-low, except for dmactive
- if (!dmcontrol_q.dmactive) begin
- dmcontrol_q.haltreq <= '0;
- dmcontrol_q.resumereq <= '0;
- dmcontrol_q.hartreset <= '0;
- dmcontrol_q.ackhavereset <= '0;
- dmcontrol_q.zero1 <= '0;
- dmcontrol_q.hasel <= '0;
- dmcontrol_q.hartsello <= '0;
- dmcontrol_q.hartselhi <= '0;
- dmcontrol_q.zero0 <= '0;
- dmcontrol_q.setresethaltreq <= '0;
- dmcontrol_q.clrresethaltreq <= '0;
- dmcontrol_q.ndmreset <= '0;
- // this is the only write-able bit during reset
- dmcontrol_q.dmactive <= dmcontrol_d.dmactive;
- cmderr_q <= dm::CmdErrNone;
- command_q <= '0;
- cmd_valid_q <= '0;
- abstractauto_q <= '0;
- progbuf_q <= '0;
- data_q <= '0;
- sbcs_q <= '0;
- sbaddr_q <= '0;
- sbdata_q <= '0;
- end else begin
- dmcontrol_q <= dmcontrol_d;
- cmderr_q <= cmderr_d;
- command_q <= command_d;
- cmd_valid_q <= cmd_valid_d;
- abstractauto_q <= abstractauto_d;
- progbuf_q <= progbuf_d;
- data_q <= data_d;
- sbcs_q <= sbcs_d;
- sbaddr_q <= sbaddr_d;
- sbdata_q <= sbdata_d;
- end
- end
- end
-
-
- //pragma translate_on
-
-endmodule : dm_csrs
diff --git a/verilog/rtl/dm_mem.sv b/verilog/rtl/dm_mem.sv
deleted file mode 100644
index 4ef7a26..0000000
--- a/verilog/rtl/dm_mem.sv
+++ /dev/null
@@ -1,523 +0,0 @@
-/* Copyright 2018 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.
-*
-* File: dm_mem.sv
-* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-* Date: 11.7.2018
-*
-* Description: Memory module for execution-based debug clients
-*
-*/
-
-module dm_mem #(
- parameter int unsigned NrHarts = 1,
- parameter int unsigned BusWidth = 32,
- parameter logic [NrHarts-1:0] SelectableHarts = {NrHarts{1'b1}},
- parameter int unsigned DmBaseAddress = '0
-) (
- input logic clk_i, // Clock
- input logic rst_ni, // debug module reset
-
- output logic [NrHarts-1:0] debug_req_o,
- input logic [19:0] hartsel_i,
- // from Ctrl and Status register
- input logic [NrHarts-1:0] haltreq_i,
- input logic [NrHarts-1:0] resumereq_i,
- input logic clear_resumeack_i,
-
- // state bits
- output logic [NrHarts-1:0] halted_o, // hart acknowledge halt
- output logic [NrHarts-1:0] resuming_o, // hart is resuming
-
- input logic [dm::ProgBufSize-1:0][31:0] progbuf_i, // program buffer to expose
-
- input logic [dm::DataCount-1:0][31:0] data_i, // data in
- output logic [dm::DataCount-1:0][31:0] data_o, // data out
- output logic data_valid_o, // data out is valid
- // abstract command interface
- input logic cmd_valid_i,
- input dm::command_t cmd_i,
- output logic cmderror_valid_o,
- output dm::cmderr_e cmderror_o,
- output logic cmdbusy_o,
- // data interface
-
- // SRAM interface
- input logic req_i,
- input logic we_i,
- input logic [BusWidth-1:0] addr_i,
- input logic [BusWidth-1:0] wdata_i,
- input logic [BusWidth/8-1:0] be_i,
- output logic [BusWidth-1:0] rdata_o
-);
- localparam int unsigned DbgAddressBits = 12;
- localparam int unsigned HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts);
- localparam int unsigned NrHartsAligned = 2**HartSelLen;
- localparam int unsigned MaxAar = (BusWidth == 64) ? 4 : 3;
- localparam bit HasSndScratch = (DmBaseAddress != 0);
- // Depending on whether we are at the zero page or not we either use `x0` or `x10/a0`
- localparam logic [4:0] LoadBaseAddr = (DmBaseAddress == 0) ? 5'd0 : 5'd10;
-
- localparam logic [DbgAddressBits-1:0] DataBaseAddr = (dm::DataAddr);
- localparam logic [DbgAddressBits-1:0] DataEndAddr = (dm::DataAddr + 4*dm::DataCount - 1);
- localparam logic [DbgAddressBits-1:0] ProgBufBaseAddr = (dm::DataAddr - 4*dm::ProgBufSize);
- localparam logic [DbgAddressBits-1:0] ProgBufEndAddr = (dm::DataAddr - 1);
- localparam logic [DbgAddressBits-1:0] AbstractCmdBaseAddr = (ProgBufBaseAddr - 4*10);
- localparam logic [DbgAddressBits-1:0] AbstractCmdEndAddr = (ProgBufBaseAddr - 1);
-
- localparam logic [DbgAddressBits-1:0] WhereToAddr = 'h300;
- localparam logic [DbgAddressBits-1:0] FlagsBaseAddr = 'h400;
- localparam logic [DbgAddressBits-1:0] FlagsEndAddr = 'h7FF;
-
- localparam logic [DbgAddressBits-1:0] HaltedAddr = 'h100;
- localparam logic [DbgAddressBits-1:0] GoingAddr = 'h104;
- localparam logic [DbgAddressBits-1:0] ResumingAddr = 'h108;
- localparam logic [DbgAddressBits-1:0] ExceptionAddr = 'h10C;
-
- logic [dm::ProgBufSize/2-1:0][63:0] progbuf;
- logic [7:0][63:0] abstract_cmd;
- logic [NrHarts-1:0] halted_d, halted_q;
- logic [NrHarts-1:0] resuming_d, resuming_q;
- logic resume, go, going;
-
- logic exception;
- logic unsupported_command;
-
- logic [63:0] rom_rdata;
- logic [63:0] rdata_d, rdata_q;
- logic word_enable32_q;
-
- // this is needed to avoid lint warnings related to array indexing
- // resize hartsel to valid range
- logic [HartSelLen-1:0] hartsel, wdata_hartsel;
-
- assign hartsel = hartsel_i[HartSelLen-1:0];
- assign wdata_hartsel = wdata_i[HartSelLen-1:0];
-
- logic [NrHartsAligned-1:0] resumereq_aligned, haltreq_aligned,
- halted_d_aligned, halted_q_aligned,
- halted_aligned, resumereq_wdata_aligned,
- resuming_d_aligned, resuming_q_aligned;
-
- assign resumereq_aligned = NrHartsAligned'(resumereq_i);
- assign haltreq_aligned = NrHartsAligned'(haltreq_i);
- assign resumereq_wdata_aligned = NrHartsAligned'(resumereq_i);
-
- assign halted_q_aligned = NrHartsAligned'(halted_q);
- assign halted_d = NrHarts'(halted_d_aligned);
- assign resuming_q_aligned = NrHartsAligned'(resuming_q);
- assign resuming_d = NrHarts'(resuming_d_aligned);
-
- // distinguish whether we need to forward data from the ROM or the FSM
- // latch the address for this
- logic fwd_rom_d, fwd_rom_q;
- dm::ac_ar_cmd_t ac_ar;
-
- // Abstract Command Access Register
- assign ac_ar = dm::ac_ar_cmd_t'(cmd_i.control);
- assign debug_req_o = haltreq_i;
- assign halted_o = halted_q;
- assign resuming_o = resuming_q;
-
- // reshape progbuf
- assign progbuf = progbuf_i;
-
- typedef enum logic [1:0] { Idle, Go, Resume, CmdExecuting } state_e;
- state_e state_d, state_q;
-
- // hart ctrl queue
- always_comb begin : p_hart_ctrl_queue
- cmderror_valid_o = 1'b0;
- cmderror_o = dm::CmdErrNone;
- state_d = state_q;
- go = 1'b0;
- resume = 1'b0;
- cmdbusy_o = 1'b1;
-
- unique case (state_q)
- Idle: begin
- cmdbusy_o = 1'b0;
- if (cmd_valid_i && halted_q_aligned[hartsel] && !unsupported_command) begin
- // give the go signal
- state_d = Go;
- end else if (cmd_valid_i) begin
- // hart must be halted for all requests
- cmderror_valid_o = 1'b1;
- cmderror_o = dm::CmdErrorHaltResume;
- end
- // CSRs want to resume, the request is ignored when the hart is
- // requested to halt or it didn't clear the resuming_q bit before
- if (resumereq_aligned[hartsel] && !resuming_q_aligned[hartsel] &&
- !haltreq_aligned[hartsel] && halted_q_aligned[hartsel]) begin
- state_d = Resume;
- end
- end
-
- Go: begin
- // we are already busy here since we scheduled the execution of a program
- cmdbusy_o = 1'b1;
- go = 1'b1;
- // the thread is now executing the command, track its state
- if (going) begin
- state_d = CmdExecuting;
- end
- end
-
- Resume: begin
- cmdbusy_o = 1'b1;
- resume = 1'b1;
- if (resuming_q_aligned[hartsel]) begin
- state_d = Idle;
- end
- end
-
- CmdExecuting: begin
- cmdbusy_o = 1'b1;
- go = 1'b0;
- // wait until the hart has halted again
- if (halted_aligned[hartsel]) begin
- state_d = Idle;
- end
- end
-
- //default: ;
- endcase
-
- // only signal once that cmd is unsupported so that we can clear cmderr
- // in subsequent writes to abstractcs
- if (unsupported_command && cmd_valid_i) begin
- cmderror_valid_o = 1'b1;
- cmderror_o = dm::CmdErrNotSupported;
- end
-
- if (exception) begin
- cmderror_valid_o = 1'b1;
- cmderror_o = dm::CmdErrorException;
- end
- end
-
- // word mux for 32bit and 64bit buses
- logic [63:0] word_mux;
- assign word_mux = (fwd_rom_q) ? rom_rdata : rdata_q;
-
- if (BusWidth == 64) begin : gen_word_mux64
- assign rdata_o = word_mux;
- end else begin : gen_word_mux32
- assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32];
- end
-
- // read/write logic
- logic [63:0] data_bits;
- logic [7:0][7:0] rdata;
- always_comb begin : p_rw_logic
-
- halted_d_aligned = NrHartsAligned'(halted_q);
- resuming_d_aligned = NrHartsAligned'(resuming_q);
- rdata_d = rdata_q;
- // convert the data in bits representation
- data_bits = data_i;
- rdata = '0;
-
- // write data in csr register
- data_valid_o = 1'b0;
- exception = 1'b0;
- halted_aligned = '0;
- going = 1'b0;
-
- // The resume ack signal is lowered when the resume request is deasserted
- if (clear_resumeack_i) begin
- resuming_d_aligned[hartsel] = 1'b0;
- end
- // we've got a new request
- if (req_i) begin
- // this is a write
- if (we_i) begin
- unique case (addr_i[DbgAddressBits-1:0]) inside
- HaltedAddr: begin
- halted_aligned[wdata_hartsel] = 1'b1;
- halted_d_aligned[wdata_hartsel] = 1'b1;
- end
- GoingAddr: begin
- going = 1'b1;
- end
- ResumingAddr: begin
- // clear the halted flag as the hart resumed execution
- halted_d_aligned[wdata_hartsel] = 1'b0;
- // set the resuming flag which needs to be cleared by the debugger
- resuming_d_aligned[wdata_hartsel] = 1'b1;
- end
- // an exception occurred during execution
- ExceptionAddr: exception = 1'b1;
- // core can write data registers
- [DataBaseAddr:DataEndAddr]: begin
- data_valid_o = 1'b1;
- for (int i = 0; i < $bits(be_i); i++) begin
- if (be_i[i]) begin
- data_bits[i*8+:8] = wdata_i[i*8+:8];
- end
- end
- end
- default ;
- endcase
-
- // this is a read
- end else begin
- unique case (addr_i[DbgAddressBits-1:0]) inside
- // variable ROM content
- WhereToAddr: begin
- // variable jump to abstract cmd, program_buffer or resume
- if (resumereq_wdata_aligned[wdata_hartsel]) begin
- rdata_d = {32'b0, dm::jal('0, 21'(dm::ResumeAddress[11:0])-21'(WhereToAddr))};
- end
-
- // there is a command active so jump there
- if (cmdbusy_o) begin
- // transfer not set is shortcut to the program buffer if postexec is set
- // keep this statement narrow to not catch invalid commands
- if (cmd_i.cmdtype == dm::AccessRegister &&
- !ac_ar.transfer && ac_ar.postexec) begin
- rdata_d = {32'b0, dm::jal('0, 21'(ProgBufBaseAddr)-21'(WhereToAddr))};
- // this is a legit abstract cmd -> execute it
- end else begin
- rdata_d = {32'b0, dm::jal('0, 21'(AbstractCmdBaseAddr)-21'(WhereToAddr))};
- end
- end
- end
-
- [DataBaseAddr:DataEndAddr]: begin
- rdata_d = {
- data_i[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] -
- DataBaseAddr[DbgAddressBits-1:3] + 1'b1)],
- data_i[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] -
- DataBaseAddr[DbgAddressBits-1:3])]
- };
- end
-
- [ProgBufBaseAddr:ProgBufEndAddr]: begin
- rdata_d = progbuf[$clog2(dm::ProgBufSize)'(addr_i[DbgAddressBits-1:3] -
- ProgBufBaseAddr[DbgAddressBits-1:3])];
- end
-
- // two slots for abstract command
- [AbstractCmdBaseAddr:AbstractCmdEndAddr]: begin
- // return the correct address index
- rdata_d = abstract_cmd[3'(addr_i[DbgAddressBits-1:3] -
- AbstractCmdBaseAddr[DbgAddressBits-1:3])];
- end
- // harts are polling for flags here
- [FlagsBaseAddr:FlagsEndAddr]: begin
- // release the corresponding hart
- if (({addr_i[DbgAddressBits-1:3], 3'b0} - FlagsBaseAddr[DbgAddressBits-1:0]) ==
- (DbgAddressBits'(hartsel) & {{(DbgAddressBits-3){1'b1}}, 3'b0})) begin
- rdata[DbgAddressBits'(hartsel) & DbgAddressBits'(3'b111)] = {6'b0, resume, go};
- end
- rdata_d = rdata;
- end
- default: ;
- endcase
- end
- end
-
- data_o = data_bits;
- end
-
- always_comb begin : p_abstract_cmd_rom
- // this abstract command is currently unsupported
- unsupported_command = 1'b0;
- // default memory
- // if ac_ar.transfer is not set then we can take a shortcut to the program buffer
- abstract_cmd[0][31:0] = dm::illegal();
- // load debug module base address into a0, this is shared among all commands
- abstract_cmd[0][63:32] = HasSndScratch ? dm::auipc(5'd10, '0) : dm::nop();
- // clr lowest 12b -> DM base offset
- abstract_cmd[1][31:0] = HasSndScratch ? dm::srli(5'd10, 5'd10, 6'd12) : dm::nop();
- abstract_cmd[1][63:32] = HasSndScratch ? dm::slli(5'd10, 5'd10, 6'd12) : dm::nop();
- abstract_cmd[2][31:0] = dm::nop();
- abstract_cmd[2][63:32] = dm::nop();
- abstract_cmd[3][31:0] = dm::nop();
- abstract_cmd[3][63:32] = dm::nop();
- abstract_cmd[4][31:0] = HasSndScratch ? dm::csrr(dm::CSR_DSCRATCH1, 5'd10) : dm::nop();
- abstract_cmd[4][63:32] = dm::ebreak();
- abstract_cmd[7:5] = '0;
-
- // this depends on the command being executed
- unique case (cmd_i.cmdtype)
- // --------------------
- // Access Register
- // --------------------
- dm::AccessRegister: begin
- if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && ac_ar.write) begin
- // store a0 in dscratch1
- abstract_cmd[0][31:0] = HasSndScratch ? dm::csrr(dm::CSR_DSCRATCH1, 5'd10) : dm::nop();
- // this range is reserved
- if (ac_ar.regno[15:14] != '0) begin
- abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
- unsupported_command = 1'b1;
- // A0 access needs to be handled separately, as we use A0 to load
- // the DM address offset need to access DSCRATCH1 in this case
- end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) &&
- (ac_ar.regno[4:0] == 5'd10)) begin
- // store s0 in dscratch
- abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
- // load from data register
- abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr);
- // and store it in the corresponding CSR
- abstract_cmd[3][31:0] = dm::csrw(dm::CSR_DSCRATCH1, 5'd8);
- // restore s0 again from dscratch
- abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
- // GPR/FPR access
- end else if (ac_ar.regno[12]) begin
- // determine whether we want to access the floating point register or not
- if (ac_ar.regno[5]) begin
- abstract_cmd[2][31:0] =
- dm::float_load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr);
- end else begin
- abstract_cmd[2][31:0] =
- dm::load(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr);
- end
- // CSR access
- end else begin
- // data register to CSR
- // store s0 in dscratch
- abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
- // load from data register
- abstract_cmd[2][63:32] = dm::load(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr);
- // and store it in the corresponding CSR
- abstract_cmd[3][31:0] = dm::csrw(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8);
- // restore s0 again from dscratch
- abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
- end
- end else if (32'(ac_ar.aarsize) < MaxAar && ac_ar.transfer && !ac_ar.write) begin
- // store a0 in dscratch1
- abstract_cmd[0][31:0] = HasSndScratch ?
- dm::csrr(dm::CSR_DSCRATCH1, LoadBaseAddr) :
- dm::nop();
- // this range is reserved
- if (ac_ar.regno[15:14] != '0) begin
- abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
- unsupported_command = 1'b1;
- // A0 access needs to be handled separately, as we use A0 to load
- // the DM address offset need to access DSCRATCH1 in this case
- end else if (HasSndScratch && ac_ar.regno[12] && (!ac_ar.regno[5]) &&
- (ac_ar.regno[4:0] == 5'd10)) begin
- // store s0 in dscratch
- abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
- // read value from CSR into s0
- abstract_cmd[2][63:32] = dm::csrr(dm::CSR_DSCRATCH1, 5'd8);
- // and store s0 into data section
- abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr);
- // restore s0 again from dscratch
- abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
- // GPR/FPR access
- end else if (ac_ar.regno[12]) begin
- // determine whether we want to access the floating point register or not
- if (ac_ar.regno[5]) begin
- abstract_cmd[2][31:0] =
- dm::float_store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr);
- end else begin
- abstract_cmd[2][31:0] =
- dm::store(ac_ar.aarsize, ac_ar.regno[4:0], LoadBaseAddr, dm::DataAddr);
- end
- // CSR access
- end else begin
- // CSR register to data
- // store s0 in dscratch
- abstract_cmd[2][31:0] = dm::csrw(dm::CSR_DSCRATCH0, 5'd8);
- // read value from CSR into s0
- abstract_cmd[2][63:32] = dm::csrr(dm::csr_reg_t'(ac_ar.regno[11:0]), 5'd8);
- // and store s0 into data section
- abstract_cmd[3][31:0] = dm::store(ac_ar.aarsize, 5'd8, LoadBaseAddr, dm::DataAddr);
- // restore s0 again from dscratch
- abstract_cmd[3][63:32] = dm::csrr(dm::CSR_DSCRATCH0, 5'd8);
- end
- end else if (32'(ac_ar.aarsize) >= MaxAar || ac_ar.aarpostincrement == 1'b1) begin
- // this should happend when e.g. ac_ar.aarsize >= MaxAar
- // Openocd will try to do an access with aarsize=64 bits
- // first before falling back to 32 bits.
- abstract_cmd[0][31:0] = dm::ebreak(); // we leave asap
- unsupported_command = 1'b1;
- end
-
- // Check whether we need to execute the program buffer. When we
- // get an unsupported command we really should abort instead of
- // still trying to execute the program buffer, makes it easier
- // for the debugger to recover
- if (ac_ar.postexec && !unsupported_command) begin
- // issue a nop, we will automatically run into the program buffer
- abstract_cmd[4][63:32] = dm::nop();
- end
- end
- // not supported at the moment
- // dm::QuickAccess:;
- // dm::AccessMemory:;
- default: begin
- abstract_cmd[0][31:0] = dm::ebreak();
- unsupported_command = 1'b1;
- end
- endcase
- end
-
- logic [63:0] rom_addr;
- assign rom_addr = 64'(addr_i);
-
- // Depending on whether the debug module is located
- // at the zero page we can instantiate a simplified version
- // which only requires one scratch register per hart.
- // For all other cases we need to set aside
- // two registers per hart, hence we also need
- // two scratch registers.
- if (HasSndScratch) begin : gen_rom_snd_scratch
- debug_rom i_debug_rom (
- .clk_i,
- .req_i,
- .addr_i ( rom_addr ),
- .rdata_o ( rom_rdata )
- );
- end else begin : gen_rom_one_scratch
- // It uses the zero register (`x0`) as the base
- // for its loads. The zero register does not need to
- // be saved.
- debug_rom_one_scratch i_debug_rom (
- .clk_i,
- .req_i,
- .addr_i ( rom_addr ),
- .rdata_o ( rom_rdata )
- );
- end
-
- // ROM starts at the HaltAddress of the core e.g.: it immediately jumps to
- // the ROM base address
- assign fwd_rom_d = logic'(addr_i[DbgAddressBits-1:0] >= dm::HaltAddress[DbgAddressBits-1:0]);
-
- always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
- if (!rst_ni) begin
- fwd_rom_q <= 1'b0;
- rdata_q <= '0;
- state_q <= Idle;
- word_enable32_q <= 1'b0;
- end else begin
- fwd_rom_q <= fwd_rom_d;
- rdata_q <= rdata_d;
- state_q <= state_d;
- word_enable32_q <= addr_i[2];
- end
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- halted_q <= 1'b0;
- resuming_q <= 1'b0;
- end else begin
- halted_q <= SelectableHarts & halted_d;
- resuming_q <= SelectableHarts & resuming_d;
- end
- end
-
-endmodule : dm_mem
diff --git a/verilog/rtl/dm_pkg.sv b/verilog/rtl/dm_pkg.sv
deleted file mode 100644
index 1b7d0f5..0000000
--- a/verilog/rtl/dm_pkg.sv
+++ /dev/null
@@ -1,414 +0,0 @@
-/* Copyright 2018 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.
- *
- * File: dm_pkg.sv
- * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
- * Date: 30.6.2018
- *
- * Description: Debug-module package, contains common system definitions.
- *
- */
-
-package dm;
- localparam logic [3:0] DbgVersion013 = 4'h2;
- // size of program buffer in junks of 32-bit words
- localparam logic [4:0] ProgBufSize = 5'h8;
-
- // amount of data count registers implemented
- localparam logic [3:0] DataCount = 4'h2;
-
- // address to which a hart should jump when it was requested to halt
- localparam logic [63:0] HaltAddress = 64'h800;
- localparam logic [63:0] ResumeAddress = HaltAddress + 4;
- localparam logic [63:0] ExceptionAddress = HaltAddress + 8;
-
- // address where data0-15 is shadowed or if shadowed in a CSR
- // address of the first CSR used for shadowing the data
- localparam logic [11:0] DataAddr = 12'h380; // we are aligned with Rocket here
-
- // debug registers
- typedef enum logic [7:0] {
- Data0 = 8'h04,
- Data1 = 8'h05,
- Data2 = 8'h06,
- Data3 = 8'h07,
- Data4 = 8'h08,
- Data5 = 8'h09,
- Data6 = 8'h0A,
- Data7 = 8'h0B,
- Data8 = 8'h0C,
- Data9 = 8'h0D,
- Data10 = 8'h0E,
- Data11 = 8'h0F,
- DMControl = 8'h10,
- DMStatus = 8'h11, // r/o
- Hartinfo = 8'h12,
- HaltSum1 = 8'h13,
- HAWindowSel = 8'h14,
- HAWindow = 8'h15,
- AbstractCS = 8'h16,
- Command = 8'h17,
- AbstractAuto = 8'h18,
- DevTreeAddr0 = 8'h19,
- DevTreeAddr1 = 8'h1A,
- DevTreeAddr2 = 8'h1B,
- DevTreeAddr3 = 8'h1C,
- NextDM = 8'h1D,
- ProgBuf0 = 8'h20,
- ProgBuf15 = 8'h2F,
- AuthData = 8'h30,
- HaltSum2 = 8'h34,
- HaltSum3 = 8'h35,
- SBAddress3 = 8'h37,
- SBCS = 8'h38,
- SBAddress0 = 8'h39,
- SBAddress1 = 8'h3A,
- SBAddress2 = 8'h3B,
- SBData0 = 8'h3C,
- SBData1 = 8'h3D,
- SBData2 = 8'h3E,
- SBData3 = 8'h3F,
- HaltSum0 = 8'h40
- } dm_csr_e;
-
- // debug causes
- localparam logic [2:0] CauseBreakpoint = 3'h1;
- localparam logic [2:0] CauseTrigger = 3'h2;
- localparam logic [2:0] CauseRequest = 3'h3;
- localparam logic [2:0] CauseSingleStep = 3'h4;
-
- typedef struct packed {
- logic [31:23] zero1;
- logic impebreak;
- logic [21:20] zero0;
- logic allhavereset;
- logic anyhavereset;
- logic allresumeack;
- logic anyresumeack;
- logic allnonexistent;
- logic anynonexistent;
- logic allunavail;
- logic anyunavail;
- logic allrunning;
- logic anyrunning;
- logic allhalted;
- logic anyhalted;
- logic authenticated;
- logic authbusy;
- logic hasresethaltreq;
- logic devtreevalid;
- logic [3:0] version;
- } dmstatus_t;
-
- typedef struct packed {
- logic haltreq;
- logic resumereq;
- logic hartreset;
- logic ackhavereset;
- logic zero1;
- logic hasel;
- logic [25:16] hartsello;
- logic [15:6] hartselhi;
- logic [5:4] zero0;
- logic setresethaltreq;
- logic clrresethaltreq;
- logic ndmreset;
- logic dmactive;
- } dmcontrol_t;
-
- typedef struct packed {
- logic [31:24] zero1;
- logic [23:20] nscratch;
- logic [19:17] zero0;
- logic dataaccess;
- logic [15:12] datasize;
- logic [11:0] dataaddr;
- } hartinfo_t;
-
- typedef enum logic [2:0] {
- CmdErrNone, CmdErrBusy, CmdErrNotSupported,
- CmdErrorException, CmdErrorHaltResume,
- CmdErrorBus, CmdErrorOther = 7
- } cmderr_e;
-
- typedef struct packed {
- logic [31:29] zero3;
- logic [28:24] progbufsize;
- logic [23:13] zero2;
- logic busy;
- logic zero1;
- cmderr_e cmderr;
- logic [7:4] zero0;
- logic [3:0] datacount;
- } abstractcs_t;
-
- typedef enum logic [7:0] {
- AccessRegister = 8'h0,
- QuickAccess = 8'h1,
- AccessMemory = 8'h2
- } cmd_e;
-
- typedef struct packed {
- cmd_e cmdtype;
- logic [23:0] control;
- } command_t;
-
- typedef struct packed {
- logic [31:16] autoexecprogbuf;
- logic [15:12] zero0;
- logic [11:0] autoexecdata;
- } abstractauto_t;
-
- typedef struct packed {
- logic zero1;
- logic [22:20] aarsize;
- logic aarpostincrement;
- logic postexec;
- logic transfer;
- logic write;
- logic [15:0] regno;
- } ac_ar_cmd_t;
-
- // DTM
- typedef enum logic [1:0] {
- DTM_NOP = 2'h0,
- DTM_READ = 2'h1,
- DTM_WRITE = 2'h2
- } dtm_op_e;
-
- typedef struct packed {
- logic [31:29] sbversion;
- logic [28:23] zero0;
- logic sbbusyerror;
- logic sbbusy;
- logic sbreadonaddr;
- logic [19:17] sbaccess;
- logic sbautoincrement;
- logic sbreadondata;
- logic [14:12] sberror;
- logic [11:5] sbasize;
- logic sbaccess128;
- logic sbaccess64;
- logic sbaccess32;
- logic sbaccess16;
- logic sbaccess8;
- } sbcs_t;
-
- localparam logic [1:0] DTM_SUCCESS = 2'h0;
-
- typedef struct packed {
- logic [6:0] addr;
- dtm_op_e op;
- logic [31:0] data;
- } dmi_req_t;
-
- typedef struct packed {
- logic [31:0] data;
- logic [1:0] resp;
- } dmi_resp_t;
-
- // privilege levels
- typedef enum logic[1:0] {
- PRIV_LVL_M = 2'b11,
- PRIV_LVL_S = 2'b01,
- PRIV_LVL_U = 2'b00
- } priv_lvl_t;
-
- // debugregs in core
- typedef struct packed {
- logic [31:28] xdebugver;
- logic [27:16] zero2;
- logic ebreakm;
- logic zero1;
- logic ebreaks;
- logic ebreaku;
- logic stepie;
- logic stopcount;
- logic stoptime;
- logic [8:6] cause;
- logic zero0;
- logic mprven;
- logic nmip;
- logic step;
- priv_lvl_t prv;
- } dcsr_t;
-
- // CSRs
- typedef enum logic [11:0] {
- // Floating-Point CSRs
- CSR_FFLAGS = 12'h001,
- CSR_FRM = 12'h002,
- CSR_FCSR = 12'h003,
- CSR_FTRAN = 12'h800,
- // Supervisor Mode CSRs
- CSR_SSTATUS = 12'h100,
- CSR_SIE = 12'h104,
- CSR_STVEC = 12'h105,
- CSR_SCOUNTEREN = 12'h106,
- CSR_SSCRATCH = 12'h140,
- CSR_SEPC = 12'h141,
- CSR_SCAUSE = 12'h142,
- CSR_STVAL = 12'h143,
- CSR_SIP = 12'h144,
- CSR_SATP = 12'h180,
- // Machine Mode CSRs
- CSR_MSTATUS = 12'h300,
- CSR_MISA = 12'h301,
- CSR_MEDELEG = 12'h302,
- CSR_MIDELEG = 12'h303,
- CSR_MIE = 12'h304,
- CSR_MTVEC = 12'h305,
- CSR_MCOUNTEREN = 12'h306,
- CSR_MSCRATCH = 12'h340,
- CSR_MEPC = 12'h341,
- CSR_MCAUSE = 12'h342,
- CSR_MTVAL = 12'h343,
- CSR_MIP = 12'h344,
- CSR_PMPCFG0 = 12'h3A0,
- CSR_PMPADDR0 = 12'h3B0,
- CSR_MVENDORID = 12'hF11,
- CSR_MARCHID = 12'hF12,
- CSR_MIMPID = 12'hF13,
- CSR_MHARTID = 12'hF14,
- CSR_MCYCLE = 12'hB00,
- CSR_MINSTRET = 12'hB02,
- CSR_DCACHE = 12'h701,
- CSR_ICACHE = 12'h700,
-
- CSR_TSELECT = 12'h7A0,
- CSR_TDATA1 = 12'h7A1,
- CSR_TDATA2 = 12'h7A2,
- CSR_TDATA3 = 12'h7A3,
- CSR_TINFO = 12'h7A4,
-
- // Debug CSR
- CSR_DCSR = 12'h7b0,
- CSR_DPC = 12'h7b1,
- CSR_DSCRATCH0 = 12'h7b2, // optional
- CSR_DSCRATCH1 = 12'h7b3, // optional
-
- // Counters and Timers
- CSR_CYCLE = 12'hC00,
- CSR_TIME = 12'hC01,
- CSR_INSTRET = 12'hC02
- } csr_reg_t;
-
-
- // Instruction Generation Helpers
- function automatic logic [31:0] jal (logic [4:0] rd,
- logic [20:0] imm);
- // OpCode Jal
- return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h6f};
- endfunction
-
- function automatic logic [31:0] jalr (logic [4:0] rd,
- logic [4:0] rs1,
- logic [11:0] offset);
- // OpCode Jal
- return {offset[11:0], rs1, 3'b0, rd, 7'h67};
- endfunction
-
- function automatic logic [31:0] andi (logic [4:0] rd,
- logic [4:0] rs1,
- logic [11:0] imm);
- // OpCode andi
- return {imm[11:0], rs1, 3'h7, rd, 7'h13};
- endfunction
-
- function automatic logic [31:0] slli (logic [4:0] rd,
- logic [4:0] rs1,
- logic [5:0] shamt);
- // OpCode slli
- return {6'b0, shamt[5:0], rs1, 3'h1, rd, 7'h13};
- endfunction
-
- function automatic logic [31:0] srli (logic [4:0] rd,
- logic [4:0] rs1,
- logic [5:0] shamt);
- // OpCode srli
- return {6'b0, shamt[5:0], rs1, 3'h5, rd, 7'h13};
- endfunction
-
- function automatic logic [31:0] load (logic [2:0] size,
- logic [4:0] dest,
- logic [4:0] base,
- logic [11:0] offset);
- // OpCode Load
- return {offset[11:0], base, size, dest, 7'h03};
- endfunction
-
- function automatic logic [31:0] auipc (logic [4:0] rd,
- logic [20:0] imm);
- // OpCode Auipc
- return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h17};
- endfunction
-
- function automatic logic [31:0] store (logic [2:0] size,
- logic [4:0] src,
- logic [4:0] base,
- logic [11:0] offset);
- // OpCode Store
- return {offset[11:5], src, base, size, offset[4:0], 7'h23};
- endfunction
-
- function automatic logic [31:0] float_load (logic [2:0] size,
- logic [4:0] dest,
- logic [4:0] base,
- logic [11:0] offset);
- // OpCode Load
- return {offset[11:0], base, size, dest, 7'b00_001_11};
- endfunction
-
- function automatic logic [31:0] float_store (logic [2:0] size,
- logic [4:0] src,
- logic [4:0] base,
- logic [11:0] offset);
- // OpCode Store
- return {offset[11:5], src, base, size, offset[4:0], 7'b01_001_11};
- endfunction
-
- function automatic logic [31:0] csrw (csr_reg_t csr,
- logic [4:0] rs1);
- // CSRRW, rd, OpCode System
- return {csr, rs1, 3'h1, 5'h0, 7'h73};
- endfunction
-
- function automatic logic [31:0] csrr (csr_reg_t csr,
- logic [4:0] dest);
- // rs1, CSRRS, rd, OpCode System
- return {csr, 5'h0, 3'h2, dest, 7'h73};
- endfunction
-
- function automatic logic [31:0] branch(logic [4:0] src2,
- logic [4:0] src1,
- logic [2:0] funct3,
- logic [11:0] offset);
- // OpCode Branch
- return {offset[11], offset[9:4], src2, src1, funct3,
- offset[3:0], offset[10], 7'b11_000_11};
- endfunction
-
- function automatic logic [31:0] ebreak ();
- return 32'h00100073;
- endfunction
-
- function automatic logic [31:0] wfi ();
- return 32'h10500073;
- endfunction
-
- function automatic logic [31:0] nop ();
- return 32'h00000013;
- endfunction
-
- function automatic logic [31:0] illegal ();
- return 32'h00000000;
- endfunction
-
-endpackage : dm
diff --git a/verilog/rtl/dm_sba.sv b/verilog/rtl/dm_sba.sv
deleted file mode 100644
index c97f956..0000000
--- a/verilog/rtl/dm_sba.sv
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright 2018 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.
-*
-* File: dm_sba.sv
-* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-* Date: 1.8.2018
-*
-* Description: System Bus Access Module
-*
-*/
-module dm_sba #(
- parameter int unsigned BusWidth = 32
-) (
- input logic clk_i, // Clock
- input logic rst_ni,
- input logic dmactive_i, // synchronous reset active low
-
- output logic master_req_o,
- output logic [BusWidth-1:0] master_add_o,
- output logic master_we_o,
- output logic [BusWidth-1:0] master_wdata_o,
- output logic [BusWidth/8-1:0] master_be_o,
- input logic master_gnt_i,
- input logic master_r_valid_i,
- input logic [BusWidth-1:0] master_r_rdata_i,
-
- input logic [BusWidth-1:0] sbaddress_i,
- input logic sbaddress_write_valid_i,
- // control signals in
- input logic sbreadonaddr_i,
- output logic [BusWidth-1:0] sbaddress_o,
- input logic sbautoincrement_i,
- input logic [2:0] sbaccess_i,
- // data in
- input logic sbreadondata_i,
- input logic [BusWidth-1:0] sbdata_i,
- input logic sbdata_read_valid_i,
- input logic sbdata_write_valid_i,
- // read data out
- output logic [BusWidth-1:0] sbdata_o,
- output logic sbdata_valid_o,
- // control signals
- output logic sbbusy_o,
- output logic sberror_valid_o, // bus error occurred
- output logic [2:0] sberror_o // bus error occurred
-);
-
- typedef enum logic [2:0] { Idle, Read, Write, WaitRead, WaitWrite } state_e;
- state_e state_d, state_q;
-
- logic [BusWidth-1:0] address;
- logic req;
- logic gnt;
- logic we;
- logic [BusWidth/8-1:0] be;
- logic [$clog2(BusWidth/8)-1:0] be_idx;
-
- assign sbbusy_o = logic'(state_q != Idle);
-
- always_comb begin : p_fsm
- req = 1'b0;
- address = sbaddress_i;
- we = 1'b0;
- be = '0;
- be_idx = sbaddress_i[$clog2(BusWidth/8)-1:0];
-
- sberror_o = '0;
- sberror_valid_o = 1'b0;
- sbaddress_o = sbaddress_i;
-
- state_d = state_q;
-
- unique case (state_q)
- Idle: begin
- // debugger requested a read
- if (sbaddress_write_valid_i && sbreadonaddr_i) state_d = Read;
- // debugger requested a write
- if (sbdata_write_valid_i) state_d = Write;
- // perform another read
- if (sbdata_read_valid_i && sbreadondata_i) state_d = Read;
- end
-
- Read: begin
- req = 1'b1;
- if (gnt) state_d = WaitRead;
- end
-
- Write: begin
- req = 1'b1;
- we = 1'b1;
- // generate byte enable mask
- unique case (sbaccess_i)
- 3'b000: begin
- be[be_idx] = '1;
- end
- 3'b001: begin
- be[int'({be_idx[$high(be_idx):1], 1'b0}) +: 2] = '1;
- end
- 3'b010: begin
- if (BusWidth == 32'd64) be[int'({be_idx[$high(be_idx)], 2'h0}) +: 4] = '1;
- else be = '1;
- end
- 3'b011: be = '1;
- default: ;
- endcase
- if (gnt) state_d = WaitWrite;
- end
-
- WaitRead: begin
- if (sbdata_valid_o) begin
- state_d = Idle;
- // auto-increment address
- if (sbautoincrement_i) sbaddress_o = sbaddress_i + (32'h1 << sbaccess_i);
- end
- end
-
- WaitWrite: begin
- if (sbdata_valid_o) begin
- state_d = Idle;
- // auto-increment address
- if (sbautoincrement_i) sbaddress_o = sbaddress_i + (32'h1 << sbaccess_i);
- end
- end
-
- default: state_d = Idle; // catch parasitic state
- endcase
-
- // handle error case
- if (sbaccess_i > 3 && state_q != Idle) begin
- req = 1'b0;
- state_d = Idle;
- sberror_valid_o = 1'b1;
- sberror_o = 3'd3;
- end
- // further error handling should go here ...
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
- if (!rst_ni) begin
- state_q <= Idle;
- end else begin
- state_q <= state_d;
- end
- end
-
- assign master_req_o = req;
- assign master_add_o = address[BusWidth-1:0];
- assign master_we_o = we;
- assign master_wdata_o = sbdata_i[BusWidth-1:0];
- assign master_be_o = be[BusWidth/8-1:0];
- assign gnt = master_gnt_i;
- assign sbdata_valid_o = master_r_valid_i;
- assign sbdata_o = master_r_rdata_i[BusWidth-1:0];
-
-
- //pragma translate_off
- `ifndef VERILATOR
- // maybe bump severity to $error if not handled at runtime
- dm_sba_access_size: assert property(@(posedge clk_i) disable iff (dmactive_i !== 1'b0)
- (state_d != Idle) |-> (sbaccess_i < 4))
- else $warning ("accesses > 8 byte not supported at the moment");
- `endif
- //pragma translate_on
-
-endmodule : dm_sba
diff --git a/verilog/rtl/dmi_cdc.sv b/verilog/rtl/dmi_cdc.sv
deleted file mode 100644
index c1c1de2..0000000
--- a/verilog/rtl/dmi_cdc.sv
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright 2018 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.
-*
-* File: axi_riscv_debug_module.sv
-* Author: Andreas Traber <atraber@iis.ee.ethz.ch>
-* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-*
-* Description: Clock domain crossings for JTAG to DMI very heavily based
-* on previous work by Andreas Traber for the PULP project.
-* This is mainly a wrapper around the existing CDCs.
-*/
-module dmi_cdc (
- // JTAG side (master side)
- input logic tck_i,
- input logic trst_ni,
-
- input dm::dmi_req_t jtag_dmi_req_i,
- output logic jtag_dmi_ready_o,
- input logic jtag_dmi_valid_i,
-
- output dm::dmi_resp_t jtag_dmi_resp_o,
- output logic jtag_dmi_valid_o,
- input logic jtag_dmi_ready_i,
-
- // core side (slave side)
- input logic clk_i,
- input logic rst_ni,
-
- output dm::dmi_req_t core_dmi_req_o,
- output logic core_dmi_valid_o,
- input logic core_dmi_ready_i,
-
- input dm::dmi_resp_t core_dmi_resp_i,
- output logic core_dmi_ready_o,
- input logic core_dmi_valid_i
-);
-
- // TODO: Make it clean for synthesis.
-
- fifo_async #(
- .Width ( $bits(dm::dmi_req_t) ),
- .Depth ( 4 )
- ) i_cdc_req (
- .clk_wr_i ( tck_i ),
- .rst_wr_ni ( trst_ni ),
- .wvalid_i ( jtag_dmi_valid_i ),
- .wready_o ( jtag_dmi_ready_o ), // wrclk
- .wdata_i ( jtag_dmi_req_i ),
- .wdepth_o ( ),
-
- .clk_rd_i ( clk_i ),
- .rst_rd_ni ( rst_ni ),
- .rvalid_o ( core_dmi_valid_o ),
- .rready_i ( core_dmi_ready_i ),
- .rdata_o ( core_dmi_req_o ),
- .rdepth_o ( )
- );
-
- fifo_async #(
- .Width ( $bits(dm::dmi_resp_t) ),
- .Depth ( 4 )
- ) i_cdc_resp (
- .clk_wr_i ( clk_i ),
- .rst_wr_ni ( rst_ni ),
- .wvalid_i ( core_dmi_valid_i ),
- .wready_o ( core_dmi_ready_o ), // wrclk
- .wdata_i ( core_dmi_resp_i ),
- .wdepth_o ( ),
-
- .clk_rd_i ( tck_i ),
- .rst_rd_ni ( trst_ni ),
- .rvalid_o ( jtag_dmi_valid_o ),
- .rready_i ( jtag_dmi_ready_i ),
- .rdata_o ( jtag_dmi_resp_o ),
- .rdepth_o ( )
- );
-
-endmodule : dmi_cdc
diff --git a/verilog/rtl/dmi_jtag.sv b/verilog/rtl/dmi_jtag.sv
deleted file mode 100644
index 917cdc6..0000000
--- a/verilog/rtl/dmi_jtag.sv
+++ /dev/null
@@ -1,264 +0,0 @@
-/* Copyright 2018 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.
-*
-* File: axi_riscv_debug_module.sv
-* Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
-* Date: 19.7.2018
-*
-* Description: JTAG DMI (debug module interface)
-*
-*/
-
-module dmi_jtag #(
- parameter logic [31:0] IdcodeValue = 32'h00000001
-) (
- input logic clk_i, // DMI Clock
- input logic rst_ni, // Asynchronous reset active low
- input logic testmode_i,
-
- output logic dmi_rst_no, // hard reset
- output dm::dmi_req_t dmi_req_o,
- output logic dmi_req_valid_o,
- input logic dmi_req_ready_i,
-
- input dm::dmi_resp_t dmi_resp_i,
- output logic dmi_resp_ready_o,
- input logic dmi_resp_valid_i,
-
- input logic tck_i, // JTAG test clock pad
- input logic tms_i, // JTAG test mode select pad
- input logic trst_ni, // JTAG test reset pad
- input logic td_i, // JTAG test data input pad
- output logic td_o, // JTAG test data output pad
- output logic tdo_oe_o // Data out output enable
-);
- assign dmi_rst_no = rst_ni;
-
- logic test_logic_reset;
- logic shift_dr;
- logic update_dr;
- logic capture_dr;
- logic dmi_access;
- logic dtmcs_select;
- logic dmi_reset;
- logic dmi_tdi;
- logic dmi_tdo;
-
- dm::dmi_req_t dmi_req;
- logic dmi_req_ready;
- logic dmi_req_valid;
-
- dm::dmi_resp_t dmi_resp;
- logic dmi_resp_valid;
- logic dmi_resp_ready;
-
- typedef struct packed {
- logic [6:0] address;
- logic [31:0] data;
- logic [1:0] op;
- } dmi_t;
-
- typedef enum logic [1:0] {
- DMINoError = 2'h0, DMIReservedError = 2'h1,
- DMIOPFailed = 2'h2, DMIBusy = 2'h3
- } dmi_error_e;
-
- typedef enum logic [2:0] { Idle, Read, WaitReadValid, Write, WaitWriteValid } state_e;
- state_e state_d, state_q;
-
- logic [$bits(dmi_t)-1:0] dr_d, dr_q;
- logic [6:0] address_d, address_q;
- logic [31:0] data_d, data_q;
-
- dmi_t dmi;
- assign dmi = dmi_t'(dr_q);
- assign dmi_req.addr = address_q;
- assign dmi_req.data = data_q;
- assign dmi_req.op = (state_q == Write) ? dm::DTM_WRITE : dm::DTM_READ;
- // we'will always be ready to accept the data we requested
- assign dmi_resp_ready = 1'b1;
-
- logic error_dmi_busy;
- dmi_error_e error_d, error_q;
-
- always_comb begin : p_fsm
- error_dmi_busy = 1'b0;
- // default assignments
- state_d = state_q;
- address_d = address_q;
- data_d = data_q;
- error_d = error_q;
-
- dmi_req_valid = 1'b0;
-
- unique case (state_q)
- Idle: begin
- // make sure that no error is sticky
- if (dmi_access && update_dr && (error_q == DMINoError)) begin
- // save address and value
- address_d = dmi.address;
- data_d = dmi.data;
- if (dm::dtm_op_e'(dmi.op) == dm::DTM_READ) begin
- state_d = Read;
- end else if (dm::dtm_op_e'(dmi.op) == dm::DTM_WRITE) begin
- state_d = Write;
- end
- // else this is a nop and we can stay here
- end
- end
-
- Read: begin
- dmi_req_valid = 1'b1;
- if (dmi_req_ready) begin
- state_d = WaitReadValid;
- end
- end
-
- WaitReadValid: begin
- // load data into register and shift out
- if (dmi_resp_valid) begin
- data_d = dmi_resp.data;
- state_d = Idle;
- end
- end
-
- Write: begin
- dmi_req_valid = 1'b1;
- // got a valid answer go back to idle
- if (dmi_req_ready) begin
- state_d = Idle;
- end
- end
-
- default: begin
- // just wait for idle here
- if (dmi_resp_valid) begin
- state_d = Idle;
- end
- end
- endcase
-
- // update_dr means we got another request but we didn't finish
- // the one in progress, this state is sticky
- if (update_dr && state_q != Idle) begin
- error_dmi_busy = 1'b1;
- end
-
- // if capture_dr goes high while we are in the read state
- // or in the corresponding wait state we are not giving back a valid word
- // -> throw an error
- if (capture_dr && state_q inside {Read, WaitReadValid}) begin
- error_dmi_busy = 1'b1;
- end
-
- if (error_dmi_busy) begin
- error_d = DMIBusy;
- end
- // clear sticky error flag
- if (dmi_reset && dtmcs_select) begin
- error_d = DMINoError;
- end
- end
-
- // shift register
- assign dmi_tdo = dr_q[0];
-
- always_comb begin : p_shift
- dr_d = dr_q;
-
- if (capture_dr) begin
- if (dmi_access) begin
- if (error_q == DMINoError && !error_dmi_busy) begin
- dr_d = {address_q, data_q, DMINoError};
- // DMI was busy, report an error
- end else if (error_q == DMIBusy || error_dmi_busy) begin
- dr_d = {address_q, data_q, DMIBusy};
- end
- end
- end
-
- if (shift_dr) begin
- if (dmi_access) begin
- dr_d = {dmi_tdi, dr_q[$bits(dr_q)-1:1]};
- end
- end
-
- if (test_logic_reset) begin
- dr_d = '0;
- end
- end
-
- always_ff @(posedge tck_i or negedge trst_ni) begin : p_regs
- if (!trst_ni) begin
- dr_q <= '0;
- state_q <= Idle;
- address_q <= '0;
- data_q <= '0;
- error_q <= DMINoError;
- end else begin
- dr_q <= dr_d;
- state_q <= state_d;
- address_q <= address_d;
- data_q <= data_d;
- error_q <= error_d;
- end
- end
-
- // ---------
- // TAP
- // ---------
- dmi_jtag_tap #(
- .IrLength (5),
- .IdcodeValue(IdcodeValue)
- ) i_dmi_jtag_tap (
- .tck_i (tck_i) ,
- .tms_i (tms_i),
- .trst_ni (trst_ni),
- .td_i (td_i),
- .td_o (td_o),
- .tdo_oe_o(tdo_oe_o),
- .testmode_i (testmode_i),
- .test_logic_reset_o ( test_logic_reset ),
- .shift_dr_o ( shift_dr ),
- .update_dr_o ( update_dr ),
- .capture_dr_o ( capture_dr ),
- .dmi_access_o ( dmi_access ),
- .dtmcs_select_o ( dtmcs_select ),
- .dmi_reset_o ( dmi_reset ),
- .dmi_error_i ( error_q ),
- .dmi_tdi_o ( dmi_tdi ),
- .dmi_tdo_i ( dmi_tdo )
- );
-
- // ---------
- // CDC
- // ---------
- dmi_cdc i_dmi_cdc (
- // JTAG side (master side)
- .tck_i (tck_i),
- .trst_ni (trst_ni),
- .jtag_dmi_req_i ( dmi_req ),
- .jtag_dmi_ready_o ( dmi_req_ready ),
- .jtag_dmi_valid_i ( dmi_req_valid ),
- .jtag_dmi_resp_o ( dmi_resp ),
- .jtag_dmi_valid_o ( dmi_resp_valid ),
- .jtag_dmi_ready_i ( dmi_resp_ready ),
- // core side
- .clk_i,
- .rst_ni,
- .core_dmi_req_o ( dmi_req_o ),
- .core_dmi_valid_o ( dmi_req_valid_o ),
- .core_dmi_ready_i ( dmi_req_ready_i ),
- .core_dmi_resp_i ( dmi_resp_i ),
- .core_dmi_ready_o ( dmi_resp_ready_o ),
- .core_dmi_valid_i ( dmi_resp_valid_i )
- );
-
-endmodule : dmi_jtag
diff --git a/verilog/rtl/dmi_jtag_tap.sv b/verilog/rtl/dmi_jtag_tap.sv
deleted file mode 100644
index e90f914..0000000
--- a/verilog/rtl/dmi_jtag_tap.sv
+++ /dev/null
@@ -1,345 +0,0 @@
-/* Copyright 2018 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.
- *
- * File: dmi_jtag_tap.sv
- * Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
- * Date: 19.7.2018
- *
- * Description: JTAG TAP for DMI (according to debug spec 0.13)
- *
- */
-
-module dmi_jtag_tap #(
- parameter int unsigned IrLength = 5,
- // JTAG IDCODE Value
- parameter logic [31:0] IdcodeValue = 32'h00000001
- // xxxx version
- // xxxxxxxxxxxxxxxx part number
- // xxxxxxxxxxx manufacturer id
- // 1 required by standard
-) (
- input logic tck_i, // JTAG test clock pad
- input logic tms_i, // JTAG test mode select pad
- input logic trst_ni, // JTAG test reset pad
- input logic td_i, // JTAG test data input pad
- output logic td_o, // JTAG test data output pad
- output logic tdo_oe_o, // Data out output enable
- input logic testmode_i,
- output logic test_logic_reset_o,
- output logic shift_dr_o,
- output logic update_dr_o,
- output logic capture_dr_o,
-
- // we want to access DMI register
- output logic dmi_access_o,
- // JTAG is interested in writing the DTM CSR register
- output logic dtmcs_select_o,
- // clear error state
- output logic dmi_reset_o,
- input logic [1:0] dmi_error_i,
- // test data to submodule
- output logic dmi_tdi_o,
- // test data in from submodule
- input logic dmi_tdo_i
-);
-
- // to submodule
- assign dmi_tdi_o = td_i;
-
- typedef enum logic [3:0] {
- TestLogicReset, RunTestIdle, SelectDrScan,
- CaptureDr, ShiftDr, Exit1Dr, PauseDr, Exit2Dr,
- UpdateDr, SelectIrScan, CaptureIr, ShiftIr,
- Exit1Ir, PauseIr, Exit2Ir, UpdateIr
- } tap_state_e;
-
- tap_state_e tap_state_q, tap_state_d;
-
- typedef enum logic [IrLength-1:0] {
- BYPASS0 = 'h0,
- IDCODE = 'h1,
- DTMCSR = 'h10,
- DMIACCESS = 'h11,
- BYPASS1 = 'h1f
- } ir_reg_e;
-
- typedef struct packed {
- logic [31:18] zero1;
- logic dmihardreset;
- logic dmireset;
- logic zero0;
- logic [14:12] idle;
- logic [11:10] dmistat;
- logic [9:4] abits;
- logic [3:0] version;
- } dtmcs_t;
-
- // ----------------
- // IR logic
- // ----------------
-
- // shift register
- logic [IrLength-1:0] jtag_ir_shift_d, jtag_ir_shift_q;
- // IR register -> this gets captured from shift register upon update_ir
- ir_reg_e jtag_ir_d, jtag_ir_q;
- logic capture_ir, shift_ir, update_ir; // pause_ir
-
- always_comb begin : p_jtag
- jtag_ir_shift_d = jtag_ir_shift_q;
- jtag_ir_d = jtag_ir_q;
-
- // IR shift register
- if (shift_ir) begin
- jtag_ir_shift_d = {td_i, jtag_ir_shift_q[IrLength-1:1]};
- end
-
- // capture IR register
- if (capture_ir) begin
- jtag_ir_shift_d = IrLength'(4'b0101);
- end
-
- // update IR register
- if (update_ir) begin
- jtag_ir_d = ir_reg_e'(jtag_ir_shift_q);
- end
-
- // synchronous test-logic reset
- if (test_logic_reset_o) begin
- jtag_ir_shift_d = '0;
- jtag_ir_d = IDCODE;
- end
- end
-
- always_ff @(posedge tck_i, negedge trst_ni) begin : p_jtag_ir_reg
- if (!trst_ni) begin
- jtag_ir_shift_q <= '0;
- jtag_ir_q <= IDCODE;
- end else begin
- jtag_ir_shift_q <= jtag_ir_shift_d;
- jtag_ir_q <= jtag_ir_d;
- end
- end
-
- // ----------------
- // TAP DR Regs
- // ----------------
- // - Bypass
- // - IDCODE
- // - DTM CS
- logic [31:0] idcode_d, idcode_q;
- logic idcode_select;
- logic bypass_select;
- dtmcs_t dtmcs_d, dtmcs_q;
- logic bypass_d, bypass_q; // this is a 1-bit register
-
- assign dmi_reset_o = dtmcs_q.dmireset;
-
- always_comb begin
- idcode_d = idcode_q;
- bypass_d = bypass_q;
- dtmcs_d = dtmcs_q;
-
- if (capture_dr_o) begin
- if (idcode_select) idcode_d = IdcodeValue;
- if (bypass_select) bypass_d = 1'b0;
- if (dtmcs_select_o) begin
- dtmcs_d = '{
- zero1 : '0,
- dmihardreset : 1'b0,
- dmireset : 1'b0,
- zero0 : '0,
- idle : 3'd1, // 1: Enter Run-Test/Idle and leave it immediately
- dmistat : dmi_error_i, // 0: No error, 1: Op failed, 2: too fast
- abits : 6'd7, // The size of address in dmi
- version : 4'd1 // Version described in spec version 0.13 (and later?)
- };
- end
- end
-
- if (shift_dr_o) begin
- if (idcode_select) idcode_d = {td_i, 31'(idcode_q >> 1)};
- if (bypass_select) bypass_d = td_i;
- if (dtmcs_select_o) dtmcs_d = {td_i, 31'(dtmcs_q >> 1)};
- end
-
- if (test_logic_reset_o) begin
- idcode_d = IdcodeValue;
- bypass_d = 1'b0;
- end
- end
-
- // ----------------
- // Data reg select
- // ----------------
- always_comb begin : p_data_reg_sel
- dmi_access_o = 1'b0;
- dtmcs_select_o = 1'b0;
- idcode_select = 1'b0;
- bypass_select = 1'b0;
- unique case (jtag_ir_q)
- BYPASS0: bypass_select = 1'b1;
- IDCODE: idcode_select = 1'b1;
- DTMCSR: dtmcs_select_o = 1'b1;
- DMIACCESS: dmi_access_o = 1'b1;
- BYPASS1: bypass_select = 1'b1;
- default: bypass_select = 1'b1;
- endcase
- end
-
- // ----------------
- // Output select
- // ----------------
- logic tdo_mux;
-
- always_comb begin : p_out_sel
- // we are shifting out the IR register
- if (shift_ir) begin
- tdo_mux = jtag_ir_shift_q[0];
- // here we are shifting the DR register
- end else begin
- unique case (jtag_ir_q)
- IDCODE: tdo_mux = idcode_q[0]; // Reading ID code
- DTMCSR: tdo_mux = dtmcs_q.version[0];
- DMIACCESS: tdo_mux = dmi_tdo_i; // Read from DMI TDO
- default: tdo_mux = bypass_q; // BYPASS instruction
- endcase
- end
- end
-
- // ----------------
- // DFT
- // ----------------
- logic tck_n;
-
- prim_generic_clock_inv #(
- .HasScanMode(1'b1)
- ) i_tck_inv (
- .clk_i ( tck_i ),
- .clk_no ( tck_n ),
- .scanmode_i ( testmode_i )
- );
-
- // TDO changes state at negative edge of TCK
- always_ff @(posedge tck_n, negedge trst_ni) begin : p_tdo_regs
- if (!trst_ni) begin
- td_o <= 1'b0;
- tdo_oe_o <= 1'b0;
- end else begin
- td_o <= tdo_mux;
- tdo_oe_o <= (shift_ir | shift_dr_o);
- end
- end
- // ----------------
- // TAP FSM
- // ----------------
- // Determination of next state; purely combinatorial
- always_comb begin : p_tap_fsm
-
- test_logic_reset_o = 1'b0;
-
- capture_dr_o = 1'b0;
- shift_dr_o = 1'b0;
- update_dr_o = 1'b0;
-
- capture_ir = 1'b0;
- shift_ir = 1'b0;
- // pause_ir = 1'b0; unused
- update_ir = 1'b0;
-
- unique case (tap_state_q)
- TestLogicReset: begin
- tap_state_d = (tms_i) ? TestLogicReset : RunTestIdle;
- test_logic_reset_o = 1'b1;
- end
- RunTestIdle: begin
- tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
- end
- // DR Path
- SelectDrScan: begin
- tap_state_d = (tms_i) ? SelectIrScan : CaptureDr;
- end
- CaptureDr: begin
- capture_dr_o = 1'b1;
- tap_state_d = (tms_i) ? Exit1Dr : ShiftDr;
- end
- ShiftDr: begin
- shift_dr_o = 1'b1;
- tap_state_d = (tms_i) ? Exit1Dr : ShiftDr;
- end
- Exit1Dr: begin
- tap_state_d = (tms_i) ? UpdateDr : PauseDr;
- end
- PauseDr: begin
- tap_state_d = (tms_i) ? Exit2Dr : PauseDr;
- end
- Exit2Dr: begin
- tap_state_d = (tms_i) ? UpdateDr : ShiftDr;
- end
- UpdateDr: begin
- update_dr_o = 1'b1;
- tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
- end
- // IR Path
- SelectIrScan: begin
- tap_state_d = (tms_i) ? TestLogicReset : CaptureIr;
- end
- // In this controller state, the shift register bank in the
- // Instruction Register parallel loads a pattern of fixed values on
- // the rising edge of TCK. The last two significant bits must always
- // be "01".
- CaptureIr: begin
- capture_ir = 1'b1;
- tap_state_d = (tms_i) ? Exit1Ir : ShiftIr;
- end
- // In this controller state, the instruction register gets connected
- // between TDI and TDO, and the captured pattern gets shifted on
- // each rising edge of TCK. The instruction available on the TDI
- // pin is also shifted in to the instruction register.
- ShiftIr: begin
- shift_ir = 1'b1;
- tap_state_d = (tms_i) ? Exit1Ir : ShiftIr;
- end
- Exit1Ir: begin
- tap_state_d = (tms_i) ? UpdateIr : PauseIr;
- end
- PauseIr: begin
- // pause_ir = 1'b1; // unused
- tap_state_d = (tms_i) ? Exit2Ir : PauseIr;
- end
- Exit2Ir: begin
- tap_state_d = (tms_i) ? UpdateIr : ShiftIr;
- end
- // In this controller state, the instruction in the instruction
- // shift register is latched to the latch bank of the Instruction
- // Register on every falling edge of TCK. This instruction becomes
- // the current instruction once it is latched.
- UpdateIr: begin
- update_ir = 1'b1;
- tap_state_d = (tms_i) ? SelectDrScan : RunTestIdle;
- end
- //default: ; // can't actually happen since case is full
- endcase
- end
-
- always_ff @(posedge tck_i or negedge trst_ni) begin : p_regs
- if (!trst_ni) begin
- tap_state_q <= RunTestIdle;
- idcode_q <= IdcodeValue;
- bypass_q <= 1'b0;
- dtmcs_q <= '0;
- end else begin
- tap_state_q <= tap_state_d;
- idcode_q <= idcode_d;
- bypass_q <= bypass_d;
- dtmcs_q <= dtmcs_d;
- end
- end
-
-endmodule : dmi_jtag_tap
diff --git a/verilog/rtl/down_clocking_even.v b/verilog/rtl/down_clocking_even.v
deleted file mode 100644
index 49a06ca..0000000
--- a/verilog/rtl/down_clocking_even.v
+++ /dev/null
@@ -1,37 +0,0 @@
-/*Down clocking module
-Output clock frequency is the original frequency divided by an even number
-*/
-module down_clocking_even(
-input clk_i,
-input rst_ni,
-input [15:0]i_divisor,
-output o_clk
-);
-
-wire [15:0]divisor;
-wire borrow;
-
-minus_one minus_one_0(
-.i_operand(i_divisor),
-.o_result(divisor),
-.o_borrow(borrow)
-);
-
-wire go;
-assign go=((i_divisor!=0)&&rst_ni);
-reg [15:0]ct;
-reg clk;
-always@(posedge clk_i )
- if(!rst_ni)begin
- ct<=0;
- clk<=0;
- end
- else if(go)begin
- if(ct>=divisor)begin
- ct<=0;
- clk<=~clk;
- end
- else ct<=ct+1;
- end
-assign o_clk=go?clk:clk_i;
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/down_clocking_odd.v b/verilog/rtl/down_clocking_odd.v
deleted file mode 100644
index 3395908..0000000
--- a/verilog/rtl/down_clocking_odd.v
+++ /dev/null
@@ -1,69 +0,0 @@
-/*Author: Zhuxu
- m99a1@yahoo.cn
-Down clocking module
-Output clock frequency is the original frequency divided by an odd number
-*/
-module down_clocking_odd(
-input clk_i,
-input rst_ni,
-input [15:0]i_divisor,
-output o_clk
-);
-
-reg a,b;
-wire c;
-
-assign c=(~a)&(~b);
-wire [15:0]divisor;
-wire borrow;
-minus_one minus_one_0(
-.i_operand(i_divisor),
-.o_result(divisor),
-.o_borrow(borrow)
-);
-
-wire go;
-assign go=((i_divisor!=0)&&rst_ni);
-reg [15:0]ct_0;
-always@(posedge clk_i )
- if(!rst_ni)begin
- a<=0;
- ct_0<=0;
- end
- else if(go)begin
- if(a)begin
- if(ct_0>=divisor)begin
- ct_0<=0;
- a<=0;
- end
- else ct_0<=ct_0+1;
- end
- else if(c)a<=c;
- end
-
-
-reg [15:0]ct_1;
-always@(negedge clk_i )
- if(!rst_ni)begin
- b<=0;
- ct_1<=0;
- end
- else if(go)begin
- if(b)begin
- if(ct_1>=divisor)begin
- ct_1<=0;
- b<=0;
- end
- else ct_1<=ct_1+1;
- end
- else if(c)b<=c;
- end
-
-reg clk;
-always@(posedge c)
- if(!rst_ni)clk<=0;
- else clk<=~clk;
-
-assign o_clk=go?clk:clk_i;
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/fifo_async.sv b/verilog/rtl/fifo_async.sv
deleted file mode 100644
index 0add43c..0000000
--- a/verilog/rtl/fifo_async.sv
+++ /dev/null
@@ -1,203 +0,0 @@
-
-// Generic asynchronous fifo for use in a variety of devices.
-
-
-module fifo_async #(
- parameter int unsigned Width = 16,
- parameter int unsigned Depth = 3,
- localparam int unsigned DepthW = $clog2(Depth+1) // derived parameter representing [0..Depth]
-) (
- // write port
- input clk_wr_i,
- input rst_wr_ni,
- input wvalid_i,
- output wready_o,
- input [Width-1:0] wdata_i,
- output [DepthW-1:0] wdepth_o,
-
- // read port
- input clk_rd_i,
- input rst_rd_ni,
- output rvalid_o,
- input rready_i,
- output [Width-1:0] rdata_o,
- output [DepthW-1:0] rdepth_o
-);
-
-
- localparam int unsigned PTRV_W = $clog2(Depth);
- localparam logic [PTRV_W-1:0] DepthMinus1 = PTRV_W'(Depth - 1);
- localparam int unsigned PTR_WIDTH = PTRV_W+1;
-
- logic [PTR_WIDTH-1:0] fifo_wptr, fifo_rptr;
- logic [PTR_WIDTH-1:0] fifo_wptr_sync_combi, fifo_rptr_sync;
- logic [PTR_WIDTH-1:0] fifo_wptr_gray_sync, fifo_rptr_gray_sync;
- logic [PTR_WIDTH-1:0] fifo_wptr_gray, fifo_rptr_gray;
- logic fifo_incr_wptr, fifo_incr_rptr, empty;
-
- logic full_wclk, full_rclk;
-
- assign wready_o = !full_wclk;
- assign rvalid_o = !empty;
-
- // create the write and read pointers
-
- assign fifo_incr_wptr = wvalid_i & wready_o;
- assign fifo_incr_rptr = rvalid_o & rready_i;
-
- ///////////////////
- // write pointer //
- ///////////////////
-
- always_ff @(posedge clk_wr_i or negedge rst_wr_ni)
- if (!rst_wr_ni) begin
- fifo_wptr <= {(PTR_WIDTH){1'b0}};
- end else if (fifo_incr_wptr) begin
- if (fifo_wptr[PTR_WIDTH-2:0] == DepthMinus1) begin
- fifo_wptr <= {~fifo_wptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}};
- end else begin
- fifo_wptr <= fifo_wptr + {{(PTR_WIDTH-1){1'b0}},1'b1};
- end
- end
-
- // gray-coded version
- always_ff @(posedge clk_wr_i or negedge rst_wr_ni)
- if (!rst_wr_ni) begin
- fifo_wptr_gray <= {(PTR_WIDTH){1'b0}};
- end else if (fifo_incr_wptr) begin
- if (fifo_wptr[PTR_WIDTH-2:0] == DepthMinus1) begin
- fifo_wptr_gray <= dec2gray({~fifo_wptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}});
- end else begin
- fifo_wptr_gray <= dec2gray(fifo_wptr + {{(PTR_WIDTH-1){1'b0}},1'b1});
- end
- end
-
- prim_generic_flop_2sync #(.Width(PTR_WIDTH)) sync_wptr (
- .clk_i (clk_rd_i),
- .rst_ni (rst_rd_ni),
- .d_i (fifo_wptr_gray),
- .q_o (fifo_wptr_gray_sync));
-
- assign fifo_wptr_sync_combi = gray2dec(fifo_wptr_gray_sync);
-
- //////////////////
- // read pointer //
- //////////////////
-
- always_ff @(posedge clk_rd_i or negedge rst_rd_ni)
- if (!rst_rd_ni) begin
- fifo_rptr <= {(PTR_WIDTH){1'b0}};
- end else if (fifo_incr_rptr) begin
- if (fifo_rptr[PTR_WIDTH-2:0] == DepthMinus1) begin
- fifo_rptr <= {~fifo_rptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}};
- end else begin
- fifo_rptr <= fifo_rptr + {{(PTR_WIDTH-1){1'b0}},1'b1};
- end
- end
-
- // gray-coded version
- always_ff @(posedge clk_rd_i or negedge rst_rd_ni)
- if (!rst_rd_ni) begin
- fifo_rptr_gray <= {(PTR_WIDTH){1'b0}};
- end else if (fifo_incr_rptr) begin
- if (fifo_rptr[PTR_WIDTH-2:0] == DepthMinus1) begin
- fifo_rptr_gray <= dec2gray({~fifo_rptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}});
- end else begin
- fifo_rptr_gray <= dec2gray(fifo_rptr + {{(PTR_WIDTH-1){1'b0}},1'b1});
- end
- end
-
- prim_generic_flop_2sync #(.Width(PTR_WIDTH)) sync_rptr (
- .clk_i (clk_wr_i),
- .rst_ni (rst_wr_ni),
- .d_i (fifo_rptr_gray),
- .q_o (fifo_rptr_gray_sync));
-
- always_ff @(posedge clk_wr_i or negedge rst_wr_ni)
- if (!rst_wr_ni) begin
- fifo_rptr_sync <= {PTR_WIDTH{1'b0}};
- end else begin
- fifo_rptr_sync <= gray2dec(fifo_rptr_gray_sync);
- end
-
- //////////////////
- // empty / full //
- //////////////////
-
- assign full_wclk = (fifo_wptr == (fifo_rptr_sync ^ {1'b1,{(PTR_WIDTH-1){1'b0}}}));
- assign full_rclk = (fifo_wptr_sync_combi == (fifo_rptr ^ {1'b1,{(PTR_WIDTH-1){1'b0}}}));
-
- // Current depth in the write clock side
- logic wptr_msb;
- logic rptr_sync_msb;
- logic [PTRV_W-1:0] wptr_value;
- logic [PTRV_W-1:0] rptr_sync_value;
- assign wptr_msb = fifo_wptr[PTR_WIDTH-1];
- assign rptr_sync_msb = fifo_rptr_sync[PTR_WIDTH-1];
- assign wptr_value = fifo_wptr[0+:PTRV_W];
- assign rptr_sync_value = fifo_rptr_sync[0+:PTRV_W];
- assign wdepth_o = (full_wclk) ? DepthW'(Depth) :
- (wptr_msb == rptr_sync_msb) ? DepthW'(wptr_value) - DepthW'(rptr_sync_value) :
- (DepthW'(Depth) - DepthW'(rptr_sync_value) + DepthW'(wptr_value)) ;
-
- // Same again in the read clock side
- assign empty = (fifo_wptr_sync_combi == fifo_rptr);
- logic rptr_msb;
- logic wptr_sync_msb;
- logic [PTRV_W-1:0] rptr_value;
- logic [PTRV_W-1:0] wptr_sync_value;
- assign wptr_sync_msb = fifo_wptr_sync_combi[PTR_WIDTH-1];
- assign rptr_msb = fifo_rptr[PTR_WIDTH-1];
- assign wptr_sync_value = fifo_wptr_sync_combi[0+:PTRV_W];
- assign rptr_value = fifo_rptr[0+:PTRV_W];
- assign rdepth_o = (full_rclk) ? DepthW'(Depth) :
- (wptr_sync_msb == rptr_msb) ? DepthW'(wptr_sync_value) - DepthW'(rptr_value) :
- (DepthW'(Depth) - DepthW'(rptr_value) + DepthW'(wptr_sync_value)) ;
-
- /////////////
- // storage //
- /////////////
-
- logic [Width-1:0] storage [Depth];
-
- always_ff @(posedge clk_wr_i)
- if (fifo_incr_wptr) begin
- storage[fifo_wptr[PTR_WIDTH-2:0]] <= wdata_i;
- end
-
- assign rdata_o = storage[fifo_rptr[PTR_WIDTH-2:0]];
-
- // gray code conversion functions. algorithm walks up from 0..N-1
- // then flips the upper bit and walks down from N-1 to 0.
-
- function automatic [PTR_WIDTH-1:0] dec2gray(input logic [PTR_WIDTH-1:0] decval);
- logic [PTR_WIDTH-1:0] decval_sub;
- logic [PTR_WIDTH-2:0] decval_in;
- logic unused_decval_msb;
-
- decval_sub = (PTR_WIDTH)'(Depth) - {1'b0, decval[PTR_WIDTH-2:0]} - 1'b1;
-
- {unused_decval_msb, decval_in} = decval[PTR_WIDTH-1] ? decval_sub : decval;
- // Was done in two assigns for low bits and top bit
- // but that generates a (bogus) verilator warning, so do in one assign
- dec2gray = {decval[PTR_WIDTH-1],
- {1'b0,decval_in[PTR_WIDTH-2:1]} ^ decval_in[PTR_WIDTH-2:0]};
- endfunction
-
- function automatic [PTR_WIDTH-1:0] gray2dec(input logic [PTR_WIDTH-1:0] grayval);
- logic [PTR_WIDTH-2:0] dec_tmp, dec_tmp_sub;
- logic unused_decsub_msb;
-
- dec_tmp[PTR_WIDTH-2] = grayval[PTR_WIDTH-2];
- for (int i = PTR_WIDTH-3; i >= 0; i--)
- dec_tmp[i] = dec_tmp[i+1]^grayval[i];
- {unused_decsub_msb, dec_tmp_sub} = (PTR_WIDTH-1)'(Depth) - {1'b0, dec_tmp} - 1'b1;
- if (grayval[PTR_WIDTH-1])
- gray2dec = {1'b1,dec_tmp_sub};
- else
- gray2dec = {1'b0,dec_tmp};
- endfunction
-
-
-
-endmodule
diff --git a/verilog/rtl/fifo_sync.sv b/verilog/rtl/fifo_sync.sv
deleted file mode 100644
index b0ab38a..0000000
--- a/verilog/rtl/fifo_sync.sv
+++ /dev/null
@@ -1,147 +0,0 @@
-
-// Generic synchronous fifo for use in a variety of devices.
-
-
-module fifo_sync #(
- parameter int unsigned Width = 16,
- parameter bit Pass = 1'b1, // if == 1 allow requests to pass through empty FIFO
- parameter int unsigned Depth = 4,
- parameter bit OutputZeroIfEmpty = 1'b1, // if == 1 always output 0 when FIFO is empty
- // derived parameter
- localparam int DepthW = tlul_pkg::vbits(Depth+1)
-) (
- input clk_i,
- input rst_ni,
- // synchronous clear / flush port
- input clr_i,
- // write port
- input wvalid_i,
- output wready_o,
- input [Width-1:0] wdata_i,
- // read port
- output rvalid_o,
- input rready_i,
- output [Width-1:0] rdata_o,
- // occupancy
- output [DepthW-1:0] depth_o
-);
-
- // FIFO is in complete passthrough mode
- if (Depth == 0) begin : gen_passthru_fifo
-
- assign depth_o = 1'b0; //output is meaningless
-
- // devie facing
- assign rvalid_o = wvalid_i;
- assign rdata_o = wdata_i;
-
- // host facing
- assign wready_o = rready_i;
-
- // this avoids lint warnings
- logic unused_clr;
- assign unused_clr = clr_i;
-
- // Normal FIFO construction
- end else begin : gen_normal_fifo
-
- localparam int unsigned PTRV_W = tlul_pkg::vbits(Depth);
- localparam int unsigned PTR_WIDTH = PTRV_W+1;
-
- logic [PTR_WIDTH-1:0] fifo_wptr, fifo_rptr;
- logic fifo_incr_wptr, fifo_incr_rptr, fifo_empty;
-
- // create the write and read pointers
- logic full, empty;
- logic wptr_msb;
- logic rptr_msb;
- logic [PTRV_W-1:0] wptr_value;
- logic [PTRV_W-1:0] rptr_value;
-
- assign wptr_msb = fifo_wptr[PTR_WIDTH-1];
- assign rptr_msb = fifo_rptr[PTR_WIDTH-1];
- assign wptr_value = fifo_wptr[0+:PTRV_W];
- assign rptr_value = fifo_rptr[0+:PTRV_W];
- assign depth_o = (full) ? DepthW'(Depth) :
- (wptr_msb == rptr_msb) ? DepthW'(wptr_value) - DepthW'(rptr_value) :
- (DepthW'(Depth) - DepthW'(rptr_value) + DepthW'(wptr_value)) ;
-
- assign fifo_incr_wptr = wvalid_i & wready_o;
- assign fifo_incr_rptr = rvalid_o & rready_i;
-
- assign wready_o = ~full;
- assign rvalid_o = ~empty;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- fifo_wptr <= {(PTR_WIDTH){1'b0}};
- end else if (clr_i) begin
- fifo_wptr <= {(PTR_WIDTH){1'b0}};
- end else if (fifo_incr_wptr) begin
- if (fifo_wptr[PTR_WIDTH-2:0] == (PTR_WIDTH-1)'(Depth-1)) begin
- fifo_wptr <= {~fifo_wptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}};
- end else begin
- fifo_wptr <= fifo_wptr + {{(PTR_WIDTH-1){1'b0}},1'b1};
- end
- end
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- fifo_rptr <= {(PTR_WIDTH){1'b0}};
- end else if (clr_i) begin
- fifo_rptr <= {(PTR_WIDTH){1'b0}};
- end else if (fifo_incr_rptr) begin
- if (fifo_rptr[PTR_WIDTH-2:0] == (PTR_WIDTH-1)'(Depth-1)) begin
- fifo_rptr <= {~fifo_rptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}};
- end else begin
- fifo_rptr <= fifo_rptr + {{(PTR_WIDTH-1){1'b0}},1'b1};
- end
- end
- end
-
- assign full = (fifo_wptr == (fifo_rptr ^ {1'b1,{(PTR_WIDTH-1){1'b0}}}));
- assign fifo_empty = (fifo_wptr == fifo_rptr);
-
-
- // the generate blocks below are needed to avoid lint errors due to array indexing
- // in the where the fifo only has one storage element
- logic [Depth-1:0][Width-1:0] storage;
- logic [Width-1:0] storage_rdata;
- if (Depth == 1) begin : gen_depth_eq1
- assign storage_rdata = storage[0];
-
- always_ff @(posedge clk_i)
- if (fifo_incr_wptr) begin
- storage[0] <= wdata_i;
- end
- // fifo with more than one storage element
- end else begin : gen_depth_gt1
- assign storage_rdata = storage[fifo_rptr[PTR_WIDTH-2:0]];
-
- always_ff @(posedge clk_i)
- if (fifo_incr_wptr) begin
- storage[fifo_wptr[PTR_WIDTH-2:0]] <= wdata_i;
- end
- end
-
- logic [Width-1:0] rdata_int;
- if (Pass == 1'b1) begin : gen_pass
- assign rdata_int = (fifo_empty && wvalid_i) ? wdata_i : storage_rdata;
- assign empty = fifo_empty & ~wvalid_i;
- end else begin : gen_nopass
- assign rdata_int = storage_rdata;
- assign empty = fifo_empty;
- end
-
- if (OutputZeroIfEmpty == 1'b1) begin : gen_output_zero
- assign rdata_o = empty ? 'b0 : rdata_int;
- end else begin : gen_no_output_zero
- assign rdata_o = rdata_int;
- end
-
- end // block: gen_normal_fifo
-
-
-
-endmodule
diff --git a/verilog/rtl/fpnew_cast_multi.sv b/verilog/rtl/fpnew_cast_multi.sv
deleted file mode 100644
index f275553..0000000
--- a/verilog/rtl/fpnew_cast_multi.sv
+++ /dev/null
@@ -1,759 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-`include "registers.svh"
-module fpnew_cast_multi #(
- parameter fpnew_pkg::fmt_logic_t FpFmtConfig = '1,
- parameter fpnew_pkg::ifmt_logic_t IntFmtConfig = '1,
- // FPU configuration
- parameter int unsigned NumPipeRegs = 0,
- parameter fpnew_pkg::pipe_config_t PipeConfig = fpnew_pkg::BEFORE,
- parameter type TagType = logic,
- parameter type AuxType = logic,
- // Do not change
- localparam int unsigned WIDTH = fpnew_pkg::maximum(fpnew_pkg::max_fp_width(FpFmtConfig),
- fpnew_pkg::max_int_width(IntFmtConfig)),
- localparam int unsigned NUM_FORMATS = fpnew_pkg::NUM_FP_FORMATS
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [WIDTH-1:0] operands_i, // 1 operand
- input logic [NUM_FORMATS-1:0] is_boxed_i, // 1 operand
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input logic op_mod_i,
- input fpnew_pkg::fp_format_e src_fmt_i,
- input fpnew_pkg::fp_format_e dst_fmt_i,
- input fpnew_pkg::int_format_e int_fmt_i,
- input TagType tag_i,
- input AuxType aux_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [WIDTH-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output logic extension_bit_o,
- output TagType tag_o,
- output AuxType aux_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- // ----------
- // Constants
- // ----------
- localparam int unsigned NUM_INT_FORMATS = fpnew_pkg::NUM_INT_FORMATS;
- localparam int unsigned MAX_INT_WIDTH = fpnew_pkg::max_int_width(IntFmtConfig);
-
- localparam fpnew_pkg::fp_encoding_t SUPER_FORMAT = fpnew_pkg::super_format(FpFmtConfig);
-
- localparam int unsigned SUPER_EXP_BITS = SUPER_FORMAT.exp_bits;
- localparam int unsigned SUPER_MAN_BITS = SUPER_FORMAT.man_bits;
- localparam int unsigned SUPER_BIAS = 2**(SUPER_EXP_BITS - 1) - 1;
-
- // The internal mantissa includes normal bit or an entire integer
- localparam int unsigned INT_MAN_WIDTH = fpnew_pkg::maximum(SUPER_MAN_BITS + 1, MAX_INT_WIDTH);
- // If needed, there will be a LZC for renormalization
- localparam int unsigned LZC_RESULT_WIDTH = $clog2(INT_MAN_WIDTH);
- // The internal exponent must be able to represent the smallest denormal input value as signed
- // or the number of bits in an integer
- localparam int unsigned INT_EXP_WIDTH = fpnew_pkg::maximum($clog2(MAX_INT_WIDTH),
- fpnew_pkg::maximum(SUPER_EXP_BITS, $clog2(SUPER_BIAS + SUPER_MAN_BITS))) + 1;
- // Pipelines
- localparam NUM_INP_REGS = PipeConfig == fpnew_pkg::BEFORE
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? ((NumPipeRegs + 1) / 3) // Second to get distributed regs
- : 0); // no regs here otherwise
- localparam NUM_MID_REGS = PipeConfig == fpnew_pkg::INSIDE
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? ((NumPipeRegs + 2) / 3) // First to get distributed regs
- : 0); // no regs here otherwise
- localparam NUM_OUT_REGS = PipeConfig == fpnew_pkg::AFTER
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? (NumPipeRegs / 3) // Last to get distributed regs
- : 0); // no regs here otherwise
-
- // ---------------
- // Input pipeline
- // ---------------
- // Selected pipeline output signals as non-arrays
- logic [WIDTH-1:0] operands_q;
- logic [NUM_FORMATS-1:0] is_boxed_q;
- logic op_mod_q;
- fpnew_pkg::fp_format_e src_fmt_q;
- fpnew_pkg::fp_format_e dst_fmt_q;
- fpnew_pkg::int_format_e int_fmt_q;
-
- // Input pipeline signals, index i holds signal after i register stages
- logic [0:NUM_INP_REGS][WIDTH-1:0] inp_pipe_operands_q;
- logic [0:NUM_INP_REGS][NUM_FORMATS-1:0] inp_pipe_is_boxed_q;
- fpnew_pkg::roundmode_e [0:NUM_INP_REGS] inp_pipe_rnd_mode_q;
- fpnew_pkg::operation_e [0:NUM_INP_REGS] inp_pipe_op_q;
- logic [0:NUM_INP_REGS] inp_pipe_op_mod_q;
- fpnew_pkg::fp_format_e [0:NUM_INP_REGS] inp_pipe_src_fmt_q;
- fpnew_pkg::fp_format_e [0:NUM_INP_REGS] inp_pipe_dst_fmt_q;
- fpnew_pkg::int_format_e [0:NUM_INP_REGS] inp_pipe_int_fmt_q;
- TagType [0:NUM_INP_REGS] inp_pipe_tag_q;
- AuxType [0:NUM_INP_REGS] inp_pipe_aux_q;
- logic [0:NUM_INP_REGS] inp_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_INP_REGS] inp_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign inp_pipe_operands_q[0] = operands_i;
- assign inp_pipe_is_boxed_q[0] = is_boxed_i;
- assign inp_pipe_rnd_mode_q[0] = rnd_mode_i;
- assign inp_pipe_op_q[0] = op_i;
- assign inp_pipe_op_mod_q[0] = op_mod_i;
- assign inp_pipe_src_fmt_q[0] = src_fmt_i;
- assign inp_pipe_dst_fmt_q[0] = dst_fmt_i;
- assign inp_pipe_int_fmt_q[0] = int_fmt_i;
- assign inp_pipe_tag_q[0] = tag_i;
- assign inp_pipe_aux_q[0] = aux_i;
- assign inp_pipe_valid_q[0] = in_valid_i;
- // Input stage: Propagate pipeline ready signal to updtream circuitry
- assign in_ready_o = inp_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_INP_REGS; i++) begin : gen_input_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign inp_pipe_ready[i] = inp_pipe_ready[i+1] | ~inp_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(inp_pipe_valid_q[i+1], inp_pipe_valid_q[i], inp_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(inp_pipe_operands_q[i+1], inp_pipe_operands_q[i], reg_ena, '0)
- `FFL(inp_pipe_is_boxed_q[i+1], inp_pipe_is_boxed_q[i], reg_ena, '0)
- `FFL(inp_pipe_rnd_mode_q[i+1], inp_pipe_rnd_mode_q[i], reg_ena, fpnew_pkg::RNE)
- `FFL(inp_pipe_op_q[i+1], inp_pipe_op_q[i], reg_ena, fpnew_pkg::FMADD)
- `FFL(inp_pipe_op_mod_q[i+1], inp_pipe_op_mod_q[i], reg_ena, '0)
- `FFL(inp_pipe_src_fmt_q[i+1], inp_pipe_src_fmt_q[i], reg_ena, fpnew_pkg::fp_format_e'(0))
- `FFL(inp_pipe_dst_fmt_q[i+1], inp_pipe_dst_fmt_q[i], reg_ena, fpnew_pkg::fp_format_e'(0))
- `FFL(inp_pipe_int_fmt_q[i+1], inp_pipe_int_fmt_q[i], reg_ena, fpnew_pkg::int_format_e'(0))
- `FFL(inp_pipe_tag_q[i+1], inp_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(inp_pipe_aux_q[i+1], inp_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: assign selected pipe outputs to signals for later use
- assign operands_q = inp_pipe_operands_q[NUM_INP_REGS];
- assign is_boxed_q = inp_pipe_is_boxed_q[NUM_INP_REGS];
- assign op_mod_q = inp_pipe_op_mod_q[NUM_INP_REGS];
- assign src_fmt_q = inp_pipe_src_fmt_q[NUM_INP_REGS];
- assign dst_fmt_q = inp_pipe_dst_fmt_q[NUM_INP_REGS];
- assign int_fmt_q = inp_pipe_int_fmt_q[NUM_INP_REGS];
-
- // -----------------
- // Input processing
- // -----------------
- logic src_is_int, dst_is_int; // if 0, it's a float
-
- assign src_is_int = (inp_pipe_op_q[NUM_INP_REGS] == fpnew_pkg::I2F);
- assign dst_is_int = (inp_pipe_op_q[NUM_INP_REGS] == fpnew_pkg::F2I);
-
- logic [INT_MAN_WIDTH-1:0] encoded_mant; // input mantissa with implicit bit
-
- logic [NUM_FORMATS-1:0] fmt_sign;
- logic signed [NUM_FORMATS-1:0][INT_EXP_WIDTH-1:0] fmt_exponent;
- logic [NUM_FORMATS-1:0][INT_MAN_WIDTH-1:0] fmt_mantissa;
- logic signed [NUM_FORMATS-1:0][INT_EXP_WIDTH-1:0] fmt_shift_compensation; // for LZC
-
- fpnew_pkg::fp_info_t [NUM_FORMATS-1:0] info;
-
- logic [NUM_INT_FORMATS-1:0][INT_MAN_WIDTH-1:0] ifmt_input_val;
- logic int_sign;
- logic [INT_MAN_WIDTH-1:0] int_value, int_mantissa;
-
- // FP Input initialization
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : fmt_init_inputs
- // Set up some constants
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(fpnew_pkg::fp_format_e'(fmt));
-
- if (FpFmtConfig[fmt]) begin : active_format
- // Classify input
- fpnew_classifier #(
- .FpFormat ( fpnew_pkg::fp_format_e'(fmt) ),
- .NumOperands ( 1 )
- ) i_fpnew_classifier (
- .operands_i ( operands_q[FP_WIDTH-1:0] ),
- .is_boxed_i ( is_boxed_q[fmt] ),
- .info_o ( info[fmt] )
- );
-
- assign fmt_sign[fmt] = operands_q[FP_WIDTH-1];
- assign fmt_exponent[fmt] = signed'({1'b0, operands_q[MAN_BITS+:EXP_BITS]});
- assign fmt_mantissa[fmt] = {info[fmt].is_normal, operands_q[MAN_BITS-1:0]}; // zero pad
- // Compensation for the difference in mantissa widths used for leading-zero count
- assign fmt_shift_compensation[fmt] = signed'(INT_MAN_WIDTH - 1 - MAN_BITS);
- end else begin : inactive_format
- assign info[fmt] = '{default: fpnew_pkg::DONT_CARE}; // format disabled
- assign fmt_sign[fmt] = fpnew_pkg::DONT_CARE; // format disabled
- assign fmt_exponent[fmt] = '{default: fpnew_pkg::DONT_CARE}; // format disabled
- assign fmt_mantissa[fmt] = '{default: fpnew_pkg::DONT_CARE}; // format disabled
- assign fmt_shift_compensation[fmt] = '{default: fpnew_pkg::DONT_CARE}; // format disabled
- end
- end
-
- // Sign-extend INT input
- for (genvar ifmt = 0; ifmt < int'(NUM_INT_FORMATS); ifmt++) begin : gen_sign_extend_int
- // Set up some constants
- localparam int unsigned INT_WIDTH = fpnew_pkg::int_width(fpnew_pkg::int_format_e'(ifmt));
-
- if (IntFmtConfig[ifmt]) begin : active_format // only active formats
- always_comb begin : sign_ext_input
- // sign-extend value only if it's signed
- ifmt_input_val[ifmt] = '{default: operands_q[INT_WIDTH-1] & ~op_mod_q};
- ifmt_input_val[ifmt][INT_WIDTH-1:0] = operands_q[INT_WIDTH-1:0];
- end
- end else begin : inactive_format
- assign ifmt_input_val[ifmt] = '{default: fpnew_pkg::DONT_CARE}; // format disabled
- end
- end
-
- // Construct input mantissa from integer
- assign int_value = ifmt_input_val[int_fmt_q];
- assign int_sign = int_value[INT_MAN_WIDTH-1] & ~op_mod_q; // only signed ints are negative
- assign int_mantissa = int_sign ? unsigned'(-int_value) : int_value; // get magnitude of negative
-
- // select mantissa with source format
- assign encoded_mant = src_is_int ? int_mantissa : fmt_mantissa[src_fmt_q];
-
- // --------------
- // Normalization
- // --------------
- logic signed [INT_EXP_WIDTH-1:0] src_bias; // src format bias
- logic signed [INT_EXP_WIDTH-1:0] src_exp; // src format exponent (biased)
- logic signed [INT_EXP_WIDTH-1:0] src_subnormal; // src is subnormal
- logic signed [INT_EXP_WIDTH-1:0] src_offset; // src offset within mantissa
-
- assign src_bias = signed'(fpnew_pkg::bias(src_fmt_q));
- assign src_exp = fmt_exponent[src_fmt_q];
- assign src_subnormal = signed'({1'b0, info[src_fmt_q].is_subnormal});
- assign src_offset = fmt_shift_compensation[src_fmt_q];
-
- logic input_sign; // input sign
- logic signed [INT_EXP_WIDTH-1:0] input_exp; // unbiased true exponent
- logic [INT_MAN_WIDTH-1:0] input_mant; // normalized input mantissa
- logic mant_is_zero; // for integer zeroes
-
- logic signed [INT_EXP_WIDTH-1:0] fp_input_exp;
- logic signed [INT_EXP_WIDTH-1:0] int_input_exp;
-
- // Input mantissa needs to be normalized
- logic [LZC_RESULT_WIDTH-1:0] renorm_shamt; // renormalization shift amount
- logic [LZC_RESULT_WIDTH:0] renorm_shamt_sgn; // signed form for calculations
-
- // Leading-zero counter is needed for renormalization
- lzc #(
- .WIDTH ( INT_MAN_WIDTH ),
- .MODE ( 1 ) // MODE = 1 counts leading zeroes
- ) i_lzc (
- .in_i ( encoded_mant ),
- .cnt_o ( renorm_shamt ),
- .empty_o ( mant_is_zero )
- );
- assign renorm_shamt_sgn = signed'({1'b0, renorm_shamt});
-
- // Get the sign from the proper source
- assign input_sign = src_is_int ? int_sign : fmt_sign[src_fmt_q];
- // Realign input mantissa, append zeroes if destination is wider
- assign input_mant = encoded_mant << renorm_shamt;
- // Unbias exponent and compensate for shift
- assign fp_input_exp = signed'(src_exp + src_subnormal - src_bias -
- renorm_shamt_sgn + src_offset); // compensate for shift
- assign int_input_exp = signed'(INT_MAN_WIDTH - 1 - renorm_shamt_sgn);
-
- assign input_exp = src_is_int ? int_input_exp : fp_input_exp;
-
- logic signed [INT_EXP_WIDTH-1:0] destination_exp; // re-biased exponent for destination
-
- // Rebias the exponent
- assign destination_exp = input_exp + signed'(fpnew_pkg::bias(dst_fmt_q));
-
- // ---------------
- // Internal pipeline
- // ---------------
- // Pipeline output signals as non-arrays
- logic input_sign_q;
- logic signed [INT_EXP_WIDTH-1:0] input_exp_q;
- logic [INT_MAN_WIDTH-1:0] input_mant_q;
- logic signed [INT_EXP_WIDTH-1:0] destination_exp_q;
- logic src_is_int_q;
- logic dst_is_int_q;
- fpnew_pkg::fp_info_t info_q;
- logic mant_is_zero_q;
- logic op_mod_q2;
- fpnew_pkg::roundmode_e rnd_mode_q;
- fpnew_pkg::fp_format_e src_fmt_q2;
- fpnew_pkg::fp_format_e dst_fmt_q2;
- fpnew_pkg::int_format_e int_fmt_q2;
- // Internal pipeline signals, index i holds signal after i register stages
-
-
- logic [0:NUM_MID_REGS] mid_pipe_input_sign_q;
- logic signed [0:NUM_MID_REGS][INT_EXP_WIDTH-1:0] mid_pipe_input_exp_q;
- logic [0:NUM_MID_REGS][INT_MAN_WIDTH-1:0] mid_pipe_input_mant_q;
- logic signed [0:NUM_MID_REGS][INT_EXP_WIDTH-1:0] mid_pipe_dest_exp_q;
- logic [0:NUM_MID_REGS] mid_pipe_src_is_int_q;
- logic [0:NUM_MID_REGS] mid_pipe_dst_is_int_q;
- fpnew_pkg::fp_info_t [0:NUM_MID_REGS] mid_pipe_info_q;
- logic [0:NUM_MID_REGS] mid_pipe_mant_zero_q;
- logic [0:NUM_MID_REGS] mid_pipe_op_mod_q;
- fpnew_pkg::roundmode_e [0:NUM_MID_REGS] mid_pipe_rnd_mode_q;
- fpnew_pkg::fp_format_e [0:NUM_MID_REGS] mid_pipe_src_fmt_q;
- fpnew_pkg::fp_format_e [0:NUM_MID_REGS] mid_pipe_dst_fmt_q;
- fpnew_pkg::int_format_e [0:NUM_MID_REGS] mid_pipe_int_fmt_q;
- TagType [0:NUM_MID_REGS] mid_pipe_tag_q;
- AuxType [0:NUM_MID_REGS] mid_pipe_aux_q;
- logic [0:NUM_MID_REGS] mid_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_MID_REGS] mid_pipe_ready;
-
- // Input stage: First element of pipeline is taken from upstream logic
- assign mid_pipe_input_sign_q[0] = input_sign;
- assign mid_pipe_input_exp_q[0] = input_exp;
- assign mid_pipe_input_mant_q[0] = input_mant;
- assign mid_pipe_dest_exp_q[0] = destination_exp;
- assign mid_pipe_src_is_int_q[0] = src_is_int;
- assign mid_pipe_dst_is_int_q[0] = dst_is_int;
- assign mid_pipe_info_q[0] = info[src_fmt_q];
- assign mid_pipe_mant_zero_q[0] = mant_is_zero;
- assign mid_pipe_op_mod_q[0] = op_mod_q;
- assign mid_pipe_rnd_mode_q[0] = inp_pipe_rnd_mode_q[NUM_INP_REGS];
- assign mid_pipe_src_fmt_q[0] = src_fmt_q;
- assign mid_pipe_dst_fmt_q[0] = dst_fmt_q;
- assign mid_pipe_int_fmt_q[0] = int_fmt_q;
- assign mid_pipe_tag_q[0] = inp_pipe_tag_q[NUM_INP_REGS];
- assign mid_pipe_aux_q[0] = inp_pipe_aux_q[NUM_INP_REGS];
- assign mid_pipe_valid_q[0] = inp_pipe_valid_q[NUM_INP_REGS];
- // Input stage: Propagate pipeline ready signal to input pipe
- assign inp_pipe_ready[NUM_INP_REGS] = mid_pipe_ready[0];
-
- // Generate the register stages
- for (genvar i = 0; i < NUM_MID_REGS; i++) begin : gen_inside_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign mid_pipe_ready[i] = mid_pipe_ready[i+1] | ~mid_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(mid_pipe_valid_q[i+1], mid_pipe_valid_q[i], mid_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = mid_pipe_ready[i] & mid_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(mid_pipe_input_sign_q[i+1], mid_pipe_input_sign_q[i], reg_ena, '0)
- `FFL(mid_pipe_input_exp_q[i+1], mid_pipe_input_exp_q[i], reg_ena, '0)
- `FFL(mid_pipe_input_mant_q[i+1], mid_pipe_input_mant_q[i], reg_ena, '0)
- `FFL(mid_pipe_dest_exp_q[i+1], mid_pipe_dest_exp_q[i], reg_ena, '0)
- `FFL(mid_pipe_src_is_int_q[i+1], mid_pipe_src_is_int_q[i], reg_ena, '0)
- `FFL(mid_pipe_dst_is_int_q[i+1], mid_pipe_dst_is_int_q[i], reg_ena, '0)
- `FFL(mid_pipe_info_q[i+1], mid_pipe_info_q[i], reg_ena, '0)
- `FFL(mid_pipe_mant_zero_q[i+1], mid_pipe_mant_zero_q[i], reg_ena, '0)
- `FFL(mid_pipe_op_mod_q[i+1], mid_pipe_op_mod_q[i], reg_ena, '0)
- `FFL(mid_pipe_rnd_mode_q[i+1], mid_pipe_rnd_mode_q[i], reg_ena, fpnew_pkg::RNE)
- `FFL(mid_pipe_src_fmt_q[i+1], mid_pipe_src_fmt_q[i], reg_ena, fpnew_pkg::fp_format_e'(0))
- `FFL(mid_pipe_dst_fmt_q[i+1], mid_pipe_dst_fmt_q[i], reg_ena, fpnew_pkg::fp_format_e'(0))
- `FFL(mid_pipe_int_fmt_q[i+1], mid_pipe_int_fmt_q[i], reg_ena, fpnew_pkg::int_format_e'(0))
- `FFL(mid_pipe_tag_q[i+1], mid_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(mid_pipe_aux_q[i+1], mid_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: assign selected pipe outputs to signals for later use
- assign input_sign_q = mid_pipe_input_sign_q[NUM_MID_REGS];
- assign input_exp_q = mid_pipe_input_exp_q[NUM_MID_REGS];
- assign input_mant_q = mid_pipe_input_mant_q[NUM_MID_REGS];
- assign destination_exp_q = mid_pipe_dest_exp_q[NUM_MID_REGS];
- assign src_is_int_q = mid_pipe_src_is_int_q[NUM_MID_REGS];
- assign dst_is_int_q = mid_pipe_dst_is_int_q[NUM_MID_REGS];
- assign info_q = mid_pipe_info_q[NUM_MID_REGS];
- assign mant_is_zero_q = mid_pipe_mant_zero_q[NUM_MID_REGS];
- assign op_mod_q2 = mid_pipe_op_mod_q[NUM_MID_REGS];
- assign rnd_mode_q = mid_pipe_rnd_mode_q[NUM_MID_REGS];
- assign src_fmt_q2 = mid_pipe_src_fmt_q[NUM_MID_REGS];
- assign dst_fmt_q2 = mid_pipe_dst_fmt_q[NUM_MID_REGS];
- assign int_fmt_q2 = mid_pipe_int_fmt_q[NUM_MID_REGS];
-
- // --------
- // Casting
- // --------
- logic [INT_EXP_WIDTH-1:0] final_exp; // after eventual adjustments
-
- logic [2*INT_MAN_WIDTH:0] preshift_mant; // mantissa before final shift
- logic [2*INT_MAN_WIDTH:0] destination_mant; // mantissa from shifter, with rnd bit
- logic [SUPER_MAN_BITS-1:0] final_mant; // mantissa after adjustments
- logic [MAX_INT_WIDTH-1:0] final_int; // integer shifted in position
-
- logic [$clog2(INT_MAN_WIDTH+1)-1:0] denorm_shamt; // shift amount for denormalization
-
- logic [1:0] fp_round_sticky_bits, int_round_sticky_bits, round_sticky_bits;
- logic of_before_round, uf_before_round;
-
-
- // Perform adjustments to mantissa and exponent
- always_comb begin : cast_value
- // Default assignment
- final_exp = unsigned'(destination_exp_q); // take exponent as is, only look at lower bits
- preshift_mant = '0; // initialize mantissa container with zeroes
- denorm_shamt = SUPER_MAN_BITS - fpnew_pkg::man_bits(dst_fmt_q2); // right of mantissa
- of_before_round = 1'b0;
- uf_before_round = 1'b0;
-
- // Place mantissa to the left of the shifter
- preshift_mant = input_mant_q << (INT_MAN_WIDTH + 1);
-
- // Handle INT casts
- if (dst_is_int_q) begin
- // By default right shift mantissa to be an integer
- denorm_shamt = unsigned'(MAX_INT_WIDTH - 1 - input_exp_q);
- // overflow: when converting to unsigned the range is larger by one
- if (input_exp_q >= signed'(fpnew_pkg::int_width(int_fmt_q2) - 1 + op_mod_q2)) begin
- denorm_shamt = '0; // prevent shifting
- of_before_round = 1'b1;
- // underflow
- end else if (input_exp_q < -1) begin
- denorm_shamt = MAX_INT_WIDTH + 1; // all bits go to the sticky
- uf_before_round = 1'b1;
- end
- // Handle FP over-/underflows
- end else begin
- // Overflow or infinities (for proper rounding)
- if ((destination_exp_q >= signed'(2**fpnew_pkg::exp_bits(dst_fmt_q2))-1) ||
- (~src_is_int_q && info_q.is_inf)) begin
- final_exp = unsigned'(2**fpnew_pkg::exp_bits(dst_fmt_q2)-2); // largest normal value
- preshift_mant = '1; // largest normal value and RS bits set
- of_before_round = 1'b1;
- // Denormalize underflowing values
- end else if (destination_exp_q < 1 &&
- destination_exp_q >= -signed'(fpnew_pkg::man_bits(dst_fmt_q2))) begin
- final_exp = '0; // denormal result
- denorm_shamt = unsigned'(denorm_shamt + 1 - destination_exp_q); // adjust right shifting
- uf_before_round = 1'b1;
- // Limit the shift to retain sticky bits
- end else if (destination_exp_q < -signed'(fpnew_pkg::man_bits(dst_fmt_q2))) begin
- final_exp = '0; // denormal result
- denorm_shamt = unsigned'(denorm_shamt + 2 + fpnew_pkg::man_bits(dst_fmt_q2)); // to sticky
- uf_before_round = 1'b1;
- end
- end
- end
-
- localparam NUM_FP_STICKY = 2 * INT_MAN_WIDTH - SUPER_MAN_BITS - 1; // removed mantissa, 1. and R
- localparam NUM_INT_STICKY = 2 * INT_MAN_WIDTH - MAX_INT_WIDTH; // removed int and R
-
- // Mantissa adjustment shift
- assign destination_mant = preshift_mant >> denorm_shamt;
- // Extract final mantissa and round bit, discard the normal bit (for FP)
- assign {final_mant, fp_round_sticky_bits[1]} =
- destination_mant[2*INT_MAN_WIDTH-1-:SUPER_MAN_BITS+1];
- assign {final_int, int_round_sticky_bits[1]} = destination_mant[2*INT_MAN_WIDTH-:MAX_INT_WIDTH+1];
- // Collapse sticky bits
- assign fp_round_sticky_bits[0] = (| {destination_mant[NUM_FP_STICKY-1:0]});
- assign int_round_sticky_bits[0] = (| {destination_mant[NUM_INT_STICKY-1:0]});
-
- // select RS bits for destination operation
- assign round_sticky_bits = dst_is_int_q ? int_round_sticky_bits : fp_round_sticky_bits;
-
- // ----------------------------
- // Rounding and classification
- // ----------------------------
- logic [WIDTH-1:0] pre_round_abs; // absolute value of result before rnd
- logic of_after_round; // overflow
- logic uf_after_round; // underflow
-
- logic [NUM_FORMATS-1:0][WIDTH-1:0] fmt_pre_round_abs; // per format
- logic [NUM_FORMATS-1:0] fmt_of_after_round;
- logic [NUM_FORMATS-1:0] fmt_uf_after_round;
-
- logic [NUM_INT_FORMATS-1:0][WIDTH-1:0] ifmt_pre_round_abs; // per format
-
- logic rounded_sign;
- logic [WIDTH-1:0] rounded_abs; // absolute value of result after rounding
- logic result_true_zero;
-
- logic [WIDTH-1:0] rounded_int_res; // after possible inversion
- logic rounded_int_res_zero; // after rounding
-
-
- // Pack exponent and mantissa into proper rounding form
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : gen_res_assemble
- // Set up some constants
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(fpnew_pkg::fp_format_e'(fmt));
-
- if (FpFmtConfig[fmt]) begin : active_format
- always_comb begin : assemble_result
- fmt_pre_round_abs[fmt] = {final_exp[EXP_BITS-1:0], final_mant[MAN_BITS-1:0]}; // 0-extend
- end
- end else begin : inactive_format
- assign fmt_pre_round_abs[fmt] = '{default: fpnew_pkg::DONT_CARE};
- end
- end
-
- // Sign-extend integer result
- for (genvar ifmt = 0; ifmt < int'(NUM_INT_FORMATS); ifmt++) begin : gen_int_res_sign_ext
- // Set up some constants
- localparam int unsigned INT_WIDTH = fpnew_pkg::int_width(fpnew_pkg::int_format_e'(ifmt));
-
- if (IntFmtConfig[ifmt]) begin : active_format
- always_comb begin : assemble_result
- // sign-extend reusult
- ifmt_pre_round_abs[ifmt] = '{default: final_int[INT_WIDTH-1]};
- ifmt_pre_round_abs[ifmt][INT_WIDTH-1:0] = final_int[INT_WIDTH-1:0];
- end
- end else begin : inactive_format
- assign ifmt_pre_round_abs[ifmt] = '{default: fpnew_pkg::DONT_CARE};
- end
- end
-
- // Select output with destination format and operation
- assign pre_round_abs = dst_is_int_q ? ifmt_pre_round_abs[int_fmt_q2] : fmt_pre_round_abs[dst_fmt_q2];
-
- fpnew_rounding #(
- .AbsWidth ( WIDTH )
- ) i_fpnew_rounding (
- .abs_value_i ( pre_round_abs ),
- .sign_i ( input_sign_q ), // source format
- .round_sticky_bits_i ( round_sticky_bits ),
- .rnd_mode_i ( rnd_mode_q ),
- .effective_subtraction_i ( 1'b0 ), // no operation happened
- .abs_rounded_o ( rounded_abs ),
- .sign_o ( rounded_sign ),
- .exact_zero_o ( result_true_zero )
- );
-
- logic [NUM_FORMATS-1:0][WIDTH-1:0] fmt_result;
-
- // Detect overflows and inject sign
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : gen_sign_inject
- // Set up some constants
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(fpnew_pkg::fp_format_e'(fmt));
-
- if (FpFmtConfig[fmt]) begin : active_format
- always_comb begin : post_process
- // detect of / uf
- fmt_uf_after_round[fmt] = rounded_abs[EXP_BITS+MAN_BITS-1:MAN_BITS] == '0; // denormal
- fmt_of_after_round[fmt] = rounded_abs[EXP_BITS+MAN_BITS-1:MAN_BITS] == '1; // inf exp.
-
- // Assemble regular result, nan box short ones. Int zeroes need to be detected`
- fmt_result[fmt] = '1;
- fmt_result[fmt][FP_WIDTH-1:0] = src_is_int_q & mant_is_zero_q
- ? '0
- : {rounded_sign, rounded_abs[EXP_BITS+MAN_BITS-1:0]};
- end
- end else begin : inactive_format
- assign fmt_uf_after_round[fmt] = fpnew_pkg::DONT_CARE;
- assign fmt_of_after_round[fmt] = fpnew_pkg::DONT_CARE;
- assign fmt_result[fmt] = '{default: fpnew_pkg::DONT_CARE};
- end
- end
-
- // Classification after rounding select by destination format
- assign uf_after_round = fmt_uf_after_round[dst_fmt_q2];
- assign of_after_round = fmt_of_after_round[dst_fmt_q2];
-
- // Negative integer result needs to be brought into two's complement
- assign rounded_int_res = rounded_sign ? unsigned'(-rounded_abs) : rounded_abs;
- assign rounded_int_res_zero = (rounded_int_res == '0);
-
- // -------------------------
- // FP Special case handling
- // -------------------------
- logic [WIDTH-1:0] fp_special_result;
- fpnew_pkg::status_t fp_special_status;
- logic fp_result_is_special;
-
- logic [NUM_FORMATS-1:0][WIDTH-1:0] fmt_special_result;
-
- // Special result construction
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : gen_special_results
- // Set up some constants
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(fpnew_pkg::fp_format_e'(fmt));
-
- localparam logic [EXP_BITS-1:0] QNAN_EXPONENT = '1;
- localparam logic [MAN_BITS-1:0] QNAN_MANTISSA = 2**(MAN_BITS-1);
-
- if (FpFmtConfig[fmt]) begin : active_format
- always_comb begin : special_results
- logic [FP_WIDTH-1:0] special_res;
- special_res = info_q.is_zero
- ? input_sign_q << FP_WIDTH-1 // signed zero
- : {1'b0, QNAN_EXPONENT, QNAN_MANTISSA}; // qNaN
-
- // Initialize special result with ones (NaN-box)
- fmt_special_result[fmt] = '1;
- fmt_special_result[fmt][FP_WIDTH-1:0] = special_res;
- end
- end else begin : inactive_format
- assign fmt_special_result[fmt] = '{default: fpnew_pkg::DONT_CARE};
- end
- end
-
- // Detect special case from source format, I2F casts don't produce a special result
- assign fp_result_is_special = ~src_is_int_q & (info_q.is_zero |
- info_q.is_nan |
- ~info_q.is_boxed);
-
- // Signalling input NaNs raise invalid flag, otherwise no flags set
- assign fp_special_status = '{NV: info_q.is_signalling, default: 1'b0};
-
- // Assemble result according to destination format
- assign fp_special_result = fmt_special_result[dst_fmt_q2]; // destination format
-
- // --------------------------
- // INT Special case handling
- // --------------------------
- logic [WIDTH-1:0] int_special_result;
- fpnew_pkg::status_t int_special_status;
- logic int_result_is_special;
-
- logic [NUM_INT_FORMATS-1:0][WIDTH-1:0] ifmt_special_result;
-
- // Special result construction
- for (genvar ifmt = 0; ifmt < int'(NUM_INT_FORMATS); ifmt++) begin : gen_special_results_int
- // Set up some constants
- localparam int unsigned INT_WIDTH = fpnew_pkg::int_width(fpnew_pkg::int_format_e'(ifmt));
-
- if (IntFmtConfig[ifmt]) begin : active_format
- always_comb begin : special_results
- automatic logic [INT_WIDTH-1:0] special_res;
-
- // Default is overflow to positive max, which is 2**INT_WIDTH-1 or 2**(INT_WIDTH-1)-1
- special_res[INT_WIDTH-2:0] = '1; // alone yields 2**(INT_WIDTH-1)-1
- special_res[INT_WIDTH-1] = op_mod_q2; // for unsigned casts yields 2**INT_WIDTH-1
-
- // Negative special case (except for nans) tie to -max or 0
- if (input_sign_q && !info_q.is_nan)
- special_res = ~special_res;
-
- // Initialize special result with sign-extension
- ifmt_special_result[ifmt] = '{default: special_res[INT_WIDTH-1]};
- ifmt_special_result[ifmt][INT_WIDTH-1:0] = special_res;
- end
- end else begin : inactive_format
- assign ifmt_special_result[ifmt] = '{default: fpnew_pkg::DONT_CARE};
- end
- end
-
- // Detect special case from source format (inf, nan, overflow, nan-boxing or negative unsigned)
- assign int_result_is_special = info_q.is_nan | info_q.is_inf |
- of_before_round | ~info_q.is_boxed |
- (input_sign_q & op_mod_q2 & ~rounded_int_res_zero);
-
- // All integer special cases are invalid
- assign int_special_status = '{NV: 1'b1, default: 1'b0};
-
- // Assemble result according to destination format
- assign int_special_result = ifmt_special_result[int_fmt_q2]; // destination format
-
- // -----------------
- // Result selection
- // -----------------
- fpnew_pkg::status_t int_regular_status, fp_regular_status;
-
- logic [WIDTH-1:0] fp_result, int_result;
- fpnew_pkg::status_t fp_status, int_status;
-
- assign fp_regular_status.NV = src_is_int_q & (of_before_round | of_after_round); // overflow is invalid for I2F casts
- assign fp_regular_status.DZ = 1'b0; // no divisions
- assign fp_regular_status.OF = ~src_is_int_q & (~info_q.is_inf & (of_before_round | of_after_round)); // inf casts no OF
- assign fp_regular_status.UF = uf_after_round & fp_regular_status.NX;
- assign fp_regular_status.NX = src_is_int_q ? (| fp_round_sticky_bits) // overflow is invalid in i2f
- : (| fp_round_sticky_bits) | (~info_q.is_inf & (of_before_round | of_after_round));
- assign int_regular_status = '{NX: (| int_round_sticky_bits), default: 1'b0};
-
- assign fp_result = fp_result_is_special ? fp_special_result : fmt_result[dst_fmt_q2];
- assign fp_status = fp_result_is_special ? fp_special_status : fp_regular_status;
- assign int_result = int_result_is_special ? int_special_result : rounded_int_res;
- assign int_status = int_result_is_special ? int_special_status : int_regular_status;
-
- // Final results for output pipeline
- logic [WIDTH-1:0] result_d;
- fpnew_pkg::status_t status_d;
- logic extension_bit;
-
- // Select output depending on special case detection
- assign result_d = dst_is_int_q ? int_result : fp_result;
- assign status_d = dst_is_int_q ? int_status : fp_status;
-
- // MSB of int result decides extension, otherwise NaN box
- assign extension_bit = dst_is_int_q ? int_result[WIDTH-1] : 1'b1;
-
- // ----------------
- // Output Pipeline
- // ----------------
- // Output pipeline signals, index i holds signal after i register stages
- logic [0:NUM_OUT_REGS][WIDTH-1:0] out_pipe_result_q;
- fpnew_pkg::status_t [0:NUM_OUT_REGS] out_pipe_status_q;
- logic [0:NUM_OUT_REGS] out_pipe_ext_bit_q;
- TagType [0:NUM_OUT_REGS] out_pipe_tag_q;
- AuxType [0:NUM_OUT_REGS] out_pipe_aux_q;
- logic [0:NUM_OUT_REGS] out_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_OUT_REGS] out_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign out_pipe_result_q[0] = result_d;
- assign out_pipe_status_q[0] = status_d;
- assign out_pipe_ext_bit_q[0] = extension_bit;
- assign out_pipe_tag_q[0] = mid_pipe_tag_q[NUM_MID_REGS];
- assign out_pipe_aux_q[0] = mid_pipe_aux_q[NUM_MID_REGS];
- assign out_pipe_valid_q[0] = mid_pipe_valid_q[NUM_MID_REGS];
- // Input stage: Propagate pipeline ready signal to inside pipe
- assign mid_pipe_ready[NUM_MID_REGS] = out_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_OUT_REGS; i++) begin : gen_output_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign out_pipe_ready[i] = out_pipe_ready[i+1] | ~out_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(out_pipe_valid_q[i+1], out_pipe_valid_q[i], out_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(out_pipe_result_q[i+1], out_pipe_result_q[i], reg_ena, '0)
- `FFL(out_pipe_status_q[i+1], out_pipe_status_q[i], reg_ena, '0)
- `FFL(out_pipe_ext_bit_q[i+1], out_pipe_ext_bit_q[i], reg_ena, '0)
- `FFL(out_pipe_tag_q[i+1], out_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(out_pipe_aux_q[i+1], out_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: Ready travels backwards from output side, driven by downstream circuitry
- assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
- // Output stage: assign module outputs
- assign result_o = out_pipe_result_q[NUM_OUT_REGS];
- assign status_o = out_pipe_status_q[NUM_OUT_REGS];
- assign extension_bit_o = out_pipe_ext_bit_q[NUM_OUT_REGS];
- assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
- assign aux_o = out_pipe_aux_q[NUM_OUT_REGS];
- assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
- assign busy_o = (| {inp_pipe_valid_q, mid_pipe_valid_q, out_pipe_valid_q});
-endmodule
diff --git a/verilog/rtl/fpnew_classifier.sv b/verilog/rtl/fpnew_classifier.sv
deleted file mode 100644
index 5e4fab9..0000000
--- a/verilog/rtl/fpnew_classifier.sv
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-module fpnew_classifier #(
- parameter fpnew_pkg::fp_format_e FpFormat = fpnew_pkg::fp_format_e'(0),
- parameter int unsigned NumOperands = 1,
- // Do not change
- localparam int unsigned WIDTH = fpnew_pkg::fp_width(FpFormat)
-) (
- input logic [NumOperands-1:0][WIDTH-1:0] operands_i,
- input logic [NumOperands-1:0] is_boxed_i,
- output fpnew_pkg::fp_info_t [NumOperands-1:0] info_o
-);
-
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(FpFormat);
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(FpFormat);
-
- // Type definition
- typedef struct packed {
- logic sign;
- logic [EXP_BITS-1:0] exponent;
- logic [MAN_BITS-1:0] mantissa;
- } fp_t;
-
- // Iterate through all operands
- for (genvar op = 0; op < int'(NumOperands); op++) begin : gen_num_values
-
- fp_t value;
- logic is_boxed;
- logic is_normal;
- logic is_inf;
- logic is_nan;
- logic is_signalling;
- logic is_quiet;
- logic is_zero;
- logic is_subnormal;
-
- // ---------------
- // Classify Input
- // ---------------
- always_comb begin : classify_input
- value = operands_i[op];
- is_boxed = is_boxed_i[op];
- is_normal = is_boxed && (value.exponent != '0) && (value.exponent != '1);
- is_zero = is_boxed && (value.exponent == '0) && (value.mantissa == '0);
- is_subnormal = is_boxed && (value.exponent == '0) && !is_zero;
- is_inf = is_boxed && ((value.exponent == '1) && (value.mantissa == '0));
- is_nan = !is_boxed || ((value.exponent == '1) && (value.mantissa != '0));
- is_signalling = is_boxed && is_nan && (value.mantissa[MAN_BITS-1] == 1'b0);
- is_quiet = is_nan && !is_signalling;
- // Assign output for current input
- info_o[op].is_normal = is_normal;
- info_o[op].is_subnormal = is_subnormal;
- info_o[op].is_zero = is_zero;
- info_o[op].is_inf = is_inf;
- info_o[op].is_nan = is_nan;
- info_o[op].is_signalling = is_signalling;
- info_o[op].is_quiet = is_quiet;
- info_o[op].is_boxed = is_boxed;
- end
- end
-endmodule
diff --git a/verilog/rtl/fpnew_divsqrt_multi.sv b/verilog/rtl/fpnew_divsqrt_multi.sv
deleted file mode 100644
index ac541a3..0000000
--- a/verilog/rtl/fpnew_divsqrt_multi.sv
+++ /dev/null
@@ -1,339 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-`include "registers.svh"
-module fpnew_divsqrt_multi #(
- parameter fpnew_pkg::fmt_logic_t FpFmtConfig = '1,
- // FPU configuration
- parameter int unsigned NumPipeRegs = 0,
- parameter fpnew_pkg::pipe_config_t PipeConfig = fpnew_pkg::AFTER,
- parameter type TagType = logic,
- parameter type AuxType = logic,
- // Do not change
- localparam int unsigned WIDTH = fpnew_pkg::max_fp_width(FpFmtConfig),
- localparam int unsigned NUM_FORMATS = fpnew_pkg::NUM_FP_FORMATS
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [1:0][WIDTH-1:0] operands_i, // 2 operands
- input logic [NUM_FORMATS-1:0][1:0] is_boxed_i, // 2 operands
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input fpnew_pkg::fp_format_e dst_fmt_i,
- input TagType tag_i,
- input AuxType aux_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [WIDTH-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output logic extension_bit_o,
- output TagType tag_o,
- output AuxType aux_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- // ----------
- // Constants
- // ----------
- // Pipelines
- localparam NUM_INP_REGS = (PipeConfig == fpnew_pkg::BEFORE)
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? (NumPipeRegs / 2) // Last to get distributed regs
- : 0); // no regs here otherwise
- localparam NUM_OUT_REGS = (PipeConfig == fpnew_pkg::AFTER || PipeConfig == fpnew_pkg::INSIDE)
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? ((NumPipeRegs + 1) / 2) // First to get distributed regs
- : 0); // no regs here otherwise
-
- // ---------------
- // Input pipeline
- // ---------------
- // Selected pipeline output signals as non-arrays
- logic [1:0][WIDTH-1:0] operands_q;
- fpnew_pkg::roundmode_e rnd_mode_q;
- fpnew_pkg::operation_e op_q;
- fpnew_pkg::fp_format_e dst_fmt_q;
- logic in_valid_q;
-
- // Input pipeline signals, index i holds signal after i register stages
- logic [0:NUM_INP_REGS][1:0][WIDTH-1:0] inp_pipe_operands_q;
- fpnew_pkg::roundmode_e [0:NUM_INP_REGS] inp_pipe_rnd_mode_q;
- fpnew_pkg::operation_e [0:NUM_INP_REGS] inp_pipe_op_q;
- fpnew_pkg::fp_format_e [0:NUM_INP_REGS] inp_pipe_dst_fmt_q;
- TagType [0:NUM_INP_REGS] inp_pipe_tag_q;
- AuxType [0:NUM_INP_REGS] inp_pipe_aux_q;
- logic [0:NUM_INP_REGS] inp_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_INP_REGS] inp_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign inp_pipe_operands_q[0] = operands_i;
- assign inp_pipe_rnd_mode_q[0] = rnd_mode_i;
- assign inp_pipe_op_q[0] = op_i;
- assign inp_pipe_dst_fmt_q[0] = dst_fmt_i;
- assign inp_pipe_tag_q[0] = tag_i;
- assign inp_pipe_aux_q[0] = aux_i;
- assign inp_pipe_valid_q[0] = in_valid_i;
- // Input stage: Propagate pipeline ready signal to updtream circuitry
- assign in_ready_o = inp_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_INP_REGS; i++) begin : gen_input_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign inp_pipe_ready[i] = inp_pipe_ready[i+1] | ~inp_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(inp_pipe_valid_q[i+1], inp_pipe_valid_q[i], inp_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(inp_pipe_operands_q[i+1], inp_pipe_operands_q[i], reg_ena, '0)
- `FFL(inp_pipe_rnd_mode_q[i+1], inp_pipe_rnd_mode_q[i], reg_ena, fpnew_pkg::RNE)
- `FFL(inp_pipe_op_q[i+1], inp_pipe_op_q[i], reg_ena, fpnew_pkg::FMADD)
- `FFL(inp_pipe_dst_fmt_q[i+1], inp_pipe_dst_fmt_q[i], reg_ena, fpnew_pkg::fp_format_e'(0))
- `FFL(inp_pipe_tag_q[i+1], inp_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(inp_pipe_aux_q[i+1], inp_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: assign selected pipe outputs to signals for later use
- assign operands_q = inp_pipe_operands_q[NUM_INP_REGS];
- assign rnd_mode_q = inp_pipe_rnd_mode_q[NUM_INP_REGS];
- assign op_q = inp_pipe_op_q[NUM_INP_REGS];
- assign dst_fmt_q = inp_pipe_dst_fmt_q[NUM_INP_REGS];
- assign in_valid_q = inp_pipe_valid_q[NUM_INP_REGS];
-
- // -----------------
- // Input processing
- // -----------------
- logic [1:0] divsqrt_fmt;
- logic [1:0][63:0] divsqrt_operands; // those are fixed to 64bit
- logic input_is_fp8;
-
- // Translate fpnew formats into divsqrt formats
- always_comb begin : translate_fmt
- unique case (dst_fmt_q)
- fpnew_pkg::FP32: divsqrt_fmt = 2'b00;
- fpnew_pkg::FP64: divsqrt_fmt = 2'b01;
- fpnew_pkg::FP16: divsqrt_fmt = 2'b10;
- fpnew_pkg::FP16ALT: divsqrt_fmt = 2'b11;
- default: divsqrt_fmt = 2'b10; // maps also FP8 to FP16
- endcase
-
- // Only if FP8 is enabled
- input_is_fp8 = FpFmtConfig[fpnew_pkg::FP8] & (dst_fmt_q == fpnew_pkg::FP8);
-
- // If FP8 is supported, map it to an FP16 value
- divsqrt_operands[0] = input_is_fp8 ? operands_q[0] << 8 : operands_q[0];
- divsqrt_operands[1] = input_is_fp8 ? operands_q[1] << 8 : operands_q[1];
- end
-
- // ------------
- // Control FSM
- // ------------
- logic in_ready; // input handshake with upstream
- logic div_valid, sqrt_valid; // input signalling with unit
- logic unit_ready, unit_done; // status signals from unit instance
- logic op_starting; // high in the cycle a new operation starts
- logic out_valid, out_ready; // output handshake with downstream
- logic hold_result; // whether to put result into hold register
- logic data_is_held; // data in hold register is valid
- logic unit_busy; // valid data in flight
- // FSM states
- typedef enum logic [1:0] {IDLE, BUSY, HOLD} fsm_state_e;
- fsm_state_e state_q, state_d;
-
- // Upstream ready comes from sanitization FSM
- assign inp_pipe_ready[NUM_INP_REGS] = in_ready;
-
- // Valids are gated by the FSM ready. Invalid input ops run a sqrt to not lose illegal instr.
- assign div_valid = in_valid_q & (op_q == fpnew_pkg::DIV) & in_ready & ~flush_i;
- assign sqrt_valid = in_valid_q & (op_q != fpnew_pkg::DIV) & in_ready & ~flush_i;
- assign op_starting = div_valid | sqrt_valid;
-
- // FSM to safely apply and receive data from DIVSQRT unit
- always_comb begin : flag_fsm
- // Default assignments
- in_ready = 1'b0;
- out_valid = 1'b0;
- hold_result = 1'b0;
- data_is_held = 1'b0;
- unit_busy = 1'b0;
- state_d = state_q;
-
- unique case (state_q)
- // Waiting for work
- IDLE: begin
- in_ready = 1'b1; // we're ready
- if (in_valid_q && unit_ready) begin // New work arrives
- state_d = BUSY; // go into processing state
- end
- end
- // Operation in progress
- BUSY: begin
- unit_busy = 1'b1; // data in flight
- // If the unit is done with processing
- if (unit_done) begin
- out_valid = 1'b1; // try to commit result downstream
- // If downstream accepts our result
- if (out_ready) begin
- state_d = IDLE; // we anticipate going back to idling..
- if (in_valid_q && unit_ready) begin // ..unless new work comes in
- in_ready = 1'b1; // we acknowledge the instruction
- state_d = BUSY; // and stay busy with it
- end
- // Otherwise if downstream is not ready for the result
- end else begin
- hold_result = 1'b1; // activate the hold register
- state_d = HOLD; // wait for the pipeline to take the data
- end
- end
- end
- // Waiting with valid result for downstream
- HOLD: begin
- unit_busy = 1'b1; // data in flight
- data_is_held = 1'b1; // data in hold register is valid
- out_valid = 1'b1; // try to commit result downstream
- // If the result is accepted by downstream
- if (out_ready) begin
- state_d = IDLE; // go back to idle..
- if (in_valid_q && unit_ready) begin // ..unless new work comes in
- in_ready = 1'b1; // acknowledge the new transaction
- state_d = BUSY; // will be busy with the next instruction
- end
- end
- end
- // fall into idle state otherwise
- default: state_d = IDLE;
- endcase
-
- // Flushing overrides the other actions
- if (flush_i) begin
- unit_busy = 1'b0; // data is invalidated
- out_valid = 1'b0; // cancel any valid data
- state_d = IDLE; // go to default state
- end
- end
-
- // FSM status register (asynch active low rst_ni)
- `FF(state_q, state_d, IDLE)
-
- // Hold additional information while the operation is in progress
- logic result_is_fp8_q;
- TagType result_tag_q;
- AuxType result_aux_q;
-
- // Fill the registers everytime a valid operation arrives (load FF, active low asynch rst)
- `FFL(result_is_fp8_q, input_is_fp8, op_starting, '0)
- `FFL(result_tag_q, inp_pipe_tag_q[NUM_INP_REGS], op_starting, '0)
- `FFL(result_aux_q, inp_pipe_aux_q[NUM_INP_REGS], op_starting, '0)
-
- // -----------------
- // DIVSQRT instance
- // -----------------
- logic [63:0] unit_result;
- logic [WIDTH-1:0] adjusted_result, held_result_q;
- fpnew_pkg::status_t unit_status, held_status_q;
-
- div_sqrt_top_mvp i_divsqrt_lei (
- .Clk_CI ( clk_i ),
- .Rst_RBI ( rst_ni ),
- .Div_start_SI ( div_valid ),
- .Sqrt_start_SI ( sqrt_valid ),
- .Operand_a_DI ( divsqrt_operands[0] ),
- .Operand_b_DI ( divsqrt_operands[1] ),
- .RM_SI ( rnd_mode_q ),
- .Precision_ctl_SI ( '0 ),
- .Format_sel_SI ( divsqrt_fmt ),
- .Kill_SI ( flush_i ),
- .Result_DO ( unit_result ),
- .Fflags_SO ( unit_status ),
- .Ready_SO ( unit_ready ),
- .Done_SO ( unit_done )
- );
-
- // Adjust result width and fix FP8
- assign adjusted_result = result_is_fp8_q ? unit_result >> 8 : unit_result;
-
- // The Hold register (load, no rst_ni)
- `FFLNR(held_result_q, adjusted_result, hold_result, clk_i)
- `FFLNR(held_status_q, unit_status, hold_result, clk_i)
-
- // --------------
- // Output Select
- // --------------
- logic [WIDTH-1:0] result_d;
- fpnew_pkg::status_t status_d;
- // Prioritize hold register data
- assign result_d = data_is_held ? held_result_q : adjusted_result;
- assign status_d = data_is_held ? held_status_q : unit_status;
-
- // ----------------
- // Output Pipeline
- // ----------------
- // Output pipeline signals, index i holds signal after i register stages
- logic [0:NUM_OUT_REGS][WIDTH-1:0] out_pipe_result_q;
- fpnew_pkg::status_t [0:NUM_OUT_REGS] out_pipe_status_q;
- TagType [0:NUM_OUT_REGS] out_pipe_tag_q;
- AuxType [0:NUM_OUT_REGS] out_pipe_aux_q;
- logic [0:NUM_OUT_REGS] out_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_OUT_REGS] out_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign out_pipe_result_q[0] = result_d;
- assign out_pipe_status_q[0] = status_d;
- assign out_pipe_tag_q[0] = result_tag_q;
- assign out_pipe_aux_q[0] = result_aux_q;
- assign out_pipe_valid_q[0] = out_valid;
- // Input stage: Propagate pipeline ready signal to inside pipe
- assign out_ready = out_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_OUT_REGS; i++) begin : gen_output_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign out_pipe_ready[i] = out_pipe_ready[i+1] | ~out_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(out_pipe_valid_q[i+1], out_pipe_valid_q[i], out_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(out_pipe_result_q[i+1], out_pipe_result_q[i], reg_ena, '0)
- `FFL(out_pipe_status_q[i+1], out_pipe_status_q[i], reg_ena, '0)
- `FFL(out_pipe_tag_q[i+1], out_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(out_pipe_aux_q[i+1], out_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: Ready travels backwards from output side, driven by downstream circuitry
- assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
- // Output stage: assign module outputs
- assign result_o = out_pipe_result_q[NUM_OUT_REGS];
- assign status_o = out_pipe_status_q[NUM_OUT_REGS];
- assign extension_bit_o = 1'b1; // always NaN-Box result
- assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
- assign aux_o = out_pipe_aux_q[NUM_OUT_REGS];
- assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
- assign busy_o = (| {inp_pipe_valid_q, unit_busy, out_pipe_valid_q});
-endmodule
diff --git a/verilog/rtl/fpnew_fma.sv b/verilog/rtl/fpnew_fma.sv
deleted file mode 100644
index 552b98a..0000000
--- a/verilog/rtl/fpnew_fma.sv
+++ /dev/null
@@ -1,672 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-`include "registers.svh"
-module fpnew_fma #(
- parameter fpnew_pkg::fp_format_e FpFormat = fpnew_pkg::fp_format_e'(0),
- parameter int unsigned NumPipeRegs = 0,
- parameter fpnew_pkg::pipe_config_t PipeConfig = fpnew_pkg::BEFORE,
- parameter type TagType = logic,
- parameter type AuxType = logic,
-
- localparam int unsigned WIDTH = fpnew_pkg::fp_width(FpFormat) // do not change
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [2:0][WIDTH-1:0] operands_i, // 3 operands
- input logic [2:0] is_boxed_i, // 3 operands
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input logic op_mod_i,
- input TagType tag_i,
- input AuxType aux_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [WIDTH-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output logic extension_bit_o,
- output TagType tag_o,
- output AuxType aux_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- // ----------
- // Constants
- // ----------
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(FpFormat);
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(FpFormat);
- localparam int unsigned BIAS = fpnew_pkg::bias(FpFormat);
- // Precision bits 'p' include the implicit bit
- localparam int unsigned PRECISION_BITS = MAN_BITS + 1;
- // The lower 2p+3 bits of the internal FMA result will be needed for leading-zero detection
- localparam int unsigned LOWER_SUM_WIDTH = 2 * PRECISION_BITS + 3;
- localparam int unsigned LZC_RESULT_WIDTH = $clog2(LOWER_SUM_WIDTH);
- // Internal exponent width of FMA must accomodate all meaningful exponent values in order to avoid
- // datapath leakage. This is either given by the exponent bits or the width of the LZC result.
- // In most reasonable FP formats the internal exponent will be wider than the LZC result.
- localparam int unsigned EXP_WIDTH = unsigned'(fpnew_pkg::maximum(EXP_BITS + 2, LZC_RESULT_WIDTH));
- // Shift amount width: maximum internal mantissa size is 3p+3 bits
- localparam int unsigned SHIFT_AMOUNT_WIDTH = $clog2(3 * PRECISION_BITS + 3);
- // Pipelines
- localparam NUM_INP_REGS = PipeConfig == fpnew_pkg::BEFORE
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? ((NumPipeRegs + 1) / 3) // Second to get distributed regs
- : 0); // no regs here otherwise
- localparam NUM_MID_REGS = PipeConfig == fpnew_pkg::INSIDE
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? ((NumPipeRegs + 2) / 3) // First to get distributed regs
- : 0); // no regs here otherwise
- localparam NUM_OUT_REGS = PipeConfig == fpnew_pkg::AFTER
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? (NumPipeRegs / 3) // Last to get distributed regs
- : 0); // no regs here otherwise
-
- // ----------------
- // Type definition
- // ----------------
- typedef struct packed {
- logic sign;
- logic [EXP_BITS-1:0] exponent;
- logic [MAN_BITS-1:0] mantissa;
- } fp_t;
-
- // ---------------
- // Input pipeline
- // ---------------
- // Input pipeline signals, index i holds signal after i register stages
- logic [0:NUM_INP_REGS][2:0][WIDTH-1:0] inp_pipe_operands_q;
- logic [0:NUM_INP_REGS][2:0] inp_pipe_is_boxed_q;
- fpnew_pkg::roundmode_e [0:NUM_INP_REGS] inp_pipe_rnd_mode_q;
- fpnew_pkg::operation_e [0:NUM_INP_REGS] inp_pipe_op_q;
- logic [0:NUM_INP_REGS] inp_pipe_op_mod_q;
- TagType [0:NUM_INP_REGS] inp_pipe_tag_q;
- AuxType [0:NUM_INP_REGS] inp_pipe_aux_q;
- logic [0:NUM_INP_REGS] inp_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_INP_REGS] inp_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign inp_pipe_operands_q[0] = operands_i;
- assign inp_pipe_is_boxed_q[0] = is_boxed_i;
- assign inp_pipe_rnd_mode_q[0] = rnd_mode_i;
- assign inp_pipe_op_q[0] = op_i;
- assign inp_pipe_op_mod_q[0] = op_mod_i;
- assign inp_pipe_tag_q[0] = tag_i;
- assign inp_pipe_aux_q[0] = aux_i;
- assign inp_pipe_valid_q[0] = in_valid_i;
- // Input stage: Propagate pipeline ready signal to updtream circuitry
- assign in_ready_o = inp_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_INP_REGS; i++) begin : gen_input_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign inp_pipe_ready[i] = inp_pipe_ready[i+1] | ~inp_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(inp_pipe_valid_q[i+1], inp_pipe_valid_q[i], inp_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(inp_pipe_operands_q[i+1], inp_pipe_operands_q[i], reg_ena, '0)
- `FFL(inp_pipe_is_boxed_q[i+1], inp_pipe_is_boxed_q[i], reg_ena, '0)
- `FFL(inp_pipe_rnd_mode_q[i+1], inp_pipe_rnd_mode_q[i], reg_ena, fpnew_pkg::RNE)
- `FFL(inp_pipe_op_q[i+1], inp_pipe_op_q[i], reg_ena, fpnew_pkg::FMADD)
- `FFL(inp_pipe_op_mod_q[i+1], inp_pipe_op_mod_q[i], reg_ena, '0)
- `FFL(inp_pipe_tag_q[i+1], inp_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(inp_pipe_aux_q[i+1], inp_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
-
- // -----------------
- // Input processing
- // -----------------
- fpnew_pkg::fp_info_t [2:0] info_q;
-
- // Classify input
- fpnew_classifier #(
- .FpFormat ( FpFormat ),
- .NumOperands ( 3 )
- ) i_class_inputs (
- .operands_i ( inp_pipe_operands_q[NUM_INP_REGS] ),
- .is_boxed_i ( inp_pipe_is_boxed_q[NUM_INP_REGS] ),
- .info_o ( info_q )
- );
-
- fp_t operand_a, operand_b, operand_c;
- fpnew_pkg::fp_info_t info_a, info_b, info_c;
-
- // Operation selection and operand adjustment
- // | \c op_q | \c op_mod_q | Operation Adjustment
- // |:--------:|:-----------:|---------------------
- // | FMADD | \c 0 | FMADD: none
- // | FMADD | \c 1 | FMSUB: Invert sign of operand C
- // | FNMSUB | \c 0 | FNMSUB: Invert sign of operand A
- // | FNMSUB | \c 1 | FNMADD: Invert sign of operands A and C
- // | ADD | \c 0 | ADD: Set operand A to +1.0
- // | ADD | \c 1 | SUB: Set operand A to +1.0, invert sign of operand C
- // | MUL | \c 0 | MUL: Set operand C to +0.0
- // | *others* | \c - | *invalid*
- // \note \c op_mod_q always inverts the sign of the addend.
- always_comb begin : op_select
-
- // Default assignments - packing-order-agnostic
- operand_a = inp_pipe_operands_q[NUM_INP_REGS][0];
- operand_b = inp_pipe_operands_q[NUM_INP_REGS][1];
- operand_c = inp_pipe_operands_q[NUM_INP_REGS][2];
- info_a = info_q[0];
- info_b = info_q[1];
- info_c = info_q[2];
-
- // op_mod_q inverts sign of operand C
- operand_c.sign = operand_c.sign ^ inp_pipe_op_mod_q[NUM_INP_REGS];
-
- unique case (inp_pipe_op_q[NUM_INP_REGS])
- fpnew_pkg::FMADD: ; // do nothing
- fpnew_pkg::FNMSUB: operand_a.sign = ~operand_a.sign; // invert sign of product
- fpnew_pkg::ADD: begin // Set multiplicand to +1
- operand_a = '{sign: 1'b0, exponent: BIAS, mantissa: '0};
- info_a = '{is_normal: 1'b1, is_boxed: 1'b1, default: 1'b0}; //normal, boxed value.
- end
- fpnew_pkg::MUL: begin // Set addend to -0 (for proper rounding with RDN)
- operand_c = '{sign: 1'b1, exponent: '0, mantissa: '0};
- info_c = '{is_zero: 1'b1, is_boxed: 1'b1, default: 1'b0}; //zero, boxed value.
- end
- default: begin // propagate don't cares
- operand_a = '{default: fpnew_pkg::DONT_CARE};
- operand_b = '{default: fpnew_pkg::DONT_CARE};
- operand_c = '{default: fpnew_pkg::DONT_CARE};
- info_a = '{default: fpnew_pkg::DONT_CARE};
- info_b = '{default: fpnew_pkg::DONT_CARE};
- info_c = '{default: fpnew_pkg::DONT_CARE};
- end
- endcase
- end
-
- // ---------------------
- // Input classification
- // ---------------------
- logic any_operand_inf;
- logic any_operand_nan;
- logic signalling_nan;
- logic effective_subtraction;
- logic tentative_sign;
-
- // Reduction for special case handling
- assign any_operand_inf = (| {info_a.is_inf, info_b.is_inf, info_c.is_inf});
- assign any_operand_nan = (| {info_a.is_nan, info_b.is_nan, info_c.is_nan});
- assign signalling_nan = (| {info_a.is_signalling, info_b.is_signalling, info_c.is_signalling});
- // Effective subtraction in FMA occurs when product and addend signs differ
- assign effective_subtraction = operand_a.sign ^ operand_b.sign ^ operand_c.sign;
- // The tentative sign of the FMA shall be the sign of the product
- assign tentative_sign = operand_a.sign ^ operand_b.sign;
-
- // ----------------------
- // Special case handling
- // ----------------------
- fp_t special_result;
- fpnew_pkg::status_t special_status;
- logic result_is_special;
-
- always_comb begin : special_cases
- // Default assignments
- special_result = '{sign: 1'b0, exponent: '1, mantissa: 2**(MAN_BITS-1)}; // canonical qNaN
- special_status = '0;
- result_is_special = 1'b0;
-
- // Handle potentially mixed nan & infinity input => important for the case where infinity and
- // zero are multiplied and added to a qnan.
- // RISC-V mandates raising the NV exception in these cases:
- // (inf * 0) + c or (0 * inf) + c INVALID, no matter c (even quiet NaNs)
- if ((info_a.is_inf && info_b.is_zero) || (info_a.is_zero && info_b.is_inf)) begin
- result_is_special = 1'b1; // bypass FMA, output is the canonical qNaN
- special_status.NV = 1'b1; // invalid operation
- // NaN Inputs cause canonical quiet NaN at the output and maybe invalid OP
- end else if (any_operand_nan) begin
- result_is_special = 1'b1; // bypass FMA, output is the canonical qNaN
- special_status.NV = signalling_nan; // raise the invalid operation flag if signalling
- // Special cases involving infinity
- end else if (any_operand_inf) begin
- result_is_special = 1'b1; // bypass FMA
- // Effective addition of opposite infinities (±inf - ±inf) is invalid!
- if ((info_a.is_inf || info_b.is_inf) && info_c.is_inf && effective_subtraction)
- special_status.NV = 1'b1; // invalid operation
- // Handle cases where output will be inf because of inf product input
- else if (info_a.is_inf || info_b.is_inf) begin
- // Result is infinity with the sign of the product
- special_result = '{sign: operand_a.sign ^ operand_b.sign, exponent: '1, mantissa: '0};
- // Handle cases where the addend is inf
- end else if (info_c.is_inf) begin
- // Result is inifinity with sign of the addend (= operand_c)
- special_result = '{sign: operand_c.sign, exponent: '1, mantissa: '0};
- end
- end
- end
-
- // ---------------------------
- // Initial exponent data path
- // ---------------------------
- logic signed [EXP_WIDTH-1:0] exponent_a, exponent_b, exponent_c;
- logic signed [EXP_WIDTH-1:0] exponent_addend, exponent_product, exponent_difference;
- logic signed [EXP_WIDTH-1:0] tentative_exponent;
-
- // Zero-extend exponents into signed container - implicit width extension
- assign exponent_a = signed'({1'b0, operand_a.exponent});
- assign exponent_b = signed'({1'b0, operand_b.exponent});
- assign exponent_c = signed'({1'b0, operand_c.exponent});
-
- // Calculate internal exponents from encoded values. Real exponents are (ex = Ex - bias + 1 - nx)
- // with Ex the encoded exponent and nx the implicit bit. Internal exponents stay biased.
- assign exponent_addend = signed'(exponent_c + $signed({1'b0, ~info_c.is_normal})); // 0 as subnorm
- // Biased product exponent is the sum of encoded exponents minus the bias.
- assign exponent_product = (info_a.is_zero || info_b.is_zero)
- ? 2 - signed'(BIAS) // in case the product is zero, set minimum exp.
- : signed'(exponent_a + info_a.is_subnormal
- + exponent_b + info_b.is_subnormal
- - signed'(BIAS));
- // Exponent difference is the addend exponent minus the product exponent
- assign exponent_difference = exponent_addend - exponent_product;
- // The tentative exponent will be the larger of the product or addend exponent
- assign tentative_exponent = (exponent_difference > 0) ? exponent_addend : exponent_product;
-
- // Shift amount for addend based on exponents (unsigned as only right shifts)
- logic [SHIFT_AMOUNT_WIDTH-1:0] addend_shamt;
-
- always_comb begin : addend_shift_amount
- // Product-anchored case, saturated shift (addend is only in the sticky bit)
- if (exponent_difference <= signed'(-2 * PRECISION_BITS - 1))
- addend_shamt = 3 * PRECISION_BITS + 4;
- // Addend and product will have mutual bits to add
- else if (exponent_difference <= signed'(PRECISION_BITS + 2))
- addend_shamt = unsigned'(signed'(PRECISION_BITS) + 3 - exponent_difference);
- // Addend-anchored case, saturated shift (product is only in the sticky bit)
- else
- addend_shamt = 0;
- end
-
- // ------------------
- // Product data path
- // ------------------
- logic [PRECISION_BITS-1:0] mantissa_a, mantissa_b, mantissa_c;
- logic [2*PRECISION_BITS-1:0] product; // the p*p product is 2p bits wide
- logic [3*PRECISION_BITS+3:0] product_shifted; // addends are 3p+4 bit wide (including G/R)
-
- // Add implicit bits to mantissae
- assign mantissa_a = {info_a.is_normal, operand_a.mantissa};
- assign mantissa_b = {info_b.is_normal, operand_b.mantissa};
- assign mantissa_c = {info_c.is_normal, operand_c.mantissa};
-
- // Mantissa multiplier (a*b)
- assign product = mantissa_a * mantissa_b;
-
- // Product is placed into a 3p+4 bit wide vector, padded with 2 bits for round and sticky:
- // | 000...000 | product | RS |
- // <- p+2 -> <- 2p -> < 2>
- assign product_shifted = product << 2; // constant shift
-
- // -----------------
- // Addend data path
- // -----------------
- logic [3*PRECISION_BITS+3:0] addend_after_shift; // upper 3p+4 bits are needed to go on
- logic [PRECISION_BITS-1:0] addend_sticky_bits; // up to p bit of shifted addend are sticky
- logic sticky_before_add; // they are compressed into a single sticky bit
- logic [3*PRECISION_BITS+3:0] addend_shifted; // addends are 3p+4 bit wide (including G/R)
- logic inject_carry_in; // inject carry for subtractions if needed
-
- // In parallel, the addend is right-shifted according to the exponent difference. Up to p bits
- // are shifted out and compressed into a sticky bit.
- // BEFORE THE SHIFT:
- // | mantissa_c | 000..000 |
- // <- p -> <- 3p+4 ->
- // AFTER THE SHIFT:
- // | 000..........000 | mantissa_c | 000...............0GR | sticky bits |
- // <- addend_shamt -> <- p -> <- 2p+4-addend_shamt -> <- up to p ->
- assign {addend_after_shift, addend_sticky_bits} =
- (mantissa_c << (3 * PRECISION_BITS + 4)) >> addend_shamt;
-
- assign sticky_before_add = (| addend_sticky_bits);
- // assign addend_after_shift[0] = sticky_before_add;
-
- // In case of a subtraction, the addend is inverted
- assign addend_shifted = (effective_subtraction) ? ~addend_after_shift : addend_after_shift;
- assign inject_carry_in = effective_subtraction & ~sticky_before_add;
-
- // ------
- // Adder
- // ------
- logic [3*PRECISION_BITS+4:0] sum_raw; // added one bit for the carry
- logic sum_carry; // observe carry bit from sum for sign fixing
- logic [3*PRECISION_BITS+3:0] sum; // discard carry as sum won't overflow
- logic final_sign;
-
- //Mantissa adder (ab+c). In normal addition, it cannot overflow.
- assign sum_raw = product_shifted + addend_shifted + inject_carry_in;
- assign sum_carry = sum_raw[3*PRECISION_BITS+4];
-
- // Complement negative sum (can only happen in subtraction -> overflows for positive results)
- assign sum = (effective_subtraction && ~sum_carry) ? -sum_raw : sum_raw;
-
- // In case of a mispredicted subtraction result, do a sign flip
- assign final_sign = (effective_subtraction && (sum_carry == tentative_sign))
- ? 1'b1
- : (effective_subtraction ? 1'b0 : tentative_sign);
-
- // ---------------
- // Internal pipeline
- // ---------------
- // Pipeline output signals as non-arrays
- logic effective_subtraction_q;
- logic signed [EXP_WIDTH-1:0] exponent_product_q;
- logic signed [EXP_WIDTH-1:0] exponent_difference_q;
- logic signed [EXP_WIDTH-1:0] tentative_exponent_q;
- logic [SHIFT_AMOUNT_WIDTH-1:0] addend_shamt_q;
- logic sticky_before_add_q;
- logic [3*PRECISION_BITS+3:0] sum_q;
- logic final_sign_q;
- fpnew_pkg::roundmode_e rnd_mode_q;
- logic result_is_special_q;
- fp_t special_result_q;
- fpnew_pkg::status_t special_status_q;
- // Internal pipeline signals, index i holds signal after i register stages
- logic [0:NUM_MID_REGS] mid_pipe_eff_sub_q;
- logic signed [0:NUM_MID_REGS][EXP_WIDTH-1:0] mid_pipe_exp_prod_q;
- logic signed [0:NUM_MID_REGS][EXP_WIDTH-1:0] mid_pipe_exp_diff_q;
- logic signed [0:NUM_MID_REGS][EXP_WIDTH-1:0] mid_pipe_tent_exp_q;
- logic [0:NUM_MID_REGS][SHIFT_AMOUNT_WIDTH-1:0] mid_pipe_add_shamt_q;
- logic [0:NUM_MID_REGS] mid_pipe_sticky_q;
- logic [0:NUM_MID_REGS][3*PRECISION_BITS+3:0] mid_pipe_sum_q;
- logic [0:NUM_MID_REGS] mid_pipe_final_sign_q;
- fpnew_pkg::roundmode_e [0:NUM_MID_REGS] mid_pipe_rnd_mode_q;
- logic [0:NUM_MID_REGS] mid_pipe_res_is_spec_q;
- fp_t [0:NUM_MID_REGS] mid_pipe_spec_res_q;
- fpnew_pkg::status_t [0:NUM_MID_REGS] mid_pipe_spec_stat_q;
- TagType [0:NUM_MID_REGS] mid_pipe_tag_q;
- AuxType [0:NUM_MID_REGS] mid_pipe_aux_q;
- logic [0:NUM_MID_REGS] mid_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_MID_REGS] mid_pipe_ready;
-
- // Input stage: First element of pipeline is taken from upstream logic
- assign mid_pipe_eff_sub_q[0] = effective_subtraction;
- assign mid_pipe_exp_prod_q[0] = exponent_product;
- assign mid_pipe_exp_diff_q[0] = exponent_difference;
- assign mid_pipe_tent_exp_q[0] = tentative_exponent;
- assign mid_pipe_add_shamt_q[0] = addend_shamt;
- assign mid_pipe_sticky_q[0] = sticky_before_add;
- assign mid_pipe_sum_q[0] = sum;
- assign mid_pipe_final_sign_q[0] = final_sign;
- assign mid_pipe_rnd_mode_q[0] = inp_pipe_rnd_mode_q[NUM_INP_REGS];
- assign mid_pipe_res_is_spec_q[0] = result_is_special;
- assign mid_pipe_spec_res_q[0] = special_result;
- assign mid_pipe_spec_stat_q[0] = special_status;
- assign mid_pipe_tag_q[0] = inp_pipe_tag_q[NUM_INP_REGS];
- assign mid_pipe_aux_q[0] = inp_pipe_aux_q[NUM_INP_REGS];
- assign mid_pipe_valid_q[0] = inp_pipe_valid_q[NUM_INP_REGS];
- // Input stage: Propagate pipeline ready signal to input pipe
- assign inp_pipe_ready[NUM_INP_REGS] = mid_pipe_ready[0];
-
- // Generate the register stages
- for (genvar i = 0; i < NUM_MID_REGS; i++) begin : gen_inside_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign mid_pipe_ready[i] = mid_pipe_ready[i+1] | ~mid_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(mid_pipe_valid_q[i+1], mid_pipe_valid_q[i], mid_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = mid_pipe_ready[i] & mid_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(mid_pipe_eff_sub_q[i+1], mid_pipe_eff_sub_q[i], reg_ena, '0)
- `FFL(mid_pipe_exp_prod_q[i+1], mid_pipe_exp_prod_q[i], reg_ena, '0)
- `FFL(mid_pipe_exp_diff_q[i+1], mid_pipe_exp_diff_q[i], reg_ena, '0)
- `FFL(mid_pipe_tent_exp_q[i+1], mid_pipe_tent_exp_q[i], reg_ena, '0)
- `FFL(mid_pipe_add_shamt_q[i+1], mid_pipe_add_shamt_q[i], reg_ena, '0)
- `FFL(mid_pipe_sticky_q[i+1], mid_pipe_sticky_q[i], reg_ena, '0)
- `FFL(mid_pipe_sum_q[i+1], mid_pipe_sum_q[i], reg_ena, '0)
- `FFL(mid_pipe_final_sign_q[i+1], mid_pipe_final_sign_q[i], reg_ena, '0)
- `FFL(mid_pipe_rnd_mode_q[i+1], mid_pipe_rnd_mode_q[i], reg_ena, fpnew_pkg::RNE)
- `FFL(mid_pipe_res_is_spec_q[i+1], mid_pipe_res_is_spec_q[i], reg_ena, '0)
- `FFL(mid_pipe_spec_res_q[i+1], mid_pipe_spec_res_q[i], reg_ena, '0)
- `FFL(mid_pipe_spec_stat_q[i+1], mid_pipe_spec_stat_q[i], reg_ena, '0)
- `FFL(mid_pipe_tag_q[i+1], mid_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(mid_pipe_aux_q[i+1], mid_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: assign selected pipe outputs to signals for later use
- assign effective_subtraction_q = mid_pipe_eff_sub_q[NUM_MID_REGS];
- assign exponent_product_q = mid_pipe_exp_prod_q[NUM_MID_REGS];
- assign exponent_difference_q = mid_pipe_exp_diff_q[NUM_MID_REGS];
- assign tentative_exponent_q = mid_pipe_tent_exp_q[NUM_MID_REGS];
- assign addend_shamt_q = mid_pipe_add_shamt_q[NUM_MID_REGS];
- assign sticky_before_add_q = mid_pipe_sticky_q[NUM_MID_REGS];
- assign sum_q = mid_pipe_sum_q[NUM_MID_REGS];
- assign final_sign_q = mid_pipe_final_sign_q[NUM_MID_REGS];
- assign rnd_mode_q = mid_pipe_rnd_mode_q[NUM_MID_REGS];
- assign result_is_special_q = mid_pipe_res_is_spec_q[NUM_MID_REGS];
- assign special_result_q = mid_pipe_spec_res_q[NUM_MID_REGS];
- assign special_status_q = mid_pipe_spec_stat_q[NUM_MID_REGS];
-
- // --------------
- // Normalization
- // --------------
- logic [LOWER_SUM_WIDTH-1:0] sum_lower; // lower 2p+3 bits of sum are searched
- logic [LZC_RESULT_WIDTH-1:0] leading_zero_count; // the number of leading zeroes
- logic signed [LZC_RESULT_WIDTH:0] leading_zero_count_sgn; // signed leading-zero count
- logic lzc_zeroes; // in case only zeroes found
-
- logic [SHIFT_AMOUNT_WIDTH-1:0] norm_shamt; // Normalization shift amount
- logic signed [EXP_WIDTH-1:0] normalized_exponent;
-
- logic [3*PRECISION_BITS+4:0] sum_shifted; // result after first normalization shift
- logic [PRECISION_BITS:0] final_mantissa; // final mantissa before rounding with round bit
- logic [2*PRECISION_BITS+2:0] sum_sticky_bits; // remaining 2p+3 sticky bits after normalization
- logic sticky_after_norm; // sticky bit after normalization
-
- logic signed [EXP_WIDTH-1:0] final_exponent;
-
- assign sum_lower = sum_q[LOWER_SUM_WIDTH-1:0];
-
- // Leading zero counter for cancellations
- lzc #(
- .WIDTH ( LOWER_SUM_WIDTH ),
- .MODE ( 1 ) // MODE = 1 counts leading zeroes
- ) i_lzc (
- .in_i ( sum_lower ),
- .cnt_o ( leading_zero_count ),
- .empty_o ( lzc_zeroes )
- );
-
- assign leading_zero_count_sgn = signed'({1'b0, leading_zero_count});
-
- // Normalization shift amount based on exponents and LZC (unsigned as only left shifts)
- always_comb begin : norm_shift_amount
- // Product-anchored case or cancellations require LZC
- if ((exponent_difference_q <= 0) || (effective_subtraction_q && (exponent_difference_q <= 2))) begin
- // Normal result (biased exponent > 0 and not a zero)
- if ((exponent_product_q - leading_zero_count_sgn + 1 >= 0) && !lzc_zeroes) begin
- // Undo initial product shift, remove the counted zeroes
- norm_shamt = PRECISION_BITS + 2 + leading_zero_count;
- normalized_exponent = exponent_product_q - leading_zero_count_sgn + 1; // account for shift
- // Subnormal result
- end else begin
- // Cap the shift distance to align mantissa with minimum exponent
- norm_shamt = unsigned'(signed'(PRECISION_BITS) + 2 + exponent_product_q);
- normalized_exponent = 0; // subnormals encoded as 0
- end
- // Addend-anchored case
- end else begin
- norm_shamt = addend_shamt_q; // Undo the initial shift
- normalized_exponent = tentative_exponent_q;
- end
- end
-
- // Do the large normalization shift
- assign sum_shifted = sum_q << norm_shamt;
-
- // The addend-anchored case needs a 1-bit normalization since the leading-one can be to the left
- // or right of the (non-carry) MSB of the sum.
- always_comb begin : small_norm
- // Default assignment, discarding carry bit
- {final_mantissa[23:0], sum_sticky_bits} = sum_shifted;
- final_exponent = normalized_exponent;
-
- // The normalized sum has overflown, align right and fix exponent
- if (sum_shifted[3*PRECISION_BITS+4]) begin // check the carry bit
- {final_mantissa, sum_sticky_bits} = sum_shifted >> 1;
- final_exponent = normalized_exponent + 1;
- // The normalized sum is normal, nothing to do
- end else if (sum_shifted[3*PRECISION_BITS+3]) begin // check the sum MSB
- // do nothing
- // The normalized sum is still denormal, align left - unless the result is not already subnormal
- end else if (normalized_exponent > 1) begin
- {final_mantissa, sum_sticky_bits} = sum_shifted << 1;
- final_exponent = normalized_exponent - 1;
- // Otherwise we're denormal
- end else begin
- final_exponent = '0;
- end
- end
-
- // Update the sticky bit with the shifted-out bits
- assign sticky_after_norm = (| {sum_sticky_bits}) | sticky_before_add_q;
-
- // ----------------------------
- // Rounding and classification
- // ----------------------------
- logic pre_round_sign;
- logic [EXP_BITS-1:0] pre_round_exponent;
- logic [MAN_BITS-1:0] pre_round_mantissa;
- logic [EXP_BITS+MAN_BITS-1:0] pre_round_abs; // absolute value of result before rounding
- logic [1:0] round_sticky_bits;
-
- logic of_before_round, of_after_round; // overflow
- logic uf_before_round, uf_after_round; // underflow
- logic result_zero;
-
- logic rounded_sign;
- logic [EXP_BITS+MAN_BITS-1:0] rounded_abs; // absolute value of result after rounding
-
- // Classification before round. RISC-V mandates checking underflow AFTER rounding!
- assign of_before_round = final_exponent >= 2**(EXP_BITS)-1; // infinity exponent is all ones
- assign uf_before_round = final_exponent == 0; // exponent for subnormals capped to 0
-
- // Assemble result before rounding. In case of overflow, the largest normal value is set.
- assign pre_round_sign = final_sign_q;
- assign pre_round_exponent = (of_before_round) ? 2**EXP_BITS-2 : unsigned'(final_exponent[EXP_BITS-1:0]);
- assign pre_round_mantissa = (of_before_round) ? '1 : final_mantissa[MAN_BITS:1]; // bit 0 is R bit
- assign pre_round_abs = {pre_round_exponent, pre_round_mantissa};
-
- // In case of overflow, the round and sticky bits are set for proper rounding
- assign round_sticky_bits = (of_before_round) ? 2'b11 : {final_mantissa[0], sticky_after_norm};
-
- // Perform the rounding
- fpnew_rounding #(
- .AbsWidth ( EXP_BITS + MAN_BITS )
- ) i_fpnew_rounding (
- .abs_value_i ( pre_round_abs ),
- .sign_i ( pre_round_sign ),
- .round_sticky_bits_i ( round_sticky_bits ),
- .rnd_mode_i ( rnd_mode_q ),
- .effective_subtraction_i ( effective_subtraction_q ),
- .abs_rounded_o ( rounded_abs ),
- .sign_o ( rounded_sign ),
- .exact_zero_o ( result_zero )
- );
-
- // Classification after rounding
- assign uf_after_round = rounded_abs[EXP_BITS+MAN_BITS-1:MAN_BITS] == '0; // exponent = 0
- assign of_after_round = rounded_abs[EXP_BITS+MAN_BITS-1:MAN_BITS] == '1; // exponent all ones
-
- // -----------------
- // Result selection
- // -----------------
- logic [WIDTH-1:0] regular_result;
- fpnew_pkg::status_t regular_status;
-
- // Assemble regular result
- assign regular_result = {rounded_sign, rounded_abs};
- assign regular_status.NV = 1'b0; // only valid cases are handled in regular path
- assign regular_status.DZ = 1'b0; // no divisions
- assign regular_status.OF = of_before_round | of_after_round; // rounding can introduce overflow
- assign regular_status.UF = uf_after_round & regular_status.NX; // only inexact results raise UF
- assign regular_status.NX = (| round_sticky_bits) | of_before_round | of_after_round;
-
- // Final results for output pipeline
- fp_t result_d;
- fpnew_pkg::status_t status_d;
-
- // Select output depending on special case detection
- assign result_d = result_is_special_q ? special_result_q : regular_result;
- assign status_d = result_is_special_q ? special_status_q : regular_status;
-
- // ----------------
- // Output Pipeline
- // ----------------
- // Output pipeline signals, index i holds signal after i register stages
- fp_t [0:NUM_OUT_REGS] out_pipe_result_q;
- fpnew_pkg::status_t [0:NUM_OUT_REGS] out_pipe_status_q;
- TagType [0:NUM_OUT_REGS] out_pipe_tag_q;
- AuxType [0:NUM_OUT_REGS] out_pipe_aux_q;
- logic [0:NUM_OUT_REGS] out_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_OUT_REGS] out_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign out_pipe_result_q[0] = result_d;
- assign out_pipe_status_q[0] = status_d;
- assign out_pipe_tag_q[0] = mid_pipe_tag_q[NUM_MID_REGS];
- assign out_pipe_aux_q[0] = mid_pipe_aux_q[NUM_MID_REGS];
- assign out_pipe_valid_q[0] = mid_pipe_valid_q[NUM_MID_REGS];
- // Input stage: Propagate pipeline ready signal to inside pipe
- assign mid_pipe_ready[NUM_MID_REGS] = out_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_OUT_REGS; i++) begin : gen_output_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign out_pipe_ready[i] = out_pipe_ready[i+1] | ~out_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(out_pipe_valid_q[i+1], out_pipe_valid_q[i], out_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(out_pipe_result_q[i+1], out_pipe_result_q[i], reg_ena, '0)
- `FFL(out_pipe_status_q[i+1], out_pipe_status_q[i], reg_ena, '0)
- `FFL(out_pipe_tag_q[i+1], out_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(out_pipe_aux_q[i+1], out_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: Ready travels backwards from output side, driven by downstream circuitry
- assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
- // Output stage: assign module outputs
- assign result_o = out_pipe_result_q[NUM_OUT_REGS];
- assign status_o = out_pipe_status_q[NUM_OUT_REGS];
- assign extension_bit_o = 1'b1; // always NaN-Box result
- assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
- assign aux_o = out_pipe_aux_q[NUM_OUT_REGS];
- assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
- assign busy_o = (| {inp_pipe_valid_q, mid_pipe_valid_q, out_pipe_valid_q});
-endmodule
diff --git a/verilog/rtl/fpnew_fma_multi.sv b/verilog/rtl/fpnew_fma_multi.sv
deleted file mode 100644
index 9b7d7b9..0000000
--- a/verilog/rtl/fpnew_fma_multi.sv
+++ /dev/null
@@ -1,821 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-`include "registers.svh"
-module fpnew_fma_multi #(
- parameter fpnew_pkg::fmt_logic_t FpFmtConfig = '1,
- parameter int unsigned NumPipeRegs = 0,
- parameter fpnew_pkg::pipe_config_t PipeConfig = fpnew_pkg::BEFORE,
- parameter type TagType = logic,
- parameter type AuxType = logic,
- // Do not change
- localparam int unsigned WIDTH = fpnew_pkg::max_fp_width(FpFmtConfig),
- localparam int unsigned NUM_FORMATS = fpnew_pkg::NUM_FP_FORMATS
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [2:0][WIDTH-1:0] operands_i, // 3 operands
- input logic [NUM_FORMATS-1:0][2:0] is_boxed_i, // 3 operands
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input logic op_mod_i,
- input fpnew_pkg::fp_format_e src_fmt_i, // format of the multiplicands
- input fpnew_pkg::fp_format_e dst_fmt_i, // format of the addend and result
- input TagType tag_i,
- input AuxType aux_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [WIDTH-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output logic extension_bit_o,
- output TagType tag_o,
- output AuxType aux_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- // ----------
- // Constants
- // ----------
- // The super-format that can hold all formats
- localparam fpnew_pkg::fp_encoding_t SUPER_FORMAT = fpnew_pkg::super_format(FpFmtConfig);
-
- localparam int unsigned SUPER_EXP_BITS = SUPER_FORMAT.exp_bits;
- localparam int unsigned SUPER_MAN_BITS = SUPER_FORMAT.man_bits;
-
- // Precision bits 'p' include the implicit bit
- localparam int unsigned PRECISION_BITS = SUPER_MAN_BITS + 1;
- // The lower 2p+3 bits of the internal FMA result will be needed for leading-zero detection
- localparam int unsigned LOWER_SUM_WIDTH = 2 * PRECISION_BITS + 3;
- localparam int unsigned LZC_RESULT_WIDTH = $clog2(LOWER_SUM_WIDTH);
- // Internal exponent width of FMA must accomodate all meaningful exponent values in order to avoid
- // datapath leakage. This is either given by the exponent bits or the width of the LZC result.
- // In most reasonable FP formats the internal exponent will be wider than the LZC result.
- localparam int unsigned EXP_WIDTH = fpnew_pkg::maximum(SUPER_EXP_BITS + 2, LZC_RESULT_WIDTH);
- // Shift amount width: maximum internal mantissa size is 3p+3 bits
- localparam int unsigned SHIFT_AMOUNT_WIDTH = $clog2(3 * PRECISION_BITS + 3);
- // Pipelines
- localparam NUM_INP_REGS = PipeConfig == fpnew_pkg::BEFORE
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? ((NumPipeRegs + 1) / 3) // Second to get distributed regs
- : 0); // no regs here otherwise
- localparam NUM_MID_REGS = PipeConfig == fpnew_pkg::INSIDE
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? ((NumPipeRegs + 2) / 3) // First to get distributed regs
- : 0); // no regs here otherwise
- localparam NUM_OUT_REGS = PipeConfig == fpnew_pkg::AFTER
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? (NumPipeRegs / 3) // Last to get distributed regs
- : 0); // no regs here otherwise
-
- // ----------------
- // Type definition
- // ----------------
- typedef struct packed {
- logic sign;
- logic [SUPER_EXP_BITS-1:0] exponent;
- logic [SUPER_MAN_BITS-1:0] mantissa;
- } fp_t;
-
- // ---------------
- // Input pipeline
- // ---------------
- // Selected pipeline output signals as non-arrays
- logic [2:0][WIDTH-1:0] operands_q;
- fpnew_pkg::fp_format_e src_fmt_q;
- fpnew_pkg::fp_format_e dst_fmt_q;
-
- // Input pipeline signals, index i holds signal after i register stages
- logic [0:NUM_INP_REGS][2:0][WIDTH-1:0] inp_pipe_operands_q;
- logic [0:NUM_INP_REGS][NUM_FORMATS-1:0][2:0] inp_pipe_is_boxed_q;
- fpnew_pkg::roundmode_e [0:NUM_INP_REGS] inp_pipe_rnd_mode_q;
- fpnew_pkg::operation_e [0:NUM_INP_REGS] inp_pipe_op_q;
- logic [0:NUM_INP_REGS] inp_pipe_op_mod_q;
- fpnew_pkg::fp_format_e [0:NUM_INP_REGS] inp_pipe_src_fmt_q;
- fpnew_pkg::fp_format_e [0:NUM_INP_REGS] inp_pipe_dst_fmt_q;
- TagType [0:NUM_INP_REGS] inp_pipe_tag_q;
- AuxType [0:NUM_INP_REGS] inp_pipe_aux_q;
- logic [0:NUM_INP_REGS] inp_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_INP_REGS] inp_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign inp_pipe_operands_q[0] = operands_i;
- assign inp_pipe_is_boxed_q[0] = is_boxed_i;
- assign inp_pipe_rnd_mode_q[0] = rnd_mode_i;
- assign inp_pipe_op_q[0] = op_i;
- assign inp_pipe_op_mod_q[0] = op_mod_i;
- assign inp_pipe_src_fmt_q[0] = src_fmt_i;
- assign inp_pipe_dst_fmt_q[0] = dst_fmt_i;
- assign inp_pipe_tag_q[0] = tag_i;
- assign inp_pipe_aux_q[0] = aux_i;
- assign inp_pipe_valid_q[0] = in_valid_i;
- // Input stage: Propagate pipeline ready signal to updtream circuitry
- assign in_ready_o = inp_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_INP_REGS; i++) begin : gen_input_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign inp_pipe_ready[i] = inp_pipe_ready[i+1] | ~inp_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(inp_pipe_valid_q[i+1], inp_pipe_valid_q[i], inp_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(inp_pipe_operands_q[i+1], inp_pipe_operands_q[i], reg_ena, '0)
- `FFL(inp_pipe_is_boxed_q[i+1], inp_pipe_is_boxed_q[i], reg_ena, '0)
- `FFL(inp_pipe_rnd_mode_q[i+1], inp_pipe_rnd_mode_q[i], reg_ena, fpnew_pkg::RNE)
- `FFL(inp_pipe_op_q[i+1], inp_pipe_op_q[i], reg_ena, fpnew_pkg::FMADD)
- `FFL(inp_pipe_op_mod_q[i+1], inp_pipe_op_mod_q[i], reg_ena, '0)
- `FFL(inp_pipe_src_fmt_q[i+1], inp_pipe_src_fmt_q[i], reg_ena, fpnew_pkg::fp_format_e'(0))
- `FFL(inp_pipe_dst_fmt_q[i+1], inp_pipe_dst_fmt_q[i], reg_ena, fpnew_pkg::fp_format_e'(0))
- `FFL(inp_pipe_tag_q[i+1], inp_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(inp_pipe_aux_q[i+1], inp_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: assign selected pipe outputs to signals for later use
- assign operands_q = inp_pipe_operands_q[NUM_INP_REGS];
- assign src_fmt_q = inp_pipe_src_fmt_q[NUM_INP_REGS];
- assign dst_fmt_q = inp_pipe_dst_fmt_q[NUM_INP_REGS];
-
- // -----------------
- // Input processing
- // -----------------
- logic [NUM_FORMATS-1:0][2:0] fmt_sign;
- logic signed [NUM_FORMATS-1:0][2:0][SUPER_EXP_BITS-1:0] fmt_exponent;
- logic [NUM_FORMATS-1:0][2:0][SUPER_MAN_BITS-1:0] fmt_mantissa;
-
- fpnew_pkg::fp_info_t [NUM_FORMATS-1:0][2:0] info_q;
-
- // FP Input initialization
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : fmt_init_inputs
- // Set up some constants
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(fpnew_pkg::fp_format_e'(fmt));
-
- if (FpFmtConfig[fmt]) begin : active_format
- logic [2:0][FP_WIDTH-1:0] trimmed_ops;
-
- // Classify input
- fpnew_classifier #(
- .FpFormat ( fpnew_pkg::fp_format_e'(fmt) ),
- .NumOperands ( 3 )
- ) i_fpnew_classifier (
- .operands_i ( trimmed_ops ),
- .is_boxed_i ( inp_pipe_is_boxed_q[NUM_INP_REGS][fmt] ),
- .info_o ( info_q[fmt] )
- );
- for (genvar op = 0; op < 3; op++) begin : gen_operands
- assign trimmed_ops[op] = operands_q[op][FP_WIDTH-1:0];
- assign fmt_sign[fmt][op] = operands_q[op][FP_WIDTH-1];
- assign fmt_exponent[fmt][op] = signed'({1'b0, operands_q[op][MAN_BITS+:EXP_BITS]});
- assign fmt_mantissa[fmt][op] = {info_q[fmt][op].is_normal, operands_q[op][MAN_BITS-1:0]} <<
- (SUPER_MAN_BITS - MAN_BITS); // move to left of mantissa
- end
- end else begin : inactive_format
- assign info_q[fmt] = '{default: fpnew_pkg::DONT_CARE}; // format disabled
- assign fmt_sign[fmt] = fpnew_pkg::DONT_CARE; // format disabled
- assign fmt_exponent[fmt] = '{default: fpnew_pkg::DONT_CARE}; // format disabled
- assign fmt_mantissa[fmt] = '{default: fpnew_pkg::DONT_CARE}; // format disabled
- end
- end
-
- fp_t operand_a, operand_b, operand_c;
- fpnew_pkg::fp_info_t info_a, info_b, info_c;
-
- // Operation selection and operand adjustment
- // | \c op_q | \c op_mod_q | Operation Adjustment
- // |:--------:|:-----------:|---------------------
- // | FMADD | \c 0 | FMADD: none
- // | FMADD | \c 1 | FMSUB: Invert sign of operand C
- // | FNMSUB | \c 0 | FNMSUB: Invert sign of operand A
- // | FNMSUB | \c 1 | FNMADD: Invert sign of operands A and C
- // | ADD | \c 0 | ADD: Set operand A to +1.0
- // | ADD | \c 1 | SUB: Set operand A to +1.0, invert sign of operand C
- // | MUL | \c 0 | MUL: Set operand C to +0.0
- // | *others* | \c - | *invalid*
- // \note \c op_mod_q always inverts the sign of the addend.
- always_comb begin : op_select
-
- // Default assignments - packing-order-agnostic
- operand_a = {fmt_sign[src_fmt_q][0], fmt_exponent[src_fmt_q][0], fmt_mantissa[src_fmt_q][0]};
- operand_b = {fmt_sign[src_fmt_q][1], fmt_exponent[src_fmt_q][1], fmt_mantissa[src_fmt_q][1]};
- operand_c = {fmt_sign[dst_fmt_q][2], fmt_exponent[dst_fmt_q][2], fmt_mantissa[dst_fmt_q][2]};
- info_a = info_q[src_fmt_q][0];
- info_b = info_q[src_fmt_q][1];
- info_c = info_q[dst_fmt_q][2];
-
- // op_mod_q inverts sign of operand C
- operand_c.sign = operand_c.sign ^ inp_pipe_op_mod_q[NUM_INP_REGS];
-
- unique case (inp_pipe_op_q[NUM_INP_REGS])
- fpnew_pkg::FMADD: ; // do nothing
- fpnew_pkg::FNMSUB: operand_a.sign = ~operand_a.sign; // invert sign of product
- fpnew_pkg::ADD: begin // Set multiplicand to +1
- operand_a = '{sign: 1'b0, exponent: fpnew_pkg::bias(src_fmt_q), mantissa: '0};
- info_a = '{is_normal: 1'b1, is_boxed: 1'b1, default: 1'b0}; //normal, boxed value.
- end
- fpnew_pkg::MUL: begin // Set addend to -0 (for proper rounding with RDN)
- operand_c = '{sign: 1'b1, exponent: '0, mantissa: '0};
- info_c = '{is_zero: 1'b1, is_boxed: 1'b1, default: 1'b0}; //zero, boxed value.
- end
- default: begin // propagate don't cares
- operand_a = '{default: fpnew_pkg::DONT_CARE};
- operand_b = '{default: fpnew_pkg::DONT_CARE};
- operand_c = '{default: fpnew_pkg::DONT_CARE};
- info_a = '{default: fpnew_pkg::DONT_CARE};
- info_b = '{default: fpnew_pkg::DONT_CARE};
- info_c = '{default: fpnew_pkg::DONT_CARE};
- end
- endcase
- end
-
- // ---------------------
- // Input classification
- // ---------------------
- logic any_operand_inf;
- logic any_operand_nan;
- logic signalling_nan;
- logic effective_subtraction;
- logic tentative_sign;
-
- // Reduction for special case handling
- assign any_operand_inf = (| {info_a.is_inf, info_b.is_inf, info_c.is_inf});
- assign any_operand_nan = (| {info_a.is_nan, info_b.is_nan, info_c.is_nan});
- assign signalling_nan = (| {info_a.is_signalling, info_b.is_signalling, info_c.is_signalling});
- // Effective subtraction in FMA occurs when product and addend signs differ
- assign effective_subtraction = operand_a.sign ^ operand_b.sign ^ operand_c.sign;
- // The tentative sign of the FMA shall be the sign of the product
- assign tentative_sign = operand_a.sign ^ operand_b.sign;
-
- // ----------------------
- // Special case handling
- // ----------------------
- logic [WIDTH-1:0] special_result;
- fpnew_pkg::status_t special_status;
- logic result_is_special;
-
- logic [NUM_FORMATS-1:0][WIDTH-1:0] fmt_special_result;
- fpnew_pkg::status_t [NUM_FORMATS-1:0] fmt_special_status;
- logic [NUM_FORMATS-1:0] fmt_result_is_special;
-
-
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : gen_special_results
- // Set up some constants
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(fpnew_pkg::fp_format_e'(fmt));
-
- localparam logic [EXP_BITS-1:0] QNAN_EXPONENT = '1;
- localparam logic [MAN_BITS-1:0] QNAN_MANTISSA = 2**(MAN_BITS-1);
- localparam logic [MAN_BITS-1:0] ZERO_MANTISSA = '0;
-
- if (FpFmtConfig[fmt]) begin : active_format
- always_comb begin : special_results
- logic [FP_WIDTH-1:0] special_res;
-
- // Default assignment
- special_res = {1'b0, QNAN_EXPONENT, QNAN_MANTISSA}; // qNaN
- fmt_special_status[fmt] = '0;
- fmt_result_is_special[fmt] = 1'b0;
-
- // Handle potentially mixed nan & infinity input => important for the case where infinity and
- // zero are multiplied and added to a qnan.
- // RISC-V mandates raising the NV exception in these cases:
- // (inf * 0) + c or (0 * inf) + c INVALID, no matter c (even quiet NaNs)
- if ((info_a.is_inf && info_b.is_zero) || (info_a.is_zero && info_b.is_inf)) begin
- fmt_result_is_special[fmt] = 1'b1; // bypass FMA, output is the canonical qNaN
- fmt_special_status[fmt].NV = 1'b1; // invalid operation
- // NaN Inputs cause canonical quiet NaN at the output and maybe invalid OP
- end else if (any_operand_nan) begin
- fmt_result_is_special[fmt] = 1'b1; // bypass FMA, output is the canonical qNaN
- fmt_special_status[fmt].NV = signalling_nan; // raise the invalid operation flag if signalling
- // Special cases involving infinity
- end else if (any_operand_inf) begin
- fmt_result_is_special[fmt] = 1'b1; // bypass FMA
- // Effective addition of opposite infinities (±inf - ±inf) is invalid!
- if ((info_a.is_inf || info_b.is_inf) && info_c.is_inf && effective_subtraction)
- fmt_special_status[fmt].NV = 1'b1; // invalid operation
- // Handle cases where output will be inf because of inf product input
- else if (info_a.is_inf || info_b.is_inf) begin
- // Result is infinity with the sign of the product
- special_res = {operand_a.sign ^ operand_b.sign, QNAN_EXPONENT, ZERO_MANTISSA};
- // Handle cases where the addend is inf
- end else if (info_c.is_inf) begin
- // Result is inifinity with sign of the addend (= operand_c)
- special_res = {operand_c.sign, QNAN_EXPONENT, ZERO_MANTISSA};
- end
- end
- // Initialize special result with ones (NaN-box)
- fmt_special_result[fmt] = '1;
- fmt_special_result[fmt][FP_WIDTH-1:0] = special_res;
- end
- end else begin : inactive_format
- assign fmt_special_result[fmt] = '{default: fpnew_pkg::DONT_CARE};
- assign fmt_special_status[fmt] = '0;
- assign fmt_result_is_special[fmt] = 1'b0;
- end
- end
-
- // Detect special case from source format, I2F casts don't produce a special result
- assign result_is_special = fmt_result_is_special[dst_fmt_q]; // they're all the same
- // Signalling input NaNs raise invalid flag, otherwise no flags set
- assign special_status = fmt_special_status[dst_fmt_q];
- // Assemble result according to destination format
- assign special_result = fmt_special_result[dst_fmt_q]; // destination format
-
- // ---------------------------
- // Initial exponent data path
- // ---------------------------
- logic signed [EXP_WIDTH-1:0] exponent_a, exponent_b, exponent_c;
- logic signed [EXP_WIDTH-1:0] exponent_addend, exponent_product, exponent_difference;
- logic signed [EXP_WIDTH-1:0] tentative_exponent;
-
- // Zero-extend exponents into signed container - implicit width extension
- assign exponent_a = signed'({1'b0, operand_a.exponent});
- assign exponent_b = signed'({1'b0, operand_b.exponent});
- assign exponent_c = signed'({1'b0, operand_c.exponent});
-
- // Calculate internal exponents from encoded values. Real exponents are (ex = Ex - bias + 1 - nx)
- // with Ex the encoded exponent and nx the implicit bit. Internal exponents are biased to dst fmt.
- assign exponent_addend = signed'(exponent_c + $signed({1'b0, ~info_c.is_normal})); // 0 as subnorm
- // Biased product exponent is the sum of encoded exponents minus the bias.
- assign exponent_product = (info_a.is_zero || info_b.is_zero) // in case the product is zero, set minimum exp.
- ? 2 - signed'(fpnew_pkg::bias(dst_fmt_q))
- : signed'(exponent_a + info_a.is_subnormal
- + exponent_b + info_b.is_subnormal
- - 2*signed'(fpnew_pkg::bias(src_fmt_q))
- + signed'(fpnew_pkg::bias(dst_fmt_q))); // rebias for dst fmt
- // Exponent difference is the addend exponent minus the product exponent
- assign exponent_difference = exponent_addend - exponent_product;
- // The tentative exponent will be the larger of the product or addend exponent
- assign tentative_exponent = (exponent_difference > 0) ? exponent_addend : exponent_product;
-
- // Shift amount for addend based on exponents (unsigned as only right shifts)
- logic [SHIFT_AMOUNT_WIDTH-1:0] addend_shamt;
-
- always_comb begin : addend_shift_amount
- // Product-anchored case, saturated shift (addend is only in the sticky bit)
- if (exponent_difference <= signed'(-2 * PRECISION_BITS - 1))
- addend_shamt = 3 * PRECISION_BITS + 4;
- // Addend and product will have mutual bits to add
- else if (exponent_difference <= signed'(PRECISION_BITS + 2))
- addend_shamt = unsigned'(signed'(PRECISION_BITS) + 3 - exponent_difference);
- // Addend-anchored case, saturated shift (product is only in the sticky bit)
- else
- addend_shamt = 0;
- end
-
- // ------------------
- // Product data path
- // ------------------
- logic [PRECISION_BITS-1:0] mantissa_a, mantissa_b, mantissa_c;
- logic [2*PRECISION_BITS-1:0] product; // the p*p product is 2p bits wide
- logic [3*PRECISION_BITS+3:0] product_shifted; // addends are 3p+4 bit wide (including G/R)
-
- // Add implicit bits to mantissae
- assign mantissa_a = {info_a.is_normal, operand_a.mantissa};
- assign mantissa_b = {info_b.is_normal, operand_b.mantissa};
- assign mantissa_c = {info_c.is_normal, operand_c.mantissa};
-
- // Mantissa multiplier (a*b)
- assign product = mantissa_a * mantissa_b;
-
- // Product is placed into a 3p+4 bit wide vector, padded with 2 bits for round and sticky:
- // | 000...000 | product | RS |
- // <- p+2 -> <- 2p -> < 2>
- assign product_shifted = product << 2; // constant shift
-
- // -----------------
- // Addend data path
- // -----------------
- logic [3*PRECISION_BITS+3:0] addend_after_shift; // upper 3p+4 bits are needed to go on
- logic [PRECISION_BITS-1:0] addend_sticky_bits; // up to p bit of shifted addend are sticky
- logic sticky_before_add; // they are compressed into a single sticky bit
- logic [3*PRECISION_BITS+3:0] addend_shifted; // addends are 3p+4 bit wide (including G/R)
- logic inject_carry_in; // inject carry for subtractions if needed
-
- // In parallel, the addend is right-shifted according to the exponent difference. Up to p bits are
- // shifted out and compressed into a sticky bit.
- // BEFORE THE SHIFT:
- // | mantissa_c | 000..000 |
- // <- p -> <- 3p+4 ->
- // AFTER THE SHIFT:
- // | 000..........000 | mantissa_c | 000...............0GR | sticky bits |
- // <- addend_shamt -> <- p -> <- 2p+4-addend_shamt -> <- up to p ->
- assign {addend_after_shift, addend_sticky_bits} =
- (mantissa_c << (3 * PRECISION_BITS + 4)) >> addend_shamt;
-
- assign sticky_before_add = (| addend_sticky_bits);
-
- // In case of a subtraction, the addend is inverted
- assign addend_shifted = (effective_subtraction) ? ~addend_after_shift : addend_after_shift;
- assign inject_carry_in = effective_subtraction & ~sticky_before_add;
-
- // ------
- // Adder
- // ------
- logic [3*PRECISION_BITS+4:0] sum_raw; // added one bit for the carry
- logic sum_carry; // observe carry bit from sum for sign fixing
- logic [3*PRECISION_BITS+3:0] sum; // discard carry as sum won't overflow
- logic final_sign;
-
- //Mantissa adder (ab+c). In normal addition, it cannot overflow.
- assign sum_raw = product_shifted + addend_shifted + inject_carry_in;
- assign sum_carry = sum_raw[3*PRECISION_BITS+4];
-
- // Complement negative sum (can only happen in subtraction -> overflows for positive results)
- assign sum = (effective_subtraction && ~sum_carry) ? -sum_raw : sum_raw;
-
- // In case of a mispredicted subtraction result, do a sign flip
- assign final_sign = (effective_subtraction && (sum_carry == tentative_sign))
- ? 1'b1
- : (effective_subtraction ? 1'b0 : tentative_sign);
-
- // ---------------
- // Internal pipeline
- // ---------------
- // Pipeline output signals as non-arrays
- logic effective_subtraction_q;
- logic signed [EXP_WIDTH-1:0] exponent_product_q;
- logic signed [EXP_WIDTH-1:0] exponent_difference_q;
- logic signed [EXP_WIDTH-1:0] tentative_exponent_q;
- logic [SHIFT_AMOUNT_WIDTH-1:0] addend_shamt_q;
- logic sticky_before_add_q;
- logic [3*PRECISION_BITS+3:0] sum_q;
- logic final_sign_q;
- fpnew_pkg::fp_format_e dst_fmt_q2;
- fpnew_pkg::roundmode_e rnd_mode_q;
- logic result_is_special_q;
- fp_t special_result_q;
- fpnew_pkg::status_t special_status_q;
- // Internal pipeline signals, index i holds signal after i register stages
- logic [0:NUM_MID_REGS] mid_pipe_eff_sub_q;
- logic signed [0:NUM_MID_REGS][EXP_WIDTH-1:0] mid_pipe_exp_prod_q;
- logic signed [0:NUM_MID_REGS][EXP_WIDTH-1:0] mid_pipe_exp_diff_q;
- logic signed [0:NUM_MID_REGS][EXP_WIDTH-1:0] mid_pipe_tent_exp_q;
- logic [0:NUM_MID_REGS][SHIFT_AMOUNT_WIDTH-1:0] mid_pipe_add_shamt_q;
- logic [0:NUM_MID_REGS] mid_pipe_sticky_q;
- logic [0:NUM_MID_REGS][3*PRECISION_BITS+3:0] mid_pipe_sum_q;
- logic [0:NUM_MID_REGS] mid_pipe_final_sign_q;
- fpnew_pkg::roundmode_e [0:NUM_MID_REGS] mid_pipe_rnd_mode_q;
- fpnew_pkg::fp_format_e [0:NUM_MID_REGS] mid_pipe_dst_fmt_q;
- logic [0:NUM_MID_REGS] mid_pipe_res_is_spec_q;
- fp_t [0:NUM_MID_REGS] mid_pipe_spec_res_q;
- fpnew_pkg::status_t [0:NUM_MID_REGS] mid_pipe_spec_stat_q;
- TagType [0:NUM_MID_REGS] mid_pipe_tag_q;
- AuxType [0:NUM_MID_REGS] mid_pipe_aux_q;
- logic [0:NUM_MID_REGS] mid_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_MID_REGS] mid_pipe_ready;
-
- // Input stage: First element of pipeline is taken from upstream logic
- assign mid_pipe_eff_sub_q[0] = effective_subtraction;
- assign mid_pipe_exp_prod_q[0] = exponent_product;
- assign mid_pipe_exp_diff_q[0] = exponent_difference;
- assign mid_pipe_tent_exp_q[0] = tentative_exponent;
- assign mid_pipe_add_shamt_q[0] = addend_shamt;
- assign mid_pipe_sticky_q[0] = sticky_before_add;
- assign mid_pipe_sum_q[0] = sum;
- assign mid_pipe_final_sign_q[0] = final_sign;
- assign mid_pipe_rnd_mode_q[0] = inp_pipe_rnd_mode_q[NUM_INP_REGS];
- assign mid_pipe_dst_fmt_q[0] = dst_fmt_q;
- assign mid_pipe_res_is_spec_q[0] = result_is_special;
- assign mid_pipe_spec_res_q[0] = special_result;
- assign mid_pipe_spec_stat_q[0] = special_status;
- assign mid_pipe_tag_q[0] = inp_pipe_tag_q[NUM_INP_REGS];
- assign mid_pipe_aux_q[0] = inp_pipe_aux_q[NUM_INP_REGS];
- assign mid_pipe_valid_q[0] = inp_pipe_valid_q[NUM_INP_REGS];
- // Input stage: Propagate pipeline ready signal to input pipe
- assign inp_pipe_ready[NUM_INP_REGS] = mid_pipe_ready[0];
-
- // Generate the register stages
- for (genvar i = 0; i < NUM_MID_REGS; i++) begin : gen_inside_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign mid_pipe_ready[i] = mid_pipe_ready[i+1] | ~mid_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(mid_pipe_valid_q[i+1], mid_pipe_valid_q[i], mid_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = mid_pipe_ready[i] & mid_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(mid_pipe_eff_sub_q[i+1], mid_pipe_eff_sub_q[i], reg_ena, '0)
- `FFL(mid_pipe_exp_prod_q[i+1], mid_pipe_exp_prod_q[i], reg_ena, '0)
- `FFL(mid_pipe_exp_diff_q[i+1], mid_pipe_exp_diff_q[i], reg_ena, '0)
- `FFL(mid_pipe_tent_exp_q[i+1], mid_pipe_tent_exp_q[i], reg_ena, '0)
- `FFL(mid_pipe_add_shamt_q[i+1], mid_pipe_add_shamt_q[i], reg_ena, '0)
- `FFL(mid_pipe_sticky_q[i+1], mid_pipe_sticky_q[i], reg_ena, '0)
- `FFL(mid_pipe_sum_q[i+1], mid_pipe_sum_q[i], reg_ena, '0)
- `FFL(mid_pipe_final_sign_q[i+1], mid_pipe_final_sign_q[i], reg_ena, '0)
- `FFL(mid_pipe_rnd_mode_q[i+1], mid_pipe_rnd_mode_q[i], reg_ena, fpnew_pkg::RNE)
- `FFL(mid_pipe_dst_fmt_q[i+1], mid_pipe_dst_fmt_q[i], reg_ena, fpnew_pkg::fp_format_e'(0))
- `FFL(mid_pipe_res_is_spec_q[i+1], mid_pipe_res_is_spec_q[i], reg_ena, '0)
- `FFL(mid_pipe_spec_res_q[i+1], mid_pipe_spec_res_q[i], reg_ena, '0)
- `FFL(mid_pipe_spec_stat_q[i+1], mid_pipe_spec_stat_q[i], reg_ena, '0)
- `FFL(mid_pipe_tag_q[i+1], mid_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(mid_pipe_aux_q[i+1], mid_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: assign selected pipe outputs to signals for later use
- assign effective_subtraction_q = mid_pipe_eff_sub_q[NUM_MID_REGS];
- assign exponent_product_q = mid_pipe_exp_prod_q[NUM_MID_REGS];
- assign exponent_difference_q = mid_pipe_exp_diff_q[NUM_MID_REGS];
- assign tentative_exponent_q = mid_pipe_tent_exp_q[NUM_MID_REGS];
- assign addend_shamt_q = mid_pipe_add_shamt_q[NUM_MID_REGS];
- assign sticky_before_add_q = mid_pipe_sticky_q[NUM_MID_REGS];
- assign sum_q = mid_pipe_sum_q[NUM_MID_REGS];
- assign final_sign_q = mid_pipe_final_sign_q[NUM_MID_REGS];
- assign rnd_mode_q = mid_pipe_rnd_mode_q[NUM_MID_REGS];
- assign dst_fmt_q2 = mid_pipe_dst_fmt_q[NUM_MID_REGS];
- assign result_is_special_q = mid_pipe_res_is_spec_q[NUM_MID_REGS];
- assign special_result_q = mid_pipe_spec_res_q[NUM_MID_REGS];
- assign special_status_q = mid_pipe_spec_stat_q[NUM_MID_REGS];
-
- // --------------
- // Normalization
- // --------------
- logic [LOWER_SUM_WIDTH-1:0] sum_lower; // lower 2p+3 bits of sum are searched
- logic [LZC_RESULT_WIDTH-1:0] leading_zero_count; // the number of leading zeroes
- logic signed [LZC_RESULT_WIDTH:0] leading_zero_count_sgn; // signed leading-zero count
- logic lzc_zeroes; // in case only zeroes found
-
- logic [SHIFT_AMOUNT_WIDTH-1:0] norm_shamt; // Normalization shift amount
- logic signed [EXP_WIDTH-1:0] normalized_exponent;
-
- logic [3*PRECISION_BITS+4:0] sum_shifted; // result after first normalization shift
- logic [PRECISION_BITS:0] final_mantissa; // final mantissa before rounding with round bit
- logic [2*PRECISION_BITS+2:0] sum_sticky_bits; // remaining 2p+3 sticky bits after normalization
- logic sticky_after_norm; // sticky bit after normalization
-
- logic signed [EXP_WIDTH-1:0] final_exponent;
-
- assign sum_lower = sum_q[LOWER_SUM_WIDTH-1:0];
-
- // Leading zero counter for cancellations
- lzc #(
- .WIDTH ( LOWER_SUM_WIDTH ),
- .MODE ( 1 ) // MODE = 1 counts leading zeroes
- ) i_lzc (
- .in_i ( sum_lower ),
- .cnt_o ( leading_zero_count ),
- .empty_o ( lzc_zeroes )
- );
-
- assign leading_zero_count_sgn = signed'({1'b0, leading_zero_count});
-
- // Normalization shift amount based on exponents and LZC (unsigned as only left shifts)
- always_comb begin : norm_shift_amount
- // Product-anchored case or cancellations require LZC
- if ((exponent_difference_q <= 0) || (effective_subtraction_q && (exponent_difference_q <= 2))) begin
- // Normal result (biased exponent > 0 and not a zero)
- if ((exponent_product_q - leading_zero_count_sgn + 1 >= 0) && !lzc_zeroes) begin
- // Undo initial product shift, remove the counted zeroes
- norm_shamt = PRECISION_BITS + 2 + leading_zero_count;
- normalized_exponent = exponent_product_q - leading_zero_count_sgn + 1; // account for shift
- // Subnormal result
- end else begin
- // Cap the shift distance to align mantissa with minimum exponent
- norm_shamt = unsigned'(signed'(PRECISION_BITS + 2 + exponent_product_q));
- normalized_exponent = 0; // subnormals encoded as 0
- end
- // Addend-anchored case
- end else begin
- norm_shamt = addend_shamt_q; // Undo the initial shift
- normalized_exponent = tentative_exponent_q;
- end
- end
-
- // Do the large normalization shift
- assign sum_shifted = sum_q << norm_shamt;
-
- // The addend-anchored case needs a 1-bit normalization since the leading-one can be to the left
- // or right of the (non-carry) MSB of the sum.
- always_comb begin : small_norm
- // Default assignment, discarding carry bit
- {final_mantissa, sum_sticky_bits} = sum_shifted;
- final_exponent = normalized_exponent;
-
- // The normalized sum has overflown, align right and fix exponent
- if (sum_shifted[3*PRECISION_BITS+4]) begin // check the carry bit
- {final_mantissa, sum_sticky_bits} = sum_shifted >> 1;
- final_exponent = normalized_exponent + 1;
- // The normalized sum is normal, nothing to do
- end else if (sum_shifted[3*PRECISION_BITS+3]) begin // check the sum MSB
- // do nothing
- // The normalized sum is still denormal, align left - unless the result is not already subnormal
- end else if (normalized_exponent > 1) begin
- {final_mantissa, sum_sticky_bits} = sum_shifted << 1;
- final_exponent = normalized_exponent - 1;
- // Otherwise we're denormal
- end else begin
- final_exponent = '0;
- end
- end
-
- // Update the sticky bit with the shifted-out bits
- assign sticky_after_norm = (| {sum_sticky_bits}) | sticky_before_add_q;
-
- // ----------------------------
- // Rounding and classification
- // ----------------------------
- logic pre_round_sign;
- logic [SUPER_EXP_BITS+SUPER_MAN_BITS-1:0] pre_round_abs; // absolute value of result before rounding
- logic [1:0] round_sticky_bits;
-
- logic of_before_round, of_after_round; // overflow
- logic uf_before_round, uf_after_round; // underflow
-
- logic [NUM_FORMATS-1:0][SUPER_EXP_BITS+SUPER_MAN_BITS-1:0] fmt_pre_round_abs; // per format
- logic [NUM_FORMATS-1:0][1:0] fmt_round_sticky_bits;
-
- logic [NUM_FORMATS-1:0] fmt_of_after_round;
- logic [NUM_FORMATS-1:0] fmt_uf_after_round;
-
- logic rounded_sign;
- logic [SUPER_EXP_BITS+SUPER_MAN_BITS-1:0] rounded_abs; // absolute value of result after rounding
- logic result_zero;
-
- // Classification before round. RISC-V mandates checking underflow AFTER rounding!
- assign of_before_round = final_exponent >= 2**(fpnew_pkg::exp_bits(dst_fmt_q2))-1; // infinity exponent is all ones
- assign uf_before_round = final_exponent == 0; // exponent for subnormals capped to 0
-
- // Pack exponent and mantissa into proper rounding form
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : gen_res_assemble
- // Set up some constants
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(fpnew_pkg::fp_format_e'(fmt));
-
- logic [EXP_BITS-1:0] pre_round_exponent;
- logic [MAN_BITS-1:0] pre_round_mantissa;
-
- if (FpFmtConfig[fmt]) begin : active_format
-
- assign pre_round_exponent = (of_before_round) ? 2**EXP_BITS-2 : final_exponent[EXP_BITS-1:0];
- assign pre_round_mantissa = (of_before_round) ? '1 : final_mantissa[SUPER_MAN_BITS-:MAN_BITS];
- // Assemble result before rounding. In case of overflow, the largest normal value is set.
- assign fmt_pre_round_abs[fmt] = {pre_round_exponent, pre_round_mantissa}; // 0-extend
-
- // Round bit is after mantissa (1 in case of overflow for rounding)
- assign fmt_round_sticky_bits[fmt][1] = final_mantissa[SUPER_MAN_BITS-MAN_BITS] |
- of_before_round;
-
- // remaining bits in mantissa to sticky (1 in case of overflow for rounding)
- if (MAN_BITS < SUPER_MAN_BITS) begin : narrow_sticky
- assign fmt_round_sticky_bits[fmt][0] = (| final_mantissa[SUPER_MAN_BITS-MAN_BITS-1:0]) |
- sticky_after_norm | of_before_round;
- end else begin : normal_sticky
- assign fmt_round_sticky_bits[fmt][0] = sticky_after_norm | of_before_round;
- end
- end else begin : inactive_format
- assign fmt_pre_round_abs[fmt] = '{default: fpnew_pkg::DONT_CARE};
- assign fmt_round_sticky_bits[fmt] = '{default: fpnew_pkg::DONT_CARE};
- end
- end
-
- // Assemble result before rounding. In case of overflow, the largest normal value is set.
- assign pre_round_sign = final_sign_q;
- assign pre_round_abs = fmt_pre_round_abs[dst_fmt_q2];
-
- // In case of overflow, the round and sticky bits are set for proper rounding
- assign round_sticky_bits = fmt_round_sticky_bits[dst_fmt_q2];
-
- // Perform the rounding
- fpnew_rounding #(
- .AbsWidth ( SUPER_EXP_BITS + SUPER_MAN_BITS )
- ) i_fpnew_rounding (
- .abs_value_i ( pre_round_abs ),
- .sign_i ( pre_round_sign ),
- .round_sticky_bits_i ( round_sticky_bits ),
- .rnd_mode_i ( rnd_mode_q ),
- .effective_subtraction_i ( effective_subtraction_q ),
- .abs_rounded_o ( rounded_abs ),
- .sign_o ( rounded_sign ),
- .exact_zero_o ( result_zero )
- );
-
- logic [NUM_FORMATS-1:0][WIDTH-1:0] fmt_result;
-
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : gen_sign_inject
- // Set up some constants
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(fpnew_pkg::fp_format_e'(fmt));
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(fpnew_pkg::fp_format_e'(fmt));
-
- if (FpFmtConfig[fmt]) begin : active_format
- always_comb begin : post_process
- // detect of / uf
- fmt_uf_after_round[fmt] = rounded_abs[EXP_BITS+MAN_BITS-1:MAN_BITS] == '0; // denormal
- fmt_of_after_round[fmt] = rounded_abs[EXP_BITS+MAN_BITS-1:MAN_BITS] == '1; // inf exp.
-
- // Assemble regular result, nan box short ones.
- fmt_result[fmt] = '1;
- fmt_result[fmt][FP_WIDTH-1:0] = {rounded_sign, rounded_abs[EXP_BITS+MAN_BITS-1:0]};
- end
- end else begin : inactive_format
- assign fmt_uf_after_round[fmt] = fpnew_pkg::DONT_CARE;
- assign fmt_of_after_round[fmt] = fpnew_pkg::DONT_CARE;
- assign fmt_result[fmt] = '{default: fpnew_pkg::DONT_CARE};
- end
- end
-
- // Classification after rounding select by destination format
- assign uf_after_round = fmt_uf_after_round[dst_fmt_q2];
- assign of_after_round = fmt_of_after_round[dst_fmt_q2];
-
-
- // -----------------
- // Result selection
- // -----------------
- logic [WIDTH-1:0] regular_result;
- fpnew_pkg::status_t regular_status;
-
- // Assemble regular result
- assign regular_result = fmt_result[dst_fmt_q2];
- assign regular_status.NV = 1'b0; // only valid cases are handled in regular path
- assign regular_status.DZ = 1'b0; // no divisions
- assign regular_status.OF = of_before_round | of_after_round; // rounding can introduce overflow
- assign regular_status.UF = uf_after_round & regular_status.NX; // only inexact results raise UF
- assign regular_status.NX = (| round_sticky_bits) | of_before_round | of_after_round;
-
- // Final results for output pipeline
- logic [WIDTH-1:0] result_d;
- fpnew_pkg::status_t status_d;
-
- // Select output depending on special case detection
- assign result_d = result_is_special_q ? special_result_q : regular_result;
- assign status_d = result_is_special_q ? special_status_q : regular_status;
-
- // ----------------
- // Output Pipeline
- // ----------------
- // Output pipeline signals, index i holds signal after i register stages
- logic [0:NUM_OUT_REGS][WIDTH-1:0] out_pipe_result_q;
- fpnew_pkg::status_t [0:NUM_OUT_REGS] out_pipe_status_q;
- TagType [0:NUM_OUT_REGS] out_pipe_tag_q;
- AuxType [0:NUM_OUT_REGS] out_pipe_aux_q;
- logic [0:NUM_OUT_REGS] out_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_OUT_REGS] out_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign out_pipe_result_q[0] = result_d;
- assign out_pipe_status_q[0] = status_d;
- assign out_pipe_tag_q[0] = mid_pipe_tag_q[NUM_MID_REGS];
- assign out_pipe_aux_q[0] = mid_pipe_aux_q[NUM_MID_REGS];
- assign out_pipe_valid_q[0] = mid_pipe_valid_q[NUM_MID_REGS];
- // Input stage: Propagate pipeline ready signal to inside pipe
- assign mid_pipe_ready[NUM_MID_REGS] = out_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_OUT_REGS; i++) begin : gen_output_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign out_pipe_ready[i] = out_pipe_ready[i+1] | ~out_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(out_pipe_valid_q[i+1], out_pipe_valid_q[i], out_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(out_pipe_result_q[i+1], out_pipe_result_q[i], reg_ena, '0)
- `FFL(out_pipe_status_q[i+1], out_pipe_status_q[i], reg_ena, '0)
- `FFL(out_pipe_tag_q[i+1], out_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(out_pipe_aux_q[i+1], out_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: Ready travels backwards from output side, driven by downstream circuitry
- assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
- // Output stage: assign module outputs
- assign result_o = out_pipe_result_q[NUM_OUT_REGS];
- assign status_o = out_pipe_status_q[NUM_OUT_REGS];
- assign extension_bit_o = 1'b1; // always NaN-Box result
- assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
- assign aux_o = out_pipe_aux_q[NUM_OUT_REGS];
- assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
- assign busy_o = (| {inp_pipe_valid_q, mid_pipe_valid_q, out_pipe_valid_q});
-endmodule
diff --git a/verilog/rtl/fpnew_noncomp.sv b/verilog/rtl/fpnew_noncomp.sv
deleted file mode 100644
index 0719c26..0000000
--- a/verilog/rtl/fpnew_noncomp.sv
+++ /dev/null
@@ -1,403 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-`include "registers.svh"
-module fpnew_noncomp #(
- parameter fpnew_pkg::fp_format_e FpFormat = fpnew_pkg::fp_format_e'(0),
- parameter int unsigned NumPipeRegs = 0,
- parameter fpnew_pkg::pipe_config_t PipeConfig = fpnew_pkg::BEFORE,
- parameter type TagType = logic,
- parameter type AuxType = logic,
-
- localparam int unsigned WIDTH = fpnew_pkg::fp_width(FpFormat) // do not change
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [1:0][WIDTH-1:0] operands_i, // 2 operands
- input logic [1:0] is_boxed_i, // 2 operands
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input logic op_mod_i,
- input TagType tag_i,
- input AuxType aux_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [WIDTH-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output logic extension_bit_o,
- output fpnew_pkg::classmask_e class_mask_o,
- output logic is_class_o,
- output TagType tag_o,
- output AuxType aux_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- // ----------
- // Constants
- // ----------
- localparam int unsigned EXP_BITS = fpnew_pkg::exp_bits(FpFormat);
- localparam int unsigned MAN_BITS = fpnew_pkg::man_bits(FpFormat);
- // Pipelines
- localparam NUM_INP_REGS = (PipeConfig == fpnew_pkg::BEFORE || PipeConfig == fpnew_pkg::INSIDE)
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? ((NumPipeRegs + 1) / 2) // First to get distributed regs
- : 0); // no regs here otherwise
- localparam NUM_OUT_REGS = PipeConfig == fpnew_pkg::AFTER
- ? NumPipeRegs
- : (PipeConfig == fpnew_pkg::DISTRIBUTED
- ? (NumPipeRegs / 2) // Last to get distributed regs
- : 0); // no regs here otherwise
-
- // ----------------
- // Type definition
- // ----------------
- typedef struct packed {
- logic sign;
- logic [EXP_BITS-1:0] exponent;
- logic [MAN_BITS-1:0] mantissa;
- } fp_t;
-
- // ---------------
- // Input pipeline
- // ---------------
- // Input pipeline signals, index i holds signal after i register stages
- logic [0:NUM_INP_REGS][1:0][WIDTH-1:0] inp_pipe_operands_q;
- logic [0:NUM_INP_REGS][1:0] inp_pipe_is_boxed_q;
- fpnew_pkg::roundmode_e [0:NUM_INP_REGS] inp_pipe_rnd_mode_q;
- fpnew_pkg::operation_e [0:NUM_INP_REGS] inp_pipe_op_q;
- logic [0:NUM_INP_REGS] inp_pipe_op_mod_q;
- TagType [0:NUM_INP_REGS] inp_pipe_tag_q;
- AuxType [0:NUM_INP_REGS] inp_pipe_aux_q;
- logic [0:NUM_INP_REGS] inp_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_INP_REGS] inp_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign inp_pipe_operands_q[0] = operands_i;
- assign inp_pipe_is_boxed_q[0] = is_boxed_i;
- assign inp_pipe_rnd_mode_q[0] = rnd_mode_i;
- assign inp_pipe_op_q[0] = op_i;
- assign inp_pipe_op_mod_q[0] = op_mod_i;
- assign inp_pipe_tag_q[0] = tag_i;
- assign inp_pipe_aux_q[0] = aux_i;
- assign inp_pipe_valid_q[0] = in_valid_i;
- // Input stage: Propagate pipeline ready signal to updtream circuitry
- assign in_ready_o = inp_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_INP_REGS; i++) begin : gen_input_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign inp_pipe_ready[i] = inp_pipe_ready[i+1] | ~inp_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(inp_pipe_valid_q[i+1], inp_pipe_valid_q[i], inp_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = inp_pipe_ready[i] & inp_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(inp_pipe_operands_q[i+1], inp_pipe_operands_q[i], reg_ena, '0)
- `FFL(inp_pipe_is_boxed_q[i+1], inp_pipe_is_boxed_q[i], reg_ena, '0)
- `FFL(inp_pipe_rnd_mode_q[i+1], inp_pipe_rnd_mode_q[i], reg_ena, fpnew_pkg::RNE)
- `FFL(inp_pipe_op_q[i+1], inp_pipe_op_q[i], reg_ena, fpnew_pkg::FMADD)
- `FFL(inp_pipe_op_mod_q[i+1], inp_pipe_op_mod_q[i], reg_ena, '0)
- `FFL(inp_pipe_tag_q[i+1], inp_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(inp_pipe_aux_q[i+1], inp_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
-
- // ---------------------
- // Input classification
- // ---------------------
- fpnew_pkg::fp_info_t [1:0] info_q;
-
- // Classify input
- fpnew_classifier #(
- .FpFormat ( FpFormat ),
- .NumOperands ( 2 )
- ) i_class_a (
- .operands_i ( inp_pipe_operands_q[NUM_INP_REGS] ),
- .is_boxed_i ( inp_pipe_is_boxed_q[NUM_INP_REGS] ),
- .info_o ( info_q )
- );
-
- fp_t operand_a, operand_b;
- fpnew_pkg::fp_info_t info_a, info_b;
-
- // Packing-order-agnostic assignments
- assign operand_a = inp_pipe_operands_q[NUM_INP_REGS][0];
- assign operand_b = inp_pipe_operands_q[NUM_INP_REGS][1];
- assign info_a = info_q[0];
- assign info_b = info_q[1];
-
- logic any_operand_inf;
- logic any_operand_nan;
- logic signalling_nan;
-
- // Reduction for special case handling
- assign any_operand_inf = (| {info_a.is_inf, info_b.is_inf});
- assign any_operand_nan = (| {info_a.is_nan, info_b.is_nan});
- assign signalling_nan = (| {info_a.is_signalling, info_b.is_signalling});
-
- logic operands_equal, operand_a_smaller;
-
- // Equality checks for zeroes too
- assign operands_equal = (operand_a == operand_b) || (info_a.is_zero && info_b.is_zero);
- // Invert result if non-zero signs involved (unsigned comparison)
- assign operand_a_smaller = (operand_a < operand_b) ^ (operand_a.sign || operand_b.sign);
-
- // ---------------
- // Sign Injection
- // ---------------
- fp_t sgnj_result;
- fpnew_pkg::status_t sgnj_status;
- logic sgnj_extension_bit;
-
- // Sign Injection - operation is encoded in rnd_mode_q:
- // RNE = SGNJ, RTZ = SGNJN, RDN = SGNJX, RUP = Passthrough (no NaN-box check)
- always_comb begin : sign_injections
- logic sign_a, sign_b; // internal signs
- // Default assignment
- sgnj_result = operand_a; // result based on operand a
-
- // NaN-boxing check will treat invalid inputs as canonical NaNs
- if (!info_a.is_boxed) sgnj_result = '{sign: 1'b0, exponent: '1, mantissa: 2**(MAN_BITS-1)};
-
- // Internal signs are treated as positive in case of non-NaN-boxed values
- sign_a = operand_a.sign & info_a.is_boxed;
- sign_b = operand_b.sign & info_b.is_boxed;
-
- // Do the sign injection based on rm field
- unique case (inp_pipe_rnd_mode_q[NUM_INP_REGS])
- fpnew_pkg::RNE: sgnj_result.sign = sign_b; // SGNJ
- fpnew_pkg::RTZ: sgnj_result.sign = ~sign_b; // SGNJN
- fpnew_pkg::RDN: sgnj_result.sign = sign_a ^ sign_b; // SGNJX
- fpnew_pkg::RUP: sgnj_result = operand_a; // passthrough
- default: sgnj_result = '{default: fpnew_pkg::DONT_CARE}; // don't care
- endcase
- end
-
- assign sgnj_status = '0; // sign injections never raise exceptions
-
- // op_mod_q enables integer sign-extension of result (for storing to integer regfile)
- assign sgnj_extension_bit = inp_pipe_op_mod_q[NUM_INP_REGS] ? sgnj_result.sign : 1'b1;
-
- // ------------------
- // Minimum / Maximum
- // ------------------
- fp_t minmax_result;
- fpnew_pkg::status_t minmax_status;
- logic minmax_extension_bit;
-
- // Minimum/Maximum - operation is encoded in rnd_mode_q:
- // RNE = MIN, RTZ = MAX
- always_comb begin : min_max
- // Default assignment
- minmax_status = '0;
-
- // Min/Max use quiet comparisons - only sNaN are invalid
- minmax_status.NV = signalling_nan;
-
- // Both NaN inputs cause a NaN output
- if (info_a.is_nan && info_b.is_nan)
- minmax_result = '{sign: 1'b0, exponent: '1, mantissa: 2**(MAN_BITS-1)}; // canonical qNaN
- // If one operand is NaN, the non-NaN operand is returned
- else if (info_a.is_nan) minmax_result = operand_b;
- else if (info_b.is_nan) minmax_result = operand_a;
- // Otherwise decide according to the operation
- else begin
- unique case (inp_pipe_rnd_mode_q[NUM_INP_REGS])
- fpnew_pkg::RNE: minmax_result = operand_a_smaller ? operand_a : operand_b; // MIN
- fpnew_pkg::RTZ: minmax_result = operand_a_smaller ? operand_b : operand_a; // MAX
- default: minmax_result = '{default: fpnew_pkg::DONT_CARE}; // don't care
- endcase
- end
- end
-
- assign minmax_extension_bit = 1'b1; // NaN-box as result is always a float value
-
- // ------------
- // Comparisons
- // ------------
- fp_t cmp_result;
- fpnew_pkg::status_t cmp_status;
- logic cmp_extension_bit;
-
- // Comparisons - operation is encoded in rnd_mode_q:
- // RNE = LE, RTZ = LT, RDN = EQ
- // op_mod_q inverts boolean outputs
- always_comb begin : comparisons
- // Default assignment
- cmp_result = '0; // false
- cmp_status = '0; // no flags
-
- // Signalling NaNs always compare as false and are illegal
- if (signalling_nan) cmp_status.NV = 1'b1; // invalid operation
- // Otherwise do comparisons
- else begin
- unique case (inp_pipe_rnd_mode_q[NUM_INP_REGS])
- fpnew_pkg::RNE: begin // Less than or equal
- if (any_operand_nan) cmp_status.NV = 1'b1; // Signalling comparison: NaNs are invalid
- else cmp_result = (operand_a_smaller | operands_equal) ^ inp_pipe_op_mod_q[NUM_INP_REGS];
- end
- fpnew_pkg::RTZ: begin // Less than
- if (any_operand_nan) cmp_status.NV = 1'b1; // Signalling comparison: NaNs are invalid
- else cmp_result = (operand_a_smaller & ~operands_equal) ^ inp_pipe_op_mod_q[NUM_INP_REGS];
- end
- fpnew_pkg::RDN: begin // Equal
- if (any_operand_nan) cmp_result = inp_pipe_op_mod_q[NUM_INP_REGS]; // NaN always not equal
- else cmp_result = operands_equal ^ inp_pipe_op_mod_q[NUM_INP_REGS];
- end
- default: cmp_result = '{default: fpnew_pkg::DONT_CARE}; // don't care
- endcase
- end
- end
-
- assign cmp_extension_bit = 1'b0; // Comparisons always produce booleans in integer registers
-
- // ---------------
- // Classification
- // ---------------
- fpnew_pkg::status_t class_status;
- logic class_extension_bit;
- fpnew_pkg::classmask_e class_mask_d; // the result is actually here
-
- // Classification - always return the classification mask on the dedicated port
- always_comb begin : classify
- if (info_a.is_normal) begin
- class_mask_d = operand_a.sign ? fpnew_pkg::NEGNORM : fpnew_pkg::POSNORM;
- end else if (info_a.is_subnormal) begin
- class_mask_d = operand_a.sign ? fpnew_pkg::NEGSUBNORM : fpnew_pkg::POSSUBNORM;
- end else if (info_a.is_zero) begin
- class_mask_d = operand_a.sign ? fpnew_pkg::NEGZERO : fpnew_pkg::POSZERO;
- end else if (info_a.is_inf) begin
- class_mask_d = operand_a.sign ? fpnew_pkg::NEGINF : fpnew_pkg::POSINF;
- end else if (info_a.is_nan) begin
- class_mask_d = info_a.is_signalling ? fpnew_pkg::SNAN : fpnew_pkg::QNAN;
- end else begin
- class_mask_d = fpnew_pkg::QNAN; // default value
- end
- end
-
- assign class_status = '0; // classification does not set flags
- assign class_extension_bit = 1'b0; // classification always produces results in integer registers
-
- // -----------------
- // Result selection
- // -----------------
- fp_t result_d;
- fpnew_pkg::status_t status_d;
- logic extension_bit_d;
- logic is_class_d;
-
- // Select result
- always_comb begin : select_result
- unique case (inp_pipe_op_q[NUM_INP_REGS])
- fpnew_pkg::SGNJ: begin
- result_d = sgnj_result;
- status_d = sgnj_status;
- extension_bit_d = sgnj_extension_bit;
- end
- fpnew_pkg::MINMAX: begin
- result_d = minmax_result;
- status_d = minmax_status;
- extension_bit_d = minmax_extension_bit;
- end
- fpnew_pkg::CMP: begin
- result_d = cmp_result;
- status_d = cmp_status;
- extension_bit_d = cmp_extension_bit;
- end
- fpnew_pkg::CLASSIFY: begin
- result_d = '{default: fpnew_pkg::DONT_CARE}; // unused
- status_d = class_status;
- extension_bit_d = class_extension_bit;
- end
- default: begin
- result_d = '{default: fpnew_pkg::DONT_CARE}; // dont care
- status_d = '{default: fpnew_pkg::DONT_CARE}; // dont care
- extension_bit_d = fpnew_pkg::DONT_CARE; // dont care
- end
- endcase
- end
-
- assign is_class_d = (inp_pipe_op_q[NUM_INP_REGS] == fpnew_pkg::CLASSIFY);
-
- // ----------------
- // Output Pipeline
- // ----------------
- // Output pipeline signals, index i holds signal after i register stages
- fp_t [0:NUM_OUT_REGS] out_pipe_result_q;
- fpnew_pkg::status_t [0:NUM_OUT_REGS] out_pipe_status_q;
- logic [0:NUM_OUT_REGS] out_pipe_extension_bit_q;
- fpnew_pkg::classmask_e [0:NUM_OUT_REGS] out_pipe_class_mask_q;
- logic [0:NUM_OUT_REGS] out_pipe_is_class_q;
- TagType [0:NUM_OUT_REGS] out_pipe_tag_q;
- AuxType [0:NUM_OUT_REGS] out_pipe_aux_q;
- logic [0:NUM_OUT_REGS] out_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NUM_OUT_REGS] out_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign out_pipe_result_q[0] = result_d;
- assign out_pipe_status_q[0] = status_d;
- assign out_pipe_extension_bit_q[0] = extension_bit_d;
- assign out_pipe_class_mask_q[0] = class_mask_d;
- assign out_pipe_is_class_q[0] = is_class_d;
- assign out_pipe_tag_q[0] = inp_pipe_tag_q[NUM_INP_REGS];
- assign out_pipe_aux_q[0] = inp_pipe_aux_q[NUM_INP_REGS];
- assign out_pipe_valid_q[0] = inp_pipe_valid_q[NUM_INP_REGS];
- // Input stage: Propagate pipeline ready signal to inside pipe
- assign inp_pipe_ready[NUM_INP_REGS] = out_pipe_ready[0];
- // Generate the register stages
- for (genvar i = 0; i < NUM_OUT_REGS; i++) begin : gen_output_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign out_pipe_ready[i] = out_pipe_ready[i+1] | ~out_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(out_pipe_valid_q[i+1], out_pipe_valid_q[i], out_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = out_pipe_ready[i] & out_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(out_pipe_result_q[i+1], out_pipe_result_q[i], reg_ena, '0)
- `FFL(out_pipe_status_q[i+1], out_pipe_status_q[i], reg_ena, '0)
- `FFL(out_pipe_extension_bit_q[i+1], out_pipe_extension_bit_q[i], reg_ena, '0)
- `FFL(out_pipe_class_mask_q[i+1], out_pipe_class_mask_q[i], reg_ena, fpnew_pkg::QNAN)
- `FFL(out_pipe_is_class_q[i+1], out_pipe_is_class_q[i], reg_ena, '0)
- `FFL(out_pipe_tag_q[i+1], out_pipe_tag_q[i], reg_ena, TagType'('0))
- `FFL(out_pipe_aux_q[i+1], out_pipe_aux_q[i], reg_ena, AuxType'('0))
- end
- // Output stage: Ready travels backwards from output side, driven by downstream circuitry
- assign out_pipe_ready[NUM_OUT_REGS] = out_ready_i;
- // Output stage: assign module outputs
- assign result_o = out_pipe_result_q[NUM_OUT_REGS];
- assign status_o = out_pipe_status_q[NUM_OUT_REGS];
- assign extension_bit_o = out_pipe_extension_bit_q[NUM_OUT_REGS];
- assign class_mask_o = out_pipe_class_mask_q[NUM_OUT_REGS];
- assign is_class_o = out_pipe_is_class_q[NUM_OUT_REGS];
- assign tag_o = out_pipe_tag_q[NUM_OUT_REGS];
- assign aux_o = out_pipe_aux_q[NUM_OUT_REGS];
- assign out_valid_o = out_pipe_valid_q[NUM_OUT_REGS];
- assign busy_o = (| {inp_pipe_valid_q, out_pipe_valid_q});
-endmodule
diff --git a/verilog/rtl/fpnew_opgroup_block.sv b/verilog/rtl/fpnew_opgroup_block.sv
deleted file mode 100644
index e3be31d..0000000
--- a/verilog/rtl/fpnew_opgroup_block.sv
+++ /dev/null
@@ -1,230 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-module fpnew_opgroup_block #(
- parameter fpnew_pkg::opgroup_e OpGroup = fpnew_pkg::ADDMUL,
- // FPU configuration
- parameter int unsigned Width = 32,
- parameter logic EnableVectors = 1'b1,
- parameter fpnew_pkg::fmt_logic_t FpFmtMask = '1,
- parameter fpnew_pkg::ifmt_logic_t IntFmtMask = '1,
- parameter fpnew_pkg::fmt_unsigned_t FmtPipeRegs = '{default: 0},
- parameter fpnew_pkg::fmt_unit_types_t FmtUnitTypes = '{default: fpnew_pkg::PARALLEL},
- parameter fpnew_pkg::pipe_config_t PipeConfig = fpnew_pkg::BEFORE,
- parameter type TagType = logic,
- // Do not change
- localparam int unsigned NUM_FORMATS = fpnew_pkg::NUM_FP_FORMATS,
- localparam int unsigned NUM_OPERANDS = fpnew_pkg::num_operands(OpGroup)
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [NUM_OPERANDS-1:0][Width-1:0] operands_i,
- input logic [NUM_FORMATS-1:0][NUM_OPERANDS-1:0] is_boxed_i,
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input logic op_mod_i,
- input fpnew_pkg::fp_format_e src_fmt_i,
- input fpnew_pkg::fp_format_e dst_fmt_i,
- input fpnew_pkg::int_format_e int_fmt_i,
- input logic vectorial_op_i,
- input TagType tag_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [Width-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output logic extension_bit_o,
- output TagType tag_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- // ----------------
- // Type Definition
- // ----------------
- typedef struct packed {
- logic [Width-1:0] result;
- fpnew_pkg::status_t status;
- logic ext_bit;
- TagType tag;
- } output_t;
-
- // Handshake signals for the slices
- logic [NUM_FORMATS-1:0] fmt_in_ready, fmt_out_valid, fmt_out_ready, fmt_busy;
- output_t [NUM_FORMATS-1:0] fmt_outputs;
-
- // -----------
- // Input Side
- // -----------
- assign in_ready_o = in_valid_i & fmt_in_ready[dst_fmt_i]; // Ready is given by selected format
-
- // -------------------------
- // Generate Parallel Slices
- // -------------------------
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : gen_parallel_slices
- // Some constants for this format
- localparam logic ANY_MERGED = fpnew_pkg::any_enabled_multi(FmtUnitTypes, FpFmtMask);
- localparam logic IS_FIRST_MERGED =
- fpnew_pkg::is_first_enabled_multi(fpnew_pkg::fp_format_e'(fmt), FmtUnitTypes, FpFmtMask);
-
- // Generate slice only if format enabled
- if (FpFmtMask[fmt] && (FmtUnitTypes[fmt] == fpnew_pkg::PARALLEL)) begin : active_format
-
- logic in_valid;
-
- assign in_valid = in_valid_i & (dst_fmt_i == fmt); // enable selected format
-
- fpnew_opgroup_fmt_slice #(
- .OpGroup ( OpGroup ),
- .FpFormat ( fpnew_pkg::fp_format_e'(fmt) ),
- .Width ( Width ),
- .EnableVectors ( EnableVectors ),
- .NumPipeRegs ( FmtPipeRegs[fmt] ),
- .PipeConfig ( PipeConfig ),
- .TagType ( TagType )
- ) i_fmt_slice (
- .clk_i,
- .rst_ni,
- .operands_i ( operands_i ),
- .is_boxed_i ( is_boxed_i[fmt] ),
- .rnd_mode_i,
- .op_i,
- .op_mod_i,
- .vectorial_op_i,
- .tag_i,
- .in_valid_i ( in_valid ),
- .in_ready_o ( fmt_in_ready[fmt] ),
- .flush_i,
- .result_o ( fmt_outputs[fmt].result ),
- .status_o ( fmt_outputs[fmt].status ),
- .extension_bit_o( fmt_outputs[fmt].ext_bit ),
- .tag_o ( fmt_outputs[fmt].tag ),
- .out_valid_o ( fmt_out_valid[fmt] ),
- .out_ready_i ( fmt_out_ready[fmt] ),
- .busy_o ( fmt_busy[fmt] )
- );
- // If the format wants to use merged ops, tie off the dangling ones not used here
- end else if (FpFmtMask[fmt] && ANY_MERGED && !IS_FIRST_MERGED) begin : merged_unused
-
- localparam FMT = fpnew_pkg::get_first_enabled_multi(FmtUnitTypes, FpFmtMask);
- // Ready is split up into formats
- assign fmt_in_ready[fmt] = fmt_in_ready[int'(FMT)];
-
- assign fmt_out_valid[fmt] = 1'b0; // don't emit values
- assign fmt_busy[fmt] = 1'b0; // never busy
- // Outputs are don't care
- assign fmt_outputs[fmt].result = '{default: fpnew_pkg::DONT_CARE};
- assign fmt_outputs[fmt].status = '{default: fpnew_pkg::DONT_CARE};
- assign fmt_outputs[fmt].ext_bit = fpnew_pkg::DONT_CARE;
- assign fmt_outputs[fmt].tag = TagType'(fpnew_pkg::DONT_CARE);
-
- // Tie off disabled formats
- end else if (!FpFmtMask[fmt] || (FmtUnitTypes[fmt] == fpnew_pkg::DISABLED)) begin : disable_fmt
- assign fmt_in_ready[fmt] = 1'b0; // don't accept operations
- assign fmt_out_valid[fmt] = 1'b0; // don't emit values
- assign fmt_busy[fmt] = 1'b0; // never busy
- // Outputs are don't care
- assign fmt_outputs[fmt].result = '{default: fpnew_pkg::DONT_CARE};
- assign fmt_outputs[fmt].status = '{default: fpnew_pkg::DONT_CARE};
- assign fmt_outputs[fmt].ext_bit = fpnew_pkg::DONT_CARE;
- assign fmt_outputs[fmt].tag = TagType'(fpnew_pkg::DONT_CARE);
- end
- end
-
- // ----------------------
- // Generate Merged Slice
- // ----------------------
- if (fpnew_pkg::any_enabled_multi(FmtUnitTypes, FpFmtMask)) begin : gen_merged_slice
-
- localparam FMT = fpnew_pkg::get_first_enabled_multi(FmtUnitTypes, FpFmtMask);
- localparam REG = fpnew_pkg::get_num_regs_multi(FmtPipeRegs, FmtUnitTypes, FpFmtMask);
-
- logic in_valid;
-
- assign in_valid = in_valid_i & (FmtUnitTypes[dst_fmt_i] == fpnew_pkg::MERGED);
-
- fpnew_opgroup_multifmt_slice #(
- .OpGroup ( OpGroup ),
- .Width ( Width ),
- .FpFmtConfig ( FpFmtMask ),
- .IntFmtConfig ( IntFmtMask ),
- .EnableVectors ( EnableVectors ),
- .NumPipeRegs ( REG ),
- .PipeConfig ( PipeConfig ),
- .TagType ( TagType )
- ) i_multifmt_slice (
- .clk_i,
- .rst_ni,
- .operands_i,
- .is_boxed_i,
- .rnd_mode_i,
- .op_i,
- .op_mod_i,
- .src_fmt_i,
- .dst_fmt_i,
- .int_fmt_i,
- .vectorial_op_i,
- .tag_i,
- .in_valid_i ( in_valid ),
- .in_ready_o ( fmt_in_ready[FMT] ),
- .flush_i,
- .result_o ( fmt_outputs[FMT].result ),
- .status_o ( fmt_outputs[FMT].status ),
- .extension_bit_o ( fmt_outputs[FMT].ext_bit ),
- .tag_o ( fmt_outputs[FMT].tag ),
- .out_valid_o ( fmt_out_valid[FMT] ),
- .out_ready_i ( fmt_out_ready[FMT] ),
- .busy_o ( fmt_busy[FMT] )
- );
-
- end
-
- // ------------------
- // Arbitrate Outputs
- // ------------------
- output_t arbiter_output;
-
- // Round-Robin arbiter to decide which result to use
- rr_arb_tree #(
- .NumIn ( NUM_FORMATS ),
- .DataType ( output_t ),
- .AxiVldRdy ( 1'b1 )
- ) i_arbiter (
- .clk_i,
- .rst_ni,
- .flush_i,
- .rr_i ( '0 ),
- .req_i ( fmt_out_valid ),
- .gnt_o ( fmt_out_ready ),
- .data_i ( fmt_outputs ),
- .gnt_i ( out_ready_i ),
- .req_o ( out_valid_o ),
- .data_o ( arbiter_output ),
- .idx_o ( /* unused */ )
- );
-
- // Unpack output
- assign result_o = arbiter_output.result;
- assign status_o = arbiter_output.status;
- assign extension_bit_o = arbiter_output.ext_bit;
- assign tag_o = arbiter_output.tag;
-
- assign busy_o = (| fmt_busy);
-
-endmodule
diff --git a/verilog/rtl/fpnew_opgroup_fmt_slice.sv b/verilog/rtl/fpnew_opgroup_fmt_slice.sv
deleted file mode 100644
index fda2a57..0000000
--- a/verilog/rtl/fpnew_opgroup_fmt_slice.sv
+++ /dev/null
@@ -1,276 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-module fpnew_opgroup_fmt_slice #(
- parameter fpnew_pkg::opgroup_e OpGroup = fpnew_pkg::ADDMUL,
- parameter fpnew_pkg::fp_format_e FpFormat = fpnew_pkg::fp_format_e'(0),
- // FPU configuration
- parameter int unsigned Width = 32,
- parameter logic EnableVectors = 1'b1,
- parameter int unsigned NumPipeRegs = 0,
- parameter fpnew_pkg::pipe_config_t PipeConfig = fpnew_pkg::BEFORE,
- parameter type TagType = logic,
- // Do not change
- localparam int unsigned NUM_OPERANDS = fpnew_pkg::num_operands(OpGroup)
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [NUM_OPERANDS-1:0][Width-1:0] operands_i,
- input logic [NUM_OPERANDS-1:0] is_boxed_i,
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input logic op_mod_i,
- input logic vectorial_op_i,
- input TagType tag_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [Width-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output logic extension_bit_o,
- output TagType tag_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(FpFormat);
- localparam int unsigned NUM_LANES = fpnew_pkg::num_lanes(Width, FpFormat, EnableVectors);
-
-
- logic [NUM_LANES-1:0] lane_in_ready, lane_out_valid; // Handshake signals for the lanes
- logic vectorial_op;
-
- logic [NUM_LANES*FP_WIDTH-1:0] slice_result;
- logic [Width-1:0] slice_regular_result, slice_class_result, slice_vec_class_result;
-
- fpnew_pkg::status_t [NUM_LANES-1:0] lane_status;
- logic [NUM_LANES-1:0] lane_ext_bit; // only the first one is actually used
- fpnew_pkg::classmask_e [NUM_LANES-1:0] lane_class_mask;
- TagType [NUM_LANES-1:0] lane_tags; // only the first one is actually used
- logic [NUM_LANES-1:0] lane_vectorial, lane_busy, lane_is_class; // dito
-
- logic result_is_vector, result_is_class;
-
- // -----------
- // Input Side
- // -----------
- assign in_ready_o = lane_in_ready[0]; // Upstream ready is given by first lane
- assign vectorial_op = vectorial_op_i & EnableVectors; // only do vectorial stuff if enabled
-
- // ---------------
- // Generate Lanes
- // ---------------
- for (genvar lane = 0; lane < int'(NUM_LANES); lane++) begin : gen_num_lanes
- logic [FP_WIDTH-1:0] local_result; // lane-local results
- logic local_sign;
-
- // Generate instances only if needed, lane 0 always generated
- if ((lane == 0) || EnableVectors) begin : active_lane
- logic in_valid, out_valid, out_ready; // lane-local handshake
-
- logic [NUM_OPERANDS-1:0][FP_WIDTH-1:0] local_operands; // lane-local operands
- logic [FP_WIDTH-1:0] op_result; // lane-local results
- fpnew_pkg::status_t op_status;
-
- assign in_valid = in_valid_i & ((lane == 0) | vectorial_op); // upper lanes only for vectors
- // Slice out the operands for this lane
- always_comb begin : prepare_input
- for (int i = 0; i < int'(NUM_OPERANDS); i++) begin
- local_operands[i] = operands_i[i][(unsigned'(lane)+1)*FP_WIDTH-1:unsigned'(lane)*FP_WIDTH];
- end
- end
-
- // Instantiate the operation from the selected opgroup
- if (OpGroup == fpnew_pkg::ADDMUL) begin : lane_instance
- fpnew_fma #(
- .FpFormat ( FpFormat ),
- .NumPipeRegs ( NumPipeRegs ),
- .PipeConfig ( PipeConfig ),
- .TagType ( TagType ),
- .AuxType ( logic )
- ) i_fma (
- .clk_i,
- .rst_ni,
- .operands_i ( local_operands ),
- .is_boxed_i ( is_boxed_i[NUM_OPERANDS-1:0] ),
- .rnd_mode_i,
- .op_i,
- .op_mod_i,
- .tag_i,
- .aux_i ( vectorial_op ), // Remember whether operation was vectorial
- .in_valid_i ( in_valid ),
- .in_ready_o ( lane_in_ready[lane] ),
- .flush_i,
- .result_o ( op_result ),
- .status_o ( op_status ),
- .extension_bit_o ( lane_ext_bit[lane] ),
- .tag_o ( lane_tags[lane] ),
- .aux_o ( lane_vectorial[lane] ),
- .out_valid_o ( out_valid ),
- .out_ready_i ( out_ready ),
- .busy_o ( lane_busy[lane] )
- );
- assign lane_is_class[lane] = 1'b0;
- assign lane_class_mask[lane] = fpnew_pkg::NEGINF;
- end else if (OpGroup == fpnew_pkg::DIVSQRT) begin : lane_instance
- // fpnew_divsqrt #(
- // .FpFormat (FpFormat),
- // .NumPipeRegs(NumPipeRegs),
- // .PipeConfig (PipeConfig),
- // .TagType (TagType),
- // .AuxType (logic)
- // ) i_divsqrt (
- // .clk_i,
- // .rst_ni,
- // .operands_i ( local_operands ),
- // .is_boxed_i ( is_boxed_i[NUM_OPERANDS-1:0] ),
- // .rnd_mode_i,
- // .op_i,
- // .op_mod_i,
- // .tag_i,
- // .aux_i ( vectorial_op ), // Remember whether operation was vectorial
- // .in_valid_i ( in_valid ),
- // .in_ready_o ( lane_in_ready[lane] ),
- // .flush_i,
- // .result_o ( op_result ),
- // .status_o ( op_status ),
- // .extension_bit_o ( lane_ext_bit[lane] ),
- // .tag_o ( lane_tags[lane] ),
- // .aux_o ( lane_vectorial[lane] ),
- // .out_valid_o ( out_valid ),
- // .out_ready_i ( out_ready ),
- // .busy_o ( lane_busy[lane] )
- // );
- // assign lane_is_class[lane] = 1'b0;
- end else if (OpGroup == fpnew_pkg::NONCOMP) begin : lane_instance
- fpnew_noncomp #(
- .FpFormat (FpFormat),
- .NumPipeRegs(NumPipeRegs),
- .PipeConfig (PipeConfig),
- .TagType (TagType),
- .AuxType (logic)
- ) i_noncomp (
- .clk_i,
- .rst_ni,
- .operands_i ( local_operands ),
- .is_boxed_i ( is_boxed_i[NUM_OPERANDS-1:0] ),
- .rnd_mode_i,
- .op_i,
- .op_mod_i,
- .tag_i,
- .aux_i ( vectorial_op ), // Remember whether operation was vectorial
- .in_valid_i ( in_valid ),
- .in_ready_o ( lane_in_ready[lane] ),
- .flush_i,
- .result_o ( op_result ),
- .status_o ( op_status ),
- .extension_bit_o ( lane_ext_bit[lane] ),
- .class_mask_o ( lane_class_mask[lane] ),
- .is_class_o ( lane_is_class[lane] ),
- .tag_o ( lane_tags[lane] ),
- .aux_o ( lane_vectorial[lane] ),
- .out_valid_o ( out_valid ),
- .out_ready_i ( out_ready ),
- .busy_o ( lane_busy[lane] )
- );
- end // ADD OTHER OPTIONS HERE
-
- // Handshakes are only done if the lane is actually used
- assign out_ready = out_ready_i & ((lane == 0) | result_is_vector);
- assign lane_out_valid[lane] = out_valid & ((lane == 0) | result_is_vector);
-
- // Properly NaN-box or sign-extend the slice result if not in use
- assign local_result = lane_out_valid[lane] ? op_result : '{default: lane_ext_bit[0]};
- assign lane_status[lane] = lane_out_valid[lane] ? op_status : '0;
-
- // Otherwise generate constant sign-extension
- end else begin
- assign lane_out_valid[lane] = 1'b0; // unused lane
- assign lane_in_ready[lane] = 1'b0; // unused lane
- assign local_result = '{default: lane_ext_bit[0]}; // sign-extend/nan box
- assign lane_status[lane] = '0;
- assign lane_busy[lane] = 1'b0;
- assign lane_is_class[lane] = 1'b0;
- end
-
- // Insert lane result into slice result
- assign slice_result[(unsigned'(lane)+1)*FP_WIDTH-1:unsigned'(lane)*FP_WIDTH] = local_result;
-
- // Create Classification results
- if ((lane+1)*8 <= Width) begin : vectorial_class // vectorial class blocks are 8bits in size
- assign local_sign = (lane_class_mask[lane] == fpnew_pkg::NEGINF ||
- lane_class_mask[lane] == fpnew_pkg::NEGNORM ||
- lane_class_mask[lane] == fpnew_pkg::NEGSUBNORM ||
- lane_class_mask[lane] == fpnew_pkg::NEGZERO);
- // Write the current block segment
- assign slice_vec_class_result[(lane+1)*8-1:lane*8] = {
- local_sign, // BIT 7
- ~local_sign, // BIT 6
- lane_class_mask[lane] == fpnew_pkg::QNAN, // BIT 5
- lane_class_mask[lane] == fpnew_pkg::SNAN, // BIT 4
- lane_class_mask[lane] == fpnew_pkg::POSZERO
- || lane_class_mask[lane] == fpnew_pkg::NEGZERO, // BIT 3
- lane_class_mask[lane] == fpnew_pkg::POSSUBNORM
- || lane_class_mask[lane] == fpnew_pkg::NEGSUBNORM, // BIT 2
- lane_class_mask[lane] == fpnew_pkg::POSNORM
- || lane_class_mask[lane] == fpnew_pkg::NEGNORM, // BIT 1
- lane_class_mask[lane] == fpnew_pkg::POSINF
- || lane_class_mask[lane] == fpnew_pkg::NEGINF // BIT 0
- };
- end
- end
-
- // ------------
- // Output Side
- // ------------
- assign result_is_vector = lane_vectorial[0];
- assign result_is_class = lane_is_class[0];
-
- assign slice_regular_result = $signed({extension_bit_o, slice_result});
-
- localparam int unsigned CLASS_VEC_BITS = (NUM_LANES*8 > Width) ? 8 * (Width / 8) : NUM_LANES*8;
-
- // Pad out unused vec_class bits
- if (CLASS_VEC_BITS < Width) begin : pad_vectorial_class
- assign slice_vec_class_result[Width-1:CLASS_VEC_BITS] = '0;
- end
-
- // localparam logic [Width-1:0] CLASS_VEC_MASK = 2**CLASS_VEC_BITS - 1;
-
- assign slice_class_result = result_is_vector ? slice_vec_class_result : lane_class_mask[0];
-
- // Select the proper result
- assign result_o = result_is_class ? slice_class_result : slice_regular_result;
-
- assign extension_bit_o = lane_ext_bit[0]; // upper lanes unused
- assign tag_o = lane_tags[0]; // upper lanes unused
- assign busy_o = (| lane_busy);
- assign out_valid_o = lane_out_valid[0]; // upper lanes unused
-
-
- // Collapse the lane status
- always_comb begin : output_processing
- // Collapse the status
- automatic fpnew_pkg::status_t temp_status;
- temp_status = '0;
- for (int i = 0; i < int'(NUM_LANES); i++)
- temp_status |= lane_status[i];
- status_o = temp_status;
- end
-endmodule
diff --git a/verilog/rtl/fpnew_opgroup_multifmt_slice.sv b/verilog/rtl/fpnew_opgroup_multifmt_slice.sv
deleted file mode 100644
index c4ee849..0000000
--- a/verilog/rtl/fpnew_opgroup_multifmt_slice.sv
+++ /dev/null
@@ -1,425 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-`include "registers.svh"
-module fpnew_opgroup_multifmt_slice #(
- parameter fpnew_pkg::opgroup_e OpGroup = fpnew_pkg::CONV,
- parameter int unsigned Width = 64,
- // FPU configuration
- parameter fpnew_pkg::fmt_logic_t FpFmtConfig = '1,
- parameter fpnew_pkg::ifmt_logic_t IntFmtConfig = '1,
- parameter logic EnableVectors = 1'b1,
- parameter int unsigned NumPipeRegs = 0,
- parameter fpnew_pkg::pipe_config_t PipeConfig = fpnew_pkg::BEFORE,
- parameter type TagType = logic,
- // Do not change
- localparam int unsigned NUM_OPERANDS = fpnew_pkg::num_operands(OpGroup),
- localparam int unsigned NUM_FORMATS = fpnew_pkg::NUM_FP_FORMATS
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [NUM_OPERANDS-1:0][Width-1:0] operands_i,
- input logic [NUM_FORMATS-1:0][NUM_OPERANDS-1:0] is_boxed_i,
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input logic op_mod_i,
- input fpnew_pkg::fp_format_e src_fmt_i,
- input fpnew_pkg::fp_format_e dst_fmt_i,
- input fpnew_pkg::int_format_e int_fmt_i,
- input logic vectorial_op_i,
- input TagType tag_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [Width-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output logic extension_bit_o,
- output TagType tag_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- localparam int unsigned MAX_FP_WIDTH = fpnew_pkg::max_fp_width(FpFmtConfig);
- localparam int unsigned MAX_INT_WIDTH = fpnew_pkg::max_int_width(IntFmtConfig);
- localparam int unsigned NUM_LANES = fpnew_pkg::max_num_lanes(Width, FpFmtConfig, 1'b1);
- localparam int unsigned NUM_INT_FORMATS = fpnew_pkg::NUM_INT_FORMATS;
- // We will send the format information along with the data
- localparam int unsigned FMT_BITS =
- fpnew_pkg::maximum($clog2(NUM_FORMATS), $clog2(NUM_INT_FORMATS));
- localparam int unsigned AUX_BITS = FMT_BITS + 2; // also add vectorial and integer flags
-
- logic [NUM_LANES-1:0] lane_in_ready, lane_out_valid; // Handshake signals for the lanes
- logic vectorial_op;
- logic [FMT_BITS-1:0] dst_fmt; // destination format to pass along with operation
- logic [AUX_BITS-1:0] aux_data;
-
- // additional flags for CONV
- logic dst_fmt_is_int, dst_is_cpk;
- logic [1:0] dst_vec_op; // info for vectorial results (for packing)
- logic [2:0] target_aux_d, target_aux_q;
- logic is_up_cast, is_down_cast;
-
- logic [NUM_FORMATS-1:0][Width-1:0] fmt_slice_result;
- logic [NUM_INT_FORMATS-1:0][Width-1:0] ifmt_slice_result;
- logic [Width-1:0] conv_slice_result;
-
-
- logic [Width-1:0] conv_target_d, conv_target_q; // vectorial conversions update a register
-
- fpnew_pkg::status_t [NUM_LANES-1:0] lane_status;
- logic [NUM_LANES-1:0] lane_ext_bit; // only the first one is actually used
- TagType [NUM_LANES-1:0] lane_tags; // only the first one is actually used
- logic [NUM_LANES-1:0][AUX_BITS-1:0] lane_aux; // only the first one is actually used
- logic [NUM_LANES-1:0] lane_busy; // dito
-
- logic result_is_vector;
- logic [FMT_BITS-1:0] result_fmt;
- logic result_fmt_is_int, result_is_cpk;
- logic [1:0] result_vec_op; // info for vectorial results (for packing)
-
- // -----------
- // Input Side
- // -----------
- assign in_ready_o = lane_in_ready[0]; // Upstream ready is given by first lane
- assign vectorial_op = vectorial_op_i & EnableVectors; // only do vectorial stuff if enabled
-
- // Cast-and-Pack ops are encoded in operation and modifier
- assign dst_fmt_is_int = (OpGroup == fpnew_pkg::CONV) & (op_i == fpnew_pkg::F2I);
- assign dst_is_cpk = (OpGroup == fpnew_pkg::CONV) & (op_i == fpnew_pkg::CPKAB ||
- op_i == fpnew_pkg::CPKCD);
- assign dst_vec_op = (OpGroup == fpnew_pkg::CONV) & {(op_i == fpnew_pkg::CPKCD), op_mod_i};
-
- assign is_up_cast = (fpnew_pkg::fp_width(dst_fmt_i) > fpnew_pkg::fp_width(src_fmt_i));
- assign is_down_cast = (fpnew_pkg::fp_width(dst_fmt_i) < fpnew_pkg::fp_width(src_fmt_i));
-
- // The destination format is the int format for F2I casts
- assign dst_fmt = dst_fmt_is_int ? int_fmt_i : dst_fmt_i;
-
- // The data sent along consists of the vectorial flag and format bits
- assign aux_data = {dst_fmt_is_int, vectorial_op, dst_fmt};
- assign target_aux_d = {dst_vec_op, dst_is_cpk};
-
- // CONV passes one operand for assembly after the unit: opC for cpk, opB for others
- if (OpGroup == fpnew_pkg::CONV) begin : conv_target
- assign conv_target_d = dst_is_cpk ? operands_i[2] : operands_i[1];
- end
-
- // For 2-operand units, prepare boxing info
- logic [NUM_FORMATS-1:0] is_boxed_1op;
- logic [NUM_FORMATS-1:0][1:0] is_boxed_2op;
-
- always_comb begin : boxed_2op
- for (int fmt = 0; fmt < NUM_FORMATS; fmt++) begin
- is_boxed_1op[fmt] = is_boxed_i[fmt][0];
- is_boxed_2op[fmt] = is_boxed_i[fmt][1:0];
- end
- end
-
- // ---------------
- // Generate Lanes
- // ---------------
- for (genvar lane = 0; lane < int'(NUM_LANES); lane++) begin : gen_num_lanes
- localparam int unsigned LANE = unsigned'(lane); // unsigned to please the linter
- // Get a mask of active formats for this lane
- localparam fpnew_pkg::fmt_logic_t ACTIVE_FORMATS =
- fpnew_pkg::get_lane_formats(Width, FpFmtConfig, LANE);
- localparam fpnew_pkg::ifmt_logic_t ACTIVE_INT_FORMATS =
- fpnew_pkg::get_lane_int_formats(Width, FpFmtConfig, IntFmtConfig, LANE);
- localparam int unsigned MAX_WIDTH = fpnew_pkg::max_fp_width(ACTIVE_FORMATS);
-
- // Cast-specific parameters
- localparam fpnew_pkg::fmt_logic_t CONV_FORMATS =
- fpnew_pkg::get_conv_lane_formats(Width, FpFmtConfig, LANE);
- localparam fpnew_pkg::ifmt_logic_t CONV_INT_FORMATS =
- fpnew_pkg::get_conv_lane_int_formats(Width, FpFmtConfig, IntFmtConfig, LANE);
- localparam int unsigned CONV_WIDTH = fpnew_pkg::max_fp_width(CONV_FORMATS);
-
- // Lane parameters from Opgroup
- localparam fpnew_pkg::fmt_logic_t LANE_FORMATS = (OpGroup == fpnew_pkg::CONV)
- ? CONV_FORMATS : ACTIVE_FORMATS;
- localparam int unsigned LANE_WIDTH = (OpGroup == fpnew_pkg::CONV) ? CONV_WIDTH : MAX_WIDTH;
-
- logic [LANE_WIDTH-1:0] local_result; // lane-local results
-
- // Generate instances only if needed, lane 0 always generated
- if ((lane == 0) || EnableVectors) begin : active_lane
- logic in_valid, out_valid, out_ready; // lane-local handshake
-
- logic [NUM_OPERANDS-1:0][LANE_WIDTH-1:0] local_operands; // lane-local oprands
- logic [LANE_WIDTH-1:0] op_result; // lane-local results
- fpnew_pkg::status_t op_status;
-
- assign in_valid = in_valid_i & ((lane == 0) | vectorial_op); // upper lanes only for vectors
-
- // Slice out the operands for this lane, upper bits are ignored in the unit
- always_comb begin : prepare_input
- for (int unsigned i = 0; i < NUM_OPERANDS; i++) begin
- local_operands[i] = operands_i[i] >> LANE*fpnew_pkg::fp_width(src_fmt_i);
- end
-
- // override operand 0 for some conversions
- if (OpGroup == fpnew_pkg::CONV) begin
- // Source is an integer
- if (op_i == fpnew_pkg::I2F) begin
- local_operands[0] = operands_i[0] >> LANE*fpnew_pkg::int_width(int_fmt_i);
- // vectorial F2F up casts
- end else if (op_i == fpnew_pkg::F2F) begin
- if (vectorial_op && op_mod_i && is_up_cast) begin // up cast with upper half
- local_operands[0] = operands_i[0] >> LANE*fpnew_pkg::fp_width(src_fmt_i) +
- MAX_FP_WIDTH/2;
- end
- // CPK
- end else if (dst_is_cpk) begin
- if (lane == 1) begin
- local_operands[0] = operands_i[1][LANE_WIDTH-1:0]; // using opB as second argument
- end
- end
- end
- end
-
- // Instantiate the operation from the selected opgroup
- if (OpGroup == fpnew_pkg::ADDMUL) begin : lane_instance
- fpnew_fma_multi #(
- .FpFmtConfig ( LANE_FORMATS ),
- .NumPipeRegs ( NumPipeRegs ),
- .PipeConfig ( PipeConfig ),
- .TagType ( TagType ),
- .AuxType ( logic [AUX_BITS-1:0] )
- ) i_fpnew_fma_multi (
- .clk_i,
- .rst_ni,
- .operands_i ( local_operands ),
- .is_boxed_i,
- .rnd_mode_i,
- .op_i,
- .op_mod_i,
- .src_fmt_i,
- .dst_fmt_i,
- .tag_i,
- .aux_i ( aux_data ),
- .in_valid_i ( in_valid ),
- .in_ready_o ( lane_in_ready[lane] ),
- .flush_i,
- .result_o ( op_result ),
- .status_o ( op_status ),
- .extension_bit_o ( lane_ext_bit[lane] ),
- .tag_o ( lane_tags[lane] ),
- .aux_o ( lane_aux[lane] ),
- .out_valid_o ( out_valid ),
- .out_ready_i ( out_ready ),
- .busy_o ( lane_busy[lane] )
- );
-
- end else if (OpGroup == fpnew_pkg::DIVSQRT) begin : lane_instance
- fpnew_divsqrt_multi #(
- .FpFmtConfig ( LANE_FORMATS ),
- .NumPipeRegs ( NumPipeRegs ),
- .PipeConfig ( PipeConfig ),
- .TagType ( TagType ),
- .AuxType ( logic [AUX_BITS-1:0] )
- ) i_fpnew_divsqrt_multi (
- .clk_i,
- .rst_ni,
- .operands_i ( local_operands[1:0] ), // 2 operands
- .is_boxed_i ( is_boxed_2op ), // 2 operands
- .rnd_mode_i,
- .op_i,
- .dst_fmt_i,
- .tag_i,
- .aux_i ( aux_data ),
- .in_valid_i ( in_valid ),
- .in_ready_o ( lane_in_ready[lane] ),
- .flush_i,
- .result_o ( op_result ),
- .status_o ( op_status ),
- .extension_bit_o ( lane_ext_bit[lane] ),
- .tag_o ( lane_tags[lane] ),
- .aux_o ( lane_aux[lane] ),
- .out_valid_o ( out_valid ),
- .out_ready_i ( out_ready ),
- .busy_o ( lane_busy[lane] )
- );
- end else if (OpGroup == fpnew_pkg::NONCOMP) begin : lane_instance
-
- end else if (OpGroup == fpnew_pkg::CONV) begin : lane_instance
- fpnew_cast_multi #(
- .FpFmtConfig ( LANE_FORMATS ),
- .IntFmtConfig ( CONV_INT_FORMATS ),
- .NumPipeRegs ( NumPipeRegs ),
- .PipeConfig ( PipeConfig ),
- .TagType ( TagType ),
- .AuxType ( logic [AUX_BITS-1:0] )
- ) i_fpnew_cast_multi (
- .clk_i,
- .rst_ni,
- .operands_i ( local_operands[0] ),
- .is_boxed_i ( is_boxed_1op ),
- .rnd_mode_i,
- .op_i,
- .op_mod_i,
- .src_fmt_i,
- .dst_fmt_i,
- .int_fmt_i,
- .tag_i,
- .aux_i ( aux_data ),
- .in_valid_i ( in_valid ),
- .in_ready_o ( lane_in_ready[lane] ),
- .flush_i,
- .result_o ( op_result ),
- .status_o ( op_status ),
- .extension_bit_o ( lane_ext_bit[lane] ),
- .tag_o ( lane_tags[lane] ),
- .aux_o ( lane_aux[lane] ),
- .out_valid_o ( out_valid ),
- .out_ready_i ( out_ready ),
- .busy_o ( lane_busy[lane] )
- );
- end // ADD OTHER OPTIONS HERE
-
- // Handshakes are only done if the lane is actually used
- assign out_ready = out_ready_i & ((lane == 0) | result_is_vector);
- assign lane_out_valid[lane] = out_valid & ((lane == 0) | result_is_vector);
-
- // Properly NaN-box or sign-extend the slice result if not in use
- assign local_result = lane_out_valid[lane] ? op_result : '{default: lane_ext_bit[0]};
- assign lane_status[lane] = lane_out_valid[lane] ? op_status : '0;
-
- // Otherwise generate constant sign-extension
- end else begin : inactive_lane
- assign lane_out_valid[lane] = 1'b0; // unused lane
- assign lane_in_ready[lane] = 1'b0; // unused lane
- assign local_result = '{default: lane_ext_bit[0]}; // sign-extend/nan box
- assign lane_status[lane] = '0;
- assign lane_busy[lane] = 1'b0;
- end
-
- // Generate result packing depending on float format
- for (genvar fmt = 0; fmt < NUM_FORMATS; fmt++) begin : pack_fp_result
- // Set up some constants
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- // only for active formats within the lane
- if (ACTIVE_FORMATS[fmt]) begin
- assign fmt_slice_result[fmt][(LANE+1)*FP_WIDTH-1:LANE*FP_WIDTH] =
- local_result[FP_WIDTH-1:0];
- end else if ((LANE+1)*FP_WIDTH <= Width) begin
- assign fmt_slice_result[fmt][(LANE+1)*FP_WIDTH-1:LANE*FP_WIDTH] =
- '{default: lane_ext_bit[LANE]};
- end else if (LANE*FP_WIDTH < Width) begin
- assign fmt_slice_result[fmt][Width-1:LANE*FP_WIDTH] =
- '{default: lane_ext_bit[LANE]};
- end
- end
-
- // Generate result packing depending on integer format
- if (OpGroup == fpnew_pkg::CONV) begin : int_results_enabled
- for (genvar ifmt = 0; ifmt < NUM_INT_FORMATS; ifmt++) begin : pack_int_result
- // Set up some constants
- localparam int unsigned INT_WIDTH = fpnew_pkg::int_width(fpnew_pkg::int_format_e'(ifmt));
- if (ACTIVE_INT_FORMATS[ifmt]) begin
- assign ifmt_slice_result[ifmt][(LANE+1)*INT_WIDTH-1:LANE*INT_WIDTH] =
- local_result[INT_WIDTH-1:0];
- end else if ((LANE+1)*INT_WIDTH <= Width) begin
- assign ifmt_slice_result[ifmt][(LANE+1)*INT_WIDTH-1:LANE*INT_WIDTH] = '0;
- end else if (LANE*INT_WIDTH < Width) begin
- assign ifmt_slice_result[ifmt][Width-1:LANE*INT_WIDTH] = '0;
- end
- end
- end
- end
-
- // Extend slice result if needed
- for (genvar fmt = 0; fmt < NUM_FORMATS; fmt++) begin : extend_fp_result
- // Set up some constants
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- if (NUM_LANES*FP_WIDTH < Width)
- assign fmt_slice_result[fmt][Width-1:NUM_LANES*FP_WIDTH] = '{default: lane_ext_bit[0]};
- end
-
- // Mute int results if unused
- for (genvar ifmt = 0; ifmt < NUM_INT_FORMATS; ifmt++) begin : int_results_disabled
- if (OpGroup != fpnew_pkg::CONV) begin : mute_int_result
- assign ifmt_slice_result[ifmt] = '0;
- end
- end
-
- // Bypass lanes with target operand for vectorial casts
- if (OpGroup == fpnew_pkg::CONV) begin : target_regs
- // Bypass pipeline signals, index i holds signal after i register stages
- logic [0:NumPipeRegs][Width-1:0] byp_pipe_target_q;
- logic [0:NumPipeRegs][2:0] byp_pipe_aux_q;
- logic [0:NumPipeRegs] byp_pipe_valid_q;
- // Ready signal is combinatorial for all stages
- logic [0:NumPipeRegs] byp_pipe_ready;
-
- // Input stage: First element of pipeline is taken from inputs
- assign byp_pipe_target_q[0] = conv_target_d;
- assign byp_pipe_aux_q[0] = target_aux_d;
- assign byp_pipe_valid_q[0] = in_valid_i & vectorial_op;
- // Generate the register stages
- for (genvar i = 0; i < NumPipeRegs; i++) begin : gen_bypass_pipeline
- // Internal register enable for this stage
- logic reg_ena;
- // Determine the ready signal of the current stage - advance the pipeline:
- // 1. if the next stage is ready for our data
- // 2. if the next stage only holds a bubble (not valid) -> we can pop it
- assign byp_pipe_ready[i] = byp_pipe_ready[i+1] | ~byp_pipe_valid_q[i+1];
- // Valid: enabled by ready signal, synchronous clear with the flush signal
- `FFLARNC(byp_pipe_valid_q[i+1], byp_pipe_valid_q[i], byp_pipe_ready[i], flush_i, 1'b0, clk_i, rst_ni)
- // Enable register if pipleine ready and a valid data item is present
- assign reg_ena = byp_pipe_ready[i] & byp_pipe_valid_q[i];
- // Generate the pipeline registers within the stages, use enable-registers
- `FFL(byp_pipe_target_q[i+1], byp_pipe_target_q[i], reg_ena, '0)
- `FFL(byp_pipe_aux_q[i+1], byp_pipe_aux_q[i], reg_ena, '0)
- end
- // Output stage: Ready travels backwards from output side, driven by downstream circuitry
- assign byp_pipe_ready[NumPipeRegs] = out_ready_i & result_is_vector;
- // Output stage: assign module outputs
- assign conv_target_q = byp_pipe_target_q[NumPipeRegs];
-
- // decode the aux data
- assign {result_vec_op, result_is_cpk} = byp_pipe_aux_q[NumPipeRegs];
- end else begin : no_conv
- assign {result_vec_op, result_is_cpk} = '0;
- end
-
- // ------------
- // Output Side
- // ------------
- assign {result_fmt_is_int, result_is_vector, result_fmt} = lane_aux[0];
-
- assign result_o = result_fmt_is_int
- ? ifmt_slice_result[result_fmt]
- : fmt_slice_result[result_fmt];
-
- assign extension_bit_o = lane_ext_bit[0]; // don't care about upper ones
- assign tag_o = lane_tags[0]; // don't care about upper ones
- assign busy_o = (| lane_busy);
-
- assign out_valid_o = lane_out_valid[0]; // don't care about upper ones
-
- // Collapse the status
- always_comb begin : output_processing
- // Collapse the status
- automatic fpnew_pkg::status_t temp_status;
- temp_status = '0;
- for (int i = 0; i < int'(NUM_LANES); i++)
- temp_status |= lane_status[i];
- status_o = temp_status;
- end
-endmodule
diff --git a/verilog/rtl/fpnew_pkg.sv b/verilog/rtl/fpnew_pkg.sv
deleted file mode 100644
index 2d258cf..0000000
--- a/verilog/rtl/fpnew_pkg.sv
+++ /dev/null
@@ -1,491 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-package fpnew_pkg;
-
- // ---------
- // FP TYPES
- // ---------
- // | Enumerator | Format | Width | EXP_BITS | MAN_BITS
- // |:----------:|------------------|-------:|:--------:|:--------:
- // | FP32 | IEEE binary32 | 32 bit | 8 | 23
- // | FP64 | IEEE binary64 | 64 bit | 11 | 52
- // | FP16 | IEEE binary16 | 16 bit | 5 | 10
- // | FP8 | binary8 | 8 bit | 5 | 2
- // | FP16ALT | binary16alt | 16 bit | 8 | 7
- // *NOTE:* Add new formats only at the end of the enumeration for backwards compatibilty!
-
- // Encoding for a format
- typedef struct packed {
- int unsigned exp_bits;
- int unsigned man_bits;
- } fp_encoding_t;
-
- localparam int unsigned NUM_FP_FORMATS = 5; // change me to add formats
- localparam int unsigned FP_FORMAT_BITS = $clog2(NUM_FP_FORMATS);
-
- // FP formats
- typedef enum logic [FP_FORMAT_BITS-1:0] {
- FP32 = 'd0,
- FP64 = 'd1,
- FP16 = 'd2,
- FP8 = 'd3,
- FP16ALT = 'd4
- // add new formats here
- } fp_format_e;
-
- // Encodings for supported FP formats
- localparam fp_encoding_t [0:NUM_FP_FORMATS-1] FP_ENCODINGS = '{
- '{8, 23}, // IEEE binary32 (single)
- '{11, 52}, // IEEE binary64 (double)
- '{5, 10}, // IEEE binary16 (half)
- '{5, 2}, // custom binary8
- '{8, 7} // custom binary16alt
- // add new formats here
- };
-
- typedef logic [0:NUM_FP_FORMATS-1] fmt_logic_t; // Logic indexed by FP format (for masks)
- typedef logic [0:NUM_FP_FORMATS-1][31:0] fmt_unsigned_t; // Unsigned indexed by FP format
-
- localparam fmt_logic_t CPK_FORMATS = 5'b11000; // FP32 and FP64 can provide CPK only
-
- // ---------
- // INT TYPES
- // ---------
- // | Enumerator | Width |
- // |:----------:|-------:|
- // | INT8 | 8 bit |
- // | INT16 | 16 bit |
- // | INT32 | 32 bit |
- // | INT64 | 64 bit |
- // *NOTE:* Add new formats only at the end of the enumeration for backwards compatibilty!
-
- localparam int unsigned NUM_INT_FORMATS = 4; // change me to add formats
- localparam int unsigned INT_FORMAT_BITS = $clog2(NUM_INT_FORMATS);
-
- // Int formats
- typedef enum logic [INT_FORMAT_BITS-1:0] {
- INT8,
- INT16,
- INT32,
- INT64
- // add new formats here
- } int_format_e;
-
- // Returns the width of an INT format by index
- function automatic int unsigned int_width(int_format_e ifmt);
- unique case (ifmt)
- INT8: return 8;
- INT16: return 16;
- INT32: return 32;
- INT64: return 64;
- // default: begin
- // pragma translate_off
- // $fatal(1, "Invalid INT format supplied");
- // pragma translate_on
- // just return any integer to avoid any latches
- // hopefully this error is caught by simulation
- //return INT8;
- //end
- endcase
- endfunction
-
- typedef logic [0:NUM_INT_FORMATS-1] ifmt_logic_t; // Logic indexed by INT format (for masks)
-
- // --------------
- // FP OPERATIONS
- // --------------
- localparam int unsigned NUM_OPGROUPS = 4;
-
- // Each FP operation belongs to an operation group
- typedef enum logic [1:0] {
- ADDMUL, DIVSQRT, NONCOMP, CONV
- } opgroup_e;
-
- localparam int unsigned OP_BITS = 4;
-
- typedef enum logic [OP_BITS-1:0] {
- FMADD, FNMSUB, ADD, MUL, // ADDMUL operation group
- DIV, SQRT, // DIVSQRT operation group
- SGNJ, MINMAX, CMP, CLASSIFY, // NONCOMP operation group
- F2F, F2I, I2F, CPKAB, CPKCD // CONV operation group
- } operation_e;
-
- // -------------------
- // RISC-V FP-SPECIFIC
- // -------------------
- // Rounding modes
- typedef enum logic [2:0] {
- RNE = 3'b000,
- RTZ = 3'b001,
- RDN = 3'b010,
- RUP = 3'b011,
- RMM = 3'b100,
- DYN = 3'b111
- } roundmode_e;
-
- // Status flags
- typedef struct packed {
- logic NV; // Invalid
- logic DZ; // Divide by zero
- logic OF; // Overflow
- logic UF; // Underflow
- logic NX; // Inexact
- } status_t;
-
- // Information about a floating point value
- typedef struct packed {
- logic is_normal; // is the value normal
- logic is_subnormal; // is the value subnormal
- logic is_zero; // is the value zero
- logic is_inf; // is the value infinity
- logic is_nan; // is the value NaN
- logic is_signalling; // is the value a signalling NaN
- logic is_quiet; // is the value a quiet NaN
- logic is_boxed; // is the value properly NaN-boxed (RISC-V specific)
- } fp_info_t;
-
- // Classification mask
- typedef enum logic [9:0] {
- NEGINF = 10'b00_0000_0001,
- NEGNORM = 10'b00_0000_0010,
- NEGSUBNORM = 10'b00_0000_0100,
- NEGZERO = 10'b00_0000_1000,
- POSZERO = 10'b00_0001_0000,
- POSSUBNORM = 10'b00_0010_0000,
- POSNORM = 10'b00_0100_0000,
- POSINF = 10'b00_1000_0000,
- SNAN = 10'b01_0000_0000,
- QNAN = 10'b10_0000_0000
- } classmask_e;
-
- // ------------------
- // FPU configuration
- // ------------------
- // Pipelining registers can be inserted (at elaboration time) into operational units
- typedef enum logic [1:0] {
- BEFORE, // registers are inserted at the inputs of the unit
- AFTER, // registers are inserted at the outputs of the unit
- INSIDE, // registers are inserted at predetermined (suboptimal) locations in the unit
- DISTRIBUTED // registers are evenly distributed, INSIDE >= AFTER >= BEFORE
- } pipe_config_t;
-
- // Arithmetic units can be arranged in parallel (per format), merged (multi-format) or not at all.
- typedef enum logic [1:0] {
- DISABLED, // arithmetic units are not generated
- PARALLEL, // arithmetic units are generated in prallel slices, one for each format
- MERGED // arithmetic units are contained within a merged unit holding multiple formats
- } unit_type_t;
-
- // Array of unit types indexed by format
- typedef unit_type_t [0:NUM_FP_FORMATS-1] fmt_unit_types_t;
-
- // Array of format-specific unit types by opgroup
- typedef fmt_unit_types_t [0:NUM_OPGROUPS-1] opgrp_fmt_unit_types_t;
- // same with unsigned
- typedef fmt_unsigned_t [0:NUM_OPGROUPS-1] opgrp_fmt_unsigned_t;
-
- // FPU configuration: features
- typedef struct packed {
- int unsigned Width;
- logic EnableVectors;
- logic EnableNanBox;
- fmt_logic_t FpFmtMask;
- ifmt_logic_t IntFmtMask;
- } fpu_features_t;
-
- localparam fpu_features_t RV64D = '{
- Width: 64,
- EnableVectors: 1'b0,
- EnableNanBox: 1'b1,
- FpFmtMask: 5'b11000,
- IntFmtMask: 4'b0011
- };
-
- localparam fpu_features_t RV32D = '{
- Width: 64,
- EnableVectors: 1'b1,
- EnableNanBox: 1'b1,
- FpFmtMask: 5'b11000,
- IntFmtMask: 4'b0010
- };
-
- localparam fpu_features_t RV32F = '{
- Width: 32,
- EnableVectors: 1'b0,
- EnableNanBox: 1'b1,
- FpFmtMask: 5'b10000,
- IntFmtMask: 4'b0010
- };
-
- localparam fpu_features_t RV64D_Xsflt = '{
- Width: 64,
- EnableVectors: 1'b1,
- EnableNanBox: 1'b1,
- FpFmtMask: 5'b11111,
- IntFmtMask: 4'b1111
- };
-
- localparam fpu_features_t RV32F_Xsflt = '{
- Width: 32,
- EnableVectors: 1'b1,
- EnableNanBox: 1'b1,
- FpFmtMask: 5'b10111,
- IntFmtMask: 4'b1110
- };
-
- localparam fpu_features_t RV32F_Xf16alt_Xfvec = '{
- Width: 32,
- EnableVectors: 1'b1,
- EnableNanBox: 1'b1,
- FpFmtMask: 5'b10001,
- IntFmtMask: 4'b0110
- };
-
- // FPU configuraion: implementation
- typedef struct packed {
- opgrp_fmt_unsigned_t PipeRegs;
- opgrp_fmt_unit_types_t UnitTypes;
- pipe_config_t PipeConfig;
- } fpu_implementation_t;
-
- localparam fpu_implementation_t DEFAULT_NOREGS = '{
- PipeRegs: '{default: 0},
- UnitTypes: '{'{default: PARALLEL}, // ADDMUL
- '{default: MERGED}, // DIVSQRT
- '{default: PARALLEL}, // NONCOMP
- '{default: MERGED}}, // CONV
- PipeConfig: BEFORE
- };
-
- localparam fpu_implementation_t DEFAULT_SNITCH = '{
- PipeRegs: '{default: 1},
- UnitTypes: '{'{default: PARALLEL}, // ADDMUL
- '{default: DISABLED}, // DIVSQRT
- '{default: PARALLEL}, // NONCOMP
- '{default: MERGED}}, // CONV
- PipeConfig: BEFORE
- };
-
- // -----------------------
- // Synthesis optimization
- // -----------------------
- localparam logic DONT_CARE = 1'b1; // the value to assign as don't care
-
- // -------------------------
- // General helper functions
- // -------------------------
- function automatic int minimum(int a, int b);
- return (a < b) ? a : b;
- endfunction
-
- function automatic int maximum(int a, int b);
- return (a > b) ? a : b;
- endfunction
-
- // -------------------------------------------
- // Helper functions for FP formats and values
- // -------------------------------------------
- // Returns the width of a FP format
- function automatic int unsigned fp_width(fp_format_e fmt);
- return FP_ENCODINGS[fmt].exp_bits + FP_ENCODINGS[fmt].man_bits + 1;
- endfunction
-
- // Returns the widest FP format present
- function automatic int unsigned max_fp_width(fmt_logic_t cfg);
- automatic int unsigned res = 0;
- for (int unsigned i = 0; i < NUM_FP_FORMATS; i++)
- if (cfg[i])
- res = unsigned'(maximum(res, fp_width(fp_format_e'(i))));
- return res;
- endfunction
-
- // Returns the narrowest FP format present
- function automatic int unsigned min_fp_width(fmt_logic_t cfg);
- automatic int unsigned res = max_fp_width(cfg);
- for (int unsigned i = 0; i < NUM_FP_FORMATS; i++)
- if (cfg[i])
- res = unsigned'(minimum(res, fp_width(fp_format_e'(i))));
- return res;
- endfunction
-
- // Returns the number of expoent bits for a format
- function automatic int unsigned exp_bits(fp_format_e fmt);
- return FP_ENCODINGS[fmt].exp_bits;
- endfunction
-
- // Returns the number of mantissa bits for a format
- function automatic int unsigned man_bits(fp_format_e fmt);
- return FP_ENCODINGS[fmt].man_bits;
- endfunction
-
- // Returns the bias value for a given format (as per IEEE 754-2008)
- function automatic int unsigned bias(fp_format_e fmt);
- return unsigned'(2**(FP_ENCODINGS[fmt].exp_bits-1)-1); // symmetrical bias
- endfunction
-
- function automatic fp_encoding_t super_format(fmt_logic_t cfg);
- automatic fp_encoding_t res;
- res = '0;
- for (int unsigned fmt = 0; fmt < NUM_FP_FORMATS; fmt++)
- if (cfg[fmt]) begin // only active format
- res.exp_bits = unsigned'(maximum(res.exp_bits, exp_bits(fp_format_e'(fmt))));
- res.man_bits = unsigned'(maximum(res.man_bits, man_bits(fp_format_e'(fmt))));
- end
- return res;
- endfunction
-
- // -------------------------------------------
- // Helper functions for INT formats and values
- // -------------------------------------------
- // Returns the widest INT format present
- function automatic int unsigned max_int_width(ifmt_logic_t cfg);
- automatic int unsigned res = 0;
- for (int ifmt = 0; ifmt < NUM_INT_FORMATS; ifmt++) begin
- if (cfg[ifmt]) res = maximum(res, int_width(int_format_e'(ifmt)));
- end
- return res;
- endfunction
-
- // --------------------------------------------------
- // Helper functions for operations and FPU structure
- // --------------------------------------------------
- // Returns the operation group of the given operation
- function automatic opgroup_e get_opgroup(operation_e op);
- unique case (op)
- FMADD, FNMSUB, ADD, MUL: return ADDMUL;
- DIV, SQRT: return DIVSQRT;
- SGNJ, MINMAX, CMP, CLASSIFY: return NONCOMP;
- F2F, F2I, I2F, CPKAB, CPKCD: return CONV;
- default: return NONCOMP;
- endcase
- endfunction
-
- // Returns the number of operands by operation group
- function automatic int unsigned num_operands(opgroup_e grp);
- unique case (grp)
- ADDMUL: return 3;
- DIVSQRT: return 2;
- NONCOMP: return 2;
- CONV: return 3; // vectorial casts use 3 operands
- default: return 0;
- endcase
- endfunction
-
- // Returns the number of lanes according to width, format and vectors
- function automatic int unsigned num_lanes(int unsigned width, fp_format_e fmt, logic vec);
- return vec ? width / fp_width(fmt) : 1; // if no vectors, only one lane
- endfunction
-
- // Returns the maximum number of lanes in the FPU according to width, format config and vectors
- function automatic int unsigned max_num_lanes(int unsigned width, fmt_logic_t cfg, logic vec);
- return vec ? width / min_fp_width(cfg) : 1; // if no vectors, only one lane
- endfunction
-
- // Returns a mask of active FP formats that are present in lane lane_no of a multiformat slice
- function automatic fmt_logic_t get_lane_formats(int unsigned width,
- fmt_logic_t cfg,
- int unsigned lane_no);
- automatic fmt_logic_t res;
- for (int unsigned fmt = 0; fmt < NUM_FP_FORMATS; fmt++)
- // Mask active formats with the number of lanes for that format
- res[fmt] = cfg[fmt] & (width / fp_width(fp_format_e'(fmt)) > lane_no);
- return res;
- endfunction
-
- // Returns a mask of active INT formats that are present in lane lane_no of a multiformat slice
- function automatic ifmt_logic_t get_lane_int_formats(int unsigned width,
- fmt_logic_t cfg,
- ifmt_logic_t icfg,
- int unsigned lane_no);
- automatic ifmt_logic_t res;
- automatic fmt_logic_t lanefmts;
- res = '0;
- lanefmts = get_lane_formats(width, cfg, lane_no);
-
- for (int unsigned ifmt = 0; ifmt < NUM_INT_FORMATS; ifmt++)
- for (int unsigned fmt = 0; fmt < NUM_FP_FORMATS; fmt++)
- // Mask active int formats with the width of the float formats
- if ((fp_width(fp_format_e'(fmt)) == int_width(int_format_e'(ifmt))))
- res[ifmt] |= icfg[ifmt] && lanefmts[fmt];
- return res;
- endfunction
-
- // Returns a mask of active FP formats that are present in lane lane_no of a CONV slice
- function automatic fmt_logic_t get_conv_lane_formats(int unsigned width,
- fmt_logic_t cfg,
- int unsigned lane_no);
- automatic fmt_logic_t res;
- for (int unsigned fmt = 0; fmt < NUM_FP_FORMATS; fmt++)
- // Mask active formats with the number of lanes for that format, CPK at least twice
- res[fmt] = cfg[fmt] && ((width / fp_width(fp_format_e'(fmt)) > lane_no) ||
- (CPK_FORMATS[fmt] && (lane_no < 2)));
- return res;
- endfunction
-
- // Returns a mask of active INT formats that are present in lane lane_no of a CONV slice
- function automatic ifmt_logic_t get_conv_lane_int_formats(int unsigned width,
- fmt_logic_t cfg,
- ifmt_logic_t icfg,
- int unsigned lane_no);
- automatic ifmt_logic_t res;
- automatic fmt_logic_t lanefmts;
- res = '0;
- lanefmts = get_conv_lane_formats(width, cfg, lane_no);
-
- for (int unsigned ifmt = 0; ifmt < NUM_INT_FORMATS; ifmt++)
- for (int unsigned fmt = 0; fmt < NUM_FP_FORMATS; fmt++)
- // Mask active int formats with the width of the float formats
- res[ifmt] |= icfg[ifmt] && lanefmts[fmt] &&
- (fp_width(fp_format_e'(fmt)) == int_width(int_format_e'(ifmt)));
- return res;
- endfunction
-
- // Return whether any active format is set as MERGED
- function automatic logic any_enabled_multi(fmt_unit_types_t types, fmt_logic_t cfg);
- for (int unsigned i = 0; i < NUM_FP_FORMATS; i++)
- if (cfg[i] && types[i] == MERGED)
- return 1'b1;
- return 1'b0;
- endfunction
-
- // Return whether the given format is the first active one set as MERGED
- function automatic logic is_first_enabled_multi(fp_format_e fmt,
- fmt_unit_types_t types,
- fmt_logic_t cfg);
- for (int unsigned i = 0; i < NUM_FP_FORMATS; i++) begin
- if (cfg[i] && types[i] == MERGED) return (fp_format_e'(i) == fmt);
- end
- return 1'b0;
- endfunction
-
- // Returns the first format that is active and is set as MERGED
- function automatic fp_format_e get_first_enabled_multi(fmt_unit_types_t types, fmt_logic_t cfg);
- for (int unsigned i = 0; i < NUM_FP_FORMATS; i++)
- if (cfg[i] && types[i] == MERGED)
- return fp_format_e'(i);
- return fp_format_e'(0);
- endfunction
-
- // Returns the largest number of regs that is active and is set as MERGED
- function automatic int unsigned get_num_regs_multi(fmt_unsigned_t regs,
- fmt_unit_types_t types,
- fmt_logic_t cfg);
- automatic int unsigned res = 0;
- for (int unsigned i = 0; i < NUM_FP_FORMATS; i++) begin
- if (cfg[i] && types[i] == MERGED) res = maximum(res, regs[i]);
- end
- return res;
- endfunction
-
-endpackage
diff --git a/verilog/rtl/fpnew_rounding.sv b/verilog/rtl/fpnew_rounding.sv
deleted file mode 100644
index 4e4b7c7..0000000
--- a/verilog/rtl/fpnew_rounding.sv
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-module fpnew_rounding #(
- parameter int unsigned AbsWidth=2 // Width of the abolute value, without sign bit
-) (
- // Input value
- input logic [AbsWidth-1:0] abs_value_i, // absolute value without sign
- input logic sign_i,
- // Rounding information
- input logic [1:0] round_sticky_bits_i, // round and sticky bits {RS}
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input logic effective_subtraction_i, // sign of inputs affects rounding of zeroes
- // Output value
- output logic [AbsWidth-1:0] abs_rounded_o, // absolute value without sign
- output logic sign_o,
- // Output classification
- output logic exact_zero_o // output is an exact zero
-);
-
- logic round_up; // Rounding decision
-
- // Take the rounding decision according to RISC-V spec
- // RoundMode | Mnemonic | Meaning
- // :--------:|:--------:|:-------
- // 000 | RNE | Round to Nearest, ties to Even
- // 001 | RTZ | Round towards Zero
- // 010 | RDN | Round Down (towards -\infty)
- // 011 | RUP | Round Up (towards \infty)
- // 100 | RMM | Round to Nearest, ties to Max Magnitude
- // others | | *invalid*
- always_comb begin : rounding_decision
- unique case (rnd_mode_i)
- fpnew_pkg::RNE: // Decide accoring to round/sticky bits
- unique case (round_sticky_bits_i)
- 2'b00,
- 2'b01: round_up = 1'b0; // < ulp/2 away, round down
- 2'b10: round_up = abs_value_i[0]; // = ulp/2 away, round towards even result
- 2'b11: round_up = 1'b1; // > ulp/2 away, round up
- //default: round_up = fpnew_pkg::DONT_CARE;
- endcase
- fpnew_pkg::RTZ: round_up = 1'b0; // always round down
- fpnew_pkg::RDN: round_up = (| round_sticky_bits_i) ? sign_i : 1'b0; // to 0 if +, away if -
- fpnew_pkg::RUP: round_up = (| round_sticky_bits_i) ? ~sign_i : 1'b0; // to 0 if -, away if +
- fpnew_pkg::RMM: round_up = round_sticky_bits_i[1]; // round down if < ulp/2 away, else up
- default: round_up = fpnew_pkg::DONT_CARE; // propagate x
- endcase
- end
-
- // Perform the rounding, exponent change and overflow to inf happens automagically
- assign abs_rounded_o = abs_value_i + round_up;
-
- // True zero result is a zero result without dirty round/sticky bits
- assign exact_zero_o = (abs_value_i == '0) && (round_sticky_bits_i == '0);
-
- // In case of effective subtraction (thus signs of addition operands must have differed) and a
- // true zero result, the result sign is '-' in case of RDN and '+' for other modes.
- assign sign_o = (exact_zero_o && effective_subtraction_i)
- ? (rnd_mode_i == fpnew_pkg::RDN)
- : sign_i;
-
-endmodule
diff --git a/verilog/rtl/fpnew_top.sv b/verilog/rtl/fpnew_top.sv
deleted file mode 100644
index 5b37edd..0000000
--- a/verilog/rtl/fpnew_top.sv
+++ /dev/null
@@ -1,172 +0,0 @@
-// 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: Stefan Mach <smach@iis.ee.ethz.ch>
-
-module fpnew_top #(
- // FPU configuration
- parameter fpnew_pkg::fpu_features_t Features = fpnew_pkg::RV64D_Xsflt,
- parameter fpnew_pkg::fpu_implementation_t Implementation = fpnew_pkg::DEFAULT_NOREGS,
- parameter type TagType = logic,
- // Do not change
- localparam int unsigned WIDTH = Features.Width,
- localparam int unsigned NUM_OPERANDS = 3
-) (
- input logic clk_i,
- input logic rst_ni,
- // Input signals
- input logic [NUM_OPERANDS-1:0][WIDTH-1:0] operands_i,
- input fpnew_pkg::roundmode_e rnd_mode_i,
- input fpnew_pkg::operation_e op_i,
- input logic op_mod_i,
- input fpnew_pkg::fp_format_e src_fmt_i,
- input fpnew_pkg::fp_format_e dst_fmt_i,
- input fpnew_pkg::int_format_e int_fmt_i,
- input logic vectorial_op_i,
- input TagType tag_i,
- // Input Handshake
- input logic in_valid_i,
- output logic in_ready_o,
- input logic flush_i,
- // Output signals
- output logic [WIDTH-1:0] result_o,
- output fpnew_pkg::status_t status_o,
- output TagType tag_o,
- // Output handshake
- output logic out_valid_o,
- input logic out_ready_i,
- // Indication of valid data in flight
- output logic busy_o
-);
-
- localparam int unsigned NUM_OPGROUPS = fpnew_pkg::NUM_OPGROUPS;
- localparam int unsigned NUM_FORMATS = fpnew_pkg::NUM_FP_FORMATS;
-
- // ----------------
- // Type Definition
- // ----------------
- typedef struct packed {
- logic [WIDTH-1:0] result;
- fpnew_pkg::status_t status;
- TagType tag;
- } output_t;
-
- // Handshake signals for the blocks
- logic [NUM_OPGROUPS-1:0] opgrp_in_ready, opgrp_out_valid, opgrp_out_ready, opgrp_ext, opgrp_busy;
- output_t [NUM_OPGROUPS-1:0] opgrp_outputs;
-
- logic [NUM_FORMATS-1:0][NUM_OPERANDS-1:0] is_boxed;
-
- // -----------
- // Input Side
- // -----------
- assign in_ready_o = in_valid_i & opgrp_in_ready[fpnew_pkg::get_opgroup(op_i)];
-
- // NaN-boxing check
- for (genvar fmt = 0; fmt < int'(NUM_FORMATS); fmt++) begin : gen_nanbox_check
- localparam int unsigned FP_WIDTH = fpnew_pkg::fp_width(fpnew_pkg::fp_format_e'(fmt));
- // NaN boxing is only generated if it's enabled and needed
- if (Features.EnableNanBox && (FP_WIDTH < WIDTH)) begin : check
- for (genvar op = 0; op < int'(NUM_OPERANDS); op++) begin : operands
- assign is_boxed[fmt][op] = (!vectorial_op_i)
- ? operands_i[op][WIDTH-1:FP_WIDTH] == '1
- : 1'b1;
- end
- end else begin : no_check
- assign is_boxed[fmt] = '1;
- end
- end
-
- // -------------------------
- // Generate Operation Blocks
- // -------------------------
- for (genvar opgrp = 0; opgrp < int'(NUM_OPGROUPS); opgrp++) begin : gen_operation_groups
- localparam int unsigned NUM_OPS = fpnew_pkg::num_operands(fpnew_pkg::opgroup_e'(opgrp));
-
- logic in_valid;
- logic [NUM_FORMATS-1:0][NUM_OPS-1:0] input_boxed;
-
- assign in_valid = in_valid_i & (fpnew_pkg::get_opgroup(op_i) == fpnew_pkg::opgroup_e'(opgrp));
-
- // slice out input boxing
- always_comb begin : slice_inputs
- for (int unsigned fmt = 0; fmt < NUM_FORMATS; fmt++)
- input_boxed[fmt] = is_boxed[fmt][NUM_OPS-1:0];
- end
-
- fpnew_opgroup_block #(
- .OpGroup ( fpnew_pkg::opgroup_e'(opgrp) ),
- .Width ( WIDTH ),
- .EnableVectors ( Features.EnableVectors ),
- .FpFmtMask ( Features.FpFmtMask ),
- .IntFmtMask ( Features.IntFmtMask ),
- .FmtPipeRegs ( Implementation.PipeRegs[opgrp] ),
- .FmtUnitTypes ( Implementation.UnitTypes[opgrp] ),
- .PipeConfig ( Implementation.PipeConfig ),
- .TagType ( TagType )
- ) i_opgroup_block (
- .clk_i,
- .rst_ni,
- .operands_i ( operands_i[NUM_OPS-1:0] ),
- .is_boxed_i ( input_boxed ),
- .rnd_mode_i,
- .op_i,
- .op_mod_i,
- .src_fmt_i,
- .dst_fmt_i,
- .int_fmt_i,
- .vectorial_op_i,
- .tag_i,
- .in_valid_i ( in_valid ),
- .in_ready_o ( opgrp_in_ready[opgrp] ),
- .flush_i,
- .result_o ( opgrp_outputs[opgrp].result ),
- .status_o ( opgrp_outputs[opgrp].status ),
- .extension_bit_o ( opgrp_ext[opgrp] ),
- .tag_o ( opgrp_outputs[opgrp].tag ),
- .out_valid_o ( opgrp_out_valid[opgrp] ),
- .out_ready_i ( opgrp_out_ready[opgrp] ),
- .busy_o ( opgrp_busy[opgrp] )
- );
- end
-
- // ------------------
- // Arbitrate Outputs
- // ------------------
- output_t arbiter_output;
-
- // Round-Robin arbiter to decide which result to use
- rr_arb_tree #(
- .NumIn ( NUM_OPGROUPS ),
- .DataType ( output_t ),
- .AxiVldRdy ( 1'b1 )
- ) i_arbiter (
- .clk_i,
- .rst_ni,
- .flush_i,
- .rr_i ( '0 ),
- .req_i ( opgrp_out_valid ),
- .gnt_o ( opgrp_out_ready ),
- .data_i ( opgrp_outputs ),
- .gnt_i ( out_ready_i ),
- .req_o ( out_valid_o ),
- .data_o ( arbiter_output ),
- .idx_o ( /* unused */ )
- );
-
- // Unpack output
- assign result_o = arbiter_output.result;
- assign status_o = arbiter_output.status;
- assign tag_o = arbiter_output.tag;
-
- assign busy_o = (| opgrp_busy);
-
-endmodule
diff --git a/verilog/rtl/gpio.sv b/verilog/rtl/gpio.sv
deleted file mode 100644
index 762553c..0000000
--- a/verilog/rtl/gpio.sv
+++ /dev/null
@@ -1,144 +0,0 @@
-
-// General Purpose Input/Output module
-
-
-module gpio (
- input clk_i,
- input rst_ni,
-
- // Below Regster interface can be changed
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
-
- input [31:0] cio_gpio_i,
- output logic [31:0] cio_gpio_o,
- output logic [31:0] cio_gpio_en_o,
-
- output logic [31:0] intr_gpio_o
-);
-
- import gpio_reg_pkg::* ;
-
- gpio_reg2hw_t reg2hw;
- gpio_hw2reg_t hw2reg;
-
- logic [31:0] cio_gpio_q;
- logic [31:0] cio_gpio_en_q;
-
- // possibly filter the input based upon register configuration
-
- logic [31:0] data_in_d;
-
- for (genvar i = 0 ; i < 32 ; i++) begin : gen_filter
- prim_filter_ctr #(.Cycles(16)) filter (
- .clk_i,
- .rst_ni,
- .enable_i(reg2hw.ctrl_en_input_filter.q[i]),
- .filter_i(cio_gpio_i[i]),
- .filter_o(data_in_d[i])
- );
- end
-
- // GPIO_IN
- assign hw2reg.data_in.de = 1'b1;
- assign hw2reg.data_in.d = data_in_d;
-
- // GPIO_OUT
- assign cio_gpio_o = cio_gpio_q;
- assign cio_gpio_en_o = cio_gpio_en_q;
-
- assign hw2reg.direct_out.d = cio_gpio_q;
- assign hw2reg.masked_out_upper.data.d = cio_gpio_q[31:16];
- assign hw2reg.masked_out_upper.mask.d = 16'h 0;
- assign hw2reg.masked_out_lower.data.d = cio_gpio_q[15:0];
- assign hw2reg.masked_out_lower.mask.d = 16'h 0;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- cio_gpio_q <= '0;
- end else if (reg2hw.direct_out.qe) begin
- cio_gpio_q <= reg2hw.direct_out.q;
- end else if (reg2hw.masked_out_upper.data.qe) begin
- cio_gpio_q[31:16] <=
- ( reg2hw.masked_out_upper.mask.q & reg2hw.masked_out_upper.data.q) |
- (~reg2hw.masked_out_upper.mask.q & cio_gpio_q[31:16]);
- end else if (reg2hw.masked_out_lower.data.qe) begin
- cio_gpio_q[15:0] <=
- ( reg2hw.masked_out_lower.mask.q & reg2hw.masked_out_lower.data.q) |
- (~reg2hw.masked_out_lower.mask.q & cio_gpio_q[15:0]);
- end
- end
-
- // GPIO OE
- assign hw2reg.direct_oe.d = cio_gpio_en_q;
- assign hw2reg.masked_oe_upper.data.d = cio_gpio_en_q[31:16];
- assign hw2reg.masked_oe_upper.mask.d = 16'h 0;
- assign hw2reg.masked_oe_lower.data.d = cio_gpio_en_q[15:0];
- assign hw2reg.masked_oe_lower.mask.d = 16'h 0;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- cio_gpio_en_q <= '0;
- end else if (reg2hw.direct_oe.qe) begin
- cio_gpio_en_q <= reg2hw.direct_oe.q;
- end else if (reg2hw.masked_oe_upper.data.qe) begin
- cio_gpio_en_q[31:16] <=
- ( reg2hw.masked_oe_upper.mask.q & reg2hw.masked_oe_upper.data.q) |
- (~reg2hw.masked_oe_upper.mask.q & cio_gpio_en_q[31:16]);
- end else if (reg2hw.masked_oe_lower.data.qe) begin
- cio_gpio_en_q[15:0] <=
- ( reg2hw.masked_oe_lower.mask.q & reg2hw.masked_oe_lower.data.q) |
- (~reg2hw.masked_oe_lower.mask.q & cio_gpio_en_q[15:0]);
- end
- end
-
- logic [31:0] data_in_q;
- always_ff @(posedge clk_i) begin
- data_in_q <= data_in_d;
- end
-
- logic [31:0] event_intr_rise, event_intr_fall, event_intr_actlow, event_intr_acthigh;
- logic [31:0] event_intr_combined;
-
- // instantiate interrupt hardware primitive
- prim_intr_hw #(.Width(32)) intr_hw (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_intr_combined),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.d),
- .intr_o (intr_gpio_o)
- );
-
- // detect four possible individual interrupts
- assign event_intr_rise = (~data_in_q & data_in_d) & reg2hw.intr_ctrl_en_rising.q;
- assign event_intr_fall = ( data_in_q & ~data_in_d) & reg2hw.intr_ctrl_en_falling.q;
- assign event_intr_acthigh = data_in_d & reg2hw.intr_ctrl_en_lvlhigh.q;
- assign event_intr_actlow = ~data_in_d & reg2hw.intr_ctrl_en_lvllow.q;
-
- assign event_intr_combined = event_intr_rise |
- event_intr_fall |
- event_intr_actlow |
- event_intr_acthigh;
-
-
- // Register module
- gpio_reg_top u_reg (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- .tl_i (tl_i),
- .tl_o (tl_o),
-
- .reg2hw (reg2hw),
- .hw2reg (hw2reg),
-
- .devmode_i (1'b1)
- );
-
-
-endmodule
diff --git a/verilog/rtl/gpio_reg_pkg.sv b/verilog/rtl/gpio_reg_pkg.sv
deleted file mode 100644
index b85347a..0000000
--- a/verilog/rtl/gpio_reg_pkg.sv
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Package auto-generated by `reggen` containing data structure
-
-package gpio_reg_pkg;
-
- // Address width within the block
- parameter int BlockAw = 6;
-
- ////////////////////////////
- // Typedefs for registers //
- ////////////////////////////
- typedef struct packed {
- logic [31:0] q;
- } gpio_reg2hw_intr_state_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- } gpio_reg2hw_intr_enable_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- logic qe;
- } gpio_reg2hw_intr_test_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- logic qe;
- } gpio_reg2hw_direct_out_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [15:0] q;
- logic qe;
- } data;
- struct packed {
- logic [15:0] q;
- logic qe;
- } mask;
- } gpio_reg2hw_masked_out_lower_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [15:0] q;
- logic qe;
- } data;
- struct packed {
- logic [15:0] q;
- logic qe;
- } mask;
- } gpio_reg2hw_masked_out_upper_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- logic qe;
- } gpio_reg2hw_direct_oe_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [15:0] q;
- logic qe;
- } data;
- struct packed {
- logic [15:0] q;
- logic qe;
- } mask;
- } gpio_reg2hw_masked_oe_lower_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [15:0] q;
- logic qe;
- } data;
- struct packed {
- logic [15:0] q;
- logic qe;
- } mask;
- } gpio_reg2hw_masked_oe_upper_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- } gpio_reg2hw_intr_ctrl_en_rising_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- } gpio_reg2hw_intr_ctrl_en_falling_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- } gpio_reg2hw_intr_ctrl_en_lvlhigh_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- } gpio_reg2hw_intr_ctrl_en_lvllow_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- } gpio_reg2hw_ctrl_en_input_filter_reg_t;
-
-
- typedef struct packed {
- logic [31:0] d;
- logic de;
- } gpio_hw2reg_intr_state_reg_t;
-
- typedef struct packed {
- logic [31:0] d;
- logic de;
- } gpio_hw2reg_data_in_reg_t;
-
- typedef struct packed {
- logic [31:0] d;
- } gpio_hw2reg_direct_out_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [15:0] d;
- } data;
- struct packed {
- logic [15:0] d;
- } mask;
- } gpio_hw2reg_masked_out_lower_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [15:0] d;
- } data;
- struct packed {
- logic [15:0] d;
- } mask;
- } gpio_hw2reg_masked_out_upper_reg_t;
-
- typedef struct packed {
- logic [31:0] d;
- } gpio_hw2reg_direct_oe_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [15:0] d;
- } data;
- struct packed {
- logic [15:0] d;
- } mask;
- } gpio_hw2reg_masked_oe_lower_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [15:0] d;
- } data;
- struct packed {
- logic [15:0] d;
- } mask;
- } gpio_hw2reg_masked_oe_upper_reg_t;
-
-
- ///////////////////////////////////////
- // Register to internal design logic //
- ///////////////////////////////////////
- typedef struct packed {
- gpio_reg2hw_intr_state_reg_t intr_state; // [458:427]
- gpio_reg2hw_intr_enable_reg_t intr_enable; // [426:395]
- gpio_reg2hw_intr_test_reg_t intr_test; // [394:362]
- gpio_reg2hw_direct_out_reg_t direct_out; // [361:329]
- gpio_reg2hw_masked_out_lower_reg_t masked_out_lower; // [328:295]
- gpio_reg2hw_masked_out_upper_reg_t masked_out_upper; // [294:261]
- gpio_reg2hw_direct_oe_reg_t direct_oe; // [260:228]
- gpio_reg2hw_masked_oe_lower_reg_t masked_oe_lower; // [227:194]
- gpio_reg2hw_masked_oe_upper_reg_t masked_oe_upper; // [193:160]
- gpio_reg2hw_intr_ctrl_en_rising_reg_t intr_ctrl_en_rising; // [159:128]
- gpio_reg2hw_intr_ctrl_en_falling_reg_t intr_ctrl_en_falling; // [127:96]
- gpio_reg2hw_intr_ctrl_en_lvlhigh_reg_t intr_ctrl_en_lvlhigh; // [95:64]
- gpio_reg2hw_intr_ctrl_en_lvllow_reg_t intr_ctrl_en_lvllow; // [63:32]
- gpio_reg2hw_ctrl_en_input_filter_reg_t ctrl_en_input_filter; // [31:0]
- } gpio_reg2hw_t;
-
- ///////////////////////////////////////
- // Internal design logic to register //
- ///////////////////////////////////////
- typedef struct packed {
- gpio_hw2reg_intr_state_reg_t intr_state; // [257:225]
- gpio_hw2reg_data_in_reg_t data_in; // [224:192]
- gpio_hw2reg_direct_out_reg_t direct_out; // [191:160]
- gpio_hw2reg_masked_out_lower_reg_t masked_out_lower; // [159:128]
- gpio_hw2reg_masked_out_upper_reg_t masked_out_upper; // [127:96]
- gpio_hw2reg_direct_oe_reg_t direct_oe; // [95:64]
- gpio_hw2reg_masked_oe_lower_reg_t masked_oe_lower; // [63:32]
- gpio_hw2reg_masked_oe_upper_reg_t masked_oe_upper; // [31:0]
- } gpio_hw2reg_t;
-
- // Register Address
- parameter logic [BlockAw-1:0] GPIO_INTR_STATE_OFFSET = 6'h 0;
- parameter logic [BlockAw-1:0] GPIO_INTR_ENABLE_OFFSET = 6'h 4;
- parameter logic [BlockAw-1:0] GPIO_INTR_TEST_OFFSET = 6'h 8;
- parameter logic [BlockAw-1:0] GPIO_DATA_IN_OFFSET = 6'h c;
- parameter logic [BlockAw-1:0] GPIO_DIRECT_OUT_OFFSET = 6'h 10;
- parameter logic [BlockAw-1:0] GPIO_MASKED_OUT_LOWER_OFFSET = 6'h 14;
- parameter logic [BlockAw-1:0] GPIO_MASKED_OUT_UPPER_OFFSET = 6'h 18;
- parameter logic [BlockAw-1:0] GPIO_DIRECT_OE_OFFSET = 6'h 1c;
- parameter logic [BlockAw-1:0] GPIO_MASKED_OE_LOWER_OFFSET = 6'h 20;
- parameter logic [BlockAw-1:0] GPIO_MASKED_OE_UPPER_OFFSET = 6'h 24;
- parameter logic [BlockAw-1:0] GPIO_INTR_CTRL_EN_RISING_OFFSET = 6'h 28;
- parameter logic [BlockAw-1:0] GPIO_INTR_CTRL_EN_FALLING_OFFSET = 6'h 2c;
- parameter logic [BlockAw-1:0] GPIO_INTR_CTRL_EN_LVLHIGH_OFFSET = 6'h 30;
- parameter logic [BlockAw-1:0] GPIO_INTR_CTRL_EN_LVLLOW_OFFSET = 6'h 34;
- parameter logic [BlockAw-1:0] GPIO_CTRL_EN_INPUT_FILTER_OFFSET = 6'h 38;
-
-
- // Register Index
- typedef enum int {
- GPIO_INTR_STATE,
- GPIO_INTR_ENABLE,
- GPIO_INTR_TEST,
- GPIO_DATA_IN,
- GPIO_DIRECT_OUT,
- GPIO_MASKED_OUT_LOWER,
- GPIO_MASKED_OUT_UPPER,
- GPIO_DIRECT_OE,
- GPIO_MASKED_OE_LOWER,
- GPIO_MASKED_OE_UPPER,
- GPIO_INTR_CTRL_EN_RISING,
- GPIO_INTR_CTRL_EN_FALLING,
- GPIO_INTR_CTRL_EN_LVLHIGH,
- GPIO_INTR_CTRL_EN_LVLLOW,
- GPIO_CTRL_EN_INPUT_FILTER
- } gpio_id_e;
-
- // Register width information to check illegal writes
- parameter logic [3:0] GPIO_PERMIT [15] = '{
- 4'b 1111, // index[ 0] GPIO_INTR_STATE
- 4'b 1111, // index[ 1] GPIO_INTR_ENABLE
- 4'b 1111, // index[ 2] GPIO_INTR_TEST
- 4'b 1111, // index[ 3] GPIO_DATA_IN
- 4'b 1111, // index[ 4] GPIO_DIRECT_OUT
- 4'b 1111, // index[ 5] GPIO_MASKED_OUT_LOWER
- 4'b 1111, // index[ 6] GPIO_MASKED_OUT_UPPER
- 4'b 1111, // index[ 7] GPIO_DIRECT_OE
- 4'b 1111, // index[ 8] GPIO_MASKED_OE_LOWER
- 4'b 1111, // index[ 9] GPIO_MASKED_OE_UPPER
- 4'b 1111, // index[10] GPIO_INTR_CTRL_EN_RISING
- 4'b 1111, // index[11] GPIO_INTR_CTRL_EN_FALLING
- 4'b 1111, // index[12] GPIO_INTR_CTRL_EN_LVLHIGH
- 4'b 1111, // index[13] GPIO_INTR_CTRL_EN_LVLLOW
- 4'b 1111 // index[14] GPIO_CTRL_EN_INPUT_FILTER
- };
-endpackage
-
diff --git a/verilog/rtl/gpio_reg_top.sv b/verilog/rtl/gpio_reg_top.sv
deleted file mode 100644
index 1c2ba13..0000000
--- a/verilog/rtl/gpio_reg_top.sv
+++ /dev/null
@@ -1,706 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Top module auto-generated by `reggen`
-
-
-module gpio_reg_top (
- input clk_i,
- input rst_ni,
-
- // Below Regster interface can be changed
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
- // To HW
- output gpio_reg_pkg::gpio_reg2hw_t reg2hw, // Write
- input gpio_reg_pkg::gpio_hw2reg_t hw2reg, // Read
-
- // Config
- input devmode_i // If 1, explicit error return for unmapped register access
-);
-
- import gpio_reg_pkg::* ;
-
- localparam int AW = 6;
- localparam int DW = 32;
- localparam int DBW = DW/8; // Byte Width
-
- // register signals
- logic reg_we;
- logic reg_re;
- logic [AW-1:0] reg_addr;
- logic [DW-1:0] reg_wdata;
- logic [DBW-1:0] reg_be;
- logic [DW-1:0] reg_rdata;
- logic reg_error;
-
- logic addrmiss, wr_err;
-
- logic [DW-1:0] reg_rdata_next;
-
- tlul_pkg::tl_h2d_t tl_reg_h2d;
- tlul_pkg::tl_d2h_t tl_reg_d2h;
-
- assign tl_reg_h2d = tl_i;
- assign tl_o = tl_reg_d2h;
-
- tlul_adapter_reg #(
- .RegAw(AW),
- .RegDw(DW)
- ) u_reg_if (
- .clk_i,
- .rst_ni,
-
- .tl_i (tl_reg_h2d),
- .tl_o (tl_reg_d2h),
-
- .we_o (reg_we),
- .re_o (reg_re),
- .addr_o (reg_addr),
- .wdata_o (reg_wdata),
- .be_o (reg_be),
- .rdata_i (reg_rdata),
- .error_i (reg_error)
- );
-
- assign reg_rdata = reg_rdata_next ;
- assign reg_error = (devmode_i & addrmiss) | wr_err ;
-
- // Define SW related signals
- // Format: <reg>_<field>_{wd|we|qs}
- // or <reg>_{wd|we|qs} if field == 1 or 0
- logic [31:0] intr_state_qs;
- logic [31:0] intr_state_wd;
- logic intr_state_we;
- logic [31:0] intr_enable_qs;
- logic [31:0] intr_enable_wd;
- logic intr_enable_we;
- logic [31:0] intr_test_wd;
- logic intr_test_we;
- logic [31:0] data_in_qs;
- logic [31:0] direct_out_qs;
- logic [31:0] direct_out_wd;
- logic direct_out_we;
- logic direct_out_re;
- logic [15:0] masked_out_lower_data_qs;
- logic [15:0] masked_out_lower_data_wd;
- logic masked_out_lower_data_we;
- logic masked_out_lower_data_re;
- logic [15:0] masked_out_lower_mask_wd;
- logic masked_out_lower_mask_we;
- logic [15:0] masked_out_upper_data_qs;
- logic [15:0] masked_out_upper_data_wd;
- logic masked_out_upper_data_we;
- logic masked_out_upper_data_re;
- logic [15:0] masked_out_upper_mask_wd;
- logic masked_out_upper_mask_we;
- logic [31:0] direct_oe_qs;
- logic [31:0] direct_oe_wd;
- logic direct_oe_we;
- logic direct_oe_re;
- logic [15:0] masked_oe_lower_data_qs;
- logic [15:0] masked_oe_lower_data_wd;
- logic masked_oe_lower_data_we;
- logic masked_oe_lower_data_re;
- logic [15:0] masked_oe_lower_mask_qs;
- logic [15:0] masked_oe_lower_mask_wd;
- logic masked_oe_lower_mask_we;
- logic masked_oe_lower_mask_re;
- logic [15:0] masked_oe_upper_data_qs;
- logic [15:0] masked_oe_upper_data_wd;
- logic masked_oe_upper_data_we;
- logic masked_oe_upper_data_re;
- logic [15:0] masked_oe_upper_mask_qs;
- logic [15:0] masked_oe_upper_mask_wd;
- logic masked_oe_upper_mask_we;
- logic masked_oe_upper_mask_re;
- logic [31:0] intr_ctrl_en_rising_qs;
- logic [31:0] intr_ctrl_en_rising_wd;
- logic intr_ctrl_en_rising_we;
- logic [31:0] intr_ctrl_en_falling_qs;
- logic [31:0] intr_ctrl_en_falling_wd;
- logic intr_ctrl_en_falling_we;
- logic [31:0] intr_ctrl_en_lvlhigh_qs;
- logic [31:0] intr_ctrl_en_lvlhigh_wd;
- logic intr_ctrl_en_lvlhigh_we;
- logic [31:0] intr_ctrl_en_lvllow_qs;
- logic [31:0] intr_ctrl_en_lvllow_wd;
- logic intr_ctrl_en_lvllow_we;
- logic [31:0] ctrl_en_input_filter_qs;
- logic [31:0] ctrl_en_input_filter_wd;
- logic ctrl_en_input_filter_we;
-
- // Register instances
- // R[intr_state]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("W1C"),
- .RESVAL (32'h0)
- ) u_intr_state (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_we),
- .wd (intr_state_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.de),
- .d (hw2reg.intr_state.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.q ),
-
- // to register interface (read)
- .qs (intr_state_qs)
- );
-
-
- // R[intr_enable]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'h0)
- ) u_intr_enable (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_we),
- .wd (intr_enable_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.q ),
-
- // to register interface (read)
- .qs (intr_enable_qs)
- );
-
-
- // R[intr_test]: V(True)
-
- prim_subreg_ext #(
- .DW (32)
- ) u_intr_test (
- .re (1'b0),
- .we (intr_test_we),
- .wd (intr_test_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.qe),
- .q (reg2hw.intr_test.q ),
- .qs ()
- );
-
-
- // R[data_in]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RO"),
- .RESVAL (32'h0)
- ) u_data_in (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.data_in.de),
- .d (hw2reg.data_in.d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (data_in_qs)
- );
-
-
- // R[direct_out]: V(True)
-
- prim_subreg_ext #(
- .DW (32)
- ) u_direct_out (
- .re (direct_out_re),
- .we (direct_out_we),
- .wd (direct_out_wd),
- .d (hw2reg.direct_out.d),
- .qre (),
- .qe (reg2hw.direct_out.qe),
- .q (reg2hw.direct_out.q ),
- .qs (direct_out_qs)
- );
-
-
- // R[masked_out_lower]: V(True)
-
- // F[data]: 15:0
- prim_subreg_ext #(
- .DW (16)
- ) u_masked_out_lower_data (
- .re (masked_out_lower_data_re),
- .we (masked_out_lower_data_we),
- .wd (masked_out_lower_data_wd),
- .d (hw2reg.masked_out_lower.data.d),
- .qre (),
- .qe (reg2hw.masked_out_lower.data.qe),
- .q (reg2hw.masked_out_lower.data.q ),
- .qs (masked_out_lower_data_qs)
- );
-
-
- // F[mask]: 31:16
- prim_subreg_ext #(
- .DW (16)
- ) u_masked_out_lower_mask (
- .re (1'b0),
- .we (masked_out_lower_mask_we),
- .wd (masked_out_lower_mask_wd),
- .d (hw2reg.masked_out_lower.mask.d),
- .qre (),
- .qe (reg2hw.masked_out_lower.mask.qe),
- .q (reg2hw.masked_out_lower.mask.q ),
- .qs ()
- );
-
-
- // R[masked_out_upper]: V(True)
-
- // F[data]: 15:0
- prim_subreg_ext #(
- .DW (16)
- ) u_masked_out_upper_data (
- .re (masked_out_upper_data_re),
- .we (masked_out_upper_data_we),
- .wd (masked_out_upper_data_wd),
- .d (hw2reg.masked_out_upper.data.d),
- .qre (),
- .qe (reg2hw.masked_out_upper.data.qe),
- .q (reg2hw.masked_out_upper.data.q ),
- .qs (masked_out_upper_data_qs)
- );
-
-
- // F[mask]: 31:16
- prim_subreg_ext #(
- .DW (16)
- ) u_masked_out_upper_mask (
- .re (1'b0),
- .we (masked_out_upper_mask_we),
- .wd (masked_out_upper_mask_wd),
- .d (hw2reg.masked_out_upper.mask.d),
- .qre (),
- .qe (reg2hw.masked_out_upper.mask.qe),
- .q (reg2hw.masked_out_upper.mask.q ),
- .qs ()
- );
-
-
- // R[direct_oe]: V(True)
-
- prim_subreg_ext #(
- .DW (32)
- ) u_direct_oe (
- .re (direct_oe_re),
- .we (direct_oe_we),
- .wd (direct_oe_wd),
- .d (hw2reg.direct_oe.d),
- .qre (),
- .qe (reg2hw.direct_oe.qe),
- .q (reg2hw.direct_oe.q ),
- .qs (direct_oe_qs)
- );
-
-
- // R[masked_oe_lower]: V(True)
-
- // F[data]: 15:0
- prim_subreg_ext #(
- .DW (16)
- ) u_masked_oe_lower_data (
- .re (masked_oe_lower_data_re),
- .we (masked_oe_lower_data_we),
- .wd (masked_oe_lower_data_wd),
- .d (hw2reg.masked_oe_lower.data.d),
- .qre (),
- .qe (reg2hw.masked_oe_lower.data.qe),
- .q (reg2hw.masked_oe_lower.data.q ),
- .qs (masked_oe_lower_data_qs)
- );
-
-
- // F[mask]: 31:16
- prim_subreg_ext #(
- .DW (16)
- ) u_masked_oe_lower_mask (
- .re (masked_oe_lower_mask_re),
- .we (masked_oe_lower_mask_we),
- .wd (masked_oe_lower_mask_wd),
- .d (hw2reg.masked_oe_lower.mask.d),
- .qre (),
- .qe (reg2hw.masked_oe_lower.mask.qe),
- .q (reg2hw.masked_oe_lower.mask.q ),
- .qs (masked_oe_lower_mask_qs)
- );
-
-
- // R[masked_oe_upper]: V(True)
-
- // F[data]: 15:0
- prim_subreg_ext #(
- .DW (16)
- ) u_masked_oe_upper_data (
- .re (masked_oe_upper_data_re),
- .we (masked_oe_upper_data_we),
- .wd (masked_oe_upper_data_wd),
- .d (hw2reg.masked_oe_upper.data.d),
- .qre (),
- .qe (reg2hw.masked_oe_upper.data.qe),
- .q (reg2hw.masked_oe_upper.data.q ),
- .qs (masked_oe_upper_data_qs)
- );
-
-
- // F[mask]: 31:16
- prim_subreg_ext #(
- .DW (16)
- ) u_masked_oe_upper_mask (
- .re (masked_oe_upper_mask_re),
- .we (masked_oe_upper_mask_we),
- .wd (masked_oe_upper_mask_wd),
- .d (hw2reg.masked_oe_upper.mask.d),
- .qre (),
- .qe (reg2hw.masked_oe_upper.mask.qe),
- .q (reg2hw.masked_oe_upper.mask.q ),
- .qs (masked_oe_upper_mask_qs)
- );
-
-
- // R[intr_ctrl_en_rising]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'h0)
- ) u_intr_ctrl_en_rising (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_ctrl_en_rising_we),
- .wd (intr_ctrl_en_rising_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_ctrl_en_rising.q ),
-
- // to register interface (read)
- .qs (intr_ctrl_en_rising_qs)
- );
-
-
- // R[intr_ctrl_en_falling]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'h0)
- ) u_intr_ctrl_en_falling (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_ctrl_en_falling_we),
- .wd (intr_ctrl_en_falling_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_ctrl_en_falling.q ),
-
- // to register interface (read)
- .qs (intr_ctrl_en_falling_qs)
- );
-
-
- // R[intr_ctrl_en_lvlhigh]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'h0)
- ) u_intr_ctrl_en_lvlhigh (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_ctrl_en_lvlhigh_we),
- .wd (intr_ctrl_en_lvlhigh_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_ctrl_en_lvlhigh.q ),
-
- // to register interface (read)
- .qs (intr_ctrl_en_lvlhigh_qs)
- );
-
-
- // R[intr_ctrl_en_lvllow]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'h0)
- ) u_intr_ctrl_en_lvllow (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_ctrl_en_lvllow_we),
- .wd (intr_ctrl_en_lvllow_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_ctrl_en_lvllow.q ),
-
- // to register interface (read)
- .qs (intr_ctrl_en_lvllow_qs)
- );
-
-
- // R[ctrl_en_input_filter]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'h0)
- ) u_ctrl_en_input_filter (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_en_input_filter_we),
- .wd (ctrl_en_input_filter_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl_en_input_filter.q ),
-
- // to register interface (read)
- .qs (ctrl_en_input_filter_qs)
- );
-
-
-
-
- logic [14:0] addr_hit;
- always_comb begin
- addr_hit = '0;
- addr_hit[ 0] = (reg_addr == GPIO_INTR_STATE_OFFSET);
- addr_hit[ 1] = (reg_addr == GPIO_INTR_ENABLE_OFFSET);
- addr_hit[ 2] = (reg_addr == GPIO_INTR_TEST_OFFSET);
- addr_hit[ 3] = (reg_addr == GPIO_DATA_IN_OFFSET);
- addr_hit[ 4] = (reg_addr == GPIO_DIRECT_OUT_OFFSET);
- addr_hit[ 5] = (reg_addr == GPIO_MASKED_OUT_LOWER_OFFSET);
- addr_hit[ 6] = (reg_addr == GPIO_MASKED_OUT_UPPER_OFFSET);
- addr_hit[ 7] = (reg_addr == GPIO_DIRECT_OE_OFFSET);
- addr_hit[ 8] = (reg_addr == GPIO_MASKED_OE_LOWER_OFFSET);
- addr_hit[ 9] = (reg_addr == GPIO_MASKED_OE_UPPER_OFFSET);
- addr_hit[10] = (reg_addr == GPIO_INTR_CTRL_EN_RISING_OFFSET);
- addr_hit[11] = (reg_addr == GPIO_INTR_CTRL_EN_FALLING_OFFSET);
- addr_hit[12] = (reg_addr == GPIO_INTR_CTRL_EN_LVLHIGH_OFFSET);
- addr_hit[13] = (reg_addr == GPIO_INTR_CTRL_EN_LVLLOW_OFFSET);
- addr_hit[14] = (reg_addr == GPIO_CTRL_EN_INPUT_FILTER_OFFSET);
- end
-
- assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
-
- // Check sub-word write is permitted
- always_comb begin
- wr_err = 1'b0;
- if (addr_hit[ 0] && reg_we && (GPIO_PERMIT[ 0] != (GPIO_PERMIT[ 0] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 1] && reg_we && (GPIO_PERMIT[ 1] != (GPIO_PERMIT[ 1] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 2] && reg_we && (GPIO_PERMIT[ 2] != (GPIO_PERMIT[ 2] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 3] && reg_we && (GPIO_PERMIT[ 3] != (GPIO_PERMIT[ 3] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 4] && reg_we && (GPIO_PERMIT[ 4] != (GPIO_PERMIT[ 4] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 5] && reg_we && (GPIO_PERMIT[ 5] != (GPIO_PERMIT[ 5] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 6] && reg_we && (GPIO_PERMIT[ 6] != (GPIO_PERMIT[ 6] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 7] && reg_we && (GPIO_PERMIT[ 7] != (GPIO_PERMIT[ 7] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 8] && reg_we && (GPIO_PERMIT[ 8] != (GPIO_PERMIT[ 8] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 9] && reg_we && (GPIO_PERMIT[ 9] != (GPIO_PERMIT[ 9] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[10] && reg_we && (GPIO_PERMIT[10] != (GPIO_PERMIT[10] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[11] && reg_we && (GPIO_PERMIT[11] != (GPIO_PERMIT[11] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[12] && reg_we && (GPIO_PERMIT[12] != (GPIO_PERMIT[12] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[13] && reg_we && (GPIO_PERMIT[13] != (GPIO_PERMIT[13] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[14] && reg_we && (GPIO_PERMIT[14] != (GPIO_PERMIT[14] & reg_be))) wr_err = 1'b1 ;
- end
-
- assign intr_state_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_wd = reg_wdata[31:0];
-
- assign intr_enable_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_wd = reg_wdata[31:0];
-
- assign intr_test_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_wd = reg_wdata[31:0];
-
-
- assign direct_out_we = addr_hit[4] & reg_we & ~wr_err;
- assign direct_out_wd = reg_wdata[31:0];
- assign direct_out_re = addr_hit[4] && reg_re;
-
- assign masked_out_lower_data_we = addr_hit[5] & reg_we & ~wr_err;
- assign masked_out_lower_data_wd = reg_wdata[15:0];
- assign masked_out_lower_data_re = addr_hit[5] && reg_re;
-
- assign masked_out_lower_mask_we = addr_hit[5] & reg_we & ~wr_err;
- assign masked_out_lower_mask_wd = reg_wdata[31:16];
-
- assign masked_out_upper_data_we = addr_hit[6] & reg_we & ~wr_err;
- assign masked_out_upper_data_wd = reg_wdata[15:0];
- assign masked_out_upper_data_re = addr_hit[6] && reg_re;
-
- assign masked_out_upper_mask_we = addr_hit[6] & reg_we & ~wr_err;
- assign masked_out_upper_mask_wd = reg_wdata[31:16];
-
- assign direct_oe_we = addr_hit[7] & reg_we & ~wr_err;
- assign direct_oe_wd = reg_wdata[31:0];
- assign direct_oe_re = addr_hit[7] && reg_re;
-
- assign masked_oe_lower_data_we = addr_hit[8] & reg_we & ~wr_err;
- assign masked_oe_lower_data_wd = reg_wdata[15:0];
- assign masked_oe_lower_data_re = addr_hit[8] && reg_re;
-
- assign masked_oe_lower_mask_we = addr_hit[8] & reg_we & ~wr_err;
- assign masked_oe_lower_mask_wd = reg_wdata[31:16];
- assign masked_oe_lower_mask_re = addr_hit[8] && reg_re;
-
- assign masked_oe_upper_data_we = addr_hit[9] & reg_we & ~wr_err;
- assign masked_oe_upper_data_wd = reg_wdata[15:0];
- assign masked_oe_upper_data_re = addr_hit[9] && reg_re;
-
- assign masked_oe_upper_mask_we = addr_hit[9] & reg_we & ~wr_err;
- assign masked_oe_upper_mask_wd = reg_wdata[31:16];
- assign masked_oe_upper_mask_re = addr_hit[9] && reg_re;
-
- assign intr_ctrl_en_rising_we = addr_hit[10] & reg_we & ~wr_err;
- assign intr_ctrl_en_rising_wd = reg_wdata[31:0];
-
- assign intr_ctrl_en_falling_we = addr_hit[11] & reg_we & ~wr_err;
- assign intr_ctrl_en_falling_wd = reg_wdata[31:0];
-
- assign intr_ctrl_en_lvlhigh_we = addr_hit[12] & reg_we & ~wr_err;
- assign intr_ctrl_en_lvlhigh_wd = reg_wdata[31:0];
-
- assign intr_ctrl_en_lvllow_we = addr_hit[13] & reg_we & ~wr_err;
- assign intr_ctrl_en_lvllow_wd = reg_wdata[31:0];
-
- assign ctrl_en_input_filter_we = addr_hit[14] & reg_we & ~wr_err;
- assign ctrl_en_input_filter_wd = reg_wdata[31:0];
-
- // Read data return
- always_comb begin
- reg_rdata_next = '0;
- unique case (1'b1)
- addr_hit[0]: begin
- reg_rdata_next[31:0] = intr_state_qs;
- end
-
- addr_hit[1]: begin
- reg_rdata_next[31:0] = intr_enable_qs;
- end
-
- addr_hit[2]: begin
- reg_rdata_next[31:0] = '0;
- end
-
- addr_hit[3]: begin
- reg_rdata_next[31:0] = data_in_qs;
- end
-
- addr_hit[4]: begin
- reg_rdata_next[31:0] = direct_out_qs;
- end
-
- addr_hit[5]: begin
- reg_rdata_next[15:0] = masked_out_lower_data_qs;
- reg_rdata_next[31:16] = '0;
- end
-
- addr_hit[6]: begin
- reg_rdata_next[15:0] = masked_out_upper_data_qs;
- reg_rdata_next[31:16] = '0;
- end
-
- addr_hit[7]: begin
- reg_rdata_next[31:0] = direct_oe_qs;
- end
-
- addr_hit[8]: begin
- reg_rdata_next[15:0] = masked_oe_lower_data_qs;
- reg_rdata_next[31:16] = masked_oe_lower_mask_qs;
- end
-
- addr_hit[9]: begin
- reg_rdata_next[15:0] = masked_oe_upper_data_qs;
- reg_rdata_next[31:16] = masked_oe_upper_mask_qs;
- end
-
- addr_hit[10]: begin
- reg_rdata_next[31:0] = intr_ctrl_en_rising_qs;
- end
-
- addr_hit[11]: begin
- reg_rdata_next[31:0] = intr_ctrl_en_falling_qs;
- end
-
- addr_hit[12]: begin
- reg_rdata_next[31:0] = intr_ctrl_en_lvlhigh_qs;
- end
-
- addr_hit[13]: begin
- reg_rdata_next[31:0] = intr_ctrl_en_lvllow_qs;
- end
-
- addr_hit[14]: begin
- reg_rdata_next[31:0] = ctrl_en_input_filter_qs;
- end
-
- default: begin
- reg_rdata_next = '1;
- end
- endcase
- end
-endmodule
diff --git a/verilog/rtl/iccm_controller.v b/verilog/rtl/iccm_controller.v
deleted file mode 100644
index 99a58ef..0000000
--- a/verilog/rtl/iccm_controller.v
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-module iccm_controller (
- clk_i,
- rst_ni,
- prog_i,
- rx_dv_i,
- rx_byte_i,
- we_o,
- addr_o,
- wdata_o,
- reset_o
-);
- input wire clk_i;
- input wire rst_ni;
- input wire prog_i;
- input wire rx_dv_i;
- input wire [7:0] rx_byte_i;
- output wire we_o;
- output wire [11:0] addr_o;
- output wire [31:0] wdata_o;
- output wire reset_o;
- reg [1:0] ctrl_fsm_cs;
- reg [1:0] ctrl_fsm_ns;
- wire [7:0] rx_byte_d;
- reg [7:0] rx_byte_q0;
- reg [7:0] rx_byte_q1;
- reg [7:0] rx_byte_q2;
- reg [7:0] rx_byte_q3;
- reg we_q;
- reg we_d;
- reg [11:0] addr_q;
- reg [11:0] addr_d;
- reg reset_q;
- reg reset_d;
- reg [1:0] byte_count;
- localparam [1:0] DONE = 3;
- localparam [1:0] LOAD = 1;
- localparam [1:0] PROG = 2;
- localparam [1:0] RESET = 0;
- always @(*) begin
- we_d = we_q;
- addr_d = addr_q;
- reset_d = reset_q;
- ctrl_fsm_ns = ctrl_fsm_cs;
- case (ctrl_fsm_cs)
- RESET: begin
- we_d = 1'b0;
- reset_d = 1'b0;
- if (rx_dv_i)
- ctrl_fsm_ns = LOAD;
- else
- ctrl_fsm_ns = RESET;
- end
- LOAD:
- if (((byte_count == 2'b11) && (rx_byte_q2 != 8'h0f)) && (rx_byte_d != 8'hff)) begin
- we_d = 1'b1;
- ctrl_fsm_ns = PROG;
- end
- else
- ctrl_fsm_ns = DONE;
- PROG: begin
- we_d = 1'b0;
- ctrl_fsm_ns = DONE;
- end
- DONE:
- if (wdata_o == 32'h00000fff || (!rst_ni)) begin
- ctrl_fsm_ns = DONE;
- reset_d = 1'b1;
- end
- else if (rx_dv_i)
- ctrl_fsm_ns = LOAD;
- else
- ctrl_fsm_ns = DONE;
- // default: ctrl_fsm_ns = RESET;
- endcase
- end
- assign rx_byte_d = rx_byte_i;
- assign we_o = we_q;
- assign addr_o = addr_q;
- assign wdata_o = {rx_byte_q0, rx_byte_q1, rx_byte_q2, rx_byte_q3};
- assign reset_o = reset_q;
- always @(posedge clk_i or negedge rst_ni)
- if (!rst_ni) begin
- we_q <= 1'b0;
- addr_q <= 12'b000000000000;
- rx_byte_q0 <= 8'b00000000;
- rx_byte_q1 <= 8'b00000000;
- rx_byte_q2 <= 8'b00000000;
- rx_byte_q3 <= 8'b00000000;
- reset_q <= 1'b1;
- byte_count <= 2'b00;
- ctrl_fsm_cs <= DONE;
- end
- else if (prog_i) begin
- we_q <= 1'b0;
- addr_q <= 12'b000000000000;
- rx_byte_q0 <= 8'b00000000;
- rx_byte_q1 <= 8'b00000000;
- rx_byte_q2 <= 8'b00000000;
- rx_byte_q3 <= 8'b00000000;
- reset_q <= 1'b0;
- byte_count <= 2'b00;
- ctrl_fsm_cs <= RESET;
- end
- else begin
- we_q <= we_d;
- if (ctrl_fsm_cs == LOAD) begin
- if (byte_count == 2'b00) begin
- rx_byte_q0 <= rx_byte_d;
- byte_count <= 2'b01;
- end
- else if (byte_count == 2'b01) begin
- rx_byte_q1 <= rx_byte_d;
- byte_count <= 2'b10;
- end
- else if (byte_count == 2'b10) begin
- rx_byte_q2 <= rx_byte_d;
- byte_count <= 2'b11;
- end
- else begin
- rx_byte_q3 <= rx_byte_d;
- byte_count <= 2'b00;
- end
- addr_q <= addr_d;
- end
- if (ctrl_fsm_cs == PROG)
- addr_q <= addr_d + 1'b1;
- reset_q <= reset_d;
- ctrl_fsm_cs <= ctrl_fsm_ns;
- end
-endmodule
diff --git a/verilog/rtl/instr_mem_top.sv b/verilog/rtl/instr_mem_top.sv
deleted file mode 100644
index 9619890..0000000
--- a/verilog/rtl/instr_mem_top.sv
+++ /dev/null
@@ -1,82 +0,0 @@
-module instr_mem_top
-(
- input clk_i,
- input rst_ni,
-
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
-// iccm controller interface
- input [11:0] iccm_ctrl_addr,
- input [31:0] iccm_ctrl_wdata,
- input iccm_ctrl_we,
- input prog_rst_ni,
-
-
-// sram interface
- output logic csb,
- output logic [11:0] addr_o,
- output logic [31:0] wdata_o,
- output logic [3:0] wmask_o,
- output logic we_o,
- input logic [31:0] rdata_i
-);
-
-
-logic rvalid;
-
-logic tl_we;
-logic [31:0] tl_wmask;
-logic [31:0] tl_wdata;
-logic [11:0] tl_addr;
-logic tl_req;
-logic [3:0] mask_sel;
-
-assign mask_sel[0] = (tl_wmask[7:0] != 8'b0) ? 1'b1: 1'b0;
-assign mask_sel[1] = (tl_wmask[15:8] != 8'b0) ? 1'b1: 1'b0;
-assign mask_sel[2] = (tl_wmask[23:16] != 8'b0) ? 1'b1: 2'b0;
-assign mask_sel[3] = (tl_wmask[31:24] != 8'b0) ? 1'b1: 2'b0;
-
-assign csb = ~(tl_req | iccm_ctrl_we);
-
-assign addr_o = (prog_rst_ni) ? tl_addr : iccm_ctrl_addr;
-assign wdata_o = (prog_rst_ni) ? tl_wdata : iccm_ctrl_wdata;
-assign we_o = ~((prog_rst_ni) ? tl_we : iccm_ctrl_we);
-assign wmask_o = (prog_rst_ni) ? mask_sel : 4'b1111;
-
-
- tlul_sram_adapter #(
- .SramAw (12),
- .SramDw (32),
- .Outstanding (2),
- .ByteAccess (1),
- .ErrOnWrite (0), // 1: Writes not allowed, automatically error
- .ErrOnRead (0) // 1: Reads not allowed, automatically error
-
-) inst_mem (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_i (tl_i),
- .tl_o (tl_o),
- .req_o (tl_req),
- .gnt_i (1'b1),
- .we_o (tl_we),
- .addr_o (tl_addr),
- .wdata_o (tl_wdata),
- .wmask_o (tl_wmask),
- .rdata_i ((rst_ni) ? rdata_i: '0),
- .rvalid_i (rvalid),
- .rerror_i (2'b0)
-);
-
- always_ff @(posedge clk_i) begin
- if (!rst_ni) begin
- rvalid <= 1'b0;
- end else if (iccm_ctrl_we | tl_we) begin
- rvalid <= 1'b0;
- end else begin
- rvalid <= tl_req;
- end
- end
-
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/iteration_div_sqrt_mvp.sv b/verilog/rtl/iteration_div_sqrt_mvp.sv
deleted file mode 100644
index 0c645e6..0000000
--- a/verilog/rtl/iteration_div_sqrt_mvp.sv
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2018 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.
-////////////////////////////////////////////////////////////////////////////////
-// Company: IIS @ ETHZ - Federal Institute of Technology //
-// //
-// Engineers: Lei Li lile@iis.ee.ethz.ch //
-// //
-// Additional contributions by: //
-// //
-// //
-// //
-// Create Date: 12/01/2017 //
-// Design Name: FPU //
-// Module Name: iteration_div_sqrt_mvp //
-// Project Name: Private FPU //
-// Language: SystemVerilog //
-// //
-// Description: iteration unit for div and sqrt //
-// //
-// //
-// Revision: 03/14/2018 //
-// For div_sqrt_mvp //
-////////////////////////////////////////////////////////////////////////////////
-
-module iteration_div_sqrt_mvp
-#(
- parameter WIDTH=25
-)
- (//Input
-
- input logic [WIDTH-1:0] A_DI,
- input logic [WIDTH-1:0] B_DI,
- input logic Div_enable_SI,
- input logic Div_start_dly_SI,
- input logic Sqrt_enable_SI,
- input logic [1:0] D_DI,
-
- output logic [1:0] D_DO,
- output logic [WIDTH-1:0] Sum_DO,
- output logic Carry_out_DO
- );
-
- logic D_carry_D;
- logic Sqrt_cin_D;
- logic Cin_D;
-
- assign D_DO[0]=~D_DI[0];
- assign D_DO[1]=~(D_DI[1] ^ D_DI[0]);
- assign D_carry_D=D_DI[1] | D_DI[0];
- assign Sqrt_cin_D=Sqrt_enable_SI&&D_carry_D;
- assign Cin_D=Div_enable_SI?1'b0:Sqrt_cin_D;
- assign {Carry_out_DO,Sum_DO}=A_DI+B_DI+Cin_D;
-
-endmodule
diff --git a/verilog/rtl/jtag_pkg.sv b/verilog/rtl/jtag_pkg.sv
deleted file mode 100644
index 2a67ee0..0000000
--- a/verilog/rtl/jtag_pkg.sv
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-
-package jtag_pkg;
-
- typedef struct packed {
- logic tck;
- logic tms;
- logic trst_n;
- logic tdi;
- } jtag_req_t;
-
- parameter jtag_req_t JTAG_REQ_DEFAULT = '0;
-
- typedef struct packed {
- logic tdo;
- logic tdo_oe;
- } jtag_rsp_t;
-
- parameter jtag_rsp_t JTAG_RSP_DEFAULT = '0;
-
-endpackage : jtag_pkg
diff --git a/verilog/rtl/lzc.sv b/verilog/rtl/lzc.sv
deleted file mode 100644
index 424eb2e..0000000
--- a/verilog/rtl/lzc.sv
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2018 - 2019 ETH Zurich, University of Bologna
-// All rights reserved.
-//
-// This code is under development and not yet released to the public.
-// Until it is released, the code is under the copyright of ETH Zurich and
-// the University of Bologna, and may contain confidential and/or unpublished
-// work. Any reuse/redistribution is strictly forbidden without written
-// permission from ETH Zurich.
-//
-// Bug fixes and contributions will eventually be released under the
-// SolderPad open hardware license in the context of the PULP platform
-// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
-// University of Bologna.
-
-/// A trailing zero counter / leading zero counter.
-/// Set MODE to 0 for trailing zero counter => cnt_o is the number of trailing zeros (from the LSB)
-/// Set MODE to 1 for leading zero counter => cnt_o is the number of leading zeros (from the MSB)
-/// If the input does not contain a zero, `empty_o` is asserted. Additionally `cnt_o` contains
-/// the maximum number of zeros - 1. For example:
-/// in_i = 000_0000, empty_o = 1, cnt_o = 6 (mode = 0)
-/// in_i = 000_0001, empty_o = 0, cnt_o = 0 (mode = 0)
-/// in_i = 000_1000, empty_o = 0, cnt_o = 3 (mode = 0)
-/// Furthermore, this unit contains a more efficient implementation for Verilator (simulation only).
-/// This speeds up simulation significantly.
-module lzc #(
- /// The width of the input vector.
- parameter int unsigned WIDTH = 2,
- /// Mode selection: 0 -> trailing zero, 1 -> leading zero
- parameter bit MODE = 1'b0,
- /// Dependent parameter. Do **not** change!
- ///
- /// Width of the output signal with the zero count.
- parameter int unsigned CNT_WIDTH = cf_math_pkg::idx_width(WIDTH)
-) (
- /// Input vector to be counted.
- input logic [WIDTH-1:0] in_i,
- /// Count of the leading / trailing zeros.
- output logic [CNT_WIDTH-1:0] cnt_o,
- /// Counter is empty: Asserted if all bits in in_i are zero.
- output logic empty_o
-);
-
- if (WIDTH == 1) begin : gen_degenerate_lzc
-
- assign cnt_o[0] = !in_i[0];
- assign empty_o = !in_i[0];
-
- end else begin : gen_lzc
-
- localparam int unsigned NumLevels = $clog2(WIDTH);
-
- // pragma translate_off
- initial begin
- assert(WIDTH > 0) else $fatal(1, "input must be at least one bit wide");
- end
- // pragma translate_on
-
- logic [WIDTH-1:0][NumLevels-1:0] index_lut;
- logic [2**NumLevels-1:0] sel_nodes;
- logic [2**NumLevels-1:0][NumLevels-1:0] index_nodes;
-
- logic [WIDTH-1:0] in_tmp;
-
- // reverse vector if required
- always_comb begin : flip_vector
- for (int unsigned i = 0; i < WIDTH; i++) begin
- in_tmp[i] = (MODE) ? in_i[WIDTH-1-i] : in_i[i];
- end
- end
-
- for (genvar j = 0; unsigned'(j) < WIDTH; j++) begin : g_index_lut
- assign index_lut[j] = (NumLevels)'(unsigned'(j));
- end
-
- for (genvar level = 0; unsigned'(level) < NumLevels; level++) begin : g_levels
- if (unsigned'(level) == NumLevels - 1) begin : g_last_level
- for (genvar k = 0; k < 2 ** level; k++) begin : g_level
- // if two successive indices are still in the vector...
- if (unsigned'(k) * 2 < WIDTH - 1) begin : g_reduce
- assign sel_nodes[2 ** level - 1 + k] = in_tmp[k * 2] | in_tmp[k * 2 + 1];
- assign index_nodes[2 ** level - 1 + k] = (in_tmp[k * 2] == 1'b1)
- ? index_lut[k * 2] :
- index_lut[k * 2 + 1];
- end
- // if only the first index is still in the vector...
- if (unsigned'(k) * 2 == WIDTH - 1) begin : g_base
- assign sel_nodes[2 ** level - 1 + k] = in_tmp[k * 2];
- assign index_nodes[2 ** level - 1 + k] = index_lut[k * 2];
- end
- // if index is out of range
- if (unsigned'(k) * 2 > WIDTH - 1) begin : g_out_of_range
- assign sel_nodes[2 ** level - 1 + k] = 1'b0;
- assign index_nodes[2 ** level - 1 + k] = '0;
- end
- end
- end else begin : g_not_last_level
- for (genvar l = 0; l < 2 ** level; l++) begin : g_level
- assign sel_nodes[2 ** level - 1 + l] =
- sel_nodes[2 ** (level + 1) - 1 + l * 2] | sel_nodes[2 ** (level + 1) - 1 + l * 2 + 1];
- assign index_nodes[2 ** level - 1 + l] = (sel_nodes[2 ** (level + 1) - 1 + l * 2] == 1'b1)
- ? index_nodes[2 ** (level + 1) - 1 + l * 2] :
- index_nodes[2 ** (level + 1) - 1 + l * 2 + 1];
- end
- end
- end
-
- assign cnt_o = NumLevels > unsigned'(0) ? index_nodes[0] : {($clog2(WIDTH)) {1'b0}};
- assign empty_o = NumLevels > unsigned'(0) ? ~sel_nodes[0] : ~(|in_i);
-
- end : gen_lzc
-
-endmodule : lzc
diff --git a/verilog/rtl/minus_one.v b/verilog/rtl/minus_one.v
deleted file mode 100644
index f3575c9..0000000
--- a/verilog/rtl/minus_one.v
+++ /dev/null
@@ -1,122 +0,0 @@
-/*Author: Zhuxu
- m99a1@yahoo.cn
-Use parallel prefix tree structure to reduce a 16-bit number by one.
-
-stage 0: number of genration=16; number of logic operation=16; G_0[xx]=~i_operand[xx];
-stage 1: NOG=16; NOO=8; G_1[2n-1]=G_0[2n-1]&&G_0[2n-2]; n=8:1
-stage 2: NOG=16; NOO=7; G_2[2n-1]=G_1[2n-1]&&G_1[2n-3]; n=8:2
-stage 3: NOG=16; NOO=6; G_3[2n-1]=G_2[2n-1]&&G_2[2n-5]; n=8:3
-stage 4: NOG=16; NOO=4; G_4[2n-1]=G_3[2n-1]&&G_3[2n-9]; n=8:5
-stage 5: NOG=16; NOO=7; G_5[2n]=G_4[2n]&&G_4[2n-1]; n=7:1
-
-*/
-module minus_one(
-input [15:0]i_operand,
-output [15:0]o_result,
-output o_borrow
-);
-//stage 0
-wire [15:0]G_0;
-assign G_0=~i_operand;
-
-//stage 1
-wire [15:0]G_1;
-assign G_1[1]=G_0[1]&G_0[0];
-assign G_1[3]=G_0[3]&G_0[2];
-assign G_1[5]=G_0[5]&G_0[4];
-assign G_1[7]=G_0[7]&G_0[6];
-assign G_1[9]=G_0[9]&G_0[8];
-assign G_1[11]=G_0[11]&G_0[10];
-assign G_1[13]=G_0[13]&G_0[12];
-assign G_1[15]=G_0[15]&G_0[14];
-assign G_1[0]=G_0[0];
-assign G_1[2]=G_0[2];
-assign G_1[4]=G_0[4];
-assign G_1[6]=G_0[6];
-assign G_1[8]=G_0[8];
-assign G_1[10]=G_0[10];
-assign G_1[12]=G_0[12];
-assign G_1[14]=G_0[14];
-
-//stage 2
-wire [15:0]G_2;
-assign G_2[3]=G_1[3]&G_1[1];
-assign G_2[5]=G_1[5]&G_1[3];
-assign G_2[7]=G_1[7]&G_1[5];
-assign G_2[9]=G_1[9]&G_1[7];
-assign G_2[11]=G_1[11]&G_1[9];
-assign G_2[13]=G_1[13]&G_1[11];
-assign G_2[15]=G_1[15]&G_1[13];
-assign G_2[0]=G_1[0];
-assign G_2[2]=G_1[2];
-assign G_2[1]=G_1[1];
-assign G_2[4]=G_1[4];
-assign G_2[6]=G_1[6];
-assign G_2[8]=G_1[8];
-assign G_2[10]=G_1[10];
-assign G_2[12]=G_1[12];
-assign G_2[14]=G_1[14];
-
-//stage 3
-wire [15:0]G_3;
-assign G_3[5]=G_2[5]&G_2[1];
-assign G_3[7]=G_2[7]&G_2[3];
-assign G_3[9]=G_2[9]&G_2[5];
-assign G_3[11]=G_2[11]&G_2[7];
-assign G_3[13]=G_2[13]&G_2[9];
-assign G_3[15]=G_2[15]&G_2[11];
-assign G_3[0]=G_2[0];
-assign G_3[2]=G_2[2];
-assign G_3[1]=G_2[1];
-assign G_3[4]=G_2[4];
-assign G_3[3]=G_2[3];
-assign G_3[6]=G_2[6];
-assign G_3[8]=G_2[8];
-assign G_3[10]=G_2[10];
-assign G_3[12]=G_2[12];
-assign G_3[14]=G_2[14];
-
-//stage 4
-wire [15:0]G_4;
-assign G_4[9]=G_3[9]&G_3[1];
-assign G_4[11]=G_3[11]&G_3[3];
-assign G_4[13]=G_3[13]&G_3[5];
-assign G_4[15]=G_3[15]&G_3[7];
-assign G_4[0]=G_3[0];
-assign G_4[2]=G_3[2];
-assign G_4[1]=G_3[1];
-assign G_4[4]=G_3[4];
-assign G_4[3]=G_3[3];
-assign G_4[6]=G_3[6];
-assign G_4[5]=G_3[5];
-assign G_4[8]=G_3[8];
-assign G_4[7]=G_3[7];
-assign G_4[10]=G_3[10];
-assign G_4[12]=G_3[12];
-assign G_4[14]=G_3[14];
-
-//stage 5
-wire [15:0]G_5;
-assign G_5[2]=G_4[2]&G_4[1];
-assign G_5[4]=G_4[4]&G_4[3];
-assign G_5[6]=G_4[6]&G_4[5];
-assign G_5[8]=G_4[8]&G_4[7];
-assign G_5[10]=G_4[10]&G_4[9];
-assign G_5[12]=G_4[12]&G_4[11];
-assign G_5[14]=G_4[14]&G_4[13];
-assign G_5[1]=G_4[1];
-assign G_5[3]=G_4[3];
-assign G_5[5]=G_4[5];
-assign G_5[7]=G_4[7];
-assign G_5[9]=G_4[9];
-assign G_5[11]=G_4[11];
-assign G_5[13]=G_4[13];
-assign G_5[15]=G_4[15];
-assign G_5[0]=G_4[0];
-
-//stage 6
-assign o_result[0]=~i_operand[0];
-assign o_result[15:1]=(G_5[14:0]&(~i_operand[15:1]))|((~G_5[14:0])&i_operand[15:1]);
-assign o_borrow=G_5[15];
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/norm_div_sqrt_mvp.sv b/verilog/rtl/norm_div_sqrt_mvp.sv
deleted file mode 100644
index 590abe9..0000000
--- a/verilog/rtl/norm_div_sqrt_mvp.sv
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright 2018 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.
-
-////////////////////////////////////////////////////////////////////////////////
-// Company: IIS @ ETHZ - Federal Institute of Technology //
-// //
-// Engineers: Lei Li lile@iis.ee.ethz.ch //
-// //
-// Additional contributions by: //
-// //
-// //
-// //
-// Create Date: 09/03/2018 //
-// Design Name: FPU //
-// Module Name: norm_div_sqrt_mvp.sv //
-// Project Name: //
-// Language: SystemVerilog //
-// //
-// Description: Floating point Normalizer/Rounding unit //
-// Since this module is design as a combinatinal logic, it can//
-// be added arbinary register stages for different frequency //
-// in the wrapper module. //
-// //
-// //
-// //
-// Revision Date: 12/04/2018 //
-// Lei Li //
-// To address some requirements by Stefan //
-// //
-// //
-// //
-// //
-// //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-import defs_div_sqrt_mvp::*;
-
-module norm_div_sqrt_mvp
- (//Inputs
- input logic [C_MANT_FP64+4:0] Mant_in_DI, // Include the needed 4-bit for rounding and hidden bit
- input logic signed [C_EXP_FP64+1:0] Exp_in_DI,
- input logic Sign_in_DI,
- input logic Div_enable_SI,
- input logic Sqrt_enable_SI,
- input logic Inf_a_SI,
- input logic Inf_b_SI,
- input logic Zero_a_SI,
- input logic Zero_b_SI,
- input logic NaN_a_SI,
- input logic NaN_b_SI,
- input logic SNaN_SI,
- input logic [C_RM-1:0] RM_SI,
- input logic Full_precision_SI,
- input logic FP32_SI,
- input logic FP64_SI,
- input logic FP16_SI,
- input logic FP16ALT_SI,
- //Outputs
- output logic [C_EXP_FP64+C_MANT_FP64:0] Result_DO,
- output logic [4:0] Fflags_SO //{NV,DZ,OF,UF,NX}
- );
-
-
- logic Sign_res_D;
-
- logic NV_OP_S;
- logic Exp_OF_S;
- logic Exp_UF_S;
- logic Div_Zero_S;
- logic In_Exact_S;
-
- /////////////////////////////////////////////////////////////////////////////
- // Normalization //
- /////////////////////////////////////////////////////////////////////////////
- logic [C_MANT_FP64:0] Mant_res_norm_D;
- logic [C_EXP_FP64-1:0] Exp_res_norm_D;
-
- /////////////////////////////////////////////////////////////////////////////
- // Right shift operations for negtive exponents //
- /////////////////////////////////////////////////////////////////////////////
-
- logic [C_EXP_FP64+1:0] Exp_Max_RS_FP64_D;
- logic [C_EXP_FP32+1:0] Exp_Max_RS_FP32_D;
- logic [C_EXP_FP16+1:0] Exp_Max_RS_FP16_D;
- logic [C_EXP_FP16ALT+1:0] Exp_Max_RS_FP16ALT_D;
- //
- assign Exp_Max_RS_FP64_D=Exp_in_DI[C_EXP_FP64:0]+C_MANT_FP64+1; // to check exponent after (C_MANT_FP64+1)-bit >> when Exp_in_DI is negative
- assign Exp_Max_RS_FP32_D=Exp_in_DI[C_EXP_FP32:0]+C_MANT_FP32+1; // to check exponent after (C_MANT_FP32+1)-bit >> when Exp_in_DI is negative
- assign Exp_Max_RS_FP16_D=Exp_in_DI[C_EXP_FP16:0]+C_MANT_FP16+1; // to check exponent after (C_MANT_FP16+1)-bit >> when Exp_in_DI is negative
- assign Exp_Max_RS_FP16ALT_D=Exp_in_DI[C_EXP_FP16ALT:0]+C_MANT_FP16ALT+1; // to check exponent after (C_MANT_FP16ALT+1)-bit >> when Exp_in_DI is negative
- logic [C_EXP_FP64+1:0] Num_RS_D;
- assign Num_RS_D=~Exp_in_DI+1+1; // How many right shifts(RS) are needed to generate a denormal number? >> is need only when Exp_in_DI is negative
- logic [C_MANT_FP64:0] Mant_RS_D;
- logic [C_MANT_FP64+4:0] Mant_forsticky_D;
- assign {Mant_RS_D,Mant_forsticky_D} ={Mant_in_DI,{(C_MANT_FP64+1){1'b0}} } >>(Num_RS_D); //
-//
- logic [C_EXP_FP64+1:0] Exp_subOne_D;
- assign Exp_subOne_D = Exp_in_DI -1;
-
- //normalization
- logic [1:0] Mant_lower_D;
- logic Mant_sticky_bit_D;
- logic [C_MANT_FP64+4:0] Mant_forround_D;
-
- always_comb
- begin
-
- if(NaN_a_SI) // if a is NaN, return NaN
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D={1'b0,C_MANT_NAN_FP64};
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=1'b0;
- NV_OP_S = SNaN_SI;
- end
-
- else if(NaN_b_SI) //if b is NaN, return NaN
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D={1'b0,C_MANT_NAN_FP64};
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=1'b0;
- NV_OP_S = SNaN_SI;
- end
-
- else if(Inf_a_SI)
- begin
- if(Div_enable_SI&&Inf_b_SI) //Inf/Inf, retrurn NaN
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D={1'b0,C_MANT_NAN_FP64};
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=1'b0;
- NV_OP_S = 1'b1;
- end
- else if (Sqrt_enable_SI && Sign_in_DI) begin // catch sqrt(-inf)
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D={1'b0,C_MANT_NAN_FP64};
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=1'b0;
- NV_OP_S = 1'b1;
- end else begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b1;
- Exp_UF_S=1'b0;
- Mant_res_norm_D= '0;
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
- end
-
- else if(Div_enable_SI&&Inf_b_SI)
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b1;
- Exp_UF_S=1'b0;
- Mant_res_norm_D= '0;
- Exp_res_norm_D='0;
- Mant_forround_D='0;
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
-
- else if(Zero_a_SI)
- begin
- if(Div_enable_SI&&Zero_b_SI)
- begin
- Div_Zero_S=1'b1;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D={1'b0,C_MANT_NAN_FP64};
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=1'b0;
- NV_OP_S = 1'b1;
- end
- else
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D='0;
- Exp_res_norm_D='0;
- Mant_forround_D='0;
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
- end
-
- else if(Div_enable_SI&&(Zero_b_SI)) //div Zero
- begin
- Div_Zero_S=1'b1;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D='0;
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
-
- else if(Sign_in_DI&&Sqrt_enable_SI) //sqrt(-a)
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D={1'b0,C_MANT_NAN_FP64};
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=1'b0;
- NV_OP_S = 1'b1;
- end
-
- else if((Exp_in_DI[C_EXP_FP64:0]=='0))
- begin
- if(Mant_in_DI!='0) //Exp=0, Mant!=0, it is denormal
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b1;
- Mant_res_norm_D={1'b0,Mant_in_DI[C_MANT_FP64+4:5]};
- Exp_res_norm_D='0;
- Mant_forround_D={Mant_in_DI[4:0],{(C_MANT_FP64){1'b0}} };
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
- else // Zero
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D='0;
- Exp_res_norm_D='0;
- Mant_forround_D='0;
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
- end
-
- else if((Exp_in_DI[C_EXP_FP64:0]==C_EXP_ONE_FP64)&&(~Mant_in_DI[C_MANT_FP64+4])) //denormal
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b1;
- Mant_res_norm_D=Mant_in_DI[C_MANT_FP64+4:4];
- Exp_res_norm_D='0;
- Mant_forround_D={Mant_in_DI[3:0],{(C_MANT_FP64+1){1'b0}}};
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
-
- else if(Exp_in_DI[C_EXP_FP64+1]) //minus //consider format
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b1;
- Mant_res_norm_D={Mant_RS_D[C_MANT_FP64:0]};
- Exp_res_norm_D='0;
- Mant_forround_D={Mant_forsticky_D[C_MANT_FP64+4:0]}; //??
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
-
- else if( (Exp_in_DI[C_EXP_FP32]&&FP32_SI) | (Exp_in_DI[C_EXP_FP64]&&FP64_SI) | (Exp_in_DI[C_EXP_FP16]&&FP16_SI) | (Exp_in_DI[C_EXP_FP16ALT]&&FP16ALT_SI) ) //OF
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b1;
- Exp_UF_S=1'b0;
- Mant_res_norm_D='0;
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
-
- else if( ((Exp_in_DI[C_EXP_FP32-1:0]=='1)&&FP32_SI) | ((Exp_in_DI[C_EXP_FP64-1:0]=='1)&&FP64_SI) | ((Exp_in_DI[C_EXP_FP16-1:0]=='1)&&FP16_SI) | ((Exp_in_DI[C_EXP_FP16ALT-1:0]=='1)&&FP16ALT_SI) )//255
- begin
- if(~Mant_in_DI[C_MANT_FP64+4]) // MSB=0
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D=Mant_in_DI[C_MANT_FP64+3:3];
- Exp_res_norm_D=Exp_subOne_D;
- Mant_forround_D={Mant_in_DI[2:0],{(C_MANT_FP64+2){1'b0}}};
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
- else if(Mant_in_DI!='0) //NaN
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b1;
- Exp_UF_S=1'b0;
- Mant_res_norm_D= '0;
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
- else //infinity
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b1;
- Exp_UF_S=1'b0;
- Mant_res_norm_D= '0;
- Exp_res_norm_D='1;
- Mant_forround_D='0;
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
- end
-
- else if(Mant_in_DI[C_MANT_FP64+4]) //normal numbers with 1.XXX
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D= Mant_in_DI[C_MANT_FP64+4:4];
- Exp_res_norm_D=Exp_in_DI[C_EXP_FP64-1:0];
- Mant_forround_D={Mant_in_DI[3:0],{(C_MANT_FP64+1){1'b0}}};
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
-
- else //normal numbers with 0.1XX
- begin
- Div_Zero_S=1'b0;
- Exp_OF_S=1'b0;
- Exp_UF_S=1'b0;
- Mant_res_norm_D=Mant_in_DI[C_MANT_FP64+3:3];
- Exp_res_norm_D=Exp_subOne_D;
- Mant_forround_D={Mant_in_DI[2:0],{(C_MANT_FP64+2){1'b0}}};
- Sign_res_D=Sign_in_DI;
- NV_OP_S = 1'b0;
- end
-
- end
-
- /////////////////////////////////////////////////////////////////////////////
- // Rounding enable only for full precision (Full_precision_SI==1'b1) //
- /////////////////////////////////////////////////////////////////////////////
-
- logic [C_MANT_FP64:0] Mant_upper_D;
- logic [C_MANT_FP64+1:0] Mant_upperRounded_D;
- logic Mant_roundUp_S;
- logic Mant_rounded_S;
-
- always_comb //determine which bits for Mant_lower_D and Mant_sticky_bit_D
- begin
- if(FP32_SI)
- begin
- Mant_upper_D = {Mant_res_norm_D[C_MANT_FP64:C_MANT_FP64-C_MANT_FP32], {(C_MANT_FP64-C_MANT_FP32){1'b0}} };
- Mant_lower_D = Mant_res_norm_D[C_MANT_FP64-C_MANT_FP32-1:C_MANT_FP64-C_MANT_FP32-2];
- Mant_sticky_bit_D = | Mant_res_norm_D[C_MANT_FP64-C_MANT_FP32-3:0];
- end
- else if(FP64_SI)
- begin
- Mant_upper_D = Mant_res_norm_D[C_MANT_FP64:0];
- Mant_lower_D = Mant_forround_D[C_MANT_FP64+4:C_MANT_FP64+3];
- Mant_sticky_bit_D = | Mant_forround_D[C_MANT_FP64+3:0];
- end
- else if(FP16_SI)
- begin
- Mant_upper_D = {Mant_res_norm_D[C_MANT_FP64:C_MANT_FP64-C_MANT_FP16], {(C_MANT_FP64-C_MANT_FP16){1'b0}} };
- Mant_lower_D = Mant_res_norm_D[C_MANT_FP64-C_MANT_FP16-1:C_MANT_FP64-C_MANT_FP16-2];
- Mant_sticky_bit_D = | Mant_res_norm_D[C_MANT_FP64-C_MANT_FP16-3:30];
- end
- else //FP16ALT
- begin
- Mant_upper_D = {Mant_res_norm_D[C_MANT_FP64:C_MANT_FP64-C_MANT_FP16ALT], {(C_MANT_FP64-C_MANT_FP16ALT){1'b0}} };
- Mant_lower_D = Mant_res_norm_D[C_MANT_FP64-C_MANT_FP16ALT-1:C_MANT_FP64-C_MANT_FP16ALT-2];
- Mant_sticky_bit_D = | Mant_res_norm_D[C_MANT_FP64-C_MANT_FP16ALT-3:30];
- end
- end
-
- assign Mant_rounded_S = (|(Mant_lower_D))| Mant_sticky_bit_D;
-
-
-
-
- always_comb //determine whether to round up or not
- begin
- Mant_roundUp_S = 1'b0;
- case (RM_SI)
- C_RM_NEAREST :
- Mant_roundUp_S = Mant_lower_D[1] && ((Mant_lower_D[0] | Mant_sticky_bit_D )| ( (FP32_SI&&Mant_upper_D[C_MANT_FP64-C_MANT_FP32]) | (FP64_SI&&Mant_upper_D[0]) | (FP16_SI&&Mant_upper_D[C_MANT_FP64-C_MANT_FP16]) | (FP16ALT_SI&&Mant_upper_D[C_MANT_FP64-C_MANT_FP16ALT]) ) );
- C_RM_TRUNC :
- Mant_roundUp_S = 0;
- C_RM_PLUSINF :
- Mant_roundUp_S = Mant_rounded_S & ~Sign_in_DI;
- C_RM_MINUSINF:
- Mant_roundUp_S = Mant_rounded_S & Sign_in_DI;
- default :
- Mant_roundUp_S = 0;
- endcase // case (RM_DI)
- end // always_comb begin
-
- logic Mant_renorm_S;
- logic [C_MANT_FP64:0] Mant_roundUp_Vector_S; // for all the formats
-
- assign Mant_roundUp_Vector_S={7'h0,(FP16ALT_SI&&Mant_roundUp_S),2'h0,(FP16_SI&&Mant_roundUp_S),12'h0,(FP32_SI&&Mant_roundUp_S),28'h0,(FP64_SI&&Mant_roundUp_S)};
-
-
- assign Mant_upperRounded_D = Mant_upper_D + Mant_roundUp_Vector_S;
- assign Mant_renorm_S = Mant_upperRounded_D[C_MANT_FP64+1];
-
- /////////////////////////////////////////////////////////////////////////////
- // Renormalization for Rounding //
- /////////////////////////////////////////////////////////////////////////////
- logic [C_MANT_FP64-1:0] Mant_res_round_D;
- logic [C_EXP_FP64-1:0] Exp_res_round_D;
-
-
- assign Mant_res_round_D = (Mant_renorm_S)?Mant_upperRounded_D[C_MANT_FP64:1]:Mant_upperRounded_D[C_MANT_FP64-1:0]; // including the process of the hidden bit
- assign Exp_res_round_D = Exp_res_norm_D+Mant_renorm_S;
-
- /////////////////////////////////////////////////////////////////////////////
- // Output Assignments //
- /////////////////////////////////////////////////////////////////////////////
- logic [C_MANT_FP64-1:0] Mant_before_format_ctl_D;
- logic [C_EXP_FP64-1:0] Exp_before_format_ctl_D;
- assign Mant_before_format_ctl_D = Full_precision_SI ? Mant_res_round_D : Mant_res_norm_D;
- assign Exp_before_format_ctl_D = Full_precision_SI ? Exp_res_round_D : Exp_res_norm_D;
-
- always_comb //NaN Boxing
- begin //
- if(FP32_SI)
- begin
- Result_DO ={32'hffff_ffff,Sign_res_D,Exp_before_format_ctl_D[C_EXP_FP32-1:0],Mant_before_format_ctl_D[C_MANT_FP64-1:C_MANT_FP64-C_MANT_FP32]};
- end
- else if(FP64_SI)
- begin
- Result_DO ={Sign_res_D,Exp_before_format_ctl_D[C_EXP_FP64-1:0],Mant_before_format_ctl_D[C_MANT_FP64-1:0]};
- end
- else if(FP16_SI)
- begin
- Result_DO ={48'hffff_ffff_ffff,Sign_res_D,Exp_before_format_ctl_D[C_EXP_FP16-1:0],Mant_before_format_ctl_D[C_MANT_FP64-1:C_MANT_FP64-C_MANT_FP16]};
- end
- else
- begin
- Result_DO ={48'hffff_ffff_ffff,Sign_res_D,Exp_before_format_ctl_D[C_EXP_FP16ALT-1:0],Mant_before_format_ctl_D[C_MANT_FP64-1:C_MANT_FP64-C_MANT_FP16ALT]};
- end
- end
-
-assign In_Exact_S = (~Full_precision_SI) | Mant_rounded_S;
-assign Fflags_SO = {NV_OP_S,Div_Zero_S,Exp_OF_S,Exp_UF_S,In_Exact_S}; //{NV,DZ,OF,UF,NX}
-
-endmodule // norm_div_sqrt_mvp
diff --git a/verilog/rtl/nrbd_nrsc_mvp.sv b/verilog/rtl/nrbd_nrsc_mvp.sv
deleted file mode 100644
index 62bd147..0000000
--- a/verilog/rtl/nrbd_nrsc_mvp.sv
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2018 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.
-////////////////////////////////////////////////////////////////////////////////
-// Company: IIS @ ETHZ - Federal Institute of Technology //
-// //
-// Engineers: Lei Li lile@iis.ee.ethz.ch //
-// //
-// Additional contributions by: //
-// //
-// //
-// //
-// Create Date: 10/04/2018 //
-// Design Name: FPU //
-// Module Name: nrbd_nrsc_mvp.sv //
-// Project Name: Private FPU //
-// Language: SystemVerilog //
-// //
-// Description: non restroring binary divisior/ square root //
-// //
-// Revision Date: 12/04/2018 //
-// Lei Li //
-// To address some requirements by Stefan and add low power //
-// control for special cases //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-import defs_div_sqrt_mvp::*;
-
-module nrbd_nrsc_mvp
-
- (//Input
- input logic Clk_CI,
- input logic Rst_RBI,
- input logic Div_start_SI,
- input logic Sqrt_start_SI,
- input logic Start_SI,
- input logic Kill_SI,
- input logic Special_case_SBI,
- input logic Special_case_dly_SBI,
- input logic [C_PC-1:0] Precision_ctl_SI,
- input logic [1:0] Format_sel_SI,
- input logic [C_MANT_FP64:0] Mant_a_DI,
- input logic [C_MANT_FP64:0] Mant_b_DI,
- input logic [C_EXP_FP64:0] Exp_a_DI,
- input logic [C_EXP_FP64:0] Exp_b_DI,
- //output
- output logic Div_enable_SO,
- output logic Sqrt_enable_SO,
-
- output logic Full_precision_SO,
- output logic FP32_SO,
- output logic FP64_SO,
- output logic FP16_SO,
- output logic FP16ALT_SO,
- output logic Ready_SO,
- output logic Done_SO,
- output logic [C_MANT_FP64+4:0] Mant_z_DO,
- output logic [C_EXP_FP64+1:0] Exp_z_DO
- );
-
-
- logic Div_start_dly_S,Sqrt_start_dly_S;
-
-
-control_mvp control_U0
-( .Clk_CI (Clk_CI ),
- .Rst_RBI (Rst_RBI ),
- .Div_start_SI (Div_start_SI ),
- .Sqrt_start_SI (Sqrt_start_SI ),
- .Start_SI (Start_SI ),
- .Kill_SI (Kill_SI ),
- .Special_case_SBI (Special_case_SBI ),
- .Special_case_dly_SBI (Special_case_dly_SBI ),
- .Precision_ctl_SI (Precision_ctl_SI ),
- .Format_sel_SI (Format_sel_SI ),
- .Numerator_DI (Mant_a_DI ),
- .Exp_num_DI (Exp_a_DI ),
- .Denominator_DI (Mant_b_DI ),
- .Exp_den_DI (Exp_b_DI ),
- .Div_start_dly_SO (Div_start_dly_S ),
- .Sqrt_start_dly_SO (Sqrt_start_dly_S ),
- .Div_enable_SO (Div_enable_SO ),
- .Sqrt_enable_SO (Sqrt_enable_SO ),
- .Full_precision_SO (Full_precision_SO ),
- .FP32_SO (FP32_SO ),
- .FP64_SO (FP64_SO ),
- .FP16_SO (FP16_SO ),
- .FP16ALT_SO (FP16ALT_SO ),
- .Ready_SO (Ready_SO ),
- .Done_SO (Done_SO ),
- .Mant_result_prenorm_DO (Mant_z_DO ),
- .Exp_result_prenorm_DO (Exp_z_DO )
-);
-
-
-
-endmodule
diff --git a/verilog/rtl/preprocess_mvp.sv b/verilog/rtl/preprocess_mvp.sv
deleted file mode 100644
index 9e0d25f..0000000
--- a/verilog/rtl/preprocess_mvp.sv
+++ /dev/null
@@ -1,425 +0,0 @@
-// Copyright 2018 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.
-////////////////////////////////////////////////////////////////////////////////
-// Company: IIS @ ETHZ - Federal Institute of Technology //
-// //
-// Engineers: Lei Li //lile@iis.ee.ethz.ch //
-// //
-// Additional contributions by: //
-// //
-// //
-// //
-// Create Date: 01/03/2018 //
-// Design Name: FPU //
-// Module Name: preprocess_mvp.sv //
-// Project Name: Private FPU //
-// Language: SystemVerilog //
-// //
-// Description: decode and data preparation //
-// //
-// Revision Date: 12/04/2018 //
-// Lei Li //
-// To address some requirements by Stefan and add low power //
-// control for special cases //
-// //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
-import defs_div_sqrt_mvp::*;
-
-module preprocess_mvp
- (
- input logic Clk_CI,
- input logic Rst_RBI,
- input logic Div_start_SI,
- input logic Sqrt_start_SI,
- input logic Ready_SI,
- //Input Operands
- input logic [C_OP_FP64-1:0] Operand_a_DI,
- input logic [C_OP_FP64-1:0] Operand_b_DI,
- input logic [C_RM-1:0] RM_SI, //Rounding Mode
- input logic [C_FS-1:0] Format_sel_SI, // Format Selection
-
- // to control
- output logic Start_SO,
- output logic [C_EXP_FP64:0] Exp_a_DO_norm,
- output logic [C_EXP_FP64:0] Exp_b_DO_norm,
- output logic [C_MANT_FP64:0] Mant_a_DO_norm,
- output logic [C_MANT_FP64:0] Mant_b_DO_norm,
-
- output logic [C_RM-1:0] RM_dly_SO,
-
- output logic Sign_z_DO,
- output logic Inf_a_SO,
- output logic Inf_b_SO,
- output logic Zero_a_SO,
- output logic Zero_b_SO,
- output logic NaN_a_SO,
- output logic NaN_b_SO,
- output logic SNaN_SO,
- output logic Special_case_SBO,
- output logic Special_case_dly_SBO
- );
-
- //Hidden Bits
- logic Hb_a_D;
- logic Hb_b_D;
-
- logic [C_EXP_FP64-1:0] Exp_a_D;
- logic [C_EXP_FP64-1:0] Exp_b_D;
- logic [C_MANT_FP64-1:0] Mant_a_NonH_D;
- logic [C_MANT_FP64-1:0] Mant_b_NonH_D;
- logic [C_MANT_FP64:0] Mant_a_D;
- logic [C_MANT_FP64:0] Mant_b_D;
-
- /////////////////////////////////////////////////////////////////////////////
- // Disassemble operands
- /////////////////////////////////////////////////////////////////////////////
- logic Sign_a_D,Sign_b_D;
- logic Start_S;
-
- always_comb
- begin
- case(Format_sel_SI)
- 2'b00:
- begin
- Sign_a_D = Operand_a_DI[C_OP_FP32-1];
- Sign_b_D = Operand_b_DI[C_OP_FP32-1];
- Exp_a_D = {3'h0, Operand_a_DI[C_OP_FP32-2:C_MANT_FP32]};
- Exp_b_D = {3'h0, Operand_b_DI[C_OP_FP32-2:C_MANT_FP32]};
- Mant_a_NonH_D = {Operand_a_DI[C_MANT_FP32-1:0],29'h0};
- Mant_b_NonH_D = {Operand_b_DI[C_MANT_FP32-1:0],29'h0};
- end
- 2'b01:
- begin
- Sign_a_D = Operand_a_DI[C_OP_FP64-1];
- Sign_b_D = Operand_b_DI[C_OP_FP64-1];
- Exp_a_D = Operand_a_DI[C_OP_FP64-2:C_MANT_FP64];
- Exp_b_D = Operand_b_DI[C_OP_FP64-2:C_MANT_FP64];
- Mant_a_NonH_D = Operand_a_DI[C_MANT_FP64-1:0];
- Mant_b_NonH_D = Operand_b_DI[C_MANT_FP64-1:0];
- end
- 2'b10:
- begin
- Sign_a_D = Operand_a_DI[C_OP_FP16-1];
- Sign_b_D = Operand_b_DI[C_OP_FP16-1];
- Exp_a_D = {6'h00, Operand_a_DI[C_OP_FP16-2:C_MANT_FP16]};
- Exp_b_D = {6'h00, Operand_b_DI[C_OP_FP16-2:C_MANT_FP16]};
- Mant_a_NonH_D = {Operand_a_DI[C_MANT_FP16-1:0],42'h0};
- Mant_b_NonH_D = {Operand_b_DI[C_MANT_FP16-1:0],42'h0};
- end
- 2'b11:
- begin
- Sign_a_D = Operand_a_DI[C_OP_FP16ALT-1];
- Sign_b_D = Operand_b_DI[C_OP_FP16ALT-1];
- Exp_a_D = {3'h0, Operand_a_DI[C_OP_FP16ALT-2:C_MANT_FP16ALT]};
- Exp_b_D = {3'h0, Operand_b_DI[C_OP_FP16ALT-2:C_MANT_FP16ALT]};
- Mant_a_NonH_D = {Operand_a_DI[C_MANT_FP16ALT-1:0],45'h0};
- Mant_b_NonH_D = {Operand_b_DI[C_MANT_FP16ALT-1:0],45'h0};
- end
- endcase
- end
-
-
- assign Mant_a_D = {Hb_a_D,Mant_a_NonH_D};
- assign Mant_b_D = {Hb_b_D,Mant_b_NonH_D};
-
- assign Hb_a_D = | Exp_a_D; // hidden bit
- assign Hb_b_D = | Exp_b_D; // hidden bit
-
- assign Start_S= Div_start_SI | Sqrt_start_SI;
-
-
-
- /////////////////////////////////////////////////////////////////////////////
- // preliminary checks for infinite/zero/NaN operands //
- /////////////////////////////////////////////////////////////////////////////
-
- logic Mant_a_prenorm_zero_S;
- logic Mant_b_prenorm_zero_S;
-
- logic Exp_a_prenorm_zero_S;
- logic Exp_b_prenorm_zero_S;
- assign Exp_a_prenorm_zero_S = ~Hb_a_D;
- assign Exp_b_prenorm_zero_S = ~Hb_b_D;
-
- logic Exp_a_prenorm_Inf_NaN_S;
- logic Exp_b_prenorm_Inf_NaN_S;
-
- logic Mant_a_prenorm_QNaN_S;
- logic Mant_a_prenorm_SNaN_S;
- logic Mant_b_prenorm_QNaN_S;
- logic Mant_b_prenorm_SNaN_S;
-
- assign Mant_a_prenorm_QNaN_S=Mant_a_NonH_D[C_MANT_FP64-1]&&(~(|Mant_a_NonH_D[C_MANT_FP64-2:0]));
- assign Mant_a_prenorm_SNaN_S=(~Mant_a_NonH_D[C_MANT_FP64-1])&&((|Mant_a_NonH_D[C_MANT_FP64-2:0]));
- assign Mant_b_prenorm_QNaN_S=Mant_b_NonH_D[C_MANT_FP64-1]&&(~(|Mant_b_NonH_D[C_MANT_FP64-2:0]));
- assign Mant_b_prenorm_SNaN_S=(~Mant_b_NonH_D[C_MANT_FP64-1])&&((|Mant_b_NonH_D[C_MANT_FP64-2:0]));
-
- always_comb
- begin
- case(Format_sel_SI)
- 2'b00:
- begin
- Mant_a_prenorm_zero_S=(Operand_a_DI[C_MANT_FP32-1:0] == C_MANT_ZERO_FP32);
- Mant_b_prenorm_zero_S=(Operand_b_DI[C_MANT_FP32-1:0] == C_MANT_ZERO_FP32);
- Exp_a_prenorm_Inf_NaN_S=(Operand_a_DI[C_OP_FP32-2:C_MANT_FP32] == C_EXP_INF_FP32);
- Exp_b_prenorm_Inf_NaN_S=(Operand_b_DI[C_OP_FP32-2:C_MANT_FP32] == C_EXP_INF_FP32);
- end
- 2'b01:
- begin
- Mant_a_prenorm_zero_S=(Operand_a_DI[C_MANT_FP64-1:0] == C_MANT_ZERO_FP64);
- Mant_b_prenorm_zero_S=(Operand_b_DI[C_MANT_FP64-1:0] == C_MANT_ZERO_FP64);
- Exp_a_prenorm_Inf_NaN_S=(Operand_a_DI[C_OP_FP64-2:C_MANT_FP64] == C_EXP_INF_FP64);
- Exp_b_prenorm_Inf_NaN_S=(Operand_b_DI[C_OP_FP64-2:C_MANT_FP64] == C_EXP_INF_FP64);
- end
- 2'b10:
- begin
- Mant_a_prenorm_zero_S=(Operand_a_DI[C_MANT_FP16-1:0] == C_MANT_ZERO_FP16);
- Mant_b_prenorm_zero_S=(Operand_b_DI[C_MANT_FP16-1:0] == C_MANT_ZERO_FP16);
- Exp_a_prenorm_Inf_NaN_S=(Operand_a_DI[C_OP_FP16-2:C_MANT_FP16] == C_EXP_INF_FP16);
- Exp_b_prenorm_Inf_NaN_S=(Operand_b_DI[C_OP_FP16-2:C_MANT_FP16] == C_EXP_INF_FP16);
- end
- 2'b11:
- begin
- Mant_a_prenorm_zero_S=(Operand_a_DI[C_MANT_FP16ALT-1:0] == C_MANT_ZERO_FP16ALT);
- Mant_b_prenorm_zero_S=(Operand_b_DI[C_MANT_FP16ALT-1:0] == C_MANT_ZERO_FP16ALT);
- Exp_a_prenorm_Inf_NaN_S=(Operand_a_DI[C_OP_FP16ALT-2:C_MANT_FP16ALT] == C_EXP_INF_FP16ALT);
- Exp_b_prenorm_Inf_NaN_S=(Operand_b_DI[C_OP_FP16ALT-2:C_MANT_FP16ALT] == C_EXP_INF_FP16ALT);
- end
- endcase
- end
-
-
-
-
- logic Zero_a_SN,Zero_a_SP;
- logic Zero_b_SN,Zero_b_SP;
- logic Inf_a_SN,Inf_a_SP;
- logic Inf_b_SN,Inf_b_SP;
- logic NaN_a_SN,NaN_a_SP;
- logic NaN_b_SN,NaN_b_SP;
- logic SNaN_SN,SNaN_SP;
-
- assign Zero_a_SN = (Start_S&&Ready_SI)?(Exp_a_prenorm_zero_S&&Mant_a_prenorm_zero_S):Zero_a_SP;
- assign Zero_b_SN = (Start_S&&Ready_SI)?(Exp_b_prenorm_zero_S&&Mant_b_prenorm_zero_S):Zero_b_SP;
- assign Inf_a_SN = (Start_S&&Ready_SI)?(Exp_a_prenorm_Inf_NaN_S&&Mant_a_prenorm_zero_S):Inf_a_SP;
- assign Inf_b_SN = (Start_S&&Ready_SI)?(Exp_b_prenorm_Inf_NaN_S&&Mant_b_prenorm_zero_S):Inf_b_SP;
- assign NaN_a_SN = (Start_S&&Ready_SI)?(Exp_a_prenorm_Inf_NaN_S&&(~Mant_a_prenorm_zero_S)):NaN_a_SP;
- assign NaN_b_SN = (Start_S&&Ready_SI)?(Exp_b_prenorm_Inf_NaN_S&&(~Mant_b_prenorm_zero_S)):NaN_b_SP;
- assign SNaN_SN = (Start_S&&Ready_SI) ? ((Mant_a_prenorm_SNaN_S&&NaN_a_SN) | (Mant_b_prenorm_SNaN_S&&NaN_b_SN)) : SNaN_SP;
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Zero_a_SP <='0;
- Zero_b_SP <='0;
- Inf_a_SP <='0;
- Inf_b_SP <='0;
- NaN_a_SP <='0;
- NaN_b_SP <='0;
- SNaN_SP <= '0;
- end
- else
- begin
- Inf_a_SP <=Inf_a_SN;
- Inf_b_SP <=Inf_b_SN;
- Zero_a_SP <=Zero_a_SN;
- Zero_b_SP <=Zero_b_SN;
- NaN_a_SP <=NaN_a_SN;
- NaN_b_SP <=NaN_b_SN;
- SNaN_SP <= SNaN_SN;
- end
- end
-
- /////////////////////////////////////////////////////////////////////////////
- // Low power control
- /////////////////////////////////////////////////////////////////////////////
-
- assign Special_case_SBO=(~{(Div_start_SI)?(Zero_a_SN | Zero_b_SN | Inf_a_SN | Inf_b_SN | NaN_a_SN | NaN_b_SN): (Zero_a_SN | Inf_a_SN | NaN_a_SN | Sign_a_D) })&&(Start_S&&Ready_SI);
-
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Special_case_dly_SBO <= '0;
- end
- else if((Start_S&&Ready_SI))
- begin
- Special_case_dly_SBO <= Special_case_SBO;
- end
- else if(Special_case_dly_SBO)
- begin
- Special_case_dly_SBO <= 1'b1;
- end
- else
- begin
- Special_case_dly_SBO <= '0;
- end
- end
-
- /////////////////////////////////////////////////////////////////////////////
- // Delay sign for normalization and round //
- /////////////////////////////////////////////////////////////////////////////
-
- logic Sign_z_DN;
- logic Sign_z_DP;
-
- always_comb
- begin
- if(Div_start_SI&&Ready_SI)
- Sign_z_DN = Sign_a_D ^ Sign_b_D;
- else if(Sqrt_start_SI&&Ready_SI)
- Sign_z_DN = Sign_a_D;
- else
- Sign_z_DN = Sign_z_DP;
- end
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Sign_z_DP <= '0;
- end
- else
- begin
- Sign_z_DP <= Sign_z_DN;
- end
- end
-
- logic [C_RM-1:0] RM_DN;
- logic [C_RM-1:0] RM_DP;
-
- always_comb
- begin
- if(Start_S&&Ready_SI)
- RM_DN = RM_SI;
- else
- RM_DN = RM_DP;
- end
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- RM_DP <= '0;
- end
- else
- begin
- RM_DP <= RM_DN;
- end
- end
- assign RM_dly_SO = RM_DP;
-
- logic [5:0] Mant_leadingOne_a, Mant_leadingOne_b;
- logic Mant_zero_S_a,Mant_zero_S_b;
-
- lzc #(
- .WIDTH ( C_MANT_FP64+1 ),
- .MODE ( 1 )
- ) LOD_Ua (
- .in_i ( Mant_a_D ),
- .cnt_o ( Mant_leadingOne_a ),
- .empty_o ( Mant_zero_S_a )
- );
-
- logic [C_MANT_FP64:0] Mant_a_norm_DN,Mant_a_norm_DP;
-
- assign Mant_a_norm_DN = ((Start_S&&Ready_SI))?(Mant_a_D<<(Mant_leadingOne_a)):Mant_a_norm_DP;
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Mant_a_norm_DP <= '0;
- end
- else
- begin
- Mant_a_norm_DP<=Mant_a_norm_DN;
- end
- end
-
- logic [C_EXP_FP64:0] Exp_a_norm_DN,Exp_a_norm_DP;
- assign Exp_a_norm_DN = ((Start_S&&Ready_SI))?(Exp_a_D-Mant_leadingOne_a+(|Mant_leadingOne_a)):Exp_a_norm_DP; //Covering the process of denormal numbers
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Exp_a_norm_DP <= '0;
- end
- else
- begin
- Exp_a_norm_DP<=Exp_a_norm_DN;
- end
- end
-
- lzc #(
- .WIDTH ( C_MANT_FP64+1 ),
- .MODE ( 1 )
- ) LOD_Ub (
- .in_i ( Mant_b_D ),
- .cnt_o ( Mant_leadingOne_b ),
- .empty_o ( Mant_zero_S_b )
- );
-
-
- logic [C_MANT_FP64:0] Mant_b_norm_DN,Mant_b_norm_DP;
-
- assign Mant_b_norm_DN = ((Start_S&&Ready_SI))?(Mant_b_D<<(Mant_leadingOne_b)):Mant_b_norm_DP;
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Mant_b_norm_DP <= '0;
- end
- else
- begin
- Mant_b_norm_DP<=Mant_b_norm_DN;
- end
- end
-
- logic [C_EXP_FP64:0] Exp_b_norm_DN,Exp_b_norm_DP;
- assign Exp_b_norm_DN = ((Start_S&&Ready_SI))?(Exp_b_D-Mant_leadingOne_b+(|Mant_leadingOne_b)):Exp_b_norm_DP; //Covering the process of denormal numbers
-
- always_ff @(posedge Clk_CI, negedge Rst_RBI)
- begin
- if(~Rst_RBI)
- begin
- Exp_b_norm_DP <= '0;
- end
- else
- begin
- Exp_b_norm_DP<=Exp_b_norm_DN;
- end
- end
-
- /////////////////////////////////////////////////////////////////////////////
- // Output assignments //
- /////////////////////////////////////////////////////////////////////////////
-
- assign Start_SO=Start_S;
- assign Exp_a_DO_norm=Exp_a_norm_DP;
- assign Exp_b_DO_norm=Exp_b_norm_DP;
- assign Mant_a_DO_norm=Mant_a_norm_DP;
- assign Mant_b_DO_norm=Mant_b_norm_DP;
- assign Sign_z_DO=Sign_z_DP;
- assign Inf_a_SO=Inf_a_SP;
- assign Inf_b_SO=Inf_b_SP;
- assign Zero_a_SO=Zero_a_SP;
- assign Zero_b_SO=Zero_b_SP;
- assign NaN_a_SO=NaN_a_SP;
- assign NaN_b_SO=NaN_b_SP;
- assign SNaN_SO=SNaN_SP;
-
-endmodule
diff --git a/verilog/rtl/prim_arbiter_ppc.sv b/verilog/rtl/prim_arbiter_ppc.sv
deleted file mode 100644
index e379f8a..0000000
--- a/verilog/rtl/prim_arbiter_ppc.sv
+++ /dev/null
@@ -1,127 +0,0 @@
-
-//
-// N:1 arbiter module
-//
-// Verilog parameter
-// N: Number of request ports
-// DW: Data width
-// DataPort: Set to 1 to enable the data port. Otherwise that port will be ignored.
-// EnReqStabA: Checks whether requests remain asserted until granted
-//
-// This is the original implementation of the arbiter which relies on parallel prefix computing
-// optimization to optimize the request / arbiter tree. Not all synthesis tools may support this.
-//
-// Note that the currently winning request is held if the data sink is not ready. This behavior is
-// required by some interconnect protocols (AXI, TL). The module contains an assertion that checks
-// this behavior.
-//
-// Also, this module contains a request stability assertion that checks that requests stay asserted
-// until they have been served. This assertion can be optionally disabled by setting EnReqStabA to
-// zero. This is a non-functional parameter and does not affect the designs behavior.
-//
-// See also: prim_arbiter_tree
-
-
-
-module prim_arbiter_ppc #(
- parameter int unsigned N = 8,
- parameter int unsigned DW = 32,
-
- // Configurations
- // EnDataPort: {0, 1}, if 0, input data will be ignored
- parameter bit EnDataPort = 1,
-
- // Non-functional parameter to switch on the request stability assertion
- parameter bit EnReqStabA = 1,
-
- // Derived parameters
- localparam int IdxW = $clog2(N)
-) (
- input clk_i,
- input rst_ni,
-
- input [ N-1:0] req_i,
- input [DW-1:0] data_i [N],
- output logic [ N-1:0] gnt_o,
- output logic [IdxW-1:0] idx_o,
-
- output logic valid_o,
- output logic [DW-1:0] data_o,
- input ready_i
-);
-
-
- // this case is basically just a bypass
- if (N == 1) begin : gen_degenerate_case
-
- assign valid_o = req_i[0];
- assign data_o = data_i[0];
- assign gnt_o[0] = valid_o & ready_i;
- assign idx_o = '0;
-
- end else begin : gen_normal_case
-
- logic [N-1:0] masked_req;
- logic [N-1:0] ppc_out;
- logic [N-1:0] arb_req;
- logic [N-1:0] mask, mask_next;
- logic [N-1:0] winner;
-
- assign masked_req = mask & req_i;
- assign arb_req = (|masked_req) ? masked_req : req_i;
-
- // PPC
- // Even below code looks O(n) but DC optimizes it to O(log(N))
- // Using Parallel Prefix Computation
- always_comb begin
- ppc_out[0] = arb_req[0];
- for (int i = 1 ; i < N ; i++) begin
- ppc_out[i] = ppc_out[i-1] | arb_req[i];
- end
- end
-
- // Grant Generation: Leading-One detector
- assign winner = ppc_out ^ {ppc_out[N-2:0], 1'b0};
- assign gnt_o = (ready_i) ? winner : '0;
-
- assign valid_o = |req_i;
- // Mask Generation
- assign mask_next = {ppc_out[N-2:0], 1'b0};
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- mask <= '0;
- end else if (valid_o && ready_i) begin
- // Latch only when requests accepted
- mask <= mask_next;
- end else if (valid_o && !ready_i) begin
- // Downstream isn't yet ready so, keep current request alive. (First come first serve)
- mask <= ppc_out;
- end
- end
-
- if (EnDataPort == 1) begin: gen_datapath
- always_comb begin
- data_o = '0;
- for (int i = 0 ; i < N ; i++) begin
- if (winner[i]) begin
- data_o = data_i[i];
- end
- end
- end
- end else begin: gen_nodatapath
- assign data_o = '1;
- // TODO: waive data_i from NOT_READ error
- end
-
- always_comb begin
- idx_o = '0;
- for (int unsigned i = 0 ; i < N ; i++) begin
- if (winner[i]) begin
- idx_o = i[IdxW-1:0];
- end
- end
- end
- end
-
-
-endmodule : prim_arbiter_ppc
diff --git a/verilog/rtl/prim_clock_gating.sv b/verilog/rtl/prim_clock_gating.sv
deleted file mode 100644
index 177d2c0..0000000
--- a/verilog/rtl/prim_clock_gating.sv
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-module prim_clock_gating (
- input clk_i,
- input en_i,
- input test_en_i,
- output logic clk_o
-);
-
-sky130_fd_sc_hd__dlclkp_1 CG( .CLK(clk_i), .GCLK(clk_o), .GATE(en_i | test_en_i));
-
-endmodule
diff --git a/verilog/rtl/prim_filter_ctr.sv b/verilog/rtl/prim_filter_ctr.sv
deleted file mode 100644
index ec635b8..0000000
--- a/verilog/rtl/prim_filter_ctr.sv
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Primitive counter-based input filter, with enable.
-// Configurable number of cycles. Cheaper version of filter for
-// large values of #Cycles
-//
-// when in reset, stored value is zero
-// when enable is false, output is input
-// when enable is true, output is stored value,
-// new input must be opposite value from stored value for
-// #Cycles before switching to new value.
-
-module prim_filter_ctr #(parameter int unsigned Cycles = 4) (
- input clk_i,
- input rst_ni,
- input enable_i,
- input filter_i,
- output filter_o
-);
-
- localparam int unsigned CTR_WIDTH = $clog2(Cycles);
- localparam logic [CTR_WIDTH-1:0] CYCLESM1 = (CTR_WIDTH)'(Cycles-1);
-
- logic [CTR_WIDTH-1:0] diff_ctr_q, diff_ctr_d;
- logic filter_q, stored_value_q, update_stored_value;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- filter_q <= 1'b0;
- end else begin
- filter_q <= filter_i;
- end
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- stored_value_q <= 1'b0;
- end else if (update_stored_value) begin
- stored_value_q <= filter_i;
- end
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- diff_ctr_q <= {CTR_WIDTH{1'b0}};
- end else begin
- diff_ctr_q <= diff_ctr_d;
- end
- end
-
- // always look for differences, even if not filter enabled
- assign diff_ctr_d =
- (filter_i != filter_q) ? '0 : // restart
- (diff_ctr_q == CYCLESM1) ? CYCLESM1 : // saturate
- (diff_ctr_q + 1'b1); // count up
- assign update_stored_value = (diff_ctr_d == CYCLESM1);
-
- assign filter_o = enable_i ? stored_value_q : filter_i;
-
-endmodule
-
diff --git a/verilog/rtl/prim_generic_clock_inv.sv b/verilog/rtl/prim_generic_clock_inv.sv
deleted file mode 100644
index ae8f6b6..0000000
--- a/verilog/rtl/prim_generic_clock_inv.sv
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Clock inverter
-// Varies on the process
-
-module prim_generic_clock_inv #(
- parameter bit HasScanMode = 1'b1
-) (
- input clk_i,
- input scanmode_i,
- output logic clk_no // Inverted
-);
-
- if (HasScanMode) begin : gen_scan
- prim_generic_clock_mux2 i_dft_tck_mux (
- .clk0_i ( ~clk_i ),
- .clk1_i ( clk_i ), // bypass the inverted clock for testing
- .sel_i ( scanmode_i ),
- .clk_o ( clk_no )
- );
- end else begin : gen_noscan
- logic unused_scanmode;
- assign unused_scanmode = scanmode_i;
- assign clk_no = ~clk_i;
- end
-
-endmodule : prim_generic_clock_inv
diff --git a/verilog/rtl/prim_generic_clock_mux2.sv b/verilog/rtl/prim_generic_clock_mux2.sv
deleted file mode 100644
index 8f296e6..0000000
--- a/verilog/rtl/prim_generic_clock_mux2.sv
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-
-
-module prim_generic_clock_mux2 #(
- parameter bit NoFpgaBufG = 1'b0 // this parameter serves no function in the generic model
-) (
- input clk0_i,
- input clk1_i,
- input sel_i,
- output logic clk_o
-);
-
- assign clk_o = (sel_i) ? clk1_i : clk0_i;
-
- // make sure sel is never X (including during reset)
- // need to use ##1 as this could break with inverted clocks that
- // start with a rising edge at the beginning of the simulation.
-
-endmodule : prim_generic_clock_mux2
diff --git a/verilog/rtl/prim_generic_flop.sv b/verilog/rtl/prim_generic_flop.sv
deleted file mode 100644
index 8eacf01..0000000
--- a/verilog/rtl/prim_generic_flop.sv
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-// `include "prim_assert.sv"
-
-module prim_generic_flop # (
- parameter int Width = 1,
- localparam int WidthSubOne = Width-1,
- parameter logic [WidthSubOne:0] ResetValue = 0
-) (
- input clk_i,
- input rst_ni,
- input [Width-1:0] d_i,
- output logic [Width-1:0] q_o
-);
-
- 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
-
-endmodule // prim_generic_flop
diff --git a/verilog/rtl/prim_generic_flop_2sync.sv b/verilog/rtl/prim_generic_flop_2sync.sv
deleted file mode 100644
index fdd1358..0000000
--- a/verilog/rtl/prim_generic_flop_2sync.sv
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Generic double-synchronizer flop
-// This may need to be moved to prim_generic if libraries have a specific cell
-// for synchronization
-
-module prim_generic_flop_2sync #(
- parameter int Width = 16,
- localparam int WidthSubOne = Width-1, // temp work around #2679
- parameter logic [WidthSubOne:0] ResetValue = '0
-) (
- input clk_i, // receive clock
- input rst_ni,
- input [Width-1:0] d_i,
- output logic [Width-1:0] q_o
-);
-
- logic [Width-1:0] intq;
-
- prim_generic_flop #(
- .Width(Width),
- .ResetValue(ResetValue)
- ) u_sync_1 (
- .clk_i,
- .rst_ni,
- .d_i,
- .q_o(intq)
- );
-
- prim_generic_flop #(
- .Width(Width),
- .ResetValue(ResetValue)
- ) u_sync_2 (
- .clk_i,
- .rst_ni,
- .d_i(intq),
- .q_o
- );
-
-
-endmodule
diff --git a/verilog/rtl/prim_intr_hw.sv b/verilog/rtl/prim_intr_hw.sv
deleted file mode 100644
index c84e389..0000000
--- a/verilog/rtl/prim_intr_hw.sv
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-module prim_intr_hw # (
- parameter int unsigned Width = 1,
- parameter bit FlopOutput = 1
-) (
- // event
- input clk_i,
- input rst_ni,
- input [Width-1:0] event_intr_i,
-
- // register interface
- input [Width-1:0] reg2hw_intr_enable_q_i,
- input [Width-1:0] reg2hw_intr_test_q_i,
- input reg2hw_intr_test_qe_i,
- input [Width-1:0] reg2hw_intr_state_q_i,
- output hw2reg_intr_state_de_o,
- output [Width-1:0] hw2reg_intr_state_d_o,
-
- // outgoing interrupt
- output logic [Width-1:0] intr_o
-);
-
- logic [Width-1:0] new_event;
- assign new_event =
- (({Width{reg2hw_intr_test_qe_i}} & reg2hw_intr_test_q_i) | event_intr_i);
- assign hw2reg_intr_state_de_o = |new_event;
- // for scalar interrupts, this resolves to '1' with new event
- // for vector interrupts, new events are OR'd in to existing interrupt state
- assign hw2reg_intr_state_d_o = new_event | reg2hw_intr_state_q_i;
-
- if (FlopOutput == 1) begin : gen_flop_intr_output
- // flop the interrupt output
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- intr_o <= 1'b0;
- end else begin
- intr_o <= reg2hw_intr_state_q_i & reg2hw_intr_enable_q_i;
- end
- end
-
- end else begin : gen_intr_passthrough_output
- logic unused_clk;
- logic unused_rst_n;
- assign unused_clk = clk_i;
- assign unused_rst_n = rst_ni;
- assign intr_o = reg2hw_intr_state_q_i & reg2hw_intr_enable_q_i;
- end
-
-
-endmodule
diff --git a/verilog/rtl/prim_pkg.sv b/verilog/rtl/prim_pkg.sv
deleted file mode 100644
index ebe38d1..0000000
--- a/verilog/rtl/prim_pkg.sv
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Constants for use in primitives
-//
-// This file is a stop-gap until the DV file list is generated by FuseSoC.
-// Its contents are taken from the file which would be generated by FuseSoC.
-// https://github.com/lowRISC/ibex/issues/893
-
-package prim_pkg;
-
- // Implementation target specialization
- typedef enum integer {
- ImplGeneric,
- ImplXilinx
- } impl_e;
-endpackage : prim_pkg
\ No newline at end of file
diff --git a/verilog/rtl/prim_subreg.sv b/verilog/rtl/prim_subreg.sv
deleted file mode 100644
index 33d4290..0000000
--- a/verilog/rtl/prim_subreg.sv
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-module prim_subreg #(
- parameter int DW = 32 ,
- parameter SWACCESS = "RW", // {RW, RO, WO, W1C, W1S, W0C, RC}
- parameter logic [DW-1:0] RESVAL = '0 // Reset value
-) (
- input clk_i,
- input rst_ni,
-
- // From SW: valid for RW, WO, W1C, W1S, W0C, RC
- // In case of RC, Top connects Read Pulse to we
- input we,
- input [DW-1:0] wd,
-
- // From HW: valid for HRW, HWO
- input de,
- input [DW-1:0] d,
-
- // output to HW and Reg Read
- output logic qe,
- output logic [DW-1:0] q,
- output logic [DW-1:0] qs
-);
-
- logic wr_en;
- logic [DW-1:0] wr_data;
-
- prim_subreg_arb #(
- .DW ( DW ),
- .SWACCESS ( SWACCESS )
- ) wr_en_data_arb (
- .we,
- .wd,
- .de,
- .d,
- .q,
- .wr_en,
- .wr_data
- );
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- qe <= 1'b0;
- end else begin
- qe <= we;
- end
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- q <= RESVAL;
- end else if (wr_en) begin
- q <= wr_data;
- end
- end
-
- assign qs = q;
-
-endmodule
diff --git a/verilog/rtl/prim_subreg_arb.sv b/verilog/rtl/prim_subreg_arb.sv
deleted file mode 100644
index adc144f..0000000
--- a/verilog/rtl/prim_subreg_arb.sv
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-module prim_subreg_arb #(
- parameter int DW = 32 ,
- parameter SWACCESS = "RW" // {RW, RO, WO, W1C, W1S, W0C, RC}
-) (
- // From SW: valid for RW, WO, W1C, W1S, W0C, RC.
- // In case of RC, top connects read pulse to we.
- input we,
- input [DW-1:0] wd,
-
- // From HW: valid for HRW, HWO.
- input de,
- input [DW-1:0] d,
-
- // From register: actual reg value.
- input [DW-1:0] q,
-
- // To register: actual write enable and write data.
- output logic wr_en,
- output logic [DW-1:0] wr_data
-);
-
- if ((SWACCESS == "RW") || (SWACCESS == "WO")) begin : gen_w
- assign wr_en = we | de;
- assign wr_data = (we == 1'b1) ? wd : d; // SW higher priority
- // Unused q - Prevent lint errors.
- logic [DW-1:0] unused_q;
- assign unused_q = q;
- end else if (SWACCESS == "RO") begin : gen_ro
- assign wr_en = de;
- assign wr_data = d;
- // Unused we, wd, q - Prevent lint errors.
- logic unused_we;
- logic [DW-1:0] unused_wd;
- logic [DW-1:0] unused_q;
- assign unused_we = we;
- assign unused_wd = wd;
- assign unused_q = q;
- end else if (SWACCESS == "W1S") begin : gen_w1s
- // If SWACCESS is W1S, then assume hw tries to clear.
- // So, give a chance HW to clear when SW tries to set.
- // If both try to set/clr at the same bit pos, SW wins.
- assign wr_en = we | de;
- assign wr_data = (de ? d : q) | (we ? wd : '0);
- end else if (SWACCESS == "W1C") begin : gen_w1c
- // If SWACCESS is W1C, then assume hw tries to set.
- // So, give a chance HW to set when SW tries to clear.
- // If both try to set/clr at the same bit pos, SW wins.
- assign wr_en = we | de;
- assign wr_data = (de ? d : q) & (we ? ~wd : '1);
- end else if (SWACCESS == "W0C") begin : gen_w0c
- assign wr_en = we | de;
- assign wr_data = (de ? d : q) & (we ? wd : '1);
- end else if (SWACCESS == "RC") begin : gen_rc
- // This swtype is not recommended but exists for compatibility.
- // WARN: we signal is actually read signal not write enable.
- assign wr_en = we | de;
- assign wr_data = (de ? d : q) & (we ? '0 : '1);
- // Unused wd - Prevent lint errors.
- logic [DW-1:0] unused_wd;
- assign unused_wd = wd;
- end else begin : gen_hw
- assign wr_en = de;
- assign wr_data = d;
- // Unused we, wd, q - Prevent lint errors.
- logic unused_we;
- logic [DW-1:0] unused_wd;
- logic [DW-1:0] unused_q;
- assign unused_we = we;
- assign unused_wd = wd;
- assign unused_q = q;
- end
-
-endmodule
diff --git a/verilog/rtl/prim_subreg_ext.sv b/verilog/rtl/prim_subreg_ext.sv
deleted file mode 100644
index 00d7e9c..0000000
--- a/verilog/rtl/prim_subreg_ext.sv
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-module prim_subreg_ext #(
- parameter int unsigned DW = 32
-) (
- input re,
- input we,
- input [DW-1:0] wd,
-
- input [DW-1:0] d,
-
- // output to HW and Reg Read
- output logic qe,
- output logic qre,
- output logic [DW-1:0] q,
- output logic [DW-1:0] qs
-);
-
- assign qs = d;
- assign q = wd;
- assign qe = we;
- assign qre = re;
-
-endmodule
diff --git a/verilog/rtl/prim_util_pkg.sv b/verilog/rtl/prim_util_pkg.sv
deleted file mode 100644
index 54d8a37..0000000
--- a/verilog/rtl/prim_util_pkg.sv
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-
-/**
- * Utility functions
- */
-package prim_util_pkg;
- /**
- * Math function: $clog2 as specified in Verilog-2005
- *
- * Do not use this function if $clog2() is available.
- *
- * clog2 = 0 for value == 0
- * ceil(log2(value)) for value >= 1
- *
- * This implementation is a synthesizable variant of the $clog2 function as
- * specified in the Verilog-2005 standard (IEEE 1364-2005).
- *
- * To quote the standard:
- * The system function $clog2 shall return the ceiling of the log
- * base 2 of the argument (the log rounded up to an integer
- * value). The argument can be an integer or an arbitrary sized
- * vector value. The argument shall be treated as an unsigned
- * value, and an argument value of 0 shall produce a result of 0.
- */
- function automatic integer _clog2(integer value);
- integer result;
- // Use an intermediate value to avoid assigning to an input port, which produces a warning in
- // Synopsys DC.
- integer v = value;
- v = v - 1;
- for (result = 0; v > 0; result++) begin
- v = v >> 1;
- end
- return result;
- endfunction
-
-
- /**
- * Math function: Number of bits needed to address |value| items.
- *
- * 0 for value == 0
- * vbits = 1 for value == 1
- * ceil(log2(value)) for value > 1
- *
- *
- * The primary use case for this function is the definition of registers/arrays
- * which are wide enough to contain |value| items.
- *
- * This function identical to $clog2() for all input values except the value 1;
- * it could be considered an "enhanced" $clog2() function.
- *
- *
- * Example 1:
- * parameter Items = 1;
- * localparam ItemsWidth = vbits(Items); // 1
- * logic [ItemsWidth-1:0] item_register; // items_register is now [0:0]
- *
- * Example 2:
- * parameter Items = 64;
- * localparam ItemsWidth = vbits(Items); // 6
- * logic [ItemsWidth-1:0] item_register; // items_register is now [5:0]
- *
- * Note: If you want to store the number "value" inside a register, you need
- * a register with size vbits(value + 1), since you also need to store
- * the number 0.
- *
- * Example 3:
- * logic [vbits(64)-1:0] store_64_logic_values; // width is [5:0]
- * logic [vbits(64 + 1)-1:0] store_number_64; // width is [6:0]
- */
- function automatic integer vbits(integer value);
-`ifdef XCELIUM
- // The use of system functions was not allowed here in Verilog-2001, but is
- // valid since (System)Verilog-2005, which is also when $clog2() first
- // appeared.
- // Xcelium < 19.10 does not yet support the use of $clog2() here, fall back
- // to an implementation without a system function. Remove this workaround
- // if we require a newer Xcelium version.
- // See #2579 and #2597.
- return (value == 1) ? 1 : _clog2(value);
-`else
- return (value == 1) ? 1 : $clog2(value);
-`endif
- endfunction
-
-endpackage
\ No newline at end of file
diff --git a/verilog/rtl/pwm.v b/verilog/rtl/pwm.v
deleted file mode 100644
index 017a89d..0000000
--- a/verilog/rtl/pwm.v
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
-control register [7:0]ctrl:
-bit 0: When set, external clock is chosen for PWM/timer. When cleared, wb clock is used for PWM/timer.
-bit 1: When set, PWM is enabled. When cleared, timer is enabled.
-bit 2: When set, PWM/timer starts. When cleared, PWM/timer stops.
-bit 3: When set, timer runs continuously. When cleared, timer runs one time.
-bit 4: When set, o_pwm enabled.
-bit 5: timer interrupt bit When it is written with 0, interrupt request is cleared.
-bit 6: When set, a 16-bit external signal i_DC is used as duty cycle. When cleared, register DC is used.
-bit 7: When set, counter reset for PWM/timer, it's output and bit 5 will also be cleared. When changing from PWM mode to timer mode reset is needed before timer starts.
-*/
-module pwm(
-//tlul interface
- input clk_i,
- input rst_ni,
-
- input re_i,
- input we_i,
- input [7:0] addr_i,
- input [31:0] wdata_i,
- input [3:0] be_i,
- output [31:0] rdata_o,
- output o_pwm,
- output o_pwm_2,
- output reg oe_pwm1,
- output reg oe_pwm2
-
-);
-
-////////////////////control logic////////////////////////////
-parameter adr_ctrl_1 = 0,
- adr_divisor_1= 4,
- adr_period_1 = 8,
- adr_DC_1 = 12;
-
-parameter adr_ctrl_2 = 16,
- adr_divisor_2= 20,
- adr_period_2 = 24,
- adr_DC_2 = 28;
-
-
-
-
-reg [7:0] ctrl;
-reg [15:0] period;
-reg [15:0] DC_1;
-reg [15:0] divisor;
-
-reg [7:0] ctrl_2;
-reg [15:0] period_2;
-reg [15:0] DC_2;
-reg [15:0] divisor_2;
-
-wire write;
-
-assign write = we_i & ~re_i;
-
-always@(posedge clk_i)
- if(~rst_ni)begin
- ctrl[4:2] <= 0;
- ctrl[0] <= 0;
- ctrl[1] <= 1'b0;
- ctrl[7:6] <= 0;
- DC_1 <= 0;
- period <= 0;
- divisor <= 0;
-
-
- ctrl_2[4:2] <= 0;
- ctrl_2[0] <= 1'b0;
- ctrl_2[7:6] <= 0;
- ctrl_2[1] <= 1'b0;
- DC_2 <= 0;
- period_2 <= 0;
- divisor_2 <= 0;
- end
- else if(write)begin
- case(addr_i)
- adr_ctrl_1:begin
- ctrl[0] <= wdata_i[0];
- ctrl[1] <= 1'b1;
- ctrl[4:2] <= wdata_i[4:2];
- ctrl[7:6] <= wdata_i[7:6];
- end
-
- adr_ctrl_2:begin
- ctrl_2[0] <= wdata_i[0];
- ctrl_2[1] <= 1'b1;
- ctrl_2[4:2] <= wdata_i[4:2];
- ctrl_2[7:6] <= wdata_i[7:6];
- end
-
- adr_divisor_1 : divisor <= wdata_i[15:0];
- adr_period_1 : period <= wdata_i[15:0];
- adr_DC_1 : DC_1 <= wdata_i[15:0];
-
- adr_divisor_2 : divisor_2 <= wdata_i[15:0];
- adr_period_2 : period_2 <= wdata_i[15:0];
- adr_DC_2 : DC_2 <= wdata_i[15:0];
- endcase
- end
-
-wire pwm_1;
-assign pwm_1 = ctrl[1];
-
-wire pwm_2;
-assign pwm_2 = ctrl_2[1];
-
-// clock division
-reg clock_p1;
-reg clock_p2;
-
-reg [15:0] counter_p1;
-reg [15:0] counter_p2;
-reg [15:0] period_counter1;
-reg [15:0] period_counter2;
-
-reg pts;
-reg pts_2;
-
-always @(posedge clk_i or negedge rst_ni) begin
- if(~rst_ni) begin
- clock_p1 <= 1'b0;
- clock_p2 <= 1'b0;
- counter_p1 <= 0;
- counter_p2 <= 0;
- end else begin
- if(pwm_1) begin
- counter_p1 <= counter_p1 + 1;
- if(counter_p1 == divisor-1) begin
- counter_p1 <= 0;
- clock_p1 <= ~clock_p1;
- end
- end
-
-
- if(pwm_2) begin
- counter_p2 <= counter_p2 + 1;
- if(counter_p2 == divisor_2-1) begin
- counter_p2 <= 0;
- clock_p2 <= ~clock_p2;
- end
- end
-
- end
-end
-
-
-
-
-
-always@(posedge clock_p1 )
- if(~rst_ni)begin
- pts <= 0;
- period_counter1 <= 0;
- end
- else begin
- if(ctrl[2])begin
- if(pwm_1) begin
- oe_pwm1 <= 1'b1;
- if(period_counter1 >= period) period_counter1 <= 0;
- else period_counter1 <= period_counter1+1;
-
- if(period_counter1 < DC_1) pts <= 1'b1;
- else pts <= 1'b0;
- end
- end
- else begin
- pts <= 1'b0;
- period_counter1 <= 0;
- oe_pwm1 <= 0;
- end
-end
-
-
-
-always@(posedge clock_p2 )
- if(~rst_ni)begin
- pts_2 <= 0;
- period_counter2 <= 0;
- end
- else begin
- if(ctrl_2[2])begin
- if(pwm_2) begin
- oe_pwm2 <= 1'b1;
- if(period_counter2 >= period_2) period_counter2 <= 0;
- else period_counter2 <= period_counter2+1;
-
- if(period_counter2 < DC_2) pts_2 <= 1'b1;
- else pts_2 <= 1'b0;
- end
- end
- else begin
- pts_2 <= 1'b0;
- period_counter2 <= 0;
- oe_pwm2 <= 1'b0;
- end
-end
-//////////////////////////////////////////////////////////
-
-assign o_pwm = ctrl[4]? pts: 0;
-assign o_pwm_2 = ctrl_2[4]? pts_2: 0;
-assign rdata_o = (addr_i == adr_ctrl_1) ? {8'h0,ctrl} :
- (addr_i == adr_divisor_1)? divisor :
- (addr_i == adr_period_1) ? period :
- (addr_i == adr_DC_1) ? DC_1 :
- (addr_i == adr_DC_2) ? DC_2 :
- (addr_i == adr_period_2) ? period_2 :
- (addr_i == adr_divisor_2)? divisor_2 :
- (addr_i == adr_ctrl_2) ? {8'h0,ctrl_2}:0;
-
-
-endmodule
diff --git a/verilog/rtl/pwm_top.sv b/verilog/rtl/pwm_top.sv
deleted file mode 100644
index 5317159..0000000
--- a/verilog/rtl/pwm_top.sv
+++ /dev/null
@@ -1,71 +0,0 @@
-
-module pwm_top (
-
- input clk_i,
- input rst_ni,
-
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
-
-
- output pwm_o,
- output pwm_o_2,
- output pwm1_oe,
- output pwm2_oe
-
-);
-
-
-localparam int AW = 8;
-localparam int DW = 32;
-localparam int DBW = DW/8;
-
-logic re;
-logic we;
-logic [7:0] addr;
-logic [31:0] wdata;
-logic [3:0] be;
-logic [31:0] rdata;
-logic err;
-
-//assign err = '0;
-
-pwm pwm_core(
-
-.clk_i (clk_i),
-.rst_ni (rst_ni),
-
-.re_i (re),
-.we_i (we),
-.addr_i (addr),
-.wdata_i (wdata),
-.be_i (be),
-.rdata_o (rdata),
-//.error_o (err),
-.o_pwm (pwm_o),
-.o_pwm_2 (pwm_o_2),
-.oe_pwm1 (pwm1_oe),
-.oe_pwm2 (pwm2_oe)
-
-);
-
-tlul_adapter_reg #(
- .RegAw(AW),
- .RegDw(DW)
-) u_reg_if (
- .clk_i,
- .rst_ni,
-
- .tl_i (tl_i),
- .tl_o (tl_o),
-
- .we_o (we),
- .re_o (re),
- .addr_o (addr),
- .wdata_o (wdata),
- .be_o (be),
- .rdata_i (rdata),
- .error_i (1'b0)
-);
-
-endmodule
diff --git a/verilog/rtl/registers.svh b/verilog/rtl/registers.svh
deleted file mode 100644
index c1975ed..0000000
--- a/verilog/rtl/registers.svh
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2018 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.
-
-// Common register defines for RTL designs
-`ifndef COMMON_CELLS_REGISTERS_SVH_
-`define COMMON_CELLS_REGISTERS_SVH_
-
-// Abridged Summary of available FF macros:
-// `FF: asynchronous active-low reset (implicit clock and reset)
-// `FFAR: asynchronous active-high reset
-// `FFARN: asynchronous active-low reset
-// `FFSR: synchronous active-high reset
-// `FFSRN: synchronous active-low reset
-// `FFNR: without reset
-// `FFL: load-enable and asynchronous active-low reset (implicit clock and reset)
-// `FFLAR: load-enable and asynchronous active-high reset
-// `FFLARN: load-enable and asynchronous active-low reset
-// `FFLARNC: load-enable and asynchronous active-low reset and synchronous active-high clear
-// `FFLSR: load-enable and synchronous active-high reset
-// `FFLSRN: load-enable and synchronous active-low reset
-// `FFLNR: load-enable without reset
-
-
-// Flip-Flop with asynchronous active-low reset (implicit clock and reset)
-// __q: Q output of FF
-// __d: D input of FF
-// __reset_value: value assigned upon reset
-// Implicit:
-// clk_i: clock input
-// rst_ni: reset input (asynchronous, active low)
-`define FF(__q, __d, __reset_value) \
- always_ff @(posedge clk_i or negedge rst_ni) begin \
- if (!rst_ni) begin \
- __q <= (__reset_value); \
- end else begin \
- __q <= (__d); \
- end \
- end
-
-// Flip-Flop with asynchronous active-high reset
-// __q: Q output of FF
-// __d: D input of FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __arst: asynchronous reset
-`define FFAR(__q, __d, __reset_value, __clk, __arst) \
- always_ff @(posedge (__clk) or posedge (__arst)) begin \
- if (__arst) begin \
- __q <= (__reset_value); \
- end else begin \
- __q <= (__d); \
- end \
- end
-
-// Flip-Flop with asynchronous active-low reset
-// __q: Q output of FF
-// __d: D input of FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __arst_n: asynchronous reset
-`define FFARN(__q, __d, __reset_value, __clk, __arst_n) \
- always_ff @(posedge (__clk) or negedge (__arst_n)) begin \
- if (!__arst_n) begin \
- __q <= (__reset_value); \
- end else begin \
- __q <= (__d); \
- end \
- end
-
-// Flip-Flop with synchronous active-high reset
-// __q: Q output of FF
-// __d: D input of FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __reset_clk: reset input
-`define FFSR(__q, __d, __reset_value, __clk, __reset_clk) \
- `ifndef VERILATOR \
- /``* synopsys sync_set_reset `"__reset_clk`" *``/ \
- `endif \
- always_ff @(posedge (__clk)) begin \
- __q <= (__reset_clk) ? (__reset_value) : (__d); \
- end
-
-// Flip-Flop with synchronous active-low reset
-// __q: Q output of FF
-// __d: D input of FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __reset_n_clk: reset input
-`define FFSRN(__q, __d, __reset_value, __clk, __reset_n_clk) \
- `ifndef VERILATOR \
- /``* synopsys sync_set_reset `"__reset_n_clk`" *``/ \
- `endif \
- always_ff @(posedge (__clk)) begin \
- __q <= (!__reset_n_clk) ? (__reset_value) : (__d); \
- end
-
-// Always-enable Flip-Flop without reset
-// __q: Q output of FF
-// __d: D input of FF
-// __clk: clock input
-`define FFNR(__q, __d, __clk) \
- always_ff @(posedge (__clk)) begin \
- __q <= (__d); \
- end
-
-// Flip-Flop with load-enable and asynchronous active-low reset (implicit clock and reset)
-// __q: Q output of FF
-// __d: D input of FF
-// __load: load d value into FF
-// __reset_value: value assigned upon reset
-// Implicit:
-// clk_i: clock input
-// rst_ni: reset input (asynchronous, active low)
-`define FFL(__q, __d, __load, __reset_value) \
- always_ff @(posedge clk_i or negedge rst_ni) begin \
- if (!rst_ni) begin \
- __q <= (__reset_value); \
- end else begin \
- __q <= (__load) ? (__d) : (__q); \
- end \
- end
-
-// Flip-Flop with load-enable and asynchronous active-high reset
-// __q: Q output of FF
-// __d: D input of FF
-// __load: load d value into FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __arst: asynchronous reset
-`define FFLAR(__q, __d, __load, __reset_value, __clk, __arst) \
- always_ff @(posedge (__clk) or posedge (__arst)) begin \
- if (__arst) begin \
- __q <= (__reset_value); \
- end else begin \
- __q <= (__load) ? (__d) : (__q); \
- end \
- end
-
-// Flip-Flop with load-enable and asynchronous active-low reset
-// __q: Q output of FF
-// __d: D input of FF
-// __load: load d value into FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __arst_n: asynchronous reset
-`define FFLARN(__q, __d, __load, __reset_value, __clk, __arst_n) \
- always_ff @(posedge (__clk) or negedge (__arst_n)) begin \
- if (!__arst_n) begin \
- __q <= (__reset_value); \
- end else begin \
- __q <= (__load) ? (__d) : (__q); \
- end \
- end
-
-// Flip-Flop with load-enable and synchronous active-high reset
-// __q: Q output of FF
-// __d: D input of FF
-// __load: load d value into FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __reset_clk: reset input
-`define FFLSR(__q, __d, __load, __reset_value, __clk, __reset_clk) \
- `ifndef VERILATOR \
- /``* synopsys sync_set_reset `"__reset_clk`" *``/ \
- `endif \
- always_ff @(posedge (__clk)) begin \
- __q <= (__reset_clk) ? (__reset_value) : ((__load) ? (__d) : (__q)); \
- end
-
-// Flip-Flop with load-enable and synchronous active-low reset
-// __q: Q output of FF
-// __d: D input of FF
-// __load: load d value into FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __reset_n_clk: reset input
-`define FFLSRN(__q, __d, __load, __reset_value, __clk, __reset_n_clk) \
- `ifndef VERILATOR \
- /``* synopsys sync_set_reset `"__reset_n_clk`" *``/ \
- `endif \
- always_ff @(posedge (__clk)) begin \
- __q <= (!__reset_n_clk) ? (__reset_value) : ((__load) ? (__d) : (__q)); \
- end
-
-// Flip-Flop with load-enable and asynchronous active-low reset and synchronous clear
-// __q: Q output of FF
-// __d: D input of FF
-// __load: load d value into FF
-// __clear: assign reset value into FF
-// __reset_value: value assigned upon reset
-// __clk: clock input
-// __arst_n: asynchronous reset
-`define FFLARNC(__q, __d, __load, __clear, __reset_value, __clk, __arst_n) \
- `ifndef VERILATOR \
- /``* synopsys sync_set_reset `"__clear`" *``/ \
- `endif \
- always_ff @(posedge (__clk) or negedge (__arst_n)) begin \
- if (!__arst_n) begin \
- __q <= (__reset_value); \
- end else begin \
- __q <= (__clear) ? (__reset_value) : (__load) ? (__d) : (__q); \
- end \
- end
-
-// Load-enable Flip-Flop without reset
-// __q: Q output of FF
-// __d: D input of FF
-// __load: load d value into FF
-// __clk: clock input
-`define FFLNR(__q, __d, __load, __clk) \
- always_ff @(posedge (__clk)) begin \
- __q <= (__load) ? (__d) : (__q); \
- end
-
-`endif
diff --git a/verilog/rtl/rr_arb_tree.sv b/verilog/rtl/rr_arb_tree.sv
deleted file mode 100644
index 9013a64..0000000
--- a/verilog/rtl/rr_arb_tree.sv
+++ /dev/null
@@ -1,343 +0,0 @@
-// 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: Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
-// Wolfgang Roenninger <wroennin@iis.ee.ethz.ch>, ETH Zurich
-// Date: 02.04.2019
-// Description: logarithmic arbitration tree with round robin arbitration scheme.
-
-/// The rr_arb_tree employs non-starving round robin-arbitration - i.e., the priorities
-/// rotate each cycle.
-///
-/// ## Fair vs. unfair Arbitration
-///
-/// This refers to fair throughput distribution when not all inputs have active requests.
-/// This module has an internal state `rr_q` which defines the highest priority input. (When
-/// `ExtPrio` is `1'b1` this state is provided from the outside.) The arbitration tree will
-/// choose the input with the same index as currently defined by the state if it has an active
-/// request. Otherwise a *random* other active input is selected. The parameter `FairArb` is used
-/// to distinguish between two methods of calculating the next state.
-/// * `1'b0`: The next state is calculated by advancing the current state by one. This leads to the
-/// state being calculated without the context of the active request. Leading to an
-/// unfair throughput distribution if not all inputs have active requests.
-/// * `1'b1`: The next state jumps to the next unserved request with higher index.
-/// This is achieved by using two trailing-zero-counters (`lzc`). The upper has the masked
-/// `req_i` signal with all indices which will have a higher priority in the next state.
-/// The trailing zero count defines the input index with the next highest priority after
-/// the current one is served. When the upper is empty the lower `lzc` provides the
-/// wrapped index if there are outstanding requests with lower or same priority.
-/// The implication of throughput fairness on the module timing are:
-/// * The trailing zero counter (`lzc`) has a loglog relation of input to output timing. This means
-/// that in this module the input to register path scales with Log(Log(`NumIn`)).
-/// * The `rr_arb_tree` data multiplexing scales with Log(`NumIn`). This means that the input to output
-/// timing path of this module also scales scales with Log(`NumIn`).
-/// This implies that in this module the input to output path is always longer than the input to
-/// register path. As the output data usually also terminates in a register the parameter `FairArb`
-/// only has implications on the area. When it is `1'b0` a static plus one adder is instantiated.
-/// If it is `1'b1` two `lzc`, a masking logic stage and a two input multiplexer are instantiated.
-/// However these are small in respect of the data multiplexers needed, as the width of the `req_i`
-/// signal is usually less as than `DataWidth`.
-module rr_arb_tree #(
- /// Number of inputs to be arbitrated.
- parameter int unsigned NumIn = 64,
- /// Data width of the payload in bits. Not needed if `DataType` is overwritten.
- parameter int unsigned DataWidth = 32,
- /// Data type of the payload, can be overwritten with custom type. Only use of `DataWidth`.
- parameter type DataType = logic [DataWidth-1:0],
- /// The `ExtPrio` option allows to override the internal round robin counter via the
- /// `rr_i` signal. This can be useful in case multiple arbiters need to have
- /// rotating priorities that are operating in lock-step. If static priority arbitration
- /// is needed, just connect `rr_i` to '0.
- ///
- /// Set to 1'b1 to enable.
- parameter bit ExtPrio = 1'b0,
- /// If `AxiVldRdy` is set, the req/gnt signals are compliant with the AXI style vld/rdy
- /// handshake. Namely, upstream vld (req) must not depend on rdy (gnt), as it can be deasserted
- /// again even though vld is asserted. Enabling `AxiVldRdy` leads to a reduction of arbiter
- /// delay and area.
- ///
- /// Set to `1'b1` to treat req/gnt as vld/rdy.
- parameter bit AxiVldRdy = 1'b0,
- /// The `LockIn` option prevents the arbiter from changing the arbitration
- /// decision when the arbiter is disabled. I.e., the index of the first request
- /// that wins the arbitration will be locked in case the destination is not
- /// able to grant the request in the same cycle.
- ///
- /// Set to `1'b1` to enable.
- parameter bit LockIn = 1'b0,
- /// When set, ensures that throughput gets distributed evenly between all inputs.
- ///
- /// Set to `1'b0` to disable.
- parameter bit FairArb = 1'b1,
- /// Dependent parameter, do **not** overwrite.
- /// Width of the arbitration priority signal and the arbitrated index.
- parameter int unsigned IdxWidth = (NumIn > 32'd1) ? unsigned'($clog2(NumIn)) : 32'd1,
- /// Dependent parameter, do **not** overwrite.
- /// Type for defining the arbitration priority and arbitrated index signal.
- parameter type idx_t = logic [IdxWidth-1:0]
-) (
- /// clk_i, positive edge triggered.
- input logic clk_i,
- /// Asynchronous rst_ni, active low.
- input logic rst_ni,
- /// Clears the arbiter state. Only used if `ExtPrio` is `1'b0` or `LockIn` is `1'b1`.
- input logic flush_i,
- /// External round-robin priority. Only used if `ExtPrio` is `1'b1.`
- input idx_t rr_i,
- /// Input requests arbitration.
- input logic [NumIn-1:0] req_i,
- /* verilator lint_off UNOPTFLAT */
- /// Input request is granted.
- output logic [NumIn-1:0] gnt_o,
- /* verilator lint_on UNOPTFLAT */
- /// Input data for arbitration.
- input DataType [NumIn-1:0] data_i,
- /// Output request is valid.
- output logic req_o,
- /// Output request is granted.
- input logic gnt_i,
- /// Output data.
- output DataType data_o,
- /// Index from which input the data came from.
- output idx_t idx_o
-);
-
- // pragma translate_off
- `ifndef VERILATOR
- // Default SVA rst_ni
- default disable iff (!rst_ni || flush_i);
- `endif
- // pragma translate_on
-
- // just pass through in this corner case
- if (NumIn == unsigned'(1)) begin : gen_pass_through
- assign req_o = req_i[0];
- assign gnt_o[0] = gnt_i;
- assign data_o = data_i[0];
- assign idx_o = '0;
- // non-degenerate cases
- end else begin : gen_arbiter
- localparam int unsigned NumLevels = unsigned'($clog2(NumIn));
-
- /* verilator lint_off UNOPTFLAT */
- idx_t [2**NumLevels-2:0] index_nodes; // used to propagate the indices
- DataType [2**NumLevels-2:0] data_nodes; // used to propagate the data
- logic [2**NumLevels-2:0] gnt_nodes; // used to propagate the grant to masters
- logic [2**NumLevels-2:0] req_nodes; // used to propagate the requests to slave
- /* lint_off */
- idx_t rr_q;
- logic [NumIn-1:0] req_d;
-
- // the final arbitration decision can be taken from the root of the tree
- assign req_o = req_nodes[0];
- assign data_o = data_nodes[0];
- assign idx_o = index_nodes[0];
-
- if (ExtPrio) begin : gen_ext_rr
- assign rr_q = rr_i;
- assign req_d = req_i;
- end else begin : gen_int_rr
- idx_t rr_d;
-
- // lock arbiter decision in case we got at least one req and no acknowledge
- if (LockIn) begin : gen_lock
- logic lock_d, lock_q;
- logic [NumIn-1:0] req_q;
-
- assign lock_d = req_o & ~gnt_i;
- assign req_d = (lock_q) ? req_q : req_i;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin : p_lock_reg
- if (!rst_ni) begin
- lock_q <= '0;
- end else begin
- if (flush_i) begin
- lock_q <= '0;
- end else begin
- lock_q <= lock_d;
- end
- end
- end
-
- // pragma translate_off
- `ifndef VERILATOR
- lock: assert property(
- @(posedge clk_i) LockIn |-> req_o && !gnt_i |=> idx_o == $past(idx_o)) else
- $fatal (1, "Lock implies same arbiter decision in next cycle if output is not \
- ready.");
-
- logic [NumIn-1:0] req_tmp;
- assign req_tmp = req_q & req_i;
- lock_req: assume property(
- @(posedge clk_i) LockIn |-> lock_d |=> req_tmp == req_q) else
- $fatal (1, "It is disallowed to deassert unserved request signals when LockIn is \
- enabled.");
- `endif
- // pragma translate_on
-
- always_ff @(posedge clk_i or negedge rst_ni) begin : p_req_regs
- if (!rst_ni) begin
- req_q <= '0;
- end else begin
- if (flush_i) begin
- req_q <= '0;
- end else begin
- req_q <= req_d;
- end
- end
- end
- end else begin : gen_no_lock
- assign req_d = req_i;
- end
-
- if (FairArb) begin : gen_fair_arb
- logic [NumIn-1:0] upper_mask, lower_mask;
- idx_t upper_idx, lower_idx, next_idx;
- logic upper_empty, lower_empty;
-
- for (genvar i = 0; i < NumIn; i++) begin : gen_mask
- assign upper_mask[i] = (i > rr_q) ? req_d[i] : 1'b0;
- assign lower_mask[i] = (i <= rr_q) ? req_d[i] : 1'b0;
- end
-
- lzc #(
- .WIDTH ( NumIn ),
- .MODE ( 1'b0 )
- ) i_lzc_upper (
- .in_i ( upper_mask ),
- .cnt_o ( upper_idx ),
- .empty_o ( upper_empty )
- );
-
- lzc #(
- .WIDTH ( NumIn ),
- .MODE ( 1'b0 )
- ) i_lzc_lower (
- .in_i ( lower_mask ),
- .cnt_o ( lower_idx ),
- .empty_o ( /*unused*/ )
- );
-
- assign next_idx = upper_empty ? lower_idx : upper_idx;
- assign rr_d = (gnt_i && req_o) ? next_idx : rr_q;
-
- end else begin : gen_unfair_arb
- assign rr_d = (gnt_i && req_o) ? ((rr_q == idx_t'(NumIn-1)) ? '0 : rr_q + 1'b1) : rr_q;
- end
-
- // this holds the highest priority
- always_ff @(posedge clk_i or negedge rst_ni) begin : p_rr_regs
- if (!rst_ni) begin
- rr_q <= '0;
- end else begin
- if (flush_i) begin
- rr_q <= '0;
- end else begin
- rr_q <= rr_d;
- end
- end
- end
- end
-
- assign gnt_nodes[0] = gnt_i;
-
- // arbiter tree
- for (genvar level = 0; unsigned'(level) < NumLevels; level++) begin : gen_levels
- for (genvar l = 0; l < 2**level; l++) begin : gen_level
- // local select signal
- logic sel;
- // index calcs
- localparam int unsigned Idx0 = 2**level-1+l;// current node
- localparam int unsigned Idx1 = 2**(level+1)-1+l*2;
- //////////////////////////////////////////////////////////////
- // uppermost level where data is fed in from the inputs
- if (unsigned'(level) == NumLevels-1) begin : gen_first_level
- // if two successive indices are still in the vector...
- if (unsigned'(l) * 2 < NumIn-1) begin : gen_reduce
- assign req_nodes[Idx0] = req_d[l*2] | req_d[l*2+1];
-
- // arbitration: round robin
- assign sel = ~req_d[l*2] | req_d[l*2+1] & rr_q[NumLevels-1-level];
-
- assign index_nodes[Idx0] = idx_t'(sel);
- assign data_nodes[Idx0] = (sel) ? data_i[l*2+1] : data_i[l*2];
- assign gnt_o[l*2] = gnt_nodes[Idx0] & (AxiVldRdy | req_d[l*2]) & ~sel;
- assign gnt_o[l*2+1] = gnt_nodes[Idx0] & (AxiVldRdy | req_d[l*2+1]) & sel;
- end
- // if only the first index is still in the vector...
- if (unsigned'(l) * 2 == NumIn-1) begin : gen_first
- assign req_nodes[Idx0] = req_d[l*2];
- assign index_nodes[Idx0] = '0;// always zero in this case
- assign data_nodes[Idx0] = data_i[l*2];
- assign gnt_o[l*2] = gnt_nodes[Idx0] & (AxiVldRdy | req_d[l*2]);
- end
- // if index is out of range, fill up with zeros (will get pruned)
- if (unsigned'(l) * 2 > NumIn-1) begin : gen_out_of_range
- assign req_nodes[Idx0] = 1'b0;
- assign index_nodes[Idx0] = idx_t'('0);
- assign data_nodes[Idx0] = DataType'('0);
- end
- //////////////////////////////////////////////////////////////
- // general case for other levels within the tree
- end else begin : gen_other_levels
- assign req_nodes[Idx0] = req_nodes[Idx1] | req_nodes[Idx1+1];
-
- // arbitration: round robin
- assign sel = ~req_nodes[Idx1] | req_nodes[Idx1+1] & rr_q[NumLevels-1-level];
-
- assign index_nodes[Idx0] = (sel) ?
- idx_t'({1'b1, index_nodes[Idx1+1][NumLevels-unsigned'(level)-2:0]}) :
- idx_t'({1'b0, index_nodes[Idx1][NumLevels-unsigned'(level)-2:0]});
-
- assign data_nodes[Idx0] = (sel) ? data_nodes[Idx1+1] : data_nodes[Idx1];
- assign gnt_nodes[Idx1] = gnt_nodes[Idx0] & ~sel;
- assign gnt_nodes[Idx1+1] = gnt_nodes[Idx0] & sel;
- end
- //////////////////////////////////////////////////////////////
- end
- end
-
- // pragma translate_off
- `ifndef VERILATOR
- initial begin : p_assert
- assert(NumIn)
- else $fatal(1, "Input must be at least one element wide.");
- assert(!(LockIn && ExtPrio))
- else $fatal(1,"Cannot use LockIn feature together with external ExtPrio.");
- end
-
- hot_one : assert property(
- @(posedge clk_i) $onehot0(gnt_o))
- else $fatal (1, "Grant signal must be hot1 or zero.");
-
- gnt0 : assert property(
- @(posedge clk_i) |gnt_o |-> gnt_i)
- else $fatal (1, "Grant out implies grant in.");
-
- gnt1 : assert property(
- @(posedge clk_i) req_o |-> gnt_i |-> |gnt_o)
- else $fatal (1, "Req out and grant in implies grant out.");
-
- gnt_idx : assert property(
- @(posedge clk_i) req_o |-> gnt_i |-> gnt_o[idx_o])
- else $fatal (1, "Idx_o / gnt_o do not match.");
-
- req0 : assert property(
- @(posedge clk_i) |req_i |-> req_o)
- else $fatal (1, "Req in implies req out.");
-
- req1 : assert property(
- @(posedge clk_i) req_o |-> |req_i)
- else $fatal (1, "Req out implies req in.");
- `endif
- // pragma translate_on
- end
-
-endmodule : rr_arb_tree
diff --git a/verilog/rtl/rstmgr.sv b/verilog/rtl/rstmgr.sv
deleted file mode 100644
index fca2e70..0000000
--- a/verilog/rtl/rstmgr.sv
+++ /dev/null
@@ -1,42 +0,0 @@
-
-// basic reset managemnet logic for azadi
-
-module rstmgr(
-
- input clk_i, //system clock
- input rst_ni, // system reset
- input prog_rst_ni,
-
- input logic ndmreset, // non-debug module reset
- output logic sys_rst_ni // reset for system except debug module
-);
-
- logic rst_d, rst_q;
- logic rst_fd, rst_fq; // follower flip flop
-
- always_comb begin
- if(!rst_ni) begin
- rst_d = 1'b0;
- end else
- if(ndmreset) begin
- rst_d = 1'b0;
- end else
- if(!prog_rst_ni)begin
- rst_d = 1'b0;
- end else begin
- rst_d = 1'b1;
- end
- end
-
- always_ff @(posedge clk_i ) begin
- rst_q <= rst_d;
- end
-
- assign rst_fd = rst_q;
- always_ff @(posedge clk_i ) begin
- rst_fq <= rst_fd;
- end
-
- assign sys_rst_ni = rst_fq;
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/rv_dm.sv b/verilog/rtl/rv_dm.sv
deleted file mode 100644
index 398652b..0000000
--- a/verilog/rtl/rv_dm.sv
+++ /dev/null
@@ -1,319 +0,0 @@
-
-
-module rv_dm #(
- parameter int NrHarts = 1,
- parameter logic [31:0] IdcodeValue = 32'h 0000_0001,
- parameter logic DirectDmiTap = 1'b1
-) (
- input logic clk_i, // clock
- input logic rst_ni, // asynchronous reset active low, connect PoR
- // here, not the system reset
- input logic testmode_i,
- output logic ndmreset_o, // non-debug module reset
- output logic dmactive_o, // debug module is active
- output logic [NrHarts-1:0] debug_req_o, // async debug request
- input logic [NrHarts-1:0] unavailable_i, // communicate whether the hart is unavailable
- // (e.g.: power down)
-
- // bus device with debug memory, for an execution based technique
- input tlul_pkg::tl_h2d_t tl_d_i,
- output tlul_pkg::tl_d2h_t tl_d_o,
-
- // bus host, for system bus accesses
- output tlul_pkg::tl_h2d_t tl_h_o,
- input tlul_pkg::tl_d2h_t tl_h_i,
-
- input jtag_pkg::jtag_req_t jtag_req_i,
- output jtag_pkg::jtag_rsp_t jtag_rsp_o
-);
-
-
- // Currently only 32 bit busses are supported by our TL-UL IP
- localparam int BusWidth = 32;
- // all harts have contiguous IDs
- localparam logic [NrHarts-1:0] SelectableHarts = {NrHarts{1'b1}};
-
- // Debug CSRs
- dm::hartinfo_t [NrHarts-1:0] hartinfo;
- logic [NrHarts-1:0] halted;
- // logic [NrHarts-1:0] running;
- logic [NrHarts-1:0] resumeack;
- logic [NrHarts-1:0] haltreq;
- logic [NrHarts-1:0] resumereq;
- logic clear_resumeack;
- logic cmd_valid;
- dm::command_t cmd;
-
- logic cmderror_valid;
- dm::cmderr_e cmderror;
- logic cmdbusy;
- logic [dm::ProgBufSize-1:0][31:0] progbuf;
- logic [dm::DataCount-1:0][31:0] data_csrs_mem;
- logic [dm::DataCount-1:0][31:0] data_mem_csrs;
- logic data_valid;
- logic [19:0] hartsel;
- // System Bus Access Module
- logic [BusWidth-1:0] sbaddress_csrs_sba;
- logic [BusWidth-1:0] sbaddress_sba_csrs;
- logic sbaddress_write_valid;
- logic sbreadonaddr;
- logic sbautoincrement;
- logic [2:0] sbaccess;
- logic sbreadondata;
- logic [BusWidth-1:0] sbdata_write;
- logic sbdata_read_valid;
- logic sbdata_write_valid;
- logic [BusWidth-1:0] sbdata_read;
- logic sbdata_valid;
- logic sbbusy;
- logic sberror_valid;
- logic [2:0] sberror;
-
- dm::dmi_req_t dmi_req;
- dm::dmi_resp_t dmi_rsp;
- logic dmi_req_valid, dmi_req_ready;
- logic dmi_rsp_valid, dmi_rsp_ready;
- logic dmi_rst_n;
-
- // static debug hartinfo
- localparam dm::hartinfo_t DebugHartInfo = '{
- zero1: '0,
- nscratch: 2, // Debug module needs at least two scratch regs
- zero0: 0,
- dataaccess: 1'b1, // data registers are memory mapped in the debugger
- datasize: dm::DataCount,
- dataaddr: dm::DataAddr
- };
- for (genvar i = 0; i < NrHarts; i++) begin : gen_dm_hart_ctrl
- assign hartinfo[i] = DebugHartInfo;
- end
-
- dm_csrs #(
- .NrHarts(NrHarts),
- .BusWidth(BusWidth),
- .SelectableHarts(SelectableHarts)
- ) i_dm_csrs (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
- .testmode_i ( testmode_i ),
- .dmi_rst_ni ( dmi_rst_n ),
- .dmi_req_valid_i ( dmi_req_valid ),
- .dmi_req_ready_o ( dmi_req_ready ),
- .dmi_req_i ( dmi_req ),
- .dmi_resp_valid_o ( dmi_rsp_valid ),
- .dmi_resp_ready_i ( dmi_rsp_ready ),
- .dmi_resp_o ( dmi_rsp ),
- .ndmreset_o ( ndmreset_o ),
- .dmactive_o ( dmactive_o ),
- .hartsel_o ( hartsel ),
- .hartinfo_i ( hartinfo ),
- .halted_i ( halted ),
- .unavailable_i,
- .resumeack_i ( resumeack ),
- .haltreq_o ( haltreq ),
- .resumereq_o ( resumereq ),
- .clear_resumeack_o ( clear_resumeack ),
- .cmd_valid_o ( cmd_valid ),
- .cmd_o ( cmd ),
- .cmderror_valid_i ( cmderror_valid ),
- .cmderror_i ( cmderror ),
- .cmdbusy_i ( cmdbusy ),
- .progbuf_o ( progbuf ),
- .data_i ( data_mem_csrs ),
- .data_valid_i ( data_valid ),
- .data_o ( data_csrs_mem ),
- .sbaddress_o ( sbaddress_csrs_sba ),
- .sbaddress_i ( sbaddress_sba_csrs ),
- .sbaddress_write_valid_o ( sbaddress_write_valid ),
- .sbreadonaddr_o ( sbreadonaddr ),
- .sbautoincrement_o ( sbautoincrement ),
- .sbaccess_o ( sbaccess ),
- .sbreadondata_o ( sbreadondata ),
- .sbdata_o ( sbdata_write ),
- .sbdata_read_valid_o ( sbdata_read_valid ),
- .sbdata_write_valid_o ( sbdata_write_valid ),
- .sbdata_i ( sbdata_read ),
- .sbdata_valid_i ( sbdata_valid ),
- .sbbusy_i ( sbbusy ),
- .sberror_valid_i ( sberror_valid ),
- .sberror_i ( sberror )
- );
-
- logic host_req;
- logic [BusWidth-1:0] host_add;
- logic host_we;
- logic [BusWidth-1:0] host_wdata;
- logic [BusWidth/8-1:0] host_be;
- logic host_gnt;
- logic host_r_valid;
- logic [BusWidth-1:0] host_r_rdata;
- logic host_r_err;
-
- dm_sba #(
- .BusWidth(BusWidth)
- ) i_dm_sba (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
- .master_req_o ( host_req ),
- .master_add_o ( host_add ),
- .master_we_o ( host_we ),
- .master_wdata_o ( host_wdata ),
- .master_be_o ( host_be ),
- .master_gnt_i ( host_gnt ),
- .master_r_valid_i ( host_r_valid ),
- .master_r_rdata_i ( host_r_rdata ),
- .dmactive_i ( dmactive_o ),
- .sbaddress_i ( sbaddress_csrs_sba ),
- .sbaddress_o ( sbaddress_sba_csrs ),
- .sbaddress_write_valid_i ( sbaddress_write_valid ),
- .sbreadonaddr_i ( sbreadonaddr ),
- .sbautoincrement_i ( sbautoincrement ),
- .sbaccess_i ( sbaccess ),
- .sbreadondata_i ( sbreadondata ),
- .sbdata_i ( sbdata_write ),
- .sbdata_read_valid_i ( sbdata_read_valid ),
- .sbdata_write_valid_i ( sbdata_write_valid ),
- .sbdata_o ( sbdata_read ),
- .sbdata_valid_o ( sbdata_valid ),
- .sbbusy_o ( sbbusy ),
- .sberror_valid_o ( sberror_valid ),
- .sberror_o ( sberror )
- );
-
- tlul_host_adapter #(
- .MAX_REQS(1)
- ) tl_adapter_host_sba (
- .clk_i(clk_i),
- .rst_ni(rst_ni),
- .req_i (host_req),
- .gnt_o (host_gnt),
- .addr_i (host_add),
- .we_i (host_we),
- .wdata_i (host_wdata),
- .be_i (host_be),
- .valid_o (host_r_valid),
- .rdata_o (host_r_rdata),
- .err_o (host_r_err),
- .tl_h_c_a (tl_h_o),
- .tl_h_c_d (tl_h_i)
- );
-
- // DBG doesn't handle error responses so raise assertion if we see one
-
- localparam int unsigned AddressWidthWords = BusWidth - $clog2(BusWidth/8);
-
- logic req;
- logic we;
- logic [BusWidth/8-1:0] be;
- logic [BusWidth-1:0] wdata;
- logic [BusWidth-1:0] rdata;
- logic rvalid;
-
- logic [BusWidth-1:0] addr_b;
- logic [AddressWidthWords-1:0] addr_w;
-
- // TODO: The tlul_adapter_sram give us a bitwise write mask currently,
- // but dm_mem only supports byte write masks. Disable sub-word access in the
- // adapter for now until we figure out a good strategy to deal with this.
- assign be = {BusWidth/8{1'b1}};
-
- assign addr_b = {addr_w, {$clog2(BusWidth/8){1'b0}}};
-
- dm_mem #(
- .NrHarts(NrHarts),
- .BusWidth(BusWidth),
- .SelectableHarts(SelectableHarts),
- // The debug module provides a simplified ROM for systems that map the debug ROM to offset 0x0
- // on the system bus. In that case, only one scratch register has to be implemented in the core.
- // However, we require that the DM can be placed at arbitrary offsets in the system, which
- // requires the generalized debug ROM implementation and two scratch registers. We hence set
- // this parameter to a non-zero value (inside dm_mem, this just feeds into a comparison with 0).
- .DmBaseAddress(1)
- ) i_dm_mem (
- .clk_i ( clk_i ),
- .rst_ni ( rst_ni ),
- .debug_req_o ( debug_req_o ),
- .hartsel_i ( hartsel ),
- .haltreq_i ( haltreq ),
- .resumereq_i ( resumereq ),
- .clear_resumeack_i ( clear_resumeack ),
- .halted_o ( halted ),
- .resuming_o ( resumeack ),
- .cmd_valid_i ( cmd_valid ),
- .cmd_i ( cmd ),
- .cmderror_valid_o ( cmderror_valid ),
- .cmderror_o ( cmderror ),
- .cmdbusy_o ( cmdbusy ),
- .progbuf_i ( progbuf ),
- .data_i ( data_csrs_mem ),
- .data_o ( data_mem_csrs ),
- .data_valid_o ( data_valid ),
- .req_i ( req ),
- .we_i ( we ),
- .addr_i ( addr_b ),
- .wdata_i ( wdata ),
- .be_i ( be ),
- .rdata_o ( rdata )
- );
-
- // Bound-in DPI module replaces the TAP
-//if (DirectDmiTap) begin
- // JTAG TAP
- dmi_jtag #(
- .IdcodeValue (IdcodeValue)
- ) dap (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .testmode_i (testmode_i),
-
- .dmi_rst_no (dmi_rst_n),
- .dmi_req_o (dmi_req),
- .dmi_req_valid_o (dmi_req_valid),
- .dmi_req_ready_i (dmi_req_ready),
-
- .dmi_resp_i (dmi_rsp ),
- .dmi_resp_ready_o (dmi_rsp_ready),
- .dmi_resp_valid_i (dmi_rsp_valid),
-
- //JTAG
- .tck_i (jtag_req_i.tck),
- .tms_i (jtag_req_i.tms),
- .trst_ni (jtag_req_i.trst_n),
- .td_i (jtag_req_i.tdi),
- .td_o (jtag_rsp_o.tdo),
- .tdo_oe_o (jtag_rsp_o.tdo_oe)
- );
-//end
-
- tlul_sram_adapter #(
- .SramAw(AddressWidthWords),
- .SramDw(BusWidth),
- .Outstanding(1),
- .ByteAccess(0)
- ) tl_adapter_device_mem (
- .clk_i(clk_i),
- .rst_ni(rst_ni),
-
- .req_o (req),
- .gnt_i (1'b1),
- .we_o (we),
- .addr_o (addr_w),
- .wdata_o (wdata),
- .wmask_o (),
- .rdata_i (rdata),
- .rvalid_i (rvalid),
- .rerror_i (2'b00),
-
- .tl_o (tl_d_o),
- .tl_i (tl_d_i)
- );
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rvalid <= '0;
- end else begin
- rvalid <= req & ~we;
- end
- end
-
-endmodule
diff --git a/verilog/rtl/rv_plic.sv b/verilog/rtl/rv_plic.sv
deleted file mode 100644
index fe41bf2..0000000
--- a/verilog/rtl/rv_plic.sv
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// RISC-V Platform-Level Interrupt Controller compliant INTC
-//
-// Current version doesn't support MSI interrupt but it is easy to add
-// the feature. Create one external register and connect qe signal to the
-// gateway module (as edge-triggered)
-//
-// Consider to set MAX_PRIO as small number as possible. It is main factor
-// of area increase if edge-triggered counter isn't implemented.
-//
-// Verilog parameter
-// MAX_PRIO: Maximum value of interrupt priority
-
-module rv_plic import rv_plic_reg_pkg::*; #(
- // derived parameter
- localparam int SRCW = $clog2(NumSrc)
-) (
- input clk_i,
- input rst_ni,
-
- // Bus Interface (device)
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
-
- // Interrupt Sources
- input [NumSrc-1:0] intr_src_i,
-
- // Interrupt notification to targets
- output [NumTarget-1:0] irq_o,
-
- output logic [NumTarget-1:0] msip_o
-);
-
- rv_plic_reg2hw_t reg2hw;
- rv_plic_hw2reg_t hw2reg;
-
- localparam int MAX_PRIO = 3;
- localparam int PRIOW = $clog2(MAX_PRIO+1);
-
- logic [SRCW:0] irq_id_o [NumTarget];
-
- logic [NumSrc-1:0] le; // 0:level 1:edge
- logic [NumSrc-1:0] ip;
-
- logic [NumSrc-1:0] ie [NumTarget];
-
- logic [NumTarget-1:0] claim_re; // Target read indicator
- logic [SRCW-1:0] claim_id [NumTarget];
- logic [NumSrc-1:0] claim; // Converted from claim_re/claim_id
-
- logic [NumTarget-1:0] complete_we; // Target write indicator
- logic [SRCW-1:0] complete_id [NumTarget];
- logic [NumSrc-1:0] complete; // Converted from complete_re/complete_id
-
- logic [SRCW:0] cc_id [NumTarget]; // Write ID
-
- logic [PRIOW-1:0] prio [NumSrc];
-
- logic [PRIOW-1:0] threshold [NumTarget];
-
- // Glue logic between rv_plic_reg_top and others
- assign cc_id = irq_id_o;
-
- always_comb begin
- claim = '0;
- for (int i = 0 ; i < NumTarget ; i++) begin
- if (claim_re[i]) begin
- claim[claim_id[i]] = 1'b1;
- end
- end
- end
- always_comb begin
- complete = '0;
- for (int i = 0 ; i < NumTarget ; i++) begin
- if (complete_we[i]) begin
- complete[complete_id[i]] = 1'b1;
- end
- end
- end
-
- //`ASSERT_PULSE(claimPulse, claim_re[i])
- //`ASSERT_PULSE(completePulse, complete_we[i])
-
-
-
- //////////////
- // Priority //
- //////////////
- assign prio[0] = reg2hw.prio0.q;
- assign prio[1] = reg2hw.prio1.q;
- assign prio[2] = reg2hw.prio2.q;
- assign prio[3] = reg2hw.prio3.q;
- assign prio[4] = reg2hw.prio4.q;
- assign prio[5] = reg2hw.prio5.q;
- assign prio[6] = reg2hw.prio6.q;
- assign prio[7] = reg2hw.prio7.q;
- assign prio[8] = reg2hw.prio8.q;
- assign prio[9] = reg2hw.prio9.q;
- assign prio[10] = reg2hw.prio10.q;
- assign prio[11] = reg2hw.prio11.q;
- assign prio[12] = reg2hw.prio12.q;
- assign prio[13] = reg2hw.prio13.q;
- assign prio[14] = reg2hw.prio14.q;
- assign prio[15] = reg2hw.prio15.q;
- assign prio[16] = reg2hw.prio16.q;
- assign prio[17] = reg2hw.prio17.q;
- assign prio[18] = reg2hw.prio18.q;
- assign prio[19] = reg2hw.prio19.q;
- assign prio[20] = reg2hw.prio20.q;
- assign prio[21] = reg2hw.prio21.q;
- assign prio[22] = reg2hw.prio22.q;
- assign prio[23] = reg2hw.prio23.q;
- assign prio[24] = reg2hw.prio24.q;
- assign prio[25] = reg2hw.prio25.q;
- assign prio[26] = reg2hw.prio26.q;
- assign prio[27] = reg2hw.prio27.q;
- assign prio[28] = reg2hw.prio28.q;
- assign prio[29] = reg2hw.prio29.q;
- assign prio[30] = reg2hw.prio30.q;
- assign prio[31] = reg2hw.prio31.q;
- assign prio[32] = reg2hw.prio32.q;
- assign prio[33] = reg2hw.prio33.q;
- assign prio[34] = reg2hw.prio34.q;
- assign prio[35] = reg2hw.prio35.q;
- assign prio[36] = reg2hw.prio36.q;
- assign prio[37] = reg2hw.prio37.q;
- assign prio[38] = reg2hw.prio38.q;
- assign prio[39] = reg2hw.prio39.q;
- assign prio[40] = reg2hw.prio40.q;
- assign prio[41] = reg2hw.prio41.q;
- assign prio[42] = reg2hw.prio42.q;
- assign prio[43] = reg2hw.prio43.q;
- //////////////////////
- // Interrupt Enable //
- //////////////////////
- for (genvar s = 0; s < 44; s++) begin : gen_ie0
- assign ie[0][s] = reg2hw.ie0[s].q;
- end
-
- ////////////////////////
- // THRESHOLD register //
- ////////////////////////
- assign threshold[0] = reg2hw.threshold0.q;
-
- /////////////////
- // CC register //
- /////////////////
- assign claim_re[0] = reg2hw.cc0.re;
- assign claim_id[0] = irq_id_o[0];
- assign complete_we[0] = reg2hw.cc0.qe;
- assign complete_id[0] = reg2hw.cc0.q;
- assign hw2reg.cc0.d = cc_id[0];
-
- ///////////////////
- // MSIP register //
- ///////////////////
- assign msip_o[0] = reg2hw.msip0.q;
-
- ////////
- // IP //
- ////////
- for (genvar s = 0; s < 44; s++) begin : gen_ip
- assign hw2reg.ip[s].de = 1'b1; // Always write
- assign hw2reg.ip[s].d = ip[s];
- end
-
- ///////////////////////////////////
- // Detection:: 0: Level, 1: Edge //
- ///////////////////////////////////
- for (genvar s = 0; s < 44; s++) begin : gen_le
- assign le[s] = reg2hw.le[s].q;
- end
-
- //////////////
- // Gateways //
- //////////////
- rv_plic_gateway #(
- .N_SOURCE (NumSrc)
- ) u_gateway (
- .clk_i,
- .rst_ni,
-
- .src_i (intr_src_i),
- .le_i (le),
-
- .claim_i (claim),
- .complete_i (complete),
-
- .ip_o (ip)
- );
-
- ///////////////////////////////////
- // Target interrupt notification //
- ///////////////////////////////////
- for (genvar i = 0 ; i < NumTarget ; i++) begin : gen_target
- rv_plic_target #(
- .N_SOURCE (NumSrc),
- .MAX_PRIO (MAX_PRIO)
- ) u_target (
- .clk_i,
- .rst_ni,
-
- .ip_i (ip),
- .ie_i (ie[i]),
-
- .prio_i (prio),
- .threshold_i (threshold[i]),
-
- .irq_o (irq_o[i]),
- .irq_id_o (irq_id_o[i])
-
- );
- end
-
- ////////////////////////
- // Register interface //
- ////////////////////////
- // Limitation of register tool prevents the module from having flexibility to parameters
- // So, signals are manually tied at the top.
- rv_plic_reg_top u_reg (
- .clk_i,
- .rst_ni,
-
- .tl_i,
- .tl_o,
-
- .reg2hw,
- .hw2reg,
-
- .devmode_i (1'b1)
- );
-
-
-
-endmodule
-
diff --git a/verilog/rtl/rv_plic_gateway.sv b/verilog/rtl/rv_plic_gateway.sv
deleted file mode 100644
index c81810b..0000000
--- a/verilog/rtl/rv_plic_gateway.sv
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// RISC-V Platform-Level Interrupt Gateways module
-
-module rv_plic_gateway #(
- parameter int N_SOURCE = 32
-) (
- input clk_i,
- input rst_ni,
-
- input [N_SOURCE-1:0] src_i,
- input [N_SOURCE-1:0] le_i, // Level0 Edge1
-
- input [N_SOURCE-1:0] claim_i, // $onehot0(claim_i)
- input [N_SOURCE-1:0] complete_i, // $onehot0(complete_i)
-
- output logic [N_SOURCE-1:0] ip_o
-);
-
- logic [N_SOURCE-1:0] ia; // Interrupt Active
-
- logic [N_SOURCE-1:0] set; // Set: (le_i) ? src_i & ~src_q : src_i ;
- logic [N_SOURCE-1:0] src_q;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) src_q <= '0;
- else src_q <= src_i;
- end
-
- always_comb begin
- for (int i = 0 ; i < N_SOURCE; i++) begin
- set[i] = (le_i[i]) ? src_i[i] & ~src_q[i] : src_i[i] ;
- end
- end
-
- // Interrupt pending is set by source (depends on le_i), cleared by claim_i.
- // Until interrupt is claimed, set doesn't affect ip_o.
- // RISC-V PLIC spec mentioned it can have counter for edge triggered
- // But skipped the feature as counter consumes substantial logic size.
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- ip_o <= '0;
- end else begin
- ip_o <= (ip_o | (set & ~ia & ~ip_o)) & (~(ip_o & claim_i));
- end
- end
-
- // Interrupt active is to control ip_o. If ip_o is set then until completed
- // by target, ip_o shouldn't be set by source even claim_i can clear ip_o.
- // ia can be cleared only when ia was set. If `set` and `complete_i` happen
- // at the same time, always `set` wins.
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- ia <= '0;
- end else begin
- ia <= (ia | (set & ~ia)) & (~(ia & complete_i & ~ip_o));
- end
- end
-
-endmodule
diff --git a/verilog/rtl/rv_plic_reg_pkg.sv b/verilog/rtl/rv_plic_reg_pkg.sv
deleted file mode 100644
index cf016d7..0000000
--- a/verilog/rtl/rv_plic_reg_pkg.sv
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Package auto-generated by `reggen` containing data structure
-
-package rv_plic_reg_pkg;
-
- // Param list
- parameter int NumSrc = 44;
- parameter int NumTarget = 1;
- parameter int PrioWidth = 2;
-
- // Address width within the block
- parameter int BlockAw = 10;
-
- ////////////////////////////
- // Typedefs for registers //
- ////////////////////////////
- typedef struct packed {
- logic q;
- } rv_plic_reg2hw_le_mreg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio0_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio1_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio2_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio3_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio4_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio5_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio6_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio7_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio8_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio9_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio10_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio11_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio12_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio13_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio14_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio15_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio16_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio17_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio18_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio19_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio20_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio21_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio22_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio23_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio24_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio25_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio26_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio27_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio28_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio29_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio30_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio31_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio32_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio33_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio34_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio35_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio36_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio37_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio38_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio39_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio40_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio41_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio42_reg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_prio43_reg_t;
-
- typedef struct packed {
- logic q;
- } rv_plic_reg2hw_ie0_mreg_t;
-
- typedef struct packed {
- logic [1:0] q;
- } rv_plic_reg2hw_threshold0_reg_t;
-
- typedef struct packed {
- logic [5:0] q;
- logic qe;
- logic re;
- } rv_plic_reg2hw_cc0_reg_t;
-
- typedef struct packed {
- logic q;
- } rv_plic_reg2hw_msip0_reg_t;
-
-
- typedef struct packed {
- logic d;
- logic de;
- } rv_plic_hw2reg_ip_mreg_t;
-
- typedef struct packed {
- logic [5:0] d;
- } rv_plic_hw2reg_cc0_reg_t;
-
-
- ///////////////////////////////////////
- // Register to internal design logic //
- ///////////////////////////////////////
- typedef struct packed {
- rv_plic_reg2hw_le_mreg_t [43:0] le; // [700:529]
- rv_plic_reg2hw_prio0_reg_t prio0; // [528:527]
- rv_plic_reg2hw_prio1_reg_t prio1; // [526:525]
- rv_plic_reg2hw_prio2_reg_t prio2; // [524:523]
- rv_plic_reg2hw_prio3_reg_t prio3; // [522:521]
- rv_plic_reg2hw_prio4_reg_t prio4; // [520:519]
- rv_plic_reg2hw_prio5_reg_t prio5; // [518:517]
- rv_plic_reg2hw_prio6_reg_t prio6; // [516:515]
- rv_plic_reg2hw_prio7_reg_t prio7; // [514:513]
- rv_plic_reg2hw_prio8_reg_t prio8; // [512:511]
- rv_plic_reg2hw_prio9_reg_t prio9; // [510:509]
- rv_plic_reg2hw_prio10_reg_t prio10; // [508:507]
- rv_plic_reg2hw_prio11_reg_t prio11; // [506:505]
- rv_plic_reg2hw_prio12_reg_t prio12; // [504:503]
- rv_plic_reg2hw_prio13_reg_t prio13; // [502:501]
- rv_plic_reg2hw_prio14_reg_t prio14; // [500:499]
- rv_plic_reg2hw_prio15_reg_t prio15; // [498:497]
- rv_plic_reg2hw_prio16_reg_t prio16; // [496:495]
- rv_plic_reg2hw_prio17_reg_t prio17; // [494:493]
- rv_plic_reg2hw_prio18_reg_t prio18; // [492:491]
- rv_plic_reg2hw_prio19_reg_t prio19; // [490:489]
- rv_plic_reg2hw_prio20_reg_t prio20; // [488:487]
- rv_plic_reg2hw_prio21_reg_t prio21; // [486:485]
- rv_plic_reg2hw_prio22_reg_t prio22; // [484:483]
- rv_plic_reg2hw_prio23_reg_t prio23; // [482:481]
- rv_plic_reg2hw_prio24_reg_t prio24; // [480:479]
- rv_plic_reg2hw_prio25_reg_t prio25; // [478:477]
- rv_plic_reg2hw_prio26_reg_t prio26; // [476:475]
- rv_plic_reg2hw_prio27_reg_t prio27; // [474:473]
- rv_plic_reg2hw_prio28_reg_t prio28; // [472:471]
- rv_plic_reg2hw_prio29_reg_t prio29; // [470:469]
- rv_plic_reg2hw_prio30_reg_t prio30; // [468:467]
- rv_plic_reg2hw_prio31_reg_t prio31; // [466:465]
- rv_plic_reg2hw_prio32_reg_t prio32; // [464:463]
- rv_plic_reg2hw_prio33_reg_t prio33; // [462:461]
- rv_plic_reg2hw_prio34_reg_t prio34; // [460:459]
- rv_plic_reg2hw_prio35_reg_t prio35; // [458:457]
- rv_plic_reg2hw_prio36_reg_t prio36; // [456:455]
- rv_plic_reg2hw_prio37_reg_t prio37; // [454:453]
- rv_plic_reg2hw_prio38_reg_t prio38; // [452:451]
- rv_plic_reg2hw_prio39_reg_t prio39; // [450:449]
- rv_plic_reg2hw_prio40_reg_t prio40; // [448:447]
- rv_plic_reg2hw_prio41_reg_t prio41; // [446:445]
- rv_plic_reg2hw_prio42_reg_t prio42; // [444:443]
- rv_plic_reg2hw_prio43_reg_t prio43; // [442:441]
- rv_plic_reg2hw_ie0_mreg_t [43:0] ie0; // [184:13]
- rv_plic_reg2hw_threshold0_reg_t threshold0; // [12:11]
- rv_plic_reg2hw_cc0_reg_t cc0; // [10:1]
- rv_plic_reg2hw_msip0_reg_t msip0; // [0:0]
- } rv_plic_reg2hw_t;
-
- ///////////////////////////////////////
- // Internal design logic to register //
- ///////////////////////////////////////
- typedef struct packed {
- rv_plic_hw2reg_ip_mreg_t [43:0] ip; // [351:8]
- rv_plic_hw2reg_cc0_reg_t cc0; // [7:0]
- } rv_plic_hw2reg_t;
-
- // Register Address
- parameter logic [BlockAw-1:0] RV_PLIC_IP_0_OFFSET = 10'h 0;
- parameter logic [BlockAw-1:0] RV_PLIC_IP_1_OFFSET = 10'h 4;
- parameter logic [BlockAw-1:0] RV_PLIC_LE_0_OFFSET = 10'h 8;
- parameter logic [BlockAw-1:0] RV_PLIC_LE_1_OFFSET = 10'h c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO0_OFFSET = 10'h 10;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO1_OFFSET = 10'h 14;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO2_OFFSET = 10'h 18;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO3_OFFSET = 10'h 1c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO4_OFFSET = 10'h 20;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO5_OFFSET = 10'h 24;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO6_OFFSET = 10'h 28;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO7_OFFSET = 10'h 2c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO8_OFFSET = 10'h 30;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO9_OFFSET = 10'h 34;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO10_OFFSET = 10'h 38;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO11_OFFSET = 10'h 3c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO12_OFFSET = 10'h 40;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO13_OFFSET = 10'h 44;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO14_OFFSET = 10'h 48;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO15_OFFSET = 10'h 4c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO16_OFFSET = 10'h 50;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO17_OFFSET = 10'h 54;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO18_OFFSET = 10'h 58;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO19_OFFSET = 10'h 5c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO20_OFFSET = 10'h 60;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO21_OFFSET = 10'h 64;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO22_OFFSET = 10'h 68;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO23_OFFSET = 10'h 6c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO24_OFFSET = 10'h 70;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO25_OFFSET = 10'h 74;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO26_OFFSET = 10'h 78;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO27_OFFSET = 10'h 7c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO28_OFFSET = 10'h 80;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO29_OFFSET = 10'h 84;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO30_OFFSET = 10'h 88;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO31_OFFSET = 10'h 8c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO32_OFFSET = 10'h 90;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO33_OFFSET = 10'h 94;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO34_OFFSET = 10'h 98;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO35_OFFSET = 10'h 9c;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO36_OFFSET = 10'h a0;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO37_OFFSET = 10'h a4;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO38_OFFSET = 10'h a8;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO39_OFFSET = 10'h ac;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO40_OFFSET = 10'h b0;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO41_OFFSET = 10'h b4;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO42_OFFSET = 10'h b8;
- parameter logic [BlockAw-1:0] RV_PLIC_PRIO43_OFFSET = 10'h bc;
- parameter logic [BlockAw-1:0] RV_PLIC_IE0_0_OFFSET = 10'h c0;
- parameter logic [BlockAw-1:0] RV_PLIC_IE0_1_OFFSET = 10'h c4;
- parameter logic [BlockAw-1:0] RV_PLIC_THRESHOLD0_OFFSET = 10'h c8;
- parameter logic [BlockAw-1:0] RV_PLIC_CC0_OFFSET = 10'h cc;
- parameter logic [BlockAw-1:0] RV_PLIC_MSIP0_OFFSET = 10'h d0;
-
-
- // Register Index
- typedef enum int {
- RV_PLIC_IP_0,
- RV_PLIC_IP_1,
- RV_PLIC_LE_0,
- RV_PLIC_LE_1,
- RV_PLIC_PRIO0,
- RV_PLIC_PRIO1,
- RV_PLIC_PRIO2,
- RV_PLIC_PRIO3,
- RV_PLIC_PRIO4,
- RV_PLIC_PRIO5,
- RV_PLIC_PRIO6,
- RV_PLIC_PRIO7,
- RV_PLIC_PRIO8,
- RV_PLIC_PRIO9,
- RV_PLIC_PRIO10,
- RV_PLIC_PRIO11,
- RV_PLIC_PRIO12,
- RV_PLIC_PRIO13,
- RV_PLIC_PRIO14,
- RV_PLIC_PRIO15,
- RV_PLIC_PRIO16,
- RV_PLIC_PRIO17,
- RV_PLIC_PRIO18,
- RV_PLIC_PRIO19,
- RV_PLIC_PRIO20,
- RV_PLIC_PRIO21,
- RV_PLIC_PRIO22,
- RV_PLIC_PRIO23,
- RV_PLIC_PRIO24,
- RV_PLIC_PRIO25,
- RV_PLIC_PRIO26,
- RV_PLIC_PRIO27,
- RV_PLIC_PRIO28,
- RV_PLIC_PRIO29,
- RV_PLIC_PRIO30,
- RV_PLIC_PRIO31,
- RV_PLIC_PRIO32,
- RV_PLIC_PRIO33,
- RV_PLIC_PRIO34,
- RV_PLIC_PRIO35,
- RV_PLIC_PRIO36,
- RV_PLIC_PRIO37,
- RV_PLIC_PRIO38,
- RV_PLIC_PRIO39,
- RV_PLIC_PRIO40,
- RV_PLIC_PRIO41,
- RV_PLIC_PRIO42,
- RV_PLIC_PRIO43,
- RV_PLIC_IE0_0,
- RV_PLIC_IE0_1,
- RV_PLIC_THRESHOLD0,
- RV_PLIC_CC0,
- RV_PLIC_MSIP0
- } rv_plic_id_e;
-
- // Register width information to check illegal writes
- parameter logic [3:0] RV_PLIC_PERMIT [53] = '{
- 4'b 1111, // index[ 0] RV_PLIC_IP_0
- 4'b 1111, // index[ 1] RV_PLIC_IP_1
- 4'b 1111, // index[ 6] RV_PLIC_LE_0
- 4'b 1111, // index[ 7] RV_PLIC_LE_1
- 4'b 0001, // index[ 12] RV_PLIC_PRIO0
- 4'b 0001, // index[ 13] RV_PLIC_PRIO1
- 4'b 0001, // index[ 14] RV_PLIC_PRIO2
- 4'b 0001, // index[ 15] RV_PLIC_PRIO3
- 4'b 0001, // index[ 16] RV_PLIC_PRIO4
- 4'b 0001, // index[ 17] RV_PLIC_PRIO5
- 4'b 0001, // index[ 18] RV_PLIC_PRIO6
- 4'b 0001, // index[ 19] RV_PLIC_PRIO7
- 4'b 0001, // index[ 20] RV_PLIC_PRIO8
- 4'b 0001, // index[ 21] RV_PLIC_PRIO9
- 4'b 0001, // index[ 22] RV_PLIC_PRIO10
- 4'b 0001, // index[ 23] RV_PLIC_PRIO11
- 4'b 0001, // index[ 24] RV_PLIC_PRIO12
- 4'b 0001, // index[ 25] RV_PLIC_PRIO13
- 4'b 0001, // index[ 26] RV_PLIC_PRIO14
- 4'b 0001, // index[ 27] RV_PLIC_PRIO15
- 4'b 0001, // index[ 28] RV_PLIC_PRIO16
- 4'b 0001, // index[ 29] RV_PLIC_PRIO17
- 4'b 0001, // index[ 30] RV_PLIC_PRIO18
- 4'b 0001, // index[ 31] RV_PLIC_PRIO19
- 4'b 0001, // index[ 32] RV_PLIC_PRIO20
- 4'b 0001, // index[ 33] RV_PLIC_PRIO21
- 4'b 0001, // index[ 34] RV_PLIC_PRIO22
- 4'b 0001, // index[ 35] RV_PLIC_PRIO23
- 4'b 0001, // index[ 36] RV_PLIC_PRIO24
- 4'b 0001, // index[ 37] RV_PLIC_PRIO25
- 4'b 0001, // index[ 38] RV_PLIC_PRIO26
- 4'b 0001, // index[ 39] RV_PLIC_PRIO27
- 4'b 0001, // index[ 40] RV_PLIC_PRIO28
- 4'b 0001, // index[ 41] RV_PLIC_PRIO29
- 4'b 0001, // index[ 42] RV_PLIC_PRIO30
- 4'b 0001, // index[ 43] RV_PLIC_PRIO31
- 4'b 0001, // index[ 44] RV_PLIC_PRIO32
- 4'b 0001, // index[ 45] RV_PLIC_PRIO33
- 4'b 0001, // index[ 46] RV_PLIC_PRIO34
- 4'b 0001, // index[ 47] RV_PLIC_PRIO35
- 4'b 0001, // index[ 48] RV_PLIC_PRIO36
- 4'b 0001, // index[ 49] RV_PLIC_PRIO37
- 4'b 0001, // index[ 50] RV_PLIC_PRIO38
- 4'b 0001, // index[ 51] RV_PLIC_PRIO39
- 4'b 0001, // index[ 52] RV_PLIC_PRIO40
- 4'b 0001, // index[ 53] RV_PLIC_PRIO41
- 4'b 0001, // index[ 54] RV_PLIC_PRIO42
- 4'b 0001, // index[ 55] RV_PLIC_PRIO43
- 4'b 1111, // index[184] RV_PLIC_IE0_0
- 4'b 1111, // index[185] RV_PLIC_IE0_1
- 4'b 0001, // index[190] RV_PLIC_THRESHOLD0
- 4'b 0001, // index[191] RV_PLIC_CC0
- 4'b 0001 // index[192] RV_PLIC_MSIP0
- };
-endpackage
-
diff --git a/verilog/rtl/rv_plic_reg_top.sv b/verilog/rtl/rv_plic_reg_top.sv
deleted file mode 100644
index 61224c7..0000000
--- a/verilog/rtl/rv_plic_reg_top.sv
+++ /dev/null
@@ -1,6065 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Top module auto-generated by `reggen`
-
-
-module rv_plic_reg_top (
- input clk_i,
- input rst_ni,
-
- // Below Regster interface can be changed
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
- // To HW
- output rv_plic_reg_pkg::rv_plic_reg2hw_t reg2hw, // Write
- input rv_plic_reg_pkg::rv_plic_hw2reg_t hw2reg, // Read
-
- // Config
- input devmode_i // If 1, explicit error return for unmapped register access
-);
-
- import rv_plic_reg_pkg::* ;
-
- localparam int AW = 10;
- localparam int DW = 32;
- localparam int DBW = DW/8; // Byte Width
-
- // register signals
- logic reg_we;
- logic reg_re;
- logic [AW-1:0] reg_addr;
- logic [DW-1:0] reg_wdata;
- logic [DBW-1:0] reg_be;
- logic [DW-1:0] reg_rdata;
- logic reg_error;
-
- logic addrmiss, wr_err;
-
- logic [DW-1:0] reg_rdata_next;
-
- tlul_pkg::tl_h2d_t tl_reg_h2d;
- tlul_pkg::tl_d2h_t tl_reg_d2h;
-
- assign tl_reg_h2d = tl_i;
- assign tl_o = tl_reg_d2h;
-
- tlul_adapter_reg #(
- .RegAw(AW),
- .RegDw(DW)
- ) u_reg_if (
- .clk_i,
- .rst_ni,
-
- .tl_i (tl_reg_h2d),
- .tl_o (tl_reg_d2h),
-
- .we_o (reg_we),
- .re_o (reg_re),
- .addr_o (reg_addr),
- .wdata_o (reg_wdata),
- .be_o (reg_be),
- .rdata_i (reg_rdata),
- .error_i (reg_error)
- );
-
- assign reg_rdata = reg_rdata_next ;
- assign reg_error = (devmode_i & addrmiss) | wr_err ;
-
- // Define SW related signals
- // Format: <reg>_<field>_{wd|we|qs}
- // or <reg>_{wd|we|qs} if field == 1 or 0
- logic ip_0_p_0_qs;
- logic ip_0_p_1_qs;
- logic ip_0_p_2_qs;
- logic ip_0_p_3_qs;
- logic ip_0_p_4_qs;
- logic ip_0_p_5_qs;
- logic ip_0_p_6_qs;
- logic ip_0_p_7_qs;
- logic ip_0_p_8_qs;
- logic ip_0_p_9_qs;
- logic ip_0_p_10_qs;
- logic ip_0_p_11_qs;
- logic ip_0_p_12_qs;
- logic ip_0_p_13_qs;
- logic ip_0_p_14_qs;
- logic ip_0_p_15_qs;
- logic ip_0_p_16_qs;
- logic ip_0_p_17_qs;
- logic ip_0_p_18_qs;
- logic ip_0_p_19_qs;
- logic ip_0_p_20_qs;
- logic ip_0_p_21_qs;
- logic ip_0_p_22_qs;
- logic ip_0_p_23_qs;
- logic ip_0_p_24_qs;
- logic ip_0_p_25_qs;
- logic ip_0_p_26_qs;
- logic ip_0_p_27_qs;
- logic ip_0_p_28_qs;
- logic ip_0_p_29_qs;
- logic ip_0_p_30_qs;
- logic ip_0_p_31_qs;
- logic ip_1_p_32_qs;
- logic ip_1_p_33_qs;
- logic ip_1_p_34_qs;
- logic ip_1_p_35_qs;
- logic ip_1_p_36_qs;
- logic ip_1_p_37_qs;
- logic ip_1_p_38_qs;
- logic ip_1_p_39_qs;
- logic ip_1_p_40_qs;
- logic ip_1_p_41_qs;
- logic ip_1_p_42_qs;
- logic ip_1_p_43_qs;
- logic le_0_le_0_qs;
- logic le_0_le_0_wd;
- logic le_0_le_0_we;
- logic le_0_le_1_qs;
- logic le_0_le_1_wd;
- logic le_0_le_1_we;
- logic le_0_le_2_qs;
- logic le_0_le_2_wd;
- logic le_0_le_2_we;
- logic le_0_le_3_qs;
- logic le_0_le_3_wd;
- logic le_0_le_3_we;
- logic le_0_le_4_qs;
- logic le_0_le_4_wd;
- logic le_0_le_4_we;
- logic le_0_le_5_qs;
- logic le_0_le_5_wd;
- logic le_0_le_5_we;
- logic le_0_le_6_qs;
- logic le_0_le_6_wd;
- logic le_0_le_6_we;
- logic le_0_le_7_qs;
- logic le_0_le_7_wd;
- logic le_0_le_7_we;
- logic le_0_le_8_qs;
- logic le_0_le_8_wd;
- logic le_0_le_8_we;
- logic le_0_le_9_qs;
- logic le_0_le_9_wd;
- logic le_0_le_9_we;
- logic le_0_le_10_qs;
- logic le_0_le_10_wd;
- logic le_0_le_10_we;
- logic le_0_le_11_qs;
- logic le_0_le_11_wd;
- logic le_0_le_11_we;
- logic le_0_le_12_qs;
- logic le_0_le_12_wd;
- logic le_0_le_12_we;
- logic le_0_le_13_qs;
- logic le_0_le_13_wd;
- logic le_0_le_13_we;
- logic le_0_le_14_qs;
- logic le_0_le_14_wd;
- logic le_0_le_14_we;
- logic le_0_le_15_qs;
- logic le_0_le_15_wd;
- logic le_0_le_15_we;
- logic le_0_le_16_qs;
- logic le_0_le_16_wd;
- logic le_0_le_16_we;
- logic le_0_le_17_qs;
- logic le_0_le_17_wd;
- logic le_0_le_17_we;
- logic le_0_le_18_qs;
- logic le_0_le_18_wd;
- logic le_0_le_18_we;
- logic le_0_le_19_qs;
- logic le_0_le_19_wd;
- logic le_0_le_19_we;
- logic le_0_le_20_qs;
- logic le_0_le_20_wd;
- logic le_0_le_20_we;
- logic le_0_le_21_qs;
- logic le_0_le_21_wd;
- logic le_0_le_21_we;
- logic le_0_le_22_qs;
- logic le_0_le_22_wd;
- logic le_0_le_22_we;
- logic le_0_le_23_qs;
- logic le_0_le_23_wd;
- logic le_0_le_23_we;
- logic le_0_le_24_qs;
- logic le_0_le_24_wd;
- logic le_0_le_24_we;
- logic le_0_le_25_qs;
- logic le_0_le_25_wd;
- logic le_0_le_25_we;
- logic le_0_le_26_qs;
- logic le_0_le_26_wd;
- logic le_0_le_26_we;
- logic le_0_le_27_qs;
- logic le_0_le_27_wd;
- logic le_0_le_27_we;
- logic le_0_le_28_qs;
- logic le_0_le_28_wd;
- logic le_0_le_28_we;
- logic le_0_le_29_qs;
- logic le_0_le_29_wd;
- logic le_0_le_29_we;
- logic le_0_le_30_qs;
- logic le_0_le_30_wd;
- logic le_0_le_30_we;
- logic le_0_le_31_qs;
- logic le_0_le_31_wd;
- logic le_0_le_31_we;
- logic le_1_le_32_qs;
- logic le_1_le_32_wd;
- logic le_1_le_32_we;
- logic le_1_le_33_qs;
- logic le_1_le_33_wd;
- logic le_1_le_33_we;
- logic le_1_le_34_qs;
- logic le_1_le_34_wd;
- logic le_1_le_34_we;
- logic le_1_le_35_qs;
- logic le_1_le_35_wd;
- logic le_1_le_35_we;
- logic le_1_le_36_qs;
- logic le_1_le_36_wd;
- logic le_1_le_36_we;
- logic le_1_le_37_qs;
- logic le_1_le_37_wd;
- logic le_1_le_37_we;
- logic le_1_le_38_qs;
- logic le_1_le_38_wd;
- logic le_1_le_38_we;
- logic le_1_le_39_qs;
- logic le_1_le_39_wd;
- logic le_1_le_39_we;
- logic le_1_le_40_qs;
- logic le_1_le_40_wd;
- logic le_1_le_40_we;
- logic le_1_le_41_qs;
- logic le_1_le_41_wd;
- logic le_1_le_41_we;
- logic le_1_le_42_qs;
- logic le_1_le_42_wd;
- logic le_1_le_42_we;
- logic le_1_le_43_qs;
- logic le_1_le_43_wd;
- logic le_1_le_43_we;
- logic [1:0] prio0_qs;
- logic [1:0] prio0_wd;
- logic prio0_we;
- logic [1:0] prio1_qs;
- logic [1:0] prio1_wd;
- logic prio1_we;
- logic [1:0] prio2_qs;
- logic [1:0] prio2_wd;
- logic prio2_we;
- logic [1:0] prio3_qs;
- logic [1:0] prio3_wd;
- logic prio3_we;
- logic [1:0] prio4_qs;
- logic [1:0] prio4_wd;
- logic prio4_we;
- logic [1:0] prio5_qs;
- logic [1:0] prio5_wd;
- logic prio5_we;
- logic [1:0] prio6_qs;
- logic [1:0] prio6_wd;
- logic prio6_we;
- logic [1:0] prio7_qs;
- logic [1:0] prio7_wd;
- logic prio7_we;
- logic [1:0] prio8_qs;
- logic [1:0] prio8_wd;
- logic prio8_we;
- logic [1:0] prio9_qs;
- logic [1:0] prio9_wd;
- logic prio9_we;
- logic [1:0] prio10_qs;
- logic [1:0] prio10_wd;
- logic prio10_we;
- logic [1:0] prio11_qs;
- logic [1:0] prio11_wd;
- logic prio11_we;
- logic [1:0] prio12_qs;
- logic [1:0] prio12_wd;
- logic prio12_we;
- logic [1:0] prio13_qs;
- logic [1:0] prio13_wd;
- logic prio13_we;
- logic [1:0] prio14_qs;
- logic [1:0] prio14_wd;
- logic prio14_we;
- logic [1:0] prio15_qs;
- logic [1:0] prio15_wd;
- logic prio15_we;
- logic [1:0] prio16_qs;
- logic [1:0] prio16_wd;
- logic prio16_we;
- logic [1:0] prio17_qs;
- logic [1:0] prio17_wd;
- logic prio17_we;
- logic [1:0] prio18_qs;
- logic [1:0] prio18_wd;
- logic prio18_we;
- logic [1:0] prio19_qs;
- logic [1:0] prio19_wd;
- logic prio19_we;
- logic [1:0] prio20_qs;
- logic [1:0] prio20_wd;
- logic prio20_we;
- logic [1:0] prio21_qs;
- logic [1:0] prio21_wd;
- logic prio21_we;
- logic [1:0] prio22_qs;
- logic [1:0] prio22_wd;
- logic prio22_we;
- logic [1:0] prio23_qs;
- logic [1:0] prio23_wd;
- logic prio23_we;
- logic [1:0] prio24_qs;
- logic [1:0] prio24_wd;
- logic prio24_we;
- logic [1:0] prio25_qs;
- logic [1:0] prio25_wd;
- logic prio25_we;
- logic [1:0] prio26_qs;
- logic [1:0] prio26_wd;
- logic prio26_we;
- logic [1:0] prio27_qs;
- logic [1:0] prio27_wd;
- logic prio27_we;
- logic [1:0] prio28_qs;
- logic [1:0] prio28_wd;
- logic prio28_we;
- logic [1:0] prio29_qs;
- logic [1:0] prio29_wd;
- logic prio29_we;
- logic [1:0] prio30_qs;
- logic [1:0] prio30_wd;
- logic prio30_we;
- logic [1:0] prio31_qs;
- logic [1:0] prio31_wd;
- logic prio31_we;
- logic [1:0] prio32_qs;
- logic [1:0] prio32_wd;
- logic prio32_we;
- logic [1:0] prio33_qs;
- logic [1:0] prio33_wd;
- logic prio33_we;
- logic [1:0] prio34_qs;
- logic [1:0] prio34_wd;
- logic prio34_we;
- logic [1:0] prio35_qs;
- logic [1:0] prio35_wd;
- logic prio35_we;
- logic [1:0] prio36_qs;
- logic [1:0] prio36_wd;
- logic prio36_we;
- logic [1:0] prio37_qs;
- logic [1:0] prio37_wd;
- logic prio37_we;
- logic [1:0] prio38_qs;
- logic [1:0] prio38_wd;
- logic prio38_we;
- logic [1:0] prio39_qs;
- logic [1:0] prio39_wd;
- logic prio39_we;
- logic [1:0] prio40_qs;
- logic [1:0] prio40_wd;
- logic prio40_we;
- logic [1:0] prio41_qs;
- logic [1:0] prio41_wd;
- logic prio41_we;
- logic [1:0] prio42_qs;
- logic [1:0] prio42_wd;
- logic prio42_we;
- logic [1:0] prio43_qs;
- logic [1:0] prio43_wd;
- logic prio43_we;
- logic ie0_0_e_0_qs;
- logic ie0_0_e_0_wd;
- logic ie0_0_e_0_we;
- logic ie0_0_e_1_qs;
- logic ie0_0_e_1_wd;
- logic ie0_0_e_1_we;
- logic ie0_0_e_2_qs;
- logic ie0_0_e_2_wd;
- logic ie0_0_e_2_we;
- logic ie0_0_e_3_qs;
- logic ie0_0_e_3_wd;
- logic ie0_0_e_3_we;
- logic ie0_0_e_4_qs;
- logic ie0_0_e_4_wd;
- logic ie0_0_e_4_we;
- logic ie0_0_e_5_qs;
- logic ie0_0_e_5_wd;
- logic ie0_0_e_5_we;
- logic ie0_0_e_6_qs;
- logic ie0_0_e_6_wd;
- logic ie0_0_e_6_we;
- logic ie0_0_e_7_qs;
- logic ie0_0_e_7_wd;
- logic ie0_0_e_7_we;
- logic ie0_0_e_8_qs;
- logic ie0_0_e_8_wd;
- logic ie0_0_e_8_we;
- logic ie0_0_e_9_qs;
- logic ie0_0_e_9_wd;
- logic ie0_0_e_9_we;
- logic ie0_0_e_10_qs;
- logic ie0_0_e_10_wd;
- logic ie0_0_e_10_we;
- logic ie0_0_e_11_qs;
- logic ie0_0_e_11_wd;
- logic ie0_0_e_11_we;
- logic ie0_0_e_12_qs;
- logic ie0_0_e_12_wd;
- logic ie0_0_e_12_we;
- logic ie0_0_e_13_qs;
- logic ie0_0_e_13_wd;
- logic ie0_0_e_13_we;
- logic ie0_0_e_14_qs;
- logic ie0_0_e_14_wd;
- logic ie0_0_e_14_we;
- logic ie0_0_e_15_qs;
- logic ie0_0_e_15_wd;
- logic ie0_0_e_15_we;
- logic ie0_0_e_16_qs;
- logic ie0_0_e_16_wd;
- logic ie0_0_e_16_we;
- logic ie0_0_e_17_qs;
- logic ie0_0_e_17_wd;
- logic ie0_0_e_17_we;
- logic ie0_0_e_18_qs;
- logic ie0_0_e_18_wd;
- logic ie0_0_e_18_we;
- logic ie0_0_e_19_qs;
- logic ie0_0_e_19_wd;
- logic ie0_0_e_19_we;
- logic ie0_0_e_20_qs;
- logic ie0_0_e_20_wd;
- logic ie0_0_e_20_we;
- logic ie0_0_e_21_qs;
- logic ie0_0_e_21_wd;
- logic ie0_0_e_21_we;
- logic ie0_0_e_22_qs;
- logic ie0_0_e_22_wd;
- logic ie0_0_e_22_we;
- logic ie0_0_e_23_qs;
- logic ie0_0_e_23_wd;
- logic ie0_0_e_23_we;
- logic ie0_0_e_24_qs;
- logic ie0_0_e_24_wd;
- logic ie0_0_e_24_we;
- logic ie0_0_e_25_qs;
- logic ie0_0_e_25_wd;
- logic ie0_0_e_25_we;
- logic ie0_0_e_26_qs;
- logic ie0_0_e_26_wd;
- logic ie0_0_e_26_we;
- logic ie0_0_e_27_qs;
- logic ie0_0_e_27_wd;
- logic ie0_0_e_27_we;
- logic ie0_0_e_28_qs;
- logic ie0_0_e_28_wd;
- logic ie0_0_e_28_we;
- logic ie0_0_e_29_qs;
- logic ie0_0_e_29_wd;
- logic ie0_0_e_29_we;
- logic ie0_0_e_30_qs;
- logic ie0_0_e_30_wd;
- logic ie0_0_e_30_we;
- logic ie0_0_e_31_qs;
- logic ie0_0_e_31_wd;
- logic ie0_0_e_31_we;
- logic ie0_1_e_32_qs;
- logic ie0_1_e_32_wd;
- logic ie0_1_e_32_we;
- logic ie0_1_e_33_qs;
- logic ie0_1_e_33_wd;
- logic ie0_1_e_33_we;
- logic ie0_1_e_34_qs;
- logic ie0_1_e_34_wd;
- logic ie0_1_e_34_we;
- logic ie0_1_e_35_qs;
- logic ie0_1_e_35_wd;
- logic ie0_1_e_35_we;
- logic ie0_1_e_36_qs;
- logic ie0_1_e_36_wd;
- logic ie0_1_e_36_we;
- logic ie0_1_e_37_qs;
- logic ie0_1_e_37_wd;
- logic ie0_1_e_37_we;
- logic ie0_1_e_38_qs;
- logic ie0_1_e_38_wd;
- logic ie0_1_e_38_we;
- logic ie0_1_e_39_qs;
- logic ie0_1_e_39_wd;
- logic ie0_1_e_39_we;
- logic ie0_1_e_40_qs;
- logic ie0_1_e_40_wd;
- logic ie0_1_e_40_we;
- logic ie0_1_e_41_qs;
- logic ie0_1_e_41_wd;
- logic ie0_1_e_41_we;
- logic ie0_1_e_42_qs;
- logic ie0_1_e_42_wd;
- logic ie0_1_e_42_we;
- logic ie0_1_e_43_qs;
- logic ie0_1_e_43_wd;
- logic ie0_1_e_43_we;
- logic [1:0] threshold0_qs;
- logic [1:0] threshold0_wd;
- logic threshold0_we;
- logic [5:0] cc0_qs;
- logic [5:0] cc0_wd;
- logic cc0_we;
- logic cc0_re;
- logic msip0_qs;
- logic msip0_wd;
- logic msip0_we;
-
- // Register instances
-
- // Subregister 0 of Multireg ip
- // R[ip_0]: V(False)
-
- // F[p_0]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[0].de),
- .d (hw2reg.ip[0].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_0_qs)
- );
-
-
- // F[p_1]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_1 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[1].de),
- .d (hw2reg.ip[1].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_1_qs)
- );
-
-
- // F[p_2]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_2 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[2].de),
- .d (hw2reg.ip[2].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_2_qs)
- );
-
-
- // F[p_3]: 3:3
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_3 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[3].de),
- .d (hw2reg.ip[3].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_3_qs)
- );
-
-
- // F[p_4]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_4 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[4].de),
- .d (hw2reg.ip[4].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_4_qs)
- );
-
-
- // F[p_5]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_5 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[5].de),
- .d (hw2reg.ip[5].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_5_qs)
- );
-
-
- // F[p_6]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_6 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[6].de),
- .d (hw2reg.ip[6].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_6_qs)
- );
-
-
- // F[p_7]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_7 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[7].de),
- .d (hw2reg.ip[7].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_7_qs)
- );
-
-
- // F[p_8]: 8:8
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_8 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[8].de),
- .d (hw2reg.ip[8].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_8_qs)
- );
-
-
- // F[p_9]: 9:9
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_9 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[9].de),
- .d (hw2reg.ip[9].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_9_qs)
- );
-
-
- // F[p_10]: 10:10
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_10 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[10].de),
- .d (hw2reg.ip[10].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_10_qs)
- );
-
-
- // F[p_11]: 11:11
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_11 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[11].de),
- .d (hw2reg.ip[11].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_11_qs)
- );
-
-
- // F[p_12]: 12:12
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_12 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[12].de),
- .d (hw2reg.ip[12].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_12_qs)
- );
-
-
- // F[p_13]: 13:13
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_13 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[13].de),
- .d (hw2reg.ip[13].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_13_qs)
- );
-
-
- // F[p_14]: 14:14
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_14 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[14].de),
- .d (hw2reg.ip[14].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_14_qs)
- );
-
-
- // F[p_15]: 15:15
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_15 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[15].de),
- .d (hw2reg.ip[15].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_15_qs)
- );
-
-
- // F[p_16]: 16:16
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_16 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[16].de),
- .d (hw2reg.ip[16].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_16_qs)
- );
-
-
- // F[p_17]: 17:17
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_17 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[17].de),
- .d (hw2reg.ip[17].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_17_qs)
- );
-
-
- // F[p_18]: 18:18
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_18 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[18].de),
- .d (hw2reg.ip[18].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_18_qs)
- );
-
-
- // F[p_19]: 19:19
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_19 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[19].de),
- .d (hw2reg.ip[19].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_19_qs)
- );
-
-
- // F[p_20]: 20:20
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_20 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[20].de),
- .d (hw2reg.ip[20].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_20_qs)
- );
-
-
- // F[p_21]: 21:21
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_21 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[21].de),
- .d (hw2reg.ip[21].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_21_qs)
- );
-
-
- // F[p_22]: 22:22
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_22 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[22].de),
- .d (hw2reg.ip[22].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_22_qs)
- );
-
-
- // F[p_23]: 23:23
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_23 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[23].de),
- .d (hw2reg.ip[23].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_23_qs)
- );
-
-
- // F[p_24]: 24:24
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_24 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[24].de),
- .d (hw2reg.ip[24].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_24_qs)
- );
-
-
- // F[p_25]: 25:25
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_25 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[25].de),
- .d (hw2reg.ip[25].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_25_qs)
- );
-
-
- // F[p_26]: 26:26
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_26 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[26].de),
- .d (hw2reg.ip[26].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_26_qs)
- );
-
-
- // F[p_27]: 27:27
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_27 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[27].de),
- .d (hw2reg.ip[27].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_27_qs)
- );
-
-
- // F[p_28]: 28:28
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_28 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[28].de),
- .d (hw2reg.ip[28].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_28_qs)
- );
-
-
- // F[p_29]: 29:29
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_29 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[29].de),
- .d (hw2reg.ip[29].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_29_qs)
- );
-
-
- // F[p_30]: 30:30
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_30 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[30].de),
- .d (hw2reg.ip[30].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_30_qs)
- );
-
-
- // F[p_31]: 31:31
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_0_p_31 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[31].de),
- .d (hw2reg.ip[31].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_0_p_31_qs)
- );
-
-
- // Subregister 32 of Multireg ip
- // R[ip_1]: V(False)
-
- // F[p_32]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_32 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[32].de),
- .d (hw2reg.ip[32].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_32_qs)
- );
-
-
- // F[p_33]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_33 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[33].de),
- .d (hw2reg.ip[33].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_33_qs)
- );
-
-
- // F[p_34]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_34 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[34].de),
- .d (hw2reg.ip[34].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_34_qs)
- );
-
-
- // F[p_35]: 3:3
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_35 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[35].de),
- .d (hw2reg.ip[35].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_35_qs)
- );
-
-
- // F[p_36]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_36 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[36].de),
- .d (hw2reg.ip[36].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_36_qs)
- );
-
-
- // F[p_37]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_37 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[37].de),
- .d (hw2reg.ip[37].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_37_qs)
- );
-
-
- // F[p_38]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_38 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[38].de),
- .d (hw2reg.ip[38].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_38_qs)
- );
-
-
- // F[p_39]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_39 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[39].de),
- .d (hw2reg.ip[39].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_39_qs)
- );
-
-
- // F[p_40]: 8:8
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_40 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[40].de),
- .d (hw2reg.ip[40].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_40_qs)
- );
-
-
- // F[p_41]: 9:9
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_41 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[41].de),
- .d (hw2reg.ip[41].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_41_qs)
- );
-
-
- // F[p_42]: 10:10
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_42 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[42].de),
- .d (hw2reg.ip[42].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_42_qs)
- );
-
-
- // F[p_43]: 11:11
- prim_subreg #(
- .DW (1),
- .SWACCESS("RO"),
- .RESVAL (1'h0)
- ) u_ip_1_p_43 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- .we (1'b0),
- .wd ('0 ),
-
- // from internal hardware
- .de (hw2reg.ip[43].de),
- .d (hw2reg.ip[43].d ),
-
- // to internal hardware
- .qe (),
- .q (),
-
- // to register interface (read)
- .qs (ip_1_p_43_qs)
- );
-
- // Subregister 0 of Multireg le
- // R[le_0]: V(False)
-
- // F[le_0]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_0_we),
- .wd (le_0_le_0_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[0].q ),
-
- // to register interface (read)
- .qs (le_0_le_0_qs)
- );
-
-
- // F[le_1]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_1 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_1_we),
- .wd (le_0_le_1_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[1].q ),
-
- // to register interface (read)
- .qs (le_0_le_1_qs)
- );
-
-
- // F[le_2]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_2 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_2_we),
- .wd (le_0_le_2_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[2].q ),
-
- // to register interface (read)
- .qs (le_0_le_2_qs)
- );
-
-
- // F[le_3]: 3:3
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_3 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_3_we),
- .wd (le_0_le_3_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[3].q ),
-
- // to register interface (read)
- .qs (le_0_le_3_qs)
- );
-
-
- // F[le_4]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_4 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_4_we),
- .wd (le_0_le_4_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[4].q ),
-
- // to register interface (read)
- .qs (le_0_le_4_qs)
- );
-
-
- // F[le_5]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_5 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_5_we),
- .wd (le_0_le_5_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[5].q ),
-
- // to register interface (read)
- .qs (le_0_le_5_qs)
- );
-
-
- // F[le_6]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_6 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_6_we),
- .wd (le_0_le_6_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[6].q ),
-
- // to register interface (read)
- .qs (le_0_le_6_qs)
- );
-
-
- // F[le_7]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_7 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_7_we),
- .wd (le_0_le_7_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[7].q ),
-
- // to register interface (read)
- .qs (le_0_le_7_qs)
- );
-
-
- // F[le_8]: 8:8
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_8 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_8_we),
- .wd (le_0_le_8_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[8].q ),
-
- // to register interface (read)
- .qs (le_0_le_8_qs)
- );
-
-
- // F[le_9]: 9:9
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_9 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_9_we),
- .wd (le_0_le_9_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[9].q ),
-
- // to register interface (read)
- .qs (le_0_le_9_qs)
- );
-
-
- // F[le_10]: 10:10
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_10 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_10_we),
- .wd (le_0_le_10_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[10].q ),
-
- // to register interface (read)
- .qs (le_0_le_10_qs)
- );
-
-
- // F[le_11]: 11:11
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_11 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_11_we),
- .wd (le_0_le_11_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[11].q ),
-
- // to register interface (read)
- .qs (le_0_le_11_qs)
- );
-
-
- // F[le_12]: 12:12
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_12 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_12_we),
- .wd (le_0_le_12_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[12].q ),
-
- // to register interface (read)
- .qs (le_0_le_12_qs)
- );
-
-
- // F[le_13]: 13:13
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_13 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_13_we),
- .wd (le_0_le_13_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[13].q ),
-
- // to register interface (read)
- .qs (le_0_le_13_qs)
- );
-
-
- // F[le_14]: 14:14
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_14 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_14_we),
- .wd (le_0_le_14_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[14].q ),
-
- // to register interface (read)
- .qs (le_0_le_14_qs)
- );
-
-
- // F[le_15]: 15:15
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_15 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_15_we),
- .wd (le_0_le_15_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[15].q ),
-
- // to register interface (read)
- .qs (le_0_le_15_qs)
- );
-
-
- // F[le_16]: 16:16
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_16 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_16_we),
- .wd (le_0_le_16_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[16].q ),
-
- // to register interface (read)
- .qs (le_0_le_16_qs)
- );
-
-
- // F[le_17]: 17:17
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_17 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_17_we),
- .wd (le_0_le_17_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[17].q ),
-
- // to register interface (read)
- .qs (le_0_le_17_qs)
- );
-
-
- // F[le_18]: 18:18
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_18 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_18_we),
- .wd (le_0_le_18_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[18].q ),
-
- // to register interface (read)
- .qs (le_0_le_18_qs)
- );
-
-
- // F[le_19]: 19:19
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_19 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_19_we),
- .wd (le_0_le_19_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[19].q ),
-
- // to register interface (read)
- .qs (le_0_le_19_qs)
- );
-
-
- // F[le_20]: 20:20
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_20 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_20_we),
- .wd (le_0_le_20_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[20].q ),
-
- // to register interface (read)
- .qs (le_0_le_20_qs)
- );
-
-
- // F[le_21]: 21:21
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_21 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_21_we),
- .wd (le_0_le_21_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[21].q ),
-
- // to register interface (read)
- .qs (le_0_le_21_qs)
- );
-
-
- // F[le_22]: 22:22
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_22 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_22_we),
- .wd (le_0_le_22_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[22].q ),
-
- // to register interface (read)
- .qs (le_0_le_22_qs)
- );
-
-
- // F[le_23]: 23:23
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_23 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_23_we),
- .wd (le_0_le_23_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[23].q ),
-
- // to register interface (read)
- .qs (le_0_le_23_qs)
- );
-
-
- // F[le_24]: 24:24
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_24 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_24_we),
- .wd (le_0_le_24_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[24].q ),
-
- // to register interface (read)
- .qs (le_0_le_24_qs)
- );
-
-
- // F[le_25]: 25:25
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_25 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_25_we),
- .wd (le_0_le_25_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[25].q ),
-
- // to register interface (read)
- .qs (le_0_le_25_qs)
- );
-
-
- // F[le_26]: 26:26
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_26 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_26_we),
- .wd (le_0_le_26_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[26].q ),
-
- // to register interface (read)
- .qs (le_0_le_26_qs)
- );
-
-
- // F[le_27]: 27:27
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_27 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_27_we),
- .wd (le_0_le_27_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[27].q ),
-
- // to register interface (read)
- .qs (le_0_le_27_qs)
- );
-
-
- // F[le_28]: 28:28
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_28 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_28_we),
- .wd (le_0_le_28_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[28].q ),
-
- // to register interface (read)
- .qs (le_0_le_28_qs)
- );
-
-
- // F[le_29]: 29:29
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_29 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_29_we),
- .wd (le_0_le_29_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[29].q ),
-
- // to register interface (read)
- .qs (le_0_le_29_qs)
- );
-
-
- // F[le_30]: 30:30
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_30 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_30_we),
- .wd (le_0_le_30_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[30].q ),
-
- // to register interface (read)
- .qs (le_0_le_30_qs)
- );
-
-
- // F[le_31]: 31:31
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_0_le_31 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_0_le_31_we),
- .wd (le_0_le_31_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[31].q ),
-
- // to register interface (read)
- .qs (le_0_le_31_qs)
- );
-
-
- // Subregister 32 of Multireg le
- // R[le_1]: V(False)
-
- // F[le_32]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_32 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_32_we),
- .wd (le_1_le_32_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[32].q ),
-
- // to register interface (read)
- .qs (le_1_le_32_qs)
- );
-
-
- // F[le_33]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_33 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_33_we),
- .wd (le_1_le_33_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[33].q ),
-
- // to register interface (read)
- .qs (le_1_le_33_qs)
- );
-
-
- // F[le_34]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_34 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_34_we),
- .wd (le_1_le_34_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[34].q ),
-
- // to register interface (read)
- .qs (le_1_le_34_qs)
- );
-
-
- // F[le_35]: 3:3
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_35 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_35_we),
- .wd (le_1_le_35_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[35].q ),
-
- // to register interface (read)
- .qs (le_1_le_35_qs)
- );
-
-
- // F[le_36]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_36 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_36_we),
- .wd (le_1_le_36_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[36].q ),
-
- // to register interface (read)
- .qs (le_1_le_36_qs)
- );
-
-
- // F[le_37]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_37 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_37_we),
- .wd (le_1_le_37_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[37].q ),
-
- // to register interface (read)
- .qs (le_1_le_37_qs)
- );
-
-
- // F[le_38]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_38 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_38_we),
- .wd (le_1_le_38_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[38].q ),
-
- // to register interface (read)
- .qs (le_1_le_38_qs)
- );
-
-
- // F[le_39]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_39 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_39_we),
- .wd (le_1_le_39_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[39].q ),
-
- // to register interface (read)
- .qs (le_1_le_39_qs)
- );
-
-
- // F[le_40]: 8:8
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_40 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_40_we),
- .wd (le_1_le_40_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[40].q ),
-
- // to register interface (read)
- .qs (le_1_le_40_qs)
- );
-
-
- // F[le_41]: 9:9
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_41 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_41_we),
- .wd (le_1_le_41_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[41].q ),
-
- // to register interface (read)
- .qs (le_1_le_41_qs)
- );
-
-
- // F[le_42]: 10:10
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_42 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_42_we),
- .wd (le_1_le_42_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[42].q ),
-
- // to register interface (read)
- .qs (le_1_le_42_qs)
- );
-
-
- // F[le_43]: 11:11
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_le_1_le_43 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (le_1_le_43_we),
- .wd (le_1_le_43_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.le[43].q ),
-
- // to register interface (read)
- .qs (le_1_le_43_qs)
- );
-
- // R[prio0]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio0_we),
- .wd (prio0_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio0.q ),
-
- // to register interface (read)
- .qs (prio0_qs)
- );
-
-
- // R[prio1]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio1 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio1_we),
- .wd (prio1_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio1.q ),
-
- // to register interface (read)
- .qs (prio1_qs)
- );
-
-
- // R[prio2]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio2 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio2_we),
- .wd (prio2_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio2.q ),
-
- // to register interface (read)
- .qs (prio2_qs)
- );
-
-
- // R[prio3]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio3 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio3_we),
- .wd (prio3_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio3.q ),
-
- // to register interface (read)
- .qs (prio3_qs)
- );
-
-
- // R[prio4]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio4 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio4_we),
- .wd (prio4_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio4.q ),
-
- // to register interface (read)
- .qs (prio4_qs)
- );
-
-
- // R[prio5]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio5 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio5_we),
- .wd (prio5_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio5.q ),
-
- // to register interface (read)
- .qs (prio5_qs)
- );
-
-
- // R[prio6]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio6 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio6_we),
- .wd (prio6_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio6.q ),
-
- // to register interface (read)
- .qs (prio6_qs)
- );
-
-
- // R[prio7]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio7 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio7_we),
- .wd (prio7_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio7.q ),
-
- // to register interface (read)
- .qs (prio7_qs)
- );
-
-
- // R[prio8]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio8 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio8_we),
- .wd (prio8_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio8.q ),
-
- // to register interface (read)
- .qs (prio8_qs)
- );
-
-
- // R[prio9]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio9 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio9_we),
- .wd (prio9_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio9.q ),
-
- // to register interface (read)
- .qs (prio9_qs)
- );
-
-
- // R[prio10]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio10 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio10_we),
- .wd (prio10_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio10.q ),
-
- // to register interface (read)
- .qs (prio10_qs)
- );
-
-
- // R[prio11]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio11 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio11_we),
- .wd (prio11_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio11.q ),
-
- // to register interface (read)
- .qs (prio11_qs)
- );
-
-
- // R[prio12]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio12 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio12_we),
- .wd (prio12_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio12.q ),
-
- // to register interface (read)
- .qs (prio12_qs)
- );
-
-
- // R[prio13]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio13 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio13_we),
- .wd (prio13_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio13.q ),
-
- // to register interface (read)
- .qs (prio13_qs)
- );
-
-
- // R[prio14]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio14 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio14_we),
- .wd (prio14_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio14.q ),
-
- // to register interface (read)
- .qs (prio14_qs)
- );
-
-
- // R[prio15]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio15 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio15_we),
- .wd (prio15_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio15.q ),
-
- // to register interface (read)
- .qs (prio15_qs)
- );
-
-
- // R[prio16]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio16 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio16_we),
- .wd (prio16_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio16.q ),
-
- // to register interface (read)
- .qs (prio16_qs)
- );
-
-
- // R[prio17]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio17 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio17_we),
- .wd (prio17_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio17.q ),
-
- // to register interface (read)
- .qs (prio17_qs)
- );
-
-
- // R[prio18]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio18 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio18_we),
- .wd (prio18_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio18.q ),
-
- // to register interface (read)
- .qs (prio18_qs)
- );
-
-
- // R[prio19]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio19 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio19_we),
- .wd (prio19_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio19.q ),
-
- // to register interface (read)
- .qs (prio19_qs)
- );
-
-
- // R[prio20]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio20 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio20_we),
- .wd (prio20_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio20.q ),
-
- // to register interface (read)
- .qs (prio20_qs)
- );
-
-
- // R[prio21]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio21 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio21_we),
- .wd (prio21_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio21.q ),
-
- // to register interface (read)
- .qs (prio21_qs)
- );
-
-
- // R[prio22]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio22 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio22_we),
- .wd (prio22_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio22.q ),
-
- // to register interface (read)
- .qs (prio22_qs)
- );
-
-
- // R[prio23]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio23 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio23_we),
- .wd (prio23_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio23.q ),
-
- // to register interface (read)
- .qs (prio23_qs)
- );
-
-
- // R[prio24]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio24 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio24_we),
- .wd (prio24_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio24.q ),
-
- // to register interface (read)
- .qs (prio24_qs)
- );
-
-
- // R[prio25]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio25 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio25_we),
- .wd (prio25_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio25.q ),
-
- // to register interface (read)
- .qs (prio25_qs)
- );
-
-
- // R[prio26]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio26 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio26_we),
- .wd (prio26_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio26.q ),
-
- // to register interface (read)
- .qs (prio26_qs)
- );
-
-
- // R[prio27]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio27 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio27_we),
- .wd (prio27_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio27.q ),
-
- // to register interface (read)
- .qs (prio27_qs)
- );
-
-
- // R[prio28]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio28 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio28_we),
- .wd (prio28_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio28.q ),
-
- // to register interface (read)
- .qs (prio28_qs)
- );
-
-
- // R[prio29]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio29 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio29_we),
- .wd (prio29_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio29.q ),
-
- // to register interface (read)
- .qs (prio29_qs)
- );
-
-
- // R[prio30]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio30 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio30_we),
- .wd (prio30_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio30.q ),
-
- // to register interface (read)
- .qs (prio30_qs)
- );
-
-
- // R[prio31]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio31 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio31_we),
- .wd (prio31_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio31.q ),
-
- // to register interface (read)
- .qs (prio31_qs)
- );
-
-
- // R[prio32]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio32 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio32_we),
- .wd (prio32_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio32.q ),
-
- // to register interface (read)
- .qs (prio32_qs)
- );
-
-
- // R[prio33]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio33 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio33_we),
- .wd (prio33_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio33.q ),
-
- // to register interface (read)
- .qs (prio33_qs)
- );
-
-
- // R[prio34]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio34 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio34_we),
- .wd (prio34_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio34.q ),
-
- // to register interface (read)
- .qs (prio34_qs)
- );
-
-
- // R[prio35]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio35 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio35_we),
- .wd (prio35_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio35.q ),
-
- // to register interface (read)
- .qs (prio35_qs)
- );
-
-
- // R[prio36]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio36 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio36_we),
- .wd (prio36_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio36.q ),
-
- // to register interface (read)
- .qs (prio36_qs)
- );
-
-
- // R[prio37]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio37 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio37_we),
- .wd (prio37_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio37.q ),
-
- // to register interface (read)
- .qs (prio37_qs)
- );
-
-
- // R[prio38]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio38 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio38_we),
- .wd (prio38_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio38.q ),
-
- // to register interface (read)
- .qs (prio38_qs)
- );
-
-
- // R[prio39]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio39 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio39_we),
- .wd (prio39_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio39.q ),
-
- // to register interface (read)
- .qs (prio39_qs)
- );
-
-
- // R[prio40]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio40 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio40_we),
- .wd (prio40_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio40.q ),
-
- // to register interface (read)
- .qs (prio40_qs)
- );
-
-
- // R[prio41]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio41 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio41_we),
- .wd (prio41_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio41.q ),
-
- // to register interface (read)
- .qs (prio41_qs)
- );
-
-
- // R[prio42]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio42 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio42_we),
- .wd (prio42_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio42.q ),
-
- // to register interface (read)
- .qs (prio42_qs)
- );
-
-
- // R[prio43]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_prio43 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (prio43_we),
- .wd (prio43_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.prio43.q ),
-
- // to register interface (read)
- .qs (prio43_qs)
- );
-
- // Subregister 0 of Multireg ie0
- // R[ie0_0]: V(False)
-
- // F[e_0]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_0_we),
- .wd (ie0_0_e_0_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[0].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_0_qs)
- );
-
-
- // F[e_1]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_1 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_1_we),
- .wd (ie0_0_e_1_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[1].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_1_qs)
- );
-
-
- // F[e_2]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_2 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_2_we),
- .wd (ie0_0_e_2_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[2].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_2_qs)
- );
-
-
- // F[e_3]: 3:3
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_3 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_3_we),
- .wd (ie0_0_e_3_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[3].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_3_qs)
- );
-
-
- // F[e_4]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_4 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_4_we),
- .wd (ie0_0_e_4_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[4].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_4_qs)
- );
-
-
- // F[e_5]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_5 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_5_we),
- .wd (ie0_0_e_5_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[5].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_5_qs)
- );
-
-
- // F[e_6]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_6 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_6_we),
- .wd (ie0_0_e_6_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[6].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_6_qs)
- );
-
-
- // F[e_7]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_7 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_7_we),
- .wd (ie0_0_e_7_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[7].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_7_qs)
- );
-
-
- // F[e_8]: 8:8
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_8 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_8_we),
- .wd (ie0_0_e_8_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[8].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_8_qs)
- );
-
-
- // F[e_9]: 9:9
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_9 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_9_we),
- .wd (ie0_0_e_9_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[9].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_9_qs)
- );
-
-
- // F[e_10]: 10:10
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_10 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_10_we),
- .wd (ie0_0_e_10_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[10].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_10_qs)
- );
-
-
- // F[e_11]: 11:11
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_11 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_11_we),
- .wd (ie0_0_e_11_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[11].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_11_qs)
- );
-
-
- // F[e_12]: 12:12
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_12 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_12_we),
- .wd (ie0_0_e_12_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[12].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_12_qs)
- );
-
-
- // F[e_13]: 13:13
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_13 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_13_we),
- .wd (ie0_0_e_13_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[13].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_13_qs)
- );
-
-
- // F[e_14]: 14:14
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_14 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_14_we),
- .wd (ie0_0_e_14_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[14].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_14_qs)
- );
-
-
- // F[e_15]: 15:15
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_15 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_15_we),
- .wd (ie0_0_e_15_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[15].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_15_qs)
- );
-
-
- // F[e_16]: 16:16
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_16 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_16_we),
- .wd (ie0_0_e_16_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[16].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_16_qs)
- );
-
-
- // F[e_17]: 17:17
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_17 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_17_we),
- .wd (ie0_0_e_17_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[17].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_17_qs)
- );
-
-
- // F[e_18]: 18:18
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_18 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_18_we),
- .wd (ie0_0_e_18_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[18].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_18_qs)
- );
-
-
- // F[e_19]: 19:19
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_19 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_19_we),
- .wd (ie0_0_e_19_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[19].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_19_qs)
- );
-
-
- // F[e_20]: 20:20
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_20 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_20_we),
- .wd (ie0_0_e_20_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[20].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_20_qs)
- );
-
-
- // F[e_21]: 21:21
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_21 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_21_we),
- .wd (ie0_0_e_21_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[21].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_21_qs)
- );
-
-
- // F[e_22]: 22:22
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_22 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_22_we),
- .wd (ie0_0_e_22_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[22].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_22_qs)
- );
-
-
- // F[e_23]: 23:23
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_23 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_23_we),
- .wd (ie0_0_e_23_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[23].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_23_qs)
- );
-
-
- // F[e_24]: 24:24
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_24 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_24_we),
- .wd (ie0_0_e_24_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[24].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_24_qs)
- );
-
-
- // F[e_25]: 25:25
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_25 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_25_we),
- .wd (ie0_0_e_25_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[25].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_25_qs)
- );
-
-
- // F[e_26]: 26:26
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_26 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_26_we),
- .wd (ie0_0_e_26_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[26].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_26_qs)
- );
-
-
- // F[e_27]: 27:27
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_27 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_27_we),
- .wd (ie0_0_e_27_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[27].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_27_qs)
- );
-
-
- // F[e_28]: 28:28
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_28 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_28_we),
- .wd (ie0_0_e_28_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[28].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_28_qs)
- );
-
-
- // F[e_29]: 29:29
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_29 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_29_we),
- .wd (ie0_0_e_29_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[29].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_29_qs)
- );
-
-
- // F[e_30]: 30:30
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_30 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_30_we),
- .wd (ie0_0_e_30_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[30].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_30_qs)
- );
-
-
- // F[e_31]: 31:31
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_0_e_31 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_0_e_31_we),
- .wd (ie0_0_e_31_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[31].q ),
-
- // to register interface (read)
- .qs (ie0_0_e_31_qs)
- );
-
-
- // Subregister 32 of Multireg ie0
- // R[ie0_1]: V(False)
-
- // F[e_32]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_32 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_32_we),
- .wd (ie0_1_e_32_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[32].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_32_qs)
- );
-
-
- // F[e_33]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_33 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_33_we),
- .wd (ie0_1_e_33_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[33].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_33_qs)
- );
-
-
- // F[e_34]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_34 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_34_we),
- .wd (ie0_1_e_34_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[34].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_34_qs)
- );
-
-
- // F[e_35]: 3:3
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_35 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_35_we),
- .wd (ie0_1_e_35_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[35].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_35_qs)
- );
-
-
- // F[e_36]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_36 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_36_we),
- .wd (ie0_1_e_36_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[36].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_36_qs)
- );
-
-
- // F[e_37]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_37 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_37_we),
- .wd (ie0_1_e_37_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[37].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_37_qs)
- );
-
-
- // F[e_38]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_38 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_38_we),
- .wd (ie0_1_e_38_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[38].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_38_qs)
- );
-
-
- // F[e_39]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_39 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_39_we),
- .wd (ie0_1_e_39_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[39].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_39_qs)
- );
-
-
- // F[e_40]: 8:8
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_40 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_40_we),
- .wd (ie0_1_e_40_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[40].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_40_qs)
- );
-
-
- // F[e_41]: 9:9
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_41 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_41_we),
- .wd (ie0_1_e_41_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[41].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_41_qs)
- );
-
-
- // F[e_42]: 10:10
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_42 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_42_we),
- .wd (ie0_1_e_42_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[42].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_42_qs)
- );
-
-
- // F[e_43]: 11:11
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ie0_1_e_43 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ie0_1_e_43_we),
- .wd (ie0_1_e_43_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ie0[43].q ),
-
- // to register interface (read)
- .qs (ie0_1_e_43_qs)
- );
-
- // R[threshold0]: V(False)
-
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_threshold0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (threshold0_we),
- .wd (threshold0_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.threshold0.q ),
-
- // to register interface (read)
- .qs (threshold0_qs)
- );
-
-
- // R[cc0]: V(True)
-
- prim_subreg_ext #(
- .DW (6)
- ) u_cc0 (
- .re (cc0_re),
- .we (cc0_we),
- .wd (cc0_wd),
- .d (hw2reg.cc0.d),
- .qre (reg2hw.cc0.re),
- .qe (reg2hw.cc0.qe),
- .q (reg2hw.cc0.q ),
- .qs (cc0_qs)
- );
-
-
- // R[msip0]: V(False)
-
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_msip0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (msip0_we),
- .wd (msip0_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.msip0.q ),
-
- // to register interface (read)
- .qs (msip0_qs)
- );
-
-
-
-
- logic [52:0] addr_hit;
- always_comb begin
- addr_hit = '0;
- addr_hit[ 0] = (reg_addr == RV_PLIC_IP_0_OFFSET);
- addr_hit[ 1] = (reg_addr == RV_PLIC_IP_1_OFFSET);
- addr_hit[ 2] = (reg_addr == RV_PLIC_LE_0_OFFSET);
- addr_hit[ 3] = (reg_addr == RV_PLIC_LE_1_OFFSET);
- addr_hit[ 4] = (reg_addr == RV_PLIC_PRIO0_OFFSET);
- addr_hit[ 5] = (reg_addr == RV_PLIC_PRIO1_OFFSET);
- addr_hit[ 6] = (reg_addr == RV_PLIC_PRIO2_OFFSET);
- addr_hit[ 7] = (reg_addr == RV_PLIC_PRIO3_OFFSET);
- addr_hit[ 8] = (reg_addr == RV_PLIC_PRIO4_OFFSET);
- addr_hit[ 9] = (reg_addr == RV_PLIC_PRIO5_OFFSET);
- addr_hit[ 10] = (reg_addr == RV_PLIC_PRIO6_OFFSET);
- addr_hit[ 11] = (reg_addr == RV_PLIC_PRIO7_OFFSET);
- addr_hit[ 12] = (reg_addr == RV_PLIC_PRIO8_OFFSET);
- addr_hit[ 13] = (reg_addr == RV_PLIC_PRIO9_OFFSET);
- addr_hit[ 14] = (reg_addr == RV_PLIC_PRIO10_OFFSET);
- addr_hit[ 15] = (reg_addr == RV_PLIC_PRIO11_OFFSET);
- addr_hit[ 16] = (reg_addr == RV_PLIC_PRIO12_OFFSET);
- addr_hit[ 17] = (reg_addr == RV_PLIC_PRIO13_OFFSET);
- addr_hit[ 18] = (reg_addr == RV_PLIC_PRIO14_OFFSET);
- addr_hit[ 19] = (reg_addr == RV_PLIC_PRIO15_OFFSET);
- addr_hit[ 20] = (reg_addr == RV_PLIC_PRIO16_OFFSET);
- addr_hit[ 21] = (reg_addr == RV_PLIC_PRIO17_OFFSET);
- addr_hit[ 22] = (reg_addr == RV_PLIC_PRIO18_OFFSET);
- addr_hit[ 23] = (reg_addr == RV_PLIC_PRIO19_OFFSET);
- addr_hit[ 24] = (reg_addr == RV_PLIC_PRIO20_OFFSET);
- addr_hit[ 25] = (reg_addr == RV_PLIC_PRIO21_OFFSET);
- addr_hit[ 26] = (reg_addr == RV_PLIC_PRIO22_OFFSET);
- addr_hit[ 27] = (reg_addr == RV_PLIC_PRIO23_OFFSET);
- addr_hit[ 28] = (reg_addr == RV_PLIC_PRIO24_OFFSET);
- addr_hit[ 29] = (reg_addr == RV_PLIC_PRIO25_OFFSET);
- addr_hit[ 30] = (reg_addr == RV_PLIC_PRIO26_OFFSET);
- addr_hit[ 31] = (reg_addr == RV_PLIC_PRIO27_OFFSET);
- addr_hit[ 32] = (reg_addr == RV_PLIC_PRIO28_OFFSET);
- addr_hit[ 33] = (reg_addr == RV_PLIC_PRIO29_OFFSET);
- addr_hit[ 34] = (reg_addr == RV_PLIC_PRIO30_OFFSET);
- addr_hit[ 35] = (reg_addr == RV_PLIC_PRIO31_OFFSET);
- addr_hit[ 36] = (reg_addr == RV_PLIC_PRIO32_OFFSET);
- addr_hit[ 37] = (reg_addr == RV_PLIC_PRIO33_OFFSET);
- addr_hit[ 38] = (reg_addr == RV_PLIC_PRIO34_OFFSET);
- addr_hit[ 39] = (reg_addr == RV_PLIC_PRIO35_OFFSET);
- addr_hit[ 40] = (reg_addr == RV_PLIC_PRIO36_OFFSET);
- addr_hit[ 41] = (reg_addr == RV_PLIC_PRIO37_OFFSET);
- addr_hit[ 42] = (reg_addr == RV_PLIC_PRIO38_OFFSET);
- addr_hit[ 43] = (reg_addr == RV_PLIC_PRIO39_OFFSET);
- addr_hit[ 44] = (reg_addr == RV_PLIC_PRIO40_OFFSET);
- addr_hit[ 45] = (reg_addr == RV_PLIC_PRIO41_OFFSET);
- addr_hit[ 46] = (reg_addr == RV_PLIC_PRIO42_OFFSET);
- addr_hit[ 47] = (reg_addr == RV_PLIC_PRIO43_OFFSET);
- addr_hit[ 48] = (reg_addr == RV_PLIC_IE0_0_OFFSET);
- addr_hit[ 49] = (reg_addr == RV_PLIC_IE0_1_OFFSET);
- addr_hit[ 50] = (reg_addr == RV_PLIC_THRESHOLD0_OFFSET);
- addr_hit[ 51] = (reg_addr == RV_PLIC_CC0_OFFSET);
- addr_hit[ 52] = (reg_addr == RV_PLIC_MSIP0_OFFSET);
- end
-
- assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
-
- // Check sub-word write is permitted
- always_comb begin
- wr_err = 1'b0;
- if (addr_hit[ 0] && reg_we && (RV_PLIC_PERMIT[ 0] != (RV_PLIC_PERMIT[ 0] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 1] && reg_we && (RV_PLIC_PERMIT[ 1] != (RV_PLIC_PERMIT[ 1] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 2] && reg_we && (RV_PLIC_PERMIT[ 2] != (RV_PLIC_PERMIT[ 2] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 3] && reg_we && (RV_PLIC_PERMIT[ 3] != (RV_PLIC_PERMIT[ 3] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 4] && reg_we && (RV_PLIC_PERMIT[ 4] != (RV_PLIC_PERMIT[ 4] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 5] && reg_we && (RV_PLIC_PERMIT[ 5] != (RV_PLIC_PERMIT[ 5] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 6] && reg_we && (RV_PLIC_PERMIT[ 6] != (RV_PLIC_PERMIT[ 6] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 7] && reg_we && (RV_PLIC_PERMIT[ 7] != (RV_PLIC_PERMIT[ 7] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 8] && reg_we && (RV_PLIC_PERMIT[ 8] != (RV_PLIC_PERMIT[ 8] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 9] && reg_we && (RV_PLIC_PERMIT[ 9] != (RV_PLIC_PERMIT[ 9] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 10] && reg_we && (RV_PLIC_PERMIT[ 10] != (RV_PLIC_PERMIT[ 10] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 11] && reg_we && (RV_PLIC_PERMIT[ 11] != (RV_PLIC_PERMIT[ 11] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 12] && reg_we && (RV_PLIC_PERMIT[ 12] != (RV_PLIC_PERMIT[ 12] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 13] && reg_we && (RV_PLIC_PERMIT[ 13] != (RV_PLIC_PERMIT[ 13] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 14] && reg_we && (RV_PLIC_PERMIT[ 14] != (RV_PLIC_PERMIT[ 14] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 15] && reg_we && (RV_PLIC_PERMIT[ 15] != (RV_PLIC_PERMIT[ 15] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 16] && reg_we && (RV_PLIC_PERMIT[ 16] != (RV_PLIC_PERMIT[ 16] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 17] && reg_we && (RV_PLIC_PERMIT[ 17] != (RV_PLIC_PERMIT[ 17] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 18] && reg_we && (RV_PLIC_PERMIT[ 18] != (RV_PLIC_PERMIT[ 18] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 19] && reg_we && (RV_PLIC_PERMIT[ 19] != (RV_PLIC_PERMIT[ 19] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 20] && reg_we && (RV_PLIC_PERMIT[ 20] != (RV_PLIC_PERMIT[ 20] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 21] && reg_we && (RV_PLIC_PERMIT[ 21] != (RV_PLIC_PERMIT[ 21] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 22] && reg_we && (RV_PLIC_PERMIT[ 22] != (RV_PLIC_PERMIT[ 22] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 23] && reg_we && (RV_PLIC_PERMIT[ 23] != (RV_PLIC_PERMIT[ 23] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 24] && reg_we && (RV_PLIC_PERMIT[ 24] != (RV_PLIC_PERMIT[ 24] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 25] && reg_we && (RV_PLIC_PERMIT[ 25] != (RV_PLIC_PERMIT[ 25] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 26] && reg_we && (RV_PLIC_PERMIT[ 26] != (RV_PLIC_PERMIT[ 26] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 27] && reg_we && (RV_PLIC_PERMIT[ 27] != (RV_PLIC_PERMIT[ 27] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 28] && reg_we && (RV_PLIC_PERMIT[ 28] != (RV_PLIC_PERMIT[ 28] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 29] && reg_we && (RV_PLIC_PERMIT[ 29] != (RV_PLIC_PERMIT[ 29] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 30] && reg_we && (RV_PLIC_PERMIT[ 30] != (RV_PLIC_PERMIT[ 30] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 31] && reg_we && (RV_PLIC_PERMIT[ 31] != (RV_PLIC_PERMIT[ 31] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 32] && reg_we && (RV_PLIC_PERMIT[ 32] != (RV_PLIC_PERMIT[ 32] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 33] && reg_we && (RV_PLIC_PERMIT[ 33] != (RV_PLIC_PERMIT[ 33] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 34] && reg_we && (RV_PLIC_PERMIT[ 34] != (RV_PLIC_PERMIT[ 34] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 35] && reg_we && (RV_PLIC_PERMIT[ 35] != (RV_PLIC_PERMIT[ 35] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 36] && reg_we && (RV_PLIC_PERMIT[ 36] != (RV_PLIC_PERMIT[ 36] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 37] && reg_we && (RV_PLIC_PERMIT[ 37] != (RV_PLIC_PERMIT[ 37] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 38] && reg_we && (RV_PLIC_PERMIT[ 38] != (RV_PLIC_PERMIT[ 38] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 39] && reg_we && (RV_PLIC_PERMIT[ 39] != (RV_PLIC_PERMIT[ 39] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 40] && reg_we && (RV_PLIC_PERMIT[ 40] != (RV_PLIC_PERMIT[ 40] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 41] && reg_we && (RV_PLIC_PERMIT[ 41] != (RV_PLIC_PERMIT[ 41] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 42] && reg_we && (RV_PLIC_PERMIT[ 42] != (RV_PLIC_PERMIT[ 42] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 43] && reg_we && (RV_PLIC_PERMIT[ 43] != (RV_PLIC_PERMIT[ 43] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 44] && reg_we && (RV_PLIC_PERMIT[ 44] != (RV_PLIC_PERMIT[ 44] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 45] && reg_we && (RV_PLIC_PERMIT[ 45] != (RV_PLIC_PERMIT[ 45] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 46] && reg_we && (RV_PLIC_PERMIT[ 46] != (RV_PLIC_PERMIT[ 46] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 47] && reg_we && (RV_PLIC_PERMIT[ 47] != (RV_PLIC_PERMIT[ 47] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 48] && reg_we && (RV_PLIC_PERMIT[ 48] != (RV_PLIC_PERMIT[ 48] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 49] && reg_we && (RV_PLIC_PERMIT[ 49] != (RV_PLIC_PERMIT[ 49] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 50] && reg_we && (RV_PLIC_PERMIT[ 50] != (RV_PLIC_PERMIT[ 50] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 51] && reg_we && (RV_PLIC_PERMIT[ 51] != (RV_PLIC_PERMIT[ 51] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 52] && reg_we && (RV_PLIC_PERMIT[ 52] != (RV_PLIC_PERMIT[ 52] & reg_be))) wr_err = 1'b1 ;
- end
-
-
-
-
-
-
- assign le_0_le_0_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_0_wd = reg_wdata[0];
-
- assign le_0_le_1_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_1_wd = reg_wdata[1];
-
- assign le_0_le_2_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_2_wd = reg_wdata[2];
-
- assign le_0_le_3_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_3_wd = reg_wdata[3];
-
- assign le_0_le_4_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_4_wd = reg_wdata[4];
-
- assign le_0_le_5_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_5_wd = reg_wdata[5];
-
- assign le_0_le_6_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_6_wd = reg_wdata[6];
-
- assign le_0_le_7_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_7_wd = reg_wdata[7];
-
- assign le_0_le_8_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_8_wd = reg_wdata[8];
-
- assign le_0_le_9_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_9_wd = reg_wdata[9];
-
- assign le_0_le_10_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_10_wd = reg_wdata[10];
-
- assign le_0_le_11_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_11_wd = reg_wdata[11];
-
- assign le_0_le_12_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_12_wd = reg_wdata[12];
-
- assign le_0_le_13_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_13_wd = reg_wdata[13];
-
- assign le_0_le_14_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_14_wd = reg_wdata[14];
-
- assign le_0_le_15_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_15_wd = reg_wdata[15];
-
- assign le_0_le_16_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_16_wd = reg_wdata[16];
-
- assign le_0_le_17_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_17_wd = reg_wdata[17];
-
- assign le_0_le_18_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_18_wd = reg_wdata[18];
-
- assign le_0_le_19_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_19_wd = reg_wdata[19];
-
- assign le_0_le_20_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_20_wd = reg_wdata[20];
-
- assign le_0_le_21_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_21_wd = reg_wdata[21];
-
- assign le_0_le_22_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_22_wd = reg_wdata[22];
-
- assign le_0_le_23_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_23_wd = reg_wdata[23];
-
- assign le_0_le_24_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_24_wd = reg_wdata[24];
-
- assign le_0_le_25_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_25_wd = reg_wdata[25];
-
- assign le_0_le_26_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_26_wd = reg_wdata[26];
-
- assign le_0_le_27_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_27_wd = reg_wdata[27];
-
- assign le_0_le_28_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_28_wd = reg_wdata[28];
-
- assign le_0_le_29_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_29_wd = reg_wdata[29];
-
- assign le_0_le_30_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_30_wd = reg_wdata[30];
-
- assign le_0_le_31_we = addr_hit[2] & reg_we & ~wr_err;
- assign le_0_le_31_wd = reg_wdata[31];
-
- assign le_1_le_32_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_32_wd = reg_wdata[0];
-
- assign le_1_le_33_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_33_wd = reg_wdata[1];
-
- assign le_1_le_34_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_34_wd = reg_wdata[2];
-
- assign le_1_le_35_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_35_wd = reg_wdata[3];
-
- assign le_1_le_36_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_36_wd = reg_wdata[4];
-
- assign le_1_le_37_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_37_wd = reg_wdata[5];
-
- assign le_1_le_38_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_38_wd = reg_wdata[6];
-
- assign le_1_le_39_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_39_wd = reg_wdata[7];
-
- assign le_1_le_40_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_40_wd = reg_wdata[8];
-
- assign le_1_le_41_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_41_wd = reg_wdata[9];
-
- assign le_1_le_42_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_42_wd = reg_wdata[10];
-
- assign le_1_le_43_we = addr_hit[3] & reg_we & ~wr_err;
- assign le_1_le_43_wd = reg_wdata[11];
-
- assign prio0_we = addr_hit[4] & reg_we & ~wr_err;
- assign prio0_wd = reg_wdata[1:0];
-
- assign prio1_we = addr_hit[5] & reg_we & ~wr_err;
- assign prio1_wd = reg_wdata[1:0];
-
- assign prio2_we = addr_hit[6] & reg_we & ~wr_err;
- assign prio2_wd = reg_wdata[1:0];
-
- assign prio3_we = addr_hit[7] & reg_we & ~wr_err;
- assign prio3_wd = reg_wdata[1:0];
-
- assign prio4_we = addr_hit[8] & reg_we & ~wr_err;
- assign prio4_wd = reg_wdata[1:0];
-
- assign prio5_we = addr_hit[9] & reg_we & ~wr_err;
- assign prio5_wd = reg_wdata[1:0];
-
- assign prio6_we = addr_hit[10] & reg_we & ~wr_err;
- assign prio6_wd = reg_wdata[1:0];
-
- assign prio7_we = addr_hit[11] & reg_we & ~wr_err;
- assign prio7_wd = reg_wdata[1:0];
-
- assign prio8_we = addr_hit[12] & reg_we & ~wr_err;
- assign prio8_wd = reg_wdata[1:0];
-
- assign prio9_we = addr_hit[13] & reg_we & ~wr_err;
- assign prio9_wd = reg_wdata[1:0];
-
- assign prio10_we = addr_hit[14] & reg_we & ~wr_err;
- assign prio10_wd = reg_wdata[1:0];
-
- assign prio11_we = addr_hit[15] & reg_we & ~wr_err;
- assign prio11_wd = reg_wdata[1:0];
-
- assign prio12_we = addr_hit[16] & reg_we & ~wr_err;
- assign prio12_wd = reg_wdata[1:0];
-
- assign prio13_we = addr_hit[17] & reg_we & ~wr_err;
- assign prio13_wd = reg_wdata[1:0];
-
- assign prio14_we = addr_hit[18] & reg_we & ~wr_err;
- assign prio14_wd = reg_wdata[1:0];
-
- assign prio15_we = addr_hit[19] & reg_we & ~wr_err;
- assign prio15_wd = reg_wdata[1:0];
-
- assign prio16_we = addr_hit[20] & reg_we & ~wr_err;
- assign prio16_wd = reg_wdata[1:0];
-
- assign prio17_we = addr_hit[21] & reg_we & ~wr_err;
- assign prio17_wd = reg_wdata[1:0];
-
- assign prio18_we = addr_hit[22] & reg_we & ~wr_err;
- assign prio18_wd = reg_wdata[1:0];
-
- assign prio19_we = addr_hit[23] & reg_we & ~wr_err;
- assign prio19_wd = reg_wdata[1:0];
-
- assign prio20_we = addr_hit[24] & reg_we & ~wr_err;
- assign prio20_wd = reg_wdata[1:0];
-
- assign prio21_we = addr_hit[25] & reg_we & ~wr_err;
- assign prio21_wd = reg_wdata[1:0];
-
- assign prio22_we = addr_hit[26] & reg_we & ~wr_err;
- assign prio22_wd = reg_wdata[1:0];
-
- assign prio23_we = addr_hit[27] & reg_we & ~wr_err;
- assign prio23_wd = reg_wdata[1:0];
-
- assign prio24_we = addr_hit[28] & reg_we & ~wr_err;
- assign prio24_wd = reg_wdata[1:0];
-
- assign prio25_we = addr_hit[29] & reg_we & ~wr_err;
- assign prio25_wd = reg_wdata[1:0];
-
- assign prio26_we = addr_hit[30] & reg_we & ~wr_err;
- assign prio26_wd = reg_wdata[1:0];
-
- assign prio27_we = addr_hit[31] & reg_we & ~wr_err;
- assign prio27_wd = reg_wdata[1:0];
-
- assign prio28_we = addr_hit[32] & reg_we & ~wr_err;
- assign prio28_wd = reg_wdata[1:0];
-
- assign prio29_we = addr_hit[33] & reg_we & ~wr_err;
- assign prio29_wd = reg_wdata[1:0];
-
- assign prio30_we = addr_hit[34] & reg_we & ~wr_err;
- assign prio30_wd = reg_wdata[1:0];
-
- assign prio31_we = addr_hit[35] & reg_we & ~wr_err;
- assign prio31_wd = reg_wdata[1:0];
-
- assign prio32_we = addr_hit[36] & reg_we & ~wr_err;
- assign prio32_wd = reg_wdata[1:0];
-
- assign prio33_we = addr_hit[37] & reg_we & ~wr_err;
- assign prio33_wd = reg_wdata[1:0];
-
- assign prio34_we = addr_hit[38] & reg_we & ~wr_err;
- assign prio34_wd = reg_wdata[1:0];
-
- assign prio35_we = addr_hit[39] & reg_we & ~wr_err;
- assign prio35_wd = reg_wdata[1:0];
-
- assign prio36_we = addr_hit[40] & reg_we & ~wr_err;
- assign prio36_wd = reg_wdata[1:0];
-
- assign prio37_we = addr_hit[41] & reg_we & ~wr_err;
- assign prio37_wd = reg_wdata[1:0];
-
- assign prio38_we = addr_hit[42] & reg_we & ~wr_err;
- assign prio38_wd = reg_wdata[1:0];
-
- assign prio39_we = addr_hit[43] & reg_we & ~wr_err;
- assign prio39_wd = reg_wdata[1:0];
-
- assign prio40_we = addr_hit[44] & reg_we & ~wr_err;
- assign prio40_wd = reg_wdata[1:0];
-
- assign prio41_we = addr_hit[45] & reg_we & ~wr_err;
- assign prio41_wd = reg_wdata[1:0];
-
- assign prio42_we = addr_hit[46] & reg_we & ~wr_err;
- assign prio42_wd = reg_wdata[1:0];
-
- assign prio43_we = addr_hit[47] & reg_we & ~wr_err;
- assign prio43_wd = reg_wdata[1:0];
-
- assign ie0_0_e_0_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_0_wd = reg_wdata[0];
-
- assign ie0_0_e_1_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_1_wd = reg_wdata[1];
-
- assign ie0_0_e_2_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_2_wd = reg_wdata[2];
-
- assign ie0_0_e_3_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_3_wd = reg_wdata[3];
-
- assign ie0_0_e_4_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_4_wd = reg_wdata[4];
-
- assign ie0_0_e_5_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_5_wd = reg_wdata[5];
-
- assign ie0_0_e_6_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_6_wd = reg_wdata[6];
-
- assign ie0_0_e_7_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_7_wd = reg_wdata[7];
-
- assign ie0_0_e_8_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_8_wd = reg_wdata[8];
-
- assign ie0_0_e_9_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_9_wd = reg_wdata[9];
-
- assign ie0_0_e_10_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_10_wd = reg_wdata[10];
-
- assign ie0_0_e_11_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_11_wd = reg_wdata[11];
-
- assign ie0_0_e_12_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_12_wd = reg_wdata[12];
-
- assign ie0_0_e_13_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_13_wd = reg_wdata[13];
-
- assign ie0_0_e_14_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_14_wd = reg_wdata[14];
-
- assign ie0_0_e_15_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_15_wd = reg_wdata[15];
-
- assign ie0_0_e_16_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_16_wd = reg_wdata[16];
-
- assign ie0_0_e_17_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_17_wd = reg_wdata[17];
-
- assign ie0_0_e_18_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_18_wd = reg_wdata[18];
-
- assign ie0_0_e_19_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_19_wd = reg_wdata[19];
-
- assign ie0_0_e_20_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_20_wd = reg_wdata[20];
-
- assign ie0_0_e_21_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_21_wd = reg_wdata[21];
-
- assign ie0_0_e_22_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_22_wd = reg_wdata[22];
-
- assign ie0_0_e_23_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_23_wd = reg_wdata[23];
-
- assign ie0_0_e_24_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_24_wd = reg_wdata[24];
-
- assign ie0_0_e_25_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_25_wd = reg_wdata[25];
-
- assign ie0_0_e_26_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_26_wd = reg_wdata[26];
-
- assign ie0_0_e_27_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_27_wd = reg_wdata[27];
-
- assign ie0_0_e_28_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_28_wd = reg_wdata[28];
-
- assign ie0_0_e_29_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_29_wd = reg_wdata[29];
-
- assign ie0_0_e_30_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_30_wd = reg_wdata[30];
-
- assign ie0_0_e_31_we = addr_hit[48] & reg_we & ~wr_err;
- assign ie0_0_e_31_wd = reg_wdata[31];
-
- assign ie0_1_e_32_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_32_wd = reg_wdata[0];
-
- assign ie0_1_e_33_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_33_wd = reg_wdata[1];
-
- assign ie0_1_e_34_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_34_wd = reg_wdata[2];
-
- assign ie0_1_e_35_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_35_wd = reg_wdata[3];
-
- assign ie0_1_e_36_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_36_wd = reg_wdata[4];
-
- assign ie0_1_e_37_we = addr_hit[6] & reg_we & ~wr_err;
- assign ie0_1_e_37_wd = reg_wdata[5];
-
- assign ie0_1_e_38_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_38_wd = reg_wdata[6];
-
- assign ie0_1_e_39_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_39_wd = reg_wdata[7];
-
- assign ie0_1_e_40_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_40_wd = reg_wdata[8];
-
- assign ie0_1_e_41_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_41_wd = reg_wdata[9];
-
- assign ie0_1_e_42_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_42_wd = reg_wdata[10];
-
- assign ie0_1_e_43_we = addr_hit[49] & reg_we & ~wr_err;
- assign ie0_1_e_43_wd = reg_wdata[11];
-
-
- assign threshold0_we = addr_hit[50] & reg_we & ~wr_err;
- assign threshold0_wd = reg_wdata[1:0];
-
- assign cc0_we = addr_hit[51] & reg_we & ~wr_err;
- assign cc0_wd = reg_wdata[7:0];
- assign cc0_re = addr_hit[51] && reg_re;
-
- assign msip0_we = addr_hit[52] & reg_we & ~wr_err;
- assign msip0_wd = reg_wdata[0];
-
- // Read data return
- always_comb begin
- reg_rdata_next = '0;
- unique case (1'b1)
- addr_hit[0]: begin
- reg_rdata_next[0] = ip_0_p_0_qs;
- reg_rdata_next[1] = ip_0_p_1_qs;
- reg_rdata_next[2] = ip_0_p_2_qs;
- reg_rdata_next[3] = ip_0_p_3_qs;
- reg_rdata_next[4] = ip_0_p_4_qs;
- reg_rdata_next[5] = ip_0_p_5_qs;
- reg_rdata_next[6] = ip_0_p_6_qs;
- reg_rdata_next[7] = ip_0_p_7_qs;
- reg_rdata_next[8] = ip_0_p_8_qs;
- reg_rdata_next[9] = ip_0_p_9_qs;
- reg_rdata_next[10] = ip_0_p_10_qs;
- reg_rdata_next[11] = ip_0_p_11_qs;
- reg_rdata_next[12] = ip_0_p_12_qs;
- reg_rdata_next[13] = ip_0_p_13_qs;
- reg_rdata_next[14] = ip_0_p_14_qs;
- reg_rdata_next[15] = ip_0_p_15_qs;
- reg_rdata_next[16] = ip_0_p_16_qs;
- reg_rdata_next[17] = ip_0_p_17_qs;
- reg_rdata_next[18] = ip_0_p_18_qs;
- reg_rdata_next[19] = ip_0_p_19_qs;
- reg_rdata_next[20] = ip_0_p_20_qs;
- reg_rdata_next[21] = ip_0_p_21_qs;
- reg_rdata_next[22] = ip_0_p_22_qs;
- reg_rdata_next[23] = ip_0_p_23_qs;
- reg_rdata_next[24] = ip_0_p_24_qs;
- reg_rdata_next[25] = ip_0_p_25_qs;
- reg_rdata_next[26] = ip_0_p_26_qs;
- reg_rdata_next[27] = ip_0_p_27_qs;
- reg_rdata_next[28] = ip_0_p_28_qs;
- reg_rdata_next[29] = ip_0_p_29_qs;
- reg_rdata_next[30] = ip_0_p_30_qs;
- reg_rdata_next[31] = ip_0_p_31_qs;
- end
-
- addr_hit[1]: begin
- reg_rdata_next[0] = ip_1_p_32_qs;
- reg_rdata_next[1] = ip_1_p_33_qs;
- reg_rdata_next[2] = ip_1_p_34_qs;
- reg_rdata_next[3] = ip_1_p_35_qs;
- reg_rdata_next[4] = ip_1_p_36_qs;
- reg_rdata_next[5] = ip_1_p_37_qs;
- reg_rdata_next[6] = ip_1_p_38_qs;
- reg_rdata_next[7] = ip_1_p_39_qs;
- reg_rdata_next[8] = ip_1_p_40_qs;
- reg_rdata_next[9] = ip_1_p_41_qs;
- reg_rdata_next[10] = ip_1_p_42_qs;
- reg_rdata_next[11] = ip_1_p_43_qs;
- end
- addr_hit[2]: begin
- reg_rdata_next[0] = le_0_le_0_qs;
- reg_rdata_next[1] = le_0_le_1_qs;
- reg_rdata_next[2] = le_0_le_2_qs;
- reg_rdata_next[3] = le_0_le_3_qs;
- reg_rdata_next[4] = le_0_le_4_qs;
- reg_rdata_next[5] = le_0_le_5_qs;
- reg_rdata_next[6] = le_0_le_6_qs;
- reg_rdata_next[7] = le_0_le_7_qs;
- reg_rdata_next[8] = le_0_le_8_qs;
- reg_rdata_next[9] = le_0_le_9_qs;
- reg_rdata_next[10] = le_0_le_10_qs;
- reg_rdata_next[11] = le_0_le_11_qs;
- reg_rdata_next[12] = le_0_le_12_qs;
- reg_rdata_next[13] = le_0_le_13_qs;
- reg_rdata_next[14] = le_0_le_14_qs;
- reg_rdata_next[15] = le_0_le_15_qs;
- reg_rdata_next[16] = le_0_le_16_qs;
- reg_rdata_next[17] = le_0_le_17_qs;
- reg_rdata_next[18] = le_0_le_18_qs;
- reg_rdata_next[19] = le_0_le_19_qs;
- reg_rdata_next[20] = le_0_le_20_qs;
- reg_rdata_next[21] = le_0_le_21_qs;
- reg_rdata_next[22] = le_0_le_22_qs;
- reg_rdata_next[23] = le_0_le_23_qs;
- reg_rdata_next[24] = le_0_le_24_qs;
- reg_rdata_next[25] = le_0_le_25_qs;
- reg_rdata_next[26] = le_0_le_26_qs;
- reg_rdata_next[27] = le_0_le_27_qs;
- reg_rdata_next[28] = le_0_le_28_qs;
- reg_rdata_next[29] = le_0_le_29_qs;
- reg_rdata_next[30] = le_0_le_30_qs;
- reg_rdata_next[31] = le_0_le_31_qs;
- end
-
- addr_hit[3]: begin
- reg_rdata_next[0] = le_1_le_32_qs;
- reg_rdata_next[1] = le_1_le_33_qs;
- reg_rdata_next[2] = le_1_le_34_qs;
- reg_rdata_next[3] = le_1_le_35_qs;
- reg_rdata_next[4] = le_1_le_36_qs;
- reg_rdata_next[5] = le_1_le_37_qs;
- reg_rdata_next[6] = le_1_le_38_qs;
- reg_rdata_next[7] = le_1_le_39_qs;
- reg_rdata_next[8] = le_1_le_40_qs;
- reg_rdata_next[9] = le_1_le_41_qs;
- reg_rdata_next[10] = le_1_le_42_qs;
- reg_rdata_next[11] = le_1_le_43_qs;
- end
- addr_hit[4]: begin
- reg_rdata_next[1:0] = prio0_qs;
- end
-
- addr_hit[5]: begin
- reg_rdata_next[1:0] = prio1_qs;
- end
-
- addr_hit[6]: begin
- reg_rdata_next[1:0] = prio2_qs;
- end
-
- addr_hit[7]: begin
- reg_rdata_next[1:0] = prio3_qs;
- end
-
- addr_hit[8]: begin
- reg_rdata_next[1:0] = prio4_qs;
- end
-
- addr_hit[9]: begin
- reg_rdata_next[1:0] = prio5_qs;
- end
-
- addr_hit[10]: begin
- reg_rdata_next[1:0] = prio6_qs;
- end
-
- addr_hit[11]: begin
- reg_rdata_next[1:0] = prio7_qs;
- end
-
- addr_hit[12]: begin
- reg_rdata_next[1:0] = prio8_qs;
- end
-
- addr_hit[13]: begin
- reg_rdata_next[1:0] = prio9_qs;
- end
-
- addr_hit[14]: begin
- reg_rdata_next[1:0] = prio10_qs;
- end
-
- addr_hit[15]: begin
- reg_rdata_next[1:0] = prio11_qs;
- end
-
- addr_hit[16]: begin
- reg_rdata_next[1:0] = prio12_qs;
- end
-
- addr_hit[17]: begin
- reg_rdata_next[1:0] = prio13_qs;
- end
-
- addr_hit[18]: begin
- reg_rdata_next[1:0] = prio14_qs;
- end
-
- addr_hit[19]: begin
- reg_rdata_next[1:0] = prio15_qs;
- end
-
- addr_hit[20]: begin
- reg_rdata_next[1:0] = prio16_qs;
- end
-
- addr_hit[21]: begin
- reg_rdata_next[1:0] = prio17_qs;
- end
-
- addr_hit[22]: begin
- reg_rdata_next[1:0] = prio18_qs;
- end
-
- addr_hit[23]: begin
- reg_rdata_next[1:0] = prio19_qs;
- end
-
- addr_hit[24]: begin
- reg_rdata_next[1:0] = prio20_qs;
- end
-
- addr_hit[25]: begin
- reg_rdata_next[1:0] = prio21_qs;
- end
-
- addr_hit[26]: begin
- reg_rdata_next[1:0] = prio22_qs;
- end
-
- addr_hit[27]: begin
- reg_rdata_next[1:0] = prio23_qs;
- end
-
- addr_hit[28]: begin
- reg_rdata_next[1:0] = prio24_qs;
- end
-
- addr_hit[29]: begin
- reg_rdata_next[1:0] = prio25_qs;
- end
-
- addr_hit[30]: begin
- reg_rdata_next[1:0] = prio26_qs;
- end
-
- addr_hit[31]: begin
- reg_rdata_next[1:0] = prio27_qs;
- end
-
- addr_hit[32]: begin
- reg_rdata_next[1:0] = prio28_qs;
- end
-
- addr_hit[33]: begin
- reg_rdata_next[1:0] = prio29_qs;
- end
-
- addr_hit[34]: begin
- reg_rdata_next[1:0] = prio30_qs;
- end
-
- addr_hit[35]: begin
- reg_rdata_next[1:0] = prio31_qs;
- end
-
- addr_hit[36]: begin
- reg_rdata_next[1:0] = prio32_qs;
- end
-
- addr_hit[37]: begin
- reg_rdata_next[1:0] = prio33_qs;
- end
-
- addr_hit[38]: begin
- reg_rdata_next[1:0] = prio34_qs;
- end
-
- addr_hit[39]: begin
- reg_rdata_next[1:0] = prio35_qs;
- end
-
- addr_hit[40]: begin
- reg_rdata_next[1:0] = prio36_qs;
- end
-
- addr_hit[41]: begin
- reg_rdata_next[1:0] = prio37_qs;
- end
-
- addr_hit[42]: begin
- reg_rdata_next[1:0] = prio38_qs;
- end
-
- addr_hit[43]: begin
- reg_rdata_next[1:0] = prio39_qs;
- end
-
- addr_hit[44]: begin
- reg_rdata_next[1:0] = prio40_qs;
- end
-
- addr_hit[45]: begin
- reg_rdata_next[1:0] = prio41_qs;
- end
-
- addr_hit[46]: begin
- reg_rdata_next[1:0] = prio42_qs;
- end
-
- addr_hit[47]: begin
- reg_rdata_next[1:0] = prio43_qs;
- end
-
- addr_hit[48]: begin
- reg_rdata_next[0] = ie0_0_e_0_qs;
- reg_rdata_next[1] = ie0_0_e_1_qs;
- reg_rdata_next[2] = ie0_0_e_2_qs;
- reg_rdata_next[3] = ie0_0_e_3_qs;
- reg_rdata_next[4] = ie0_0_e_4_qs;
- reg_rdata_next[5] = ie0_0_e_5_qs;
- reg_rdata_next[6] = ie0_0_e_6_qs;
- reg_rdata_next[7] = ie0_0_e_7_qs;
- reg_rdata_next[8] = ie0_0_e_8_qs;
- reg_rdata_next[9] = ie0_0_e_9_qs;
- reg_rdata_next[10] = ie0_0_e_10_qs;
- reg_rdata_next[11] = ie0_0_e_11_qs;
- reg_rdata_next[12] = ie0_0_e_12_qs;
- reg_rdata_next[13] = ie0_0_e_13_qs;
- reg_rdata_next[14] = ie0_0_e_14_qs;
- reg_rdata_next[15] = ie0_0_e_15_qs;
- reg_rdata_next[16] = ie0_0_e_16_qs;
- reg_rdata_next[17] = ie0_0_e_17_qs;
- reg_rdata_next[18] = ie0_0_e_18_qs;
- reg_rdata_next[19] = ie0_0_e_19_qs;
- reg_rdata_next[20] = ie0_0_e_20_qs;
- reg_rdata_next[21] = ie0_0_e_21_qs;
- reg_rdata_next[22] = ie0_0_e_22_qs;
- reg_rdata_next[23] = ie0_0_e_23_qs;
- reg_rdata_next[24] = ie0_0_e_24_qs;
- reg_rdata_next[25] = ie0_0_e_25_qs;
- reg_rdata_next[26] = ie0_0_e_26_qs;
- reg_rdata_next[27] = ie0_0_e_27_qs;
- reg_rdata_next[28] = ie0_0_e_28_qs;
- reg_rdata_next[29] = ie0_0_e_29_qs;
- reg_rdata_next[30] = ie0_0_e_30_qs;
- reg_rdata_next[31] = ie0_0_e_31_qs;
- end
-
- addr_hit[49]: begin
- reg_rdata_next[0] = ie0_1_e_32_qs;
- reg_rdata_next[1] = ie0_1_e_33_qs;
- reg_rdata_next[2] = ie0_1_e_34_qs;
- reg_rdata_next[3] = ie0_1_e_35_qs;
- reg_rdata_next[4] = ie0_1_e_36_qs;
- reg_rdata_next[5] = ie0_1_e_37_qs;
- reg_rdata_next[6] = ie0_1_e_38_qs;
- reg_rdata_next[7] = ie0_1_e_39_qs;
- reg_rdata_next[8] = ie0_1_e_40_qs;
- reg_rdata_next[9] = ie0_1_e_41_qs;
- reg_rdata_next[10] = ie0_1_e_42_qs;
- reg_rdata_next[11] = ie0_1_e_43_qs;
- end
-
-
- addr_hit[50]: begin
- reg_rdata_next[1:0] = threshold0_qs;
- end
-
- addr_hit[51]: begin
- reg_rdata_next[7:0] = cc0_qs;
- end
-
- addr_hit[52]: begin
- reg_rdata_next[0] = msip0_qs;
- end
-
- default: begin
- reg_rdata_next = '1;
- end
- endcase
- end
-
-endmodule
diff --git a/verilog/rtl/rv_plic_target.sv b/verilog/rtl/rv_plic_target.sv
deleted file mode 100644
index 045c202..0000000
--- a/verilog/rtl/rv_plic_target.sv
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// RISC-V Platform-Level Interrupt Generator for Target
-//
-// This module basically doing IE & IP based on priority and threshold_i.
-// Keep in mind that increasing MAX_PRIO affects logic size a lot.
-//
-// The module implements a binary tree to find the maximal entry. the solution
-// has O(N) area and O(log(N)) delay complexity, and thus scales well with
-// many input sources.
-//
-
-
-module rv_plic_target #(
- parameter int N_SOURCE = 32,
- parameter int MAX_PRIO = 7,
-
- // Local param (Do not change this through parameter
- localparam int SrcWidth = $clog2(N_SOURCE+1), // derived parameter
- localparam int PrioWidth = $clog2(MAX_PRIO+1) // derived parameter
-) (
- input clk_i,
- input rst_ni,
-
- input [N_SOURCE-1:0] ip_i,
- input [N_SOURCE-1:0] ie_i,
-
- input [PrioWidth-1:0] prio_i [N_SOURCE],
- input [PrioWidth-1:0] threshold_i,
-
- output logic irq_o,
- output logic [SrcWidth-1:0] irq_id_o
-);
-
- // this only works with 2 or more sources
-
-
- // align to powers of 2 for simplicity
- // a full binary tree with N levels has 2**N + 2**N-1 nodes
- localparam int NumLevels = $clog2(N_SOURCE);
- logic [2**(NumLevels+1)-2:0] is_tree;
- logic [2**(NumLevels+1)-2:0][SrcWidth-1:0] id_tree;
- logic [2**(NumLevels+1)-2:0][PrioWidth-1:0] max_tree;
-
- for (genvar level = 0; level < NumLevels+1; level++) begin : gen_tree
- //
- // level+1 C0 C1 <- "Base1" points to the first node on "level+1",
- // \ / these nodes are the children of the nodes one level below
- // level Pa <- "Base0", points to the first node on "level",
- // these nodes are the parents of the nodes one level above
- //
- // hence we have the following indices for the paPa, C0, C1 nodes:
- // Pa = 2**level - 1 + offset = Base0 + offset
- // C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset
- // C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1
- //
- localparam int Base0 = (2**level)-1;
- localparam int Base1 = (2**(level+1))-1;
-
- for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level
- localparam int Pa = Base0 + offset;
- localparam int C0 = Base1 + 2*offset;
- localparam int C1 = Base1 + 2*offset + 1;
-
- // this assigns the gated interrupt source signals, their
- // corresponding IDs and priorities to the tree leafs
- if (level == NumLevels) begin : gen_leafs
- if (offset < N_SOURCE) begin : gen_assign
- assign is_tree[Pa] = ip_i[offset] & ie_i[offset];
- assign id_tree[Pa] = offset;
- assign max_tree[Pa] = prio_i[offset];
- end else begin : gen_tie_off
- assign is_tree[Pa] = '0;
- assign id_tree[Pa] = '0;
- assign max_tree[Pa] = '0;
- end
- // this creates the node assignments
- end else begin : gen_nodes
- // NOTE: the code below has been written in this way in order to work
- // around a synthesis issue in Vivado 2018.3 and 2019.2 where the whole
- // module would be optimized away if these assign statements contained
- // ternary statements to implement the muxes.
- //
- // TODO: rewrite these lines with ternary statmements onec the problem
- // has been fixed in the tool.
- //
- // See also originating issue:
- // https://github.com/lowRISC/opentitan/issues/1355
- // Xilinx issue:
- // https://forums.xilinx.com/t5/Synthesis/Simulation-Synthesis-Mismatch-with-Vivado-2018-3/m-p/1065923#M33849
-
- logic sel; // local helper variable
- // in case only one of the parent has a pending irq_o, forward that one
- // in case both irqs are pending, forward the one with higher priority
- assign sel = (~is_tree[C0] & is_tree[C1]) |
- (is_tree[C0] & is_tree[C1] & logic'(max_tree[C1] > max_tree[C0]));
- // forwarding muxes
- assign is_tree[Pa] = (sel & is_tree[C1]) | ((~sel) & is_tree[C0]);
- assign id_tree[Pa] = ({SrcWidth{sel}} & id_tree[C1]) | ({SrcWidth{~sel}} & id_tree[C0]);
- assign max_tree[Pa] = ({PrioWidth{sel}} & max_tree[C1]) | ({PrioWidth{~sel}} & max_tree[C0]);
- end
- end : gen_level
- end : gen_tree
-
- logic irq_d, irq_q;
- logic [SrcWidth-1:0] irq_id_d, irq_id_q;
-
- // the results can be found at the tree root
- assign irq_d = (max_tree[0] > threshold_i) ? is_tree[0] : 1'b0;
- assign irq_id_d = (is_tree[0]) ? id_tree[0] : '0;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin : gen_regs
- if (!rst_ni) begin
- irq_q <= 1'b0;
- irq_id_q <= '0;
- end else begin
- irq_q <= irq_d;
- irq_id_q <= irq_id_d;
- end
- end
-
- assign irq_o = irq_q;
- assign irq_id_o = irq_id_q;
-
-endmodule
-
diff --git a/verilog/rtl/rv_timer.sv b/verilog/rtl/rv_timer.sv
deleted file mode 100644
index d88c28e..0000000
--- a/verilog/rtl/rv_timer.sv
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-
-
-
-
-module rv_timer (
- input clk_i,
- input rst_ni,
-
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
-
- output logic intr_timer_expired_0_0_o
-);
-
- localparam int N_HARTS = 1;
- localparam int N_TIMERS = 1;
-
- import rv_timer_reg_pkg::*;
-
- rv_timer_reg2hw_t reg2hw;
- rv_timer_hw2reg_t hw2reg;
-
- logic [N_HARTS-1:0] active;
-
- logic [11:0] prescaler [N_HARTS];
- logic [7:0] step [N_HARTS];
-
- logic [N_HARTS-1:0] tick;
-
- logic [63:0] mtime_d [N_HARTS];
- logic [63:0] mtime [N_HARTS];
- logic [63:0] mtimecmp [N_HARTS][N_TIMERS]; // Only [harts][0] is connected to mtimecmp CSRs
- logic mtimecmp_update [N_HARTS][N_TIMERS];
-
- logic [N_HARTS*N_TIMERS-1:0] intr_timer_set;
- logic [N_HARTS*N_TIMERS-1:0] intr_timer_en;
- logic [N_HARTS*N_TIMERS-1:0] intr_timer_test_q;
- logic [N_HARTS-1:0] intr_timer_test_qe;
- logic [N_HARTS*N_TIMERS-1:0] intr_timer_state_q;
- logic [N_HARTS-1:0] intr_timer_state_de;
- logic [N_HARTS*N_TIMERS-1:0] intr_timer_state_d;
-
- logic [N_HARTS*N_TIMERS-1:0] intr_out;
-
- /////////////////////////////////////////////////
- // Connecting register interface to the signal //
- /////////////////////////////////////////////////
-
- // Once reggen supports nested multireg, the following can be automated. For the moment, it must
- // be connected manually.
- assign active[0] = reg2hw.ctrl[0].q;
- assign prescaler = '{reg2hw.cfg0.prescale.q};
- assign step = '{reg2hw.cfg0.step.q};
-
- assign hw2reg.timer_v_upper0.de = tick[0];
- assign hw2reg.timer_v_lower0.de = tick[0];
- assign hw2reg.timer_v_upper0.d = mtime_d[0][63:32];
- assign hw2reg.timer_v_lower0.d = mtime_d[0][31: 0];
- assign mtime[0] = {reg2hw.timer_v_upper0.q, reg2hw.timer_v_lower0.q};
- assign mtimecmp = '{'{{reg2hw.compare_upper0_0.q,reg2hw.compare_lower0_0.q}}};
- assign mtimecmp_update[0][0] = reg2hw.compare_upper0_0.qe | reg2hw.compare_lower0_0.qe;
-
- assign intr_timer_expired_0_0_o = intr_out[0];
- assign intr_timer_en = reg2hw.intr_enable0[0].q;
- assign intr_timer_state_q = reg2hw.intr_state0[0].q;
- assign intr_timer_test_q = reg2hw.intr_test0[0].q;
- assign intr_timer_test_qe = reg2hw.intr_test0[0].qe;
- assign hw2reg.intr_state0[0].de = intr_timer_state_de | mtimecmp_update[0][0];
- assign hw2reg.intr_state0[0].d = intr_timer_state_d & ~mtimecmp_update[0][0];
-
-
- for (genvar h = 0 ; h < N_HARTS ; h++) begin : gen_harts
- prim_intr_hw #(
- .Width(N_TIMERS)
- ) u_intr_hw (
- .clk_i,
- .rst_ni,
- .event_intr_i (intr_timer_set),
-
- .reg2hw_intr_enable_q_i (intr_timer_en[h*N_TIMERS+:N_TIMERS]),
- .reg2hw_intr_test_q_i (intr_timer_test_q[h*N_TIMERS+:N_TIMERS]),
- .reg2hw_intr_test_qe_i (intr_timer_test_qe[h]),
- .reg2hw_intr_state_q_i (intr_timer_state_q[h*N_TIMERS+:N_TIMERS]),
- .hw2reg_intr_state_de_o (intr_timer_state_de),
- .hw2reg_intr_state_d_o (intr_timer_state_d[h*N_TIMERS+:N_TIMERS]),
-
- .intr_o (intr_out[h*N_TIMERS+:N_TIMERS])
- );
-
- timer_core #(
- .N (N_TIMERS)
- ) u_core (
- .clk_i,
- .rst_ni,
-
- .active (active[h]),
- .prescaler (prescaler[h]),
- .step (step[h]),
-
- .tick (tick[h]),
-
- .mtime_d (mtime_d[h]),
- .mtime (mtime[h]),
- .mtimecmp (mtimecmp[h]),
-
- .intr (intr_timer_set[h*N_TIMERS+:N_TIMERS])
- );
- end : gen_harts
-
- // Register module
- rv_timer_reg_top u_reg (
- .clk_i,
- .rst_ni,
-
- .tl_i,
- .tl_o,
-
- .reg2hw,
- .hw2reg,
-
- .devmode_i (1'b1)
- );
-
-
-endmodule
diff --git a/verilog/rtl/rv_timer_reg_pkg.sv b/verilog/rtl/rv_timer_reg_pkg.sv
deleted file mode 100644
index 30cfb44..0000000
--- a/verilog/rtl/rv_timer_reg_pkg.sv
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Package auto-generated by `reggen` containing data structure
-
-package rv_timer_reg_pkg;
-
- // Param list
- parameter int N_HARTS = 1;
- parameter int N_TIMERS = 1;
-
- // Address width within the block
- parameter int BlockAw = 9;
-
- ////////////////////////////
- // Typedefs for registers //
- ////////////////////////////
- typedef struct packed {
- logic q;
- } rv_timer_reg2hw_ctrl_mreg_t;
-
- typedef struct packed {
- struct packed {
- logic [11:0] q;
- } prescale;
- struct packed {
- logic [7:0] q;
- } step;
- } rv_timer_reg2hw_cfg0_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- } rv_timer_reg2hw_timer_v_lower0_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- } rv_timer_reg2hw_timer_v_upper0_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- logic qe;
- } rv_timer_reg2hw_compare_lower0_0_reg_t;
-
- typedef struct packed {
- logic [31:0] q;
- logic qe;
- } rv_timer_reg2hw_compare_upper0_0_reg_t;
-
- typedef struct packed {
- logic q;
- } rv_timer_reg2hw_intr_enable0_mreg_t;
-
- typedef struct packed {
- logic q;
- } rv_timer_reg2hw_intr_state0_mreg_t;
-
- typedef struct packed {
- logic q;
- logic qe;
- } rv_timer_reg2hw_intr_test0_mreg_t;
-
-
- typedef struct packed {
- logic [31:0] d;
- logic de;
- } rv_timer_hw2reg_timer_v_lower0_reg_t;
-
- typedef struct packed {
- logic [31:0] d;
- logic de;
- } rv_timer_hw2reg_timer_v_upper0_reg_t;
-
- typedef struct packed {
- logic d;
- logic de;
- } rv_timer_hw2reg_intr_state0_mreg_t;
-
-
- ///////////////////////////////////////
- // Register to internal design logic //
- ///////////////////////////////////////
- typedef struct packed {
- rv_timer_reg2hw_ctrl_mreg_t [0:0] ctrl; // [154:154]
- rv_timer_reg2hw_cfg0_reg_t cfg0; // [153:134]
- rv_timer_reg2hw_timer_v_lower0_reg_t timer_v_lower0; // [133:102]
- rv_timer_reg2hw_timer_v_upper0_reg_t timer_v_upper0; // [101:70]
- rv_timer_reg2hw_compare_lower0_0_reg_t compare_lower0_0; // [69:37]
- rv_timer_reg2hw_compare_upper0_0_reg_t compare_upper0_0; // [36:4]
- rv_timer_reg2hw_intr_enable0_mreg_t [0:0] intr_enable0; // [3:3]
- rv_timer_reg2hw_intr_state0_mreg_t [0:0] intr_state0; // [2:2]
- rv_timer_reg2hw_intr_test0_mreg_t [0:0] intr_test0; // [1:0]
- } rv_timer_reg2hw_t;
-
- ///////////////////////////////////////
- // Internal design logic to register //
- ///////////////////////////////////////
- typedef struct packed {
- rv_timer_hw2reg_timer_v_lower0_reg_t timer_v_lower0; // [67:35]
- rv_timer_hw2reg_timer_v_upper0_reg_t timer_v_upper0; // [34:2]
- rv_timer_hw2reg_intr_state0_mreg_t [0:0] intr_state0; // [1:0]
- } rv_timer_hw2reg_t;
-
- // Register Address
- parameter logic [BlockAw-1:0] RV_TIMER_CTRL_OFFSET = 9'h 0;
- parameter logic [BlockAw-1:0] RV_TIMER_CFG0_OFFSET = 9'h 100;
- parameter logic [BlockAw-1:0] RV_TIMER_TIMER_V_LOWER0_OFFSET = 9'h 104;
- parameter logic [BlockAw-1:0] RV_TIMER_TIMER_V_UPPER0_OFFSET = 9'h 108;
- parameter logic [BlockAw-1:0] RV_TIMER_COMPARE_LOWER0_0_OFFSET = 9'h 10c;
- parameter logic [BlockAw-1:0] RV_TIMER_COMPARE_UPPER0_0_OFFSET = 9'h 110;
- parameter logic [BlockAw-1:0] RV_TIMER_INTR_ENABLE0_OFFSET = 9'h 114;
- parameter logic [BlockAw-1:0] RV_TIMER_INTR_STATE0_OFFSET = 9'h 118;
- parameter logic [BlockAw-1:0] RV_TIMER_INTR_TEST0_OFFSET = 9'h 11c;
-
-
- // Register Index
- typedef enum int {
- RV_TIMER_CTRL,
- RV_TIMER_CFG0,
- RV_TIMER_TIMER_V_LOWER0,
- RV_TIMER_TIMER_V_UPPER0,
- RV_TIMER_COMPARE_LOWER0_0,
- RV_TIMER_COMPARE_UPPER0_0,
- RV_TIMER_INTR_ENABLE0,
- RV_TIMER_INTR_STATE0,
- RV_TIMER_INTR_TEST0
- } rv_timer_id_e;
-
- // Register width information to check illegal writes
- parameter logic [3:0] RV_TIMER_PERMIT [9] = '{
- 4'b 0001, // index[0] RV_TIMER_CTRL
- 4'b 0111, // index[1] RV_TIMER_CFG0
- 4'b 1111, // index[2] RV_TIMER_TIMER_V_LOWER0
- 4'b 1111, // index[3] RV_TIMER_TIMER_V_UPPER0
- 4'b 1111, // index[4] RV_TIMER_COMPARE_LOWER0_0
- 4'b 1111, // index[5] RV_TIMER_COMPARE_UPPER0_0
- 4'b 0001, // index[6] RV_TIMER_INTR_ENABLE0
- 4'b 0001, // index[7] RV_TIMER_INTR_STATE0
- 4'b 0001 // index[8] RV_TIMER_INTR_TEST0
- };
-endpackage
-
diff --git a/verilog/rtl/rv_timer_reg_top.sv b/verilog/rtl/rv_timer_reg_top.sv
deleted file mode 100644
index 62f1c51..0000000
--- a/verilog/rtl/rv_timer_reg_top.sv
+++ /dev/null
@@ -1,482 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Top module auto-generated by `reggen`
-
-
-
-module rv_timer_reg_top (
- input clk_i,
- input rst_ni,
-
- // Below Regster interface can be changed
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
- // To HW
- output rv_timer_reg_pkg::rv_timer_reg2hw_t reg2hw, // Write
- input rv_timer_reg_pkg::rv_timer_hw2reg_t hw2reg, // Read
-
- // Config
- input devmode_i // If 1, explicit error return for unmapped register access
-);
-
- import rv_timer_reg_pkg::* ;
-
- localparam int AW = 9;
- localparam int DW = 32;
- localparam int DBW = DW/8; // Byte Width
-
- // register signals
- logic reg_we;
- logic reg_re;
- logic [AW-1:0] reg_addr;
- logic [DW-1:0] reg_wdata;
- logic [DBW-1:0] reg_be;
- logic [DW-1:0] reg_rdata;
- logic reg_error;
-
- logic addrmiss, wr_err;
-
- logic [DW-1:0] reg_rdata_next;
-
- tlul_pkg::tl_h2d_t tl_reg_h2d;
- tlul_pkg::tl_d2h_t tl_reg_d2h;
-
- assign tl_reg_h2d = tl_i;
- assign tl_o = tl_reg_d2h;
-
- tlul_adapter_reg #(
- .RegAw(AW),
- .RegDw(DW)
- ) u_reg_if (
- .clk_i,
- .rst_ni,
-
- .tl_i (tl_reg_h2d),
- .tl_o (tl_reg_d2h),
-
- .we_o (reg_we),
- .re_o (reg_re),
- .addr_o (reg_addr),
- .wdata_o (reg_wdata),
- .be_o (reg_be),
- .rdata_i (reg_rdata),
- .error_i (reg_error)
- );
-
- assign reg_rdata = reg_rdata_next ;
- assign reg_error = (devmode_i & addrmiss) | wr_err ;
-
- // Define SW related signals
- // Format: <reg>_<field>_{wd|we|qs}
- // or <reg>_{wd|we|qs} if field == 1 or 0
- logic ctrl_qs;
- logic ctrl_wd;
- logic ctrl_we;
- logic [11:0] cfg0_prescale_qs;
- logic [11:0] cfg0_prescale_wd;
- logic cfg0_prescale_we;
- logic [7:0] cfg0_step_qs;
- logic [7:0] cfg0_step_wd;
- logic cfg0_step_we;
- logic [31:0] timer_v_lower0_qs;
- logic [31:0] timer_v_lower0_wd;
- logic timer_v_lower0_we;
- logic [31:0] timer_v_upper0_qs;
- logic [31:0] timer_v_upper0_wd;
- logic timer_v_upper0_we;
- logic [31:0] compare_lower0_0_qs;
- logic [31:0] compare_lower0_0_wd;
- logic compare_lower0_0_we;
- logic [31:0] compare_upper0_0_qs;
- logic [31:0] compare_upper0_0_wd;
- logic compare_upper0_0_we;
- logic intr_enable0_qs;
- logic intr_enable0_wd;
- logic intr_enable0_we;
- logic intr_state0_qs;
- logic intr_state0_wd;
- logic intr_state0_we;
- logic intr_test0_wd;
- logic intr_test0_we;
-
- // Register instances
-
- // Subregister 0 of Multireg ctrl
- // R[ctrl]: V(False)
-
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ctrl (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_we),
- .wd (ctrl_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl[0].q ),
-
- // to register interface (read)
- .qs (ctrl_qs)
- );
-
-
- // R[cfg0]: V(False)
-
- // F[prescale]: 11:0
- prim_subreg #(
- .DW (12),
- .SWACCESS("RW"),
- .RESVAL (12'h0)
- ) u_cfg0_prescale (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (cfg0_prescale_we),
- .wd (cfg0_prescale_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.cfg0.prescale.q ),
-
- // to register interface (read)
- .qs (cfg0_prescale_qs)
- );
-
-
- // F[step]: 23:16
- prim_subreg #(
- .DW (8),
- .SWACCESS("RW"),
- .RESVAL (8'h1)
- ) u_cfg0_step (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (cfg0_step_we),
- .wd (cfg0_step_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.cfg0.step.q ),
-
- // to register interface (read)
- .qs (cfg0_step_qs)
- );
-
-
- // R[timer_v_lower0]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'h0)
- ) u_timer_v_lower0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (timer_v_lower0_we),
- .wd (timer_v_lower0_wd),
-
- // from internal hardware
- .de (hw2reg.timer_v_lower0.de),
- .d (hw2reg.timer_v_lower0.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.timer_v_lower0.q ),
-
- // to register interface (read)
- .qs (timer_v_lower0_qs)
- );
-
-
- // R[timer_v_upper0]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'h0)
- ) u_timer_v_upper0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (timer_v_upper0_we),
- .wd (timer_v_upper0_wd),
-
- // from internal hardware
- .de (hw2reg.timer_v_upper0.de),
- .d (hw2reg.timer_v_upper0.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.timer_v_upper0.q ),
-
- // to register interface (read)
- .qs (timer_v_upper0_qs)
- );
-
-
- // R[compare_lower0_0]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'hffffffff)
- ) u_compare_lower0_0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (compare_lower0_0_we),
- .wd (compare_lower0_0_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (reg2hw.compare_lower0_0.qe),
- .q (reg2hw.compare_lower0_0.q ),
-
- // to register interface (read)
- .qs (compare_lower0_0_qs)
- );
-
-
- // R[compare_upper0_0]: V(False)
-
- prim_subreg #(
- .DW (32),
- .SWACCESS("RW"),
- .RESVAL (32'hffffffff)
- ) u_compare_upper0_0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (compare_upper0_0_we),
- .wd (compare_upper0_0_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (reg2hw.compare_upper0_0.qe),
- .q (reg2hw.compare_upper0_0.q ),
-
- // to register interface (read)
- .qs (compare_upper0_0_qs)
- );
-
-
-
- // Subregister 0 of Multireg intr_enable0
- // R[intr_enable0]: V(False)
-
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable0_we),
- .wd (intr_enable0_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable0[0].q ),
-
- // to register interface (read)
- .qs (intr_enable0_qs)
- );
-
-
-
- // Subregister 0 of Multireg intr_state0
- // R[intr_state0]: V(False)
-
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state0 (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state0_we),
- .wd (intr_state0_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state0[0].de),
- .d (hw2reg.intr_state0[0].d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state0[0].q ),
-
- // to register interface (read)
- .qs (intr_state0_qs)
- );
-
-
-
- // Subregister 0 of Multireg intr_test0
- // R[intr_test0]: V(True)
-
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test0 (
- .re (1'b0),
- .we (intr_test0_we),
- .wd (intr_test0_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test0[0].qe),
- .q (reg2hw.intr_test0[0].q ),
- .qs ()
- );
-
-
-
-
- logic [8:0] addr_hit;
- always_comb begin
- addr_hit = '0;
- addr_hit[0] = (reg_addr == RV_TIMER_CTRL_OFFSET);
- addr_hit[1] = (reg_addr == RV_TIMER_CFG0_OFFSET);
- addr_hit[2] = (reg_addr == RV_TIMER_TIMER_V_LOWER0_OFFSET);
- addr_hit[3] = (reg_addr == RV_TIMER_TIMER_V_UPPER0_OFFSET);
- addr_hit[4] = (reg_addr == RV_TIMER_COMPARE_LOWER0_0_OFFSET);
- addr_hit[5] = (reg_addr == RV_TIMER_COMPARE_UPPER0_0_OFFSET);
- addr_hit[6] = (reg_addr == RV_TIMER_INTR_ENABLE0_OFFSET);
- addr_hit[7] = (reg_addr == RV_TIMER_INTR_STATE0_OFFSET);
- addr_hit[8] = (reg_addr == RV_TIMER_INTR_TEST0_OFFSET);
- end
-
- assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
-
- // Check sub-word write is permitted
- always_comb begin
- wr_err = 1'b0;
- if (addr_hit[0] && reg_we && (RV_TIMER_PERMIT[0] != (RV_TIMER_PERMIT[0] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[1] && reg_we && (RV_TIMER_PERMIT[1] != (RV_TIMER_PERMIT[1] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[2] && reg_we && (RV_TIMER_PERMIT[2] != (RV_TIMER_PERMIT[2] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[3] && reg_we && (RV_TIMER_PERMIT[3] != (RV_TIMER_PERMIT[3] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[4] && reg_we && (RV_TIMER_PERMIT[4] != (RV_TIMER_PERMIT[4] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[5] && reg_we && (RV_TIMER_PERMIT[5] != (RV_TIMER_PERMIT[5] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[6] && reg_we && (RV_TIMER_PERMIT[6] != (RV_TIMER_PERMIT[6] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[7] && reg_we && (RV_TIMER_PERMIT[7] != (RV_TIMER_PERMIT[7] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[8] && reg_we && (RV_TIMER_PERMIT[8] != (RV_TIMER_PERMIT[8] & reg_be))) wr_err = 1'b1 ;
- end
-
- assign ctrl_we = addr_hit[0] & reg_we & ~wr_err;
- assign ctrl_wd = reg_wdata[0];
-
- assign cfg0_prescale_we = addr_hit[1] & reg_we & ~wr_err;
- assign cfg0_prescale_wd = reg_wdata[11:0];
-
- assign cfg0_step_we = addr_hit[1] & reg_we & ~wr_err;
- assign cfg0_step_wd = reg_wdata[23:16];
-
- assign timer_v_lower0_we = addr_hit[2] & reg_we & ~wr_err;
- assign timer_v_lower0_wd = reg_wdata[31:0];
-
- assign timer_v_upper0_we = addr_hit[3] & reg_we & ~wr_err;
- assign timer_v_upper0_wd = reg_wdata[31:0];
-
- assign compare_lower0_0_we = addr_hit[4] & reg_we & ~wr_err;
- assign compare_lower0_0_wd = reg_wdata[31:0];
-
- assign compare_upper0_0_we = addr_hit[5] & reg_we & ~wr_err;
- assign compare_upper0_0_wd = reg_wdata[31:0];
-
- assign intr_enable0_we = addr_hit[6] & reg_we & ~wr_err;
- assign intr_enable0_wd = reg_wdata[0];
-
- assign intr_state0_we = addr_hit[7] & reg_we & ~wr_err;
- assign intr_state0_wd = reg_wdata[0];
-
- assign intr_test0_we = addr_hit[8] & reg_we & ~wr_err;
- assign intr_test0_wd = reg_wdata[0];
-
- // Read data return
- always_comb begin
- reg_rdata_next = '0;
- unique case (1'b1)
- addr_hit[0]: begin
- reg_rdata_next[0] = ctrl_qs;
- end
-
- addr_hit[1]: begin
- reg_rdata_next[11:0] = cfg0_prescale_qs;
- reg_rdata_next[23:16] = cfg0_step_qs;
- end
-
- addr_hit[2]: begin
- reg_rdata_next[31:0] = timer_v_lower0_qs;
- end
-
- addr_hit[3]: begin
- reg_rdata_next[31:0] = timer_v_upper0_qs;
- end
-
- addr_hit[4]: begin
- reg_rdata_next[31:0] = compare_lower0_0_qs;
- end
-
- addr_hit[5]: begin
- reg_rdata_next[31:0] = compare_upper0_0_qs;
- end
-
- addr_hit[6]: begin
- reg_rdata_next[0] = intr_enable0_qs;
- end
-
- addr_hit[7]: begin
- reg_rdata_next[0] = intr_state0_qs;
- end
-
- addr_hit[8]: begin
- reg_rdata_next[0] = '0;
- end
-
- default: begin
- reg_rdata_next = '1;
- end
- endcase
- end
-
-
-endmodule
diff --git a/verilog/rtl/spi_clgen.v b/verilog/rtl/spi_clgen.v
deleted file mode 100644
index e7eafcf..0000000
--- a/verilog/rtl/spi_clgen.v
+++ /dev/null
@@ -1,67 +0,0 @@
-// `include "/home/merl/github_repos/azadi/src/spi_host/rtl/spi_defines.v"
-`include "spi_defines.v"
-
-module spi_clgen (
- input clk_i, // input clock (system clock)
- input rst_ni, // reset
- input enable, // clock enable
- input go, // start transfer
- input last_clk, // last clock
- input [`SPI_DIVIDER_LEN-1:0] divider, // clock divider (output clock is divided by this value)
- output reg clk_out, // output clock
- output reg pos_edge, // pulse marking positive edge of clk_out
- output reg neg_edge // pulse marking negative edge of clk_out
-
-);
-
- //reg clk_out;
- //reg pos_edge;
- //reg neg_edge;
-
- reg [`SPI_DIVIDER_LEN-1:0] cnt; // clock counter
- wire cnt_zero; // conter is equal to zero
- wire cnt_one; // conter is equal to one
-
-
- assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}};
- assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
-
- // Counter counts half period
- always @(posedge clk_i or negedge rst_ni)
- begin
- if(~rst_ni)
- cnt <= {`SPI_DIVIDER_LEN{1'b1}};
- else
- begin
- if(!enable || cnt_zero)
- cnt <= divider;
- else
- cnt <= cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
- end
- end
-
- // clk_out is asserted every other half period
- always @(posedge clk_i or negedge rst_ni)
- begin
- if(~rst_ni)
- clk_out <= 1'b0;
- else
- clk_out <= (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
- end
-
- // Pos and neg edge signals
- always @(posedge clk_i or negedge rst_ni)
- begin
- if(~rst_ni)
- begin
- pos_edge <= 1'b0;
- neg_edge <= 1'b0;
- end
- else
- begin
- pos_edge <= (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
- neg_edge <= (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
- end
- end
-endmodule
-
diff --git a/verilog/rtl/spi_core.sv b/verilog/rtl/spi_core.sv
deleted file mode 100644
index 74d9df9..0000000
--- a/verilog/rtl/spi_core.sv
+++ /dev/null
@@ -1,201 +0,0 @@
-// `include "/home/merl/github_repos/azadi/src/spi_host/rtl/spi_defines.v"
-//`include "/home/zeeshan/fyp/azadi/src/spi_host/rtl/spi_defines.v"
-`include "spi_defines.v"
-module spi_core
-(
- // tlul signals
- input clk_i,
- input rst_ni,
- input [7:0] addr_i,
- input [31:0] wdata_i,
- output reg [31:0] rdata_o,
- input [3:0] be_i,
- input we_i,
- input re_i,
- output reg error_o,
- output reg intr_rx_o,
- output reg intr_tx_o,
-
- // SPI signals
- output [`SPI_SS_NB-1:0] ss_o, // slave select
- output sclk_o, // serial clock
- output sd_o,
- output reg sd_oe, // master out slave in
- input sd_i // master in slave out
-);
-
-
- // Internal signals
- reg [`SPI_DIVIDER_LEN-1:0] divider; // Divider register
- reg [`SPI_CTRL_BIT_NB-1:0] ctrl; // Control and status register
- reg [`SPI_SS_NB-1:0] ss; // Slave select register
- reg [32-1:0] wb_dat; // wb data out
- wire [`SPI_MAX_CHAR-1:0] rx; // Rx register
- wire rx_negedge; // miso is sampled on negative edge
- wire tx_negedge; // mosi is driven on negative edge
- wire [`SPI_CHAR_LEN_BITS-1:0] char_len; // char len
- wire go; // go
- wire lsb; // lsb first on line
- wire ie; // interrupt enable
- wire ass; // automatic slave select
- wire spi_divider_sel; // divider register select
- wire spi_ctrl_sel; // ctrl register select
- wire spi_tx_sel; // tx_l register select
- wire spi_ss_sel; // ss register select
- wire tip; // transfer in progress
- wire pos_edge; // recognize posedge of sclk
- wire neg_edge; // recognize negedge of sclk
- wire last_bit; // marks last character bit
- wire tx_en; // enables spi transmission
- wire rx_en; // enables spi reception
-
- // Address decoder
- assign spi_divider_sel = we_i & ~re_i & (addr_i[`SPI_OFS_BITS] == `SPI_DEVIDE);
- assign spi_ctrl_sel = we_i & ~re_i & (addr_i[`SPI_OFS_BITS] == `SPI_CTRL);
- assign spi_tx_sel = we_i & ~re_i & (addr_i[`SPI_OFS_BITS] == `SPI_TX_0) & tx_en;
- assign spi_ss_sel = we_i & ~re_i & (addr_i[`SPI_OFS_BITS] == `SPI_SS);
-
- // Read from registers
- always @(addr_i or rx or ctrl or divider or ss)
- begin
- case (addr_i[`SPI_OFS_BITS])
- `SPI_RX_0: wb_dat = rx[`SPI_MAX_CHAR-1:0];
- `SPI_CTRL: wb_dat = ctrl;
- `SPI_DEVIDE: wb_dat = divider;
- `SPI_SS: wb_dat = ss;
- default: wb_dat = 32'b0;
- endcase
- end
-
- // Wb data out
- always @(posedge clk_i)
- begin
- if (~rst_ni)
- rdata_o <= 32'b0;
- else
- rdata_o <= wb_dat;
- end
-
-
- // Wb error
- assign error_o = 1'b0;
-
- // Interrupt
- always @(posedge clk_i)
- begin
- if (~rst_ni)
- intr_tx_o <= 1'b0;
- else if (ie && tip && last_bit && pos_edge && tx_en)
- intr_tx_o <= 1'b1;
- else
- intr_tx_o <= 1'b0;
- end
-
- always @(posedge clk_i )
- begin
- if (~rst_ni)
- intr_rx_o <= 1'b0;
- else if (ie && tip && last_bit && pos_edge && rx_en)
- intr_rx_o <= 1'b1;
- else
- intr_rx_o <= 1'b0;
- end
-
- // Divider register
- always @(posedge clk_i)
- begin
- if (~rst_ni)
- divider <= {`SPI_DIVIDER_LEN{1'b0}};
- else if (spi_divider_sel && we_i && !tip)
- begin
- if (be_i[0])
- divider[7:0] <= wdata_i[7:0];
- if (be_i[1])
- divider[`SPI_DIVIDER_LEN-1:8] <= wdata_i[`SPI_DIVIDER_LEN-1:8];
- end
- end
-
- // Ctrl register
- always @(posedge clk_i)
- begin
- if (~rst_ni)
- ctrl <= {`SPI_CTRL_BIT_NB{1'b0}};
- else if(spi_ctrl_sel && we_i && !tip)
- begin
- if (be_i[0])
- ctrl[7:0] <= wdata_i[7:0] | {7'b0, ctrl[0]};
- if (be_i[1])
- ctrl[`SPI_CTRL_BIT_NB-1:8] <= wdata_i[`SPI_CTRL_BIT_NB-1:8];
- end
- else if(tip && last_bit && pos_edge)
- ctrl[`SPI_CTRL_GO] <= 1'b0;
- end
-
- assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE];
- assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE];
- assign go = ctrl[`SPI_CTRL_GO];
- assign char_len = ctrl[`SPI_CTRL_CHAR_LEN];
- assign lsb = ctrl[`SPI_CTRL_LSB];
- assign ie = ctrl[`SPI_CTRL_IE];
- assign ass = ctrl[`SPI_CTRL_ASS];
- assign rx_en = ctrl[`SPI_RX_SEL];
- assign tx_en = ctrl[`SPI_TX_SEL];
-
- always @(posedge clk_i or negedge rst_ni) begin
- if(~rst_ni) begin
- sd_oe <= 1'b0;
- end else if (tx_en & !rx_en) begin
- sd_oe <= 1'b1;
- end else begin
- sd_oe <= 1'b0;
- end
- end
- // Slave select register
- always @(posedge clk_i)
- begin
- if (~rst_ni)
- ss <= {`SPI_SS_NB{1'b0}};
- else if(spi_ss_sel && we_i && !tip)
- begin
- if (be_i[0])
- ss <= wdata_i[`SPI_SS_NB-1:0];
- end
- end
-
- assign ss_o = ~((ss & {`SPI_SS_NB{tip & ass}}) | (ss & {`SPI_SS_NB{!ass}}));
-
- spi_clgen clgen (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .go (go),
- .enable (tip),
- .last_clk (last_bit),
- .divider (divider),
- .clk_out (sclk_o),
- .pos_edge (pos_edge),
- .neg_edge (neg_edge)
- );
-
- spi_shift shift (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .len (char_len[`SPI_CHAR_LEN_BITS-1:0]),
- .latch (spi_tx_sel & we_i),
- .byte_sel (be_i),
- .lsb (lsb),
- .go (go),
- .pos_edge (pos_edge),
- .neg_edge (neg_edge),
- .rx_negedge (rx_negedge),
- .tx_negedge (tx_negedge),
- .tip (tip),
- .last (last_bit),
- .p_in (wdata_i),
- .p_out (rx),
- .s_clk (sclk_o),
- .s_in (sd_i),
- .s_out (sd_o),
- .rx_en (rx_en)
- );
-endmodule
-
diff --git a/verilog/rtl/spi_defines.v b/verilog/rtl/spi_defines.v
deleted file mode 100644
index 3e43ac9..0000000
--- a/verilog/rtl/spi_defines.v
+++ /dev/null
@@ -1,117 +0,0 @@
-
-// Number of bits used for devider register. If used in system with
-// low frequency of system clock this can be reduced.
-// Use SPI_DIVIDER_LEN for fine tuning theexact number.
-//
-//`define SPI_DIVIDER_LEN_8
-`define SPI_DIVIDER_LEN_16
-//`define SPI_DIVIDER_LEN_24
-//`define SPI_DIVIDER_LEN_32
-
-`ifdef SPI_DIVIDER_LEN_8
- `define SPI_DIVIDER_LEN 8 // Can be set from 1 to 8
-`endif
-`ifdef SPI_DIVIDER_LEN_16
- `define SPI_DIVIDER_LEN 16 // Can be set from 9 to 16
-`endif
-`ifdef SPI_DIVIDER_LEN_24
- `define SPI_DIVIDER_LEN 24 // Can be set from 17 to 24
-`endif
-`ifdef SPI_DIVIDER_LEN_32
- `define SPI_DIVIDER_LEN 32 // Can be set from 25 to 32
-`endif
-
-//
-// Maximum nuber of bits that can be send/received at once.
-// Use SPI_MAX_CHAR for fine tuning the exact number, when using
-// SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8.
-//
-`define SPI_MAX_CHAR_32
-//`define SPI_MAX_CHAR_64
-//`define SPI_MAX_CHAR_32
-//`define SPI_MAX_CHAR_24
-//`define SPI_MAX_CHAR_16
-//`define SPI_MAX_CHAR_8
-
-`ifdef SPI_MAX_CHAR_128
- `define SPI_MAX_CHAR 128 // Can only be set to 128
- `define SPI_CHAR_LEN_BITS 7
-`endif
-`ifdef SPI_MAX_CHAR_64
- `define SPI_MAX_CHAR 64 // Can only be set to 64
- `define SPI_CHAR_LEN_BITS 6
-`endif
-`ifdef SPI_MAX_CHAR_32
- `define SPI_MAX_CHAR 32 // Can be set from 25 to 32
- `define SPI_CHAR_LEN_BITS 5
-`endif
-`ifdef SPI_MAX_CHAR_24
- `define SPI_MAX_CHAR 24 // Can be set from 17 to 24
- `define SPI_CHAR_LEN_BITS 5
-`endif
-`ifdef SPI_MAX_CHAR_16
- `define SPI_MAX_CHAR 16 // Can be set from 9 to 16
- `define SPI_CHAR_LEN_BITS 4
-`endif
-`ifdef SPI_MAX_CHAR_8
- `define SPI_MAX_CHAR 8 // Can be set from 1 to 8
- `define SPI_CHAR_LEN_BITS 3
-`endif
-
-//
-// Number of device select signals. Use SPI_SS_NB for fine tuning the
-// exact number.
-//
-`define SPI_SS_NB_4
-//`define SPI_SS_NB_16
-//`define SPI_SS_NB_24
-//`define SPI_SS_NB_32
-`ifdef SPI_SS_NB_4
- `define SPI_SS_NB 4 // Can be set from 1 to 4
-`endif
-`ifdef SPI_SS_NB_8
- `define SPI_SS_NB 8 // Can be set from 1 to 8
-`endif
-`ifdef SPI_SS_NB_16
- `define SPI_SS_NB 16 // Can be set from 9 to 16
-`endif
-`ifdef SPI_SS_NB_24
- `define SPI_SS_NB 24 // Can be set from 17 to 24
-`endif
-`ifdef SPI_SS_NB_32
- `define SPI_SS_NB 32 // Can be set from 25 to 32
-`endif
-
-//
-// Bits of WISHBONE address used for partial decoding of SPI registers.
-//
-`define SPI_OFS_BITS 6:2
-
-//
-// Register offset
-//
-`define SPI_RX_0 8
-`define SPI_TX_0 0
-`define SPI_CTRL 4
-`define SPI_DEVIDE 5
-`define SPI_SS 6
-
-//
-// Number of bits in ctrl register
-//
-`define SPI_CTRL_BIT_NB 16
-
-//
-// Control register bit position
-//
-`define SPI_RX_SEL 15
-`define SPI_TX_SEL 14
-`define SPI_CTRL_ASS 13
-`define SPI_CTRL_IE 12
-`define SPI_CTRL_LSB 11
-`define SPI_CTRL_TX_NEGEDGE 10
-`define SPI_CTRL_RX_NEGEDGE 9
-`define SPI_CTRL_GO 8
-`define SPI_CTRL_RES_1 7
-`define SPI_CTRL_CHAR_LEN 6:0
-
diff --git a/verilog/rtl/spi_shift.v b/verilog/rtl/spi_shift.v
deleted file mode 100644
index efaf414..0000000
--- a/verilog/rtl/spi_shift.v
+++ /dev/null
@@ -1,103 +0,0 @@
-`include "spi_defines.v"
-
-module spi_shift (
- input clk_i, // system clock
- input rst_ni, // reset
- input latch, // latch signal for storing the data in shift register
- input [3:0] byte_sel, // byte select signals for storing the data in shift register
- input [`SPI_CHAR_LEN_BITS-1:0] len, // data len in bits (minus one)
- input lsb, // lbs first_ni on the line
- input go, // start stansfer
- input pos_edge, // recognize posedge of sclk_i
- input neg_edge, // recognize negedge of sclk_i
- input rx_negedge, // s_in is sampled on negative edge
- input tx_negedge, // s_out is driven on negative edge
- output reg tip, // transfer in progress
- output last, // last bit
- input [31:0] p_in, // parallel in
- output [`SPI_MAX_CHAR-1:0] p_out, // parallel out
- input s_clk, // serial clock
- input s_in, // serial in
- output reg s_out, // serial out
- input rx_en // serial rx enable
-);
-
- // reg s_out;
- // reg tip;
-
- reg [`SPI_CHAR_LEN_BITS:0] cnt; // data bit count
- reg [`SPI_MAX_CHAR-1:0] data;
- reg [`SPI_MAX_CHAR-1:0] data_rx; // shift register
- wire [`SPI_CHAR_LEN_BITS:0] tx_bit_pos; // next bit position
- wire [`SPI_CHAR_LEN_BITS:0] rx_bit_pos; // next bit position
- wire rx_clk_i; // rx clock enable
- wire tx_clk_i; // tx clock enable
-
- assign p_out = data_rx;
-
- assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1};
- assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} : cnt) :
- (rx_negedge ? cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1});
-
- assign last = !(|cnt);
-
- assign rx_clk_i = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk);
- assign tx_clk_i = (tx_negedge ? neg_edge : pos_edge) && !last;
-
- // Character bit counter
- always @(posedge clk_i or negedge rst_ni)
- begin
- if(~rst_ni)
- cnt <= {`SPI_CHAR_LEN_BITS+1{1'b0}};
- else
- begin
- if(tip)
- cnt <= pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;
- else
- cnt <= !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};
- end
- end
-
- // Transfer in progress
- always @(posedge clk_i or negedge rst_ni)
- begin
- if(~rst_ni)
- tip <= 1'b0;
- else if(go && ~tip)
- tip <= 1'b1;
- else if(tip && last && pos_edge)
- tip <= 1'b0;
- end
-
- // Sending bits to the line
- always @(posedge clk_i or negedge rst_ni)
- begin
- if (~rst_ni)
- s_out <= 1'b0;
- else
- s_out <= (tx_clk_i || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;
- end
-
- // Receiving bits from the line
- always @(posedge clk_i )
- begin
- if (~rst_ni)
- data <= {`SPI_MAX_CHAR{1'b0}};
- else if (latch && !tip)
- begin
- if (byte_sel[0])
- data[7:0] <= p_in[7:0];
- if (byte_sel[1])
- data[15:8] <= p_in[15:8];
- if (byte_sel[2])
- data[23:16] <= p_in[23:16];
- if (byte_sel[3])
- data[`SPI_MAX_CHAR-1:24] <= p_in[`SPI_MAX_CHAR-1:24];
- end
- else if (rx_en && tip) begin
- data_rx[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= rx_clk_i ? s_in : data_rx[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
- end
- end
-
-endmodule
-
diff --git a/verilog/rtl/spi_top.sv b/verilog/rtl/spi_top.sv
deleted file mode 100644
index c99852f..0000000
--- a/verilog/rtl/spi_top.sv
+++ /dev/null
@@ -1,77 +0,0 @@
-// `include "/home/merl/github_repos/azadi/src/spi_host/rtl/spi_defines.v"
-//`include "/home/zeeshan/fyp/azadi/src/spi_host/rtl/spi_defines.v"
-`include "spi_defines.v"
-module spi_top(
-
- input clk_i,
- input rst_ni,
-
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
-
- // SPI signals
- output intr_rx_o,
- output intr_tx_o,
- output [`SPI_SS_NB-1:0] ss_o,
- output sclk_o,
- output sd_o,
- output sd_oe,
- input sd_i
-
-);
-
-localparam int AW = 8;
-localparam int DW = 32;
-
-logic re;
-logic we;
-logic [7:0] addr;
-logic [31:0] wdata;
-logic [3:0] be;
-logic [31:0] rdata;
-logic err;
-
-spi_core spi_host(
- // tlul signals
- .clk_i,
- .rst_ni,
- .addr_i (addr),
- .wdata_i (wdata),
- .rdata_o (rdata),
- .be_i (be),
- .we_i (we),
- .re_i (re),
- .error_o (err),
-
- .intr_rx_o (intr_rx_o),
- .intr_tx_o (intr_tx_o),
-
- // SPI signals
- .ss_o (ss_o), // slave select
- .sclk_o (sclk_o), // serial clock
- .sd_o (sd_o), // master out slave in
- .sd_oe (sd_oe),
- .sd_i (sd_i) // master in slave out
-);
-
-
-tlul_adapter_reg #(
- .RegAw(AW),
- .RegDw(DW)
-) u_reg_if (
- .clk_i,
- .rst_ni,
-
- .tl_i (tl_i),
- .tl_o (tl_o),
-
- .we_o (we),
- .re_o (re),
- .addr_o (addr),
- .wdata_o (wdata),
- .be_o (be),
- .rdata_i (rdata),
- .error_i (err)
-);
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/sram.v b/verilog/rtl/sram.v
deleted file mode 100644
index bec8fd0..0000000
--- a/verilog/rtl/sram.v
+++ /dev/null
@@ -1,127 +0,0 @@
-// OpenRAM SRAM model
-// Words: 1024
-// Word size: 32
-// Write size: 8
-
-module sram #(
- parameter NUM_WMASKS = 4 ,
- parameter DATA_WIDTH = 32 ,
- parameter ADDR_WIDTH = 10 ,
- parameter RAM_DEPTH = 1 << ADDR_WIDTH,
- // FIXME: This delay is arbitrary.
- parameter DELAY = 3 ,
- parameter VERBOSE = 1 , //Set to 0 to only display warnings
- parameter T_HOLD = 1 ,//Delay to hold dout value after posedge. Value is arbitrary
- parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over INITFILE)
- parameter IFILE = ""
-)
-(
-// Port 0: RW
- clk0,csb0,web0,wmask0,addr0,din0,dout0,
-// Port 1: R
- clk1,csb1,addr1,dout1
- );
-
- /*parameter NUM_WMASKS = 4 ;
- parameter DATA_WIDTH = 32 ;
- parameter ADDR_WIDTH = 10 ;
- parameter RAM_DEPTH = 1 << ADDR_WIDTH;
- // FIXME: This delay is arbitrary.
- parameter DELAY = 3 ;
- parameter VERBOSE = 1 ; //Set to 0 to only display warnings
- parameter T_HOLD = 1 ; //Delay to hold dout value after posedge. Value is arbitrary
- parameter IZERO = 0 ; // binary / Initial RAM with zeros (has priority over INITFILE)
- parameter IFILE = "";
-*/
- input clk0; // clock
- input csb0; // active low chip select
- input web0; // active low write control
- input [NUM_WMASKS-1:0] wmask0; // write mask
- input [ADDR_WIDTH-1:0] addr0;
- input [DATA_WIDTH-1:0] din0;
- output [DATA_WIDTH-1:0] dout0;
- input clk1; // clock
- input csb1; // active low chip select
- input [ADDR_WIDTH-1:0] addr1;
- output [DATA_WIDTH-1:0] dout1;
-
- reg csb0_reg;
- reg web0_reg;
- reg [NUM_WMASKS-1:0] wmask0_reg;
- reg [ADDR_WIDTH-1:0] addr0_reg;
- reg [DATA_WIDTH-1:0] din0_reg;
- reg [DATA_WIDTH-1:0] dout0;
-
- // All inputs are registers
- always @(posedge clk0)
- begin
- csb0_reg = csb0;
- web0_reg = web0;
- wmask0_reg = wmask0;
- addr0_reg = addr0;
- din0_reg = din0;
- //#(T_HOLD) dout0 = 32'bx;
- //if ( !csb0_reg && web0_reg && VERBOSE )
- //$display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]);
- //if ( !csb0_reg && !web0_reg && VERBOSE )
- //$display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg);
- end
-
- reg csb1_reg;
- reg [ADDR_WIDTH-1:0] addr1_reg;
- reg [DATA_WIDTH-1:0] dout1;
-
-
- // All inputs are registers
- always @(posedge clk1)
- begin
- csb1_reg = csb1;
- addr1_reg = addr1;
- //if (!csb0 && !web0 && !csb1 && (addr0 == addr1))
- //$display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1);
- //#(T_HOLD) dout1 = 32'bx;
- //if ( !csb1_reg && VERBOSE )
- //$display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]);
- end
-
-integer i;
-reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
-//initial
- //if (IZERO)
- //for (i=0; i<RAM_DEPTH; i=i+1) mem[i] = {DATA_WIDTH{1'b0}};
- //else
- //if (IFILE != "") $readmemh({IFILE,".hex"}, mem);
-
- // Memory Write Block Port 0
- // Write Operation : When web0 = 0, csb0 = 0
- always @ (negedge clk0)
- begin : MEM_WRITE0
- if ( !csb0_reg && !web0_reg ) begin
- if (wmask0_reg[0])
- mem[addr0_reg][7:0] = din0_reg[7:0];
- if (wmask0_reg[1])
- mem[addr0_reg][15:8] = din0_reg[15:8];
- if (wmask0_reg[2])
- mem[addr0_reg][23:16] = din0_reg[23:16];
- if (wmask0_reg[3])
- mem[addr0_reg][31:24] = din0_reg[31:24];
- end
- end
-
- // Memory Read Block Port 0
- // Read Operation : When web0 = 1, csb0 = 0
- always @ (negedge clk0)
- begin : MEM_READ0
- if (!csb0_reg && web0_reg)
- dout0 <= mem[addr0_reg];
- end
-
- // Memory Read Block Port 1
- // Read Operation : When web1 = 1, csb1 = 0
- always @ (negedge clk1)
- begin : MEM_READ1
- if (!csb1_reg)
- dout1 <= mem[addr1_reg];
- end
-
-endmodule
diff --git a/verilog/rtl/sram_top.v b/verilog/rtl/sram_top.v
deleted file mode 100644
index d68b365..0000000
--- a/verilog/rtl/sram_top.v
+++ /dev/null
@@ -1,133 +0,0 @@
-`include "utils.vh"
-module sram_top
- #( parameter NUM_WMASKS = 4,
- parameter MEMD = 2048,
- parameter DATA_WIDTH = 32, // data width
- parameter nRPORTS = 1 , // number of reading ports
- parameter nWPORTS = 1, // number of write ports
- parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over IFILE)
- parameter IFILE = "", // initialization mif file (don't pass extension), optional
- parameter BASIC_MODEL = 1024,
- parameter ADDR_WIDTH = 11,
- parameter DELAY = 3
- )( /*`ifdef USE_POWER_PINS
- inout vdd;
- inout gnd;
-`endif*/
- input clk, // clock
- input csb, // active low chip select
- input web, // active low write control
- input [NUM_WMASKS-1:0] wmask, // write mask
- input [ADDR_WIDTH-1:0] addr,
- input [DATA_WIDTH-1:0] din,
- output reg[DATA_WIDTH-1:0] dout,
- input clk1,
- input csb1,
- input [ADDR_WIDTH-1:0] addr1,
- output reg [DATA_WIDTH-1:0] dout1);
-
-localparam ADDRW = ADDR_WIDTH; // address width
-localparam NUM_OF_BANKS = MEMD / BASIC_MODEL;
-localparam Basic_ADDRW = `log2(BASIC_MODEL); // address width
-
-reg [DATA_WIDTH-1:0] RData_out;
-wire[DATA_WIDTH-1:0] Rdata [NUM_OF_BANKS-1:0];
-wire [(NUM_OF_BANKS-1)/2:0] Addr_sel;
-reg [(NUM_OF_BANKS-1)/2:0] Raddr_sel;
-reg [Basic_ADDRW-1:0] Addr [NUM_OF_BANKS-1:0];
-reg wen [NUM_OF_BANKS-1:0];
-reg csb_i [NUM_OF_BANKS-1:0];
-reg web_reg;
-
-// port 2
-reg [DATA_WIDTH-1:0] RData_out_1;
-wire[DATA_WIDTH-1:0] Rdata_1 [NUM_OF_BANKS-1:0];
-wire [(NUM_OF_BANKS-1)/2:0] Addr_sel_1;
-reg [(NUM_OF_BANKS-1)/2:0] Raddr_sel_1;
-reg [Basic_ADDRW-1:0] Addr_1 [NUM_OF_BANKS-1:0];
-reg csb_i_1 [NUM_OF_BANKS-1:0];
-
-
-assign Addr_sel = addr % NUM_OF_BANKS;
-assign Addr_sel_1 = addr1 % NUM_OF_BANKS;
-
-always @(negedge clk) begin
-Raddr_sel = addr % NUM_OF_BANKS;
-Raddr_sel_1 = addr1 % NUM_OF_BANKS;
-web_reg = web;
-end
-
-integer i;
-integer j;
-
- always @* begin
- for(i=0; i<NUM_OF_BANKS; i=i+1) begin
- Addr[i] = (Addr_sel == i) ? addr[ADDRW-1:ADDRW-Basic_ADDRW] : 0;
- wen[i] = (Addr_sel == i) ? web : 1;
- csb_i[i] = (Addr_sel == i) ? csb : 1;
- end
-end
-
-always @* begin
- for(i=0; i<NUM_OF_BANKS; i=i+1) begin
- Addr_1[i] = (Addr_sel_1 == i) ? addr1[ADDRW-1:ADDRW-Basic_ADDRW] : 0;
- csb_i_1[i] = (Addr_sel_1 == i) ? csb1 : 1;
- end
-end
-
-genvar p;
-generate
- for(p=0; p<NUM_OF_BANKS; p=p+1) begin
- sram #( .NUM_WMASKS (NUM_WMASKS),
- .DATA_WIDTH (DATA_WIDTH),
- .ADDR_WIDTH (Basic_ADDRW),
- .RAM_DEPTH (BASIC_MODEL),
- .DELAY(DELAY),
- .IZERO(IZERO),
- .IFILE(IFILE))
- sram_i( .clk0(clk),
- .csb0(csb_i[p]),
- .web0(wen[p]),
- .wmask0(wmask),
- .addr0(Addr[p]),
- .din0(din),
- .dout0(Rdata[p]),
- .clk1(clk1),
- .csb1(csb_i_1[p]),
- .addr1(Addr_1[p]),
- .dout1(Rdata_1[p]));
- end
-endgenerate
-
-always @(posedge clk) begin
- if(web_reg==1) begin
- for(j=0; j<NUM_OF_BANKS; j=j+1) begin
- RData_out = (Raddr_sel == j) ? Rdata[j] : RData_out;
- end
- end
- else
- RData_out = RData_out;
- // Port 2
-end
-always @(posedge clk) begin
- for(j=0; j<NUM_OF_BANKS; j=j+1) begin
- //RData_out_1 = (Raddr_sel_1 == q) ? Rdata_1[q] : RData_out_1;
- if(Raddr_sel_1 == j)
- RData_out_1 = Rdata_1[j];
- else
- RData_out_1 = RData_out_1;
- end
-end
-
-
-
-always @* begin
-dout = RData_out;
-end
-
-always @* begin
-dout1 = RData_out_1;
-end
-endmodule
-
-
diff --git a/verilog/rtl/timer_core.sv b/verilog/rtl/timer_core.sv
deleted file mode 100644
index 7cd1c62..0000000
--- a/verilog/rtl/timer_core.sv
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-
-
-module timer_core #(
- parameter int N = 1
-) (
- input clk_i,
- input rst_ni,
-
- input active,
- input [11:0] prescaler,
- input [ 7:0] step,
-
- output logic tick,
- output logic [63:0] mtime_d,
- input [63:0] mtime,
- input [63:0] mtimecmp [N],
-
- output logic [N-1:0] intr
-);
-
- logic [11:0] tick_count;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin : generate_tick
- if (!rst_ni) begin
- tick_count <= 12'h0;
- end else if (!active) begin
- tick_count <= 12'h0;
- end else if (tick_count == prescaler) begin
- tick_count <= 12'h0;
- end else begin
- tick_count <= tick_count + 1'b1;
- end
- end
-
- assign tick = active & (tick_count >= prescaler);
-
- assign mtime_d = mtime + 64'(step);
-
- // interrupt is generated if mtime is greater than or equal to mtimecmp
- // TODO: Check if it must consider overflow case
- for (genvar t = 0 ; t < N ; t++) begin : gen_intr
- assign intr[t] = active & (mtime >= mtimecmp[t]);
- end
-
-endmodule : timer_core
diff --git a/verilog/rtl/tl_main_pkg.sv b/verilog/rtl/tl_main_pkg.sv
deleted file mode 100644
index 4421478..0000000
--- a/verilog/rtl/tl_main_pkg.sv
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// tl_main package generated by `tlgen.py` tool
-
-package tl_main_pkg;
-
- localparam logic [31:0] ADDR_SPACE_ICCM = 32'h 20000000;
- localparam logic [31:0] ADDR_SPACE_DEBUG_ROM = 32'h 10040000;
- localparam logic [31:0] ADDR_SPACE_DCCM = 32'h 10000000;
- localparam logic [31:0] ADDR_SPACE_TIMER0 = 32'h 40000000;
- localparam logic [31:0] ADDR_SPACE_UART0 = 32'h 40060000;
- localparam logic [31:0] ADDR_SPACE_SPI0 = 32'h 40080000;
- localparam logic [31:0] ADDR_SPACE_PWM = 32'h 400b0000;
- localparam logic [31:0] ADDR_SPACE_GPIO = 32'h 400c0000;
- localparam logic [31:0] ADDR_SPACE_PLIC = 32'h 40050000;
-
- localparam logic [31:0] ADDR_MASK_ICCM = 32'h 0000ffff;
- localparam logic [31:0] ADDR_MASK_DEBUG_ROM = 32'h 0000ffff;
- localparam logic [31:0] ADDR_MASK_DCCM = 32'h 0000ffff;
- localparam logic [31:0] ADDR_MASK_TIMER0 = 32'h 0000ffff;
- localparam logic [31:0] ADDR_MASK_UART0 = 32'h 0000ffff;
- localparam logic [31:0] ADDR_MASK_SPI0 = 32'h 0000ffff;
- localparam logic [31:0] ADDR_MASK_PWM = 32'h 0000ffff;
- localparam logic [31:0] ADDR_MASK_GPIO = 32'h 0000ffff;
- localparam logic [31:0] ADDR_MASK_PLIC = 32'h 0000ffff;
-
- localparam int N_HOST = 3;
- localparam int N_DEVICE = 9;
-
- typedef enum int {
- TlIccm = 0,
- TlDebugRom = 1,
- TlDccm = 2,
- TlTimer0 = 3,
- TlUart0 = 4,
- TlSpi0 = 5,
- TlPwm = 6,
- TlGpio = 7,
- TlPlic = 8
- } tl_device_e;
-
- typedef enum int {
- TlBrqif = 0,
- TlBrqlsu = 1,
- TlDmSba = 2
- } tl_host_e;
-
-endpackage
diff --git a/verilog/rtl/tl_xbar_main.sv b/verilog/rtl/tl_xbar_main.sv
deleted file mode 100644
index 65f3a0b..0000000
--- a/verilog/rtl/tl_xbar_main.sv
+++ /dev/null
@@ -1,424 +0,0 @@
-
-// main XBAR
-
-module tl_xbar_main (
-
- input clk_i,
- input rst_ni,
-
-
- // Host interfaces
- input tlul_pkg::tl_h2d_t tl_brqif_i,
- output tlul_pkg::tl_d2h_t tl_brqif_o,
- input tlul_pkg::tl_h2d_t tl_brqlsu_i,
- output tlul_pkg::tl_d2h_t tl_brqlsu_o,
- input tlul_pkg::tl_h2d_t tl_dm_sba_i,
- output tlul_pkg::tl_d2h_t tl_dm_sba_o,
-
- // Device interfaces
- output tlul_pkg::tl_h2d_t tl_iccm_o,
- input tlul_pkg::tl_d2h_t tl_iccm_i,
- output tlul_pkg::tl_h2d_t tl_debug_rom_o,
- input tlul_pkg::tl_d2h_t tl_debug_rom_i,
- output tlul_pkg::tl_h2d_t tl_dccm_o,
- input tlul_pkg::tl_d2h_t tl_dccm_i,
- output tlul_pkg::tl_h2d_t tl_timer0_o,
- input tlul_pkg::tl_d2h_t tl_timer0_i,
- output tlul_pkg::tl_h2d_t tl_uart_o,
- input tlul_pkg::tl_d2h_t tl_uart_i,
- output tlul_pkg::tl_h2d_t tl_spi_o,
- input tlul_pkg::tl_d2h_t tl_spi_i,
- output tlul_pkg::tl_h2d_t tl_pwm_o,
- input tlul_pkg::tl_d2h_t tl_pwm_i,
- output tlul_pkg::tl_h2d_t tl_gpio_o,
- input tlul_pkg::tl_d2h_t tl_gpio_i,
- output tlul_pkg::tl_h2d_t tl_plic_o,
- input tlul_pkg::tl_d2h_t tl_plic_i
-
-
-);
-
- import tlul_pkg::*;
- import tl_main_pkg::*;
-
- // scanmode_i is currently not used, but provisioned for future use
- // this assignment prevents lint warnings
-
-
-// host 1 IFU
- tlul_pkg::tl_h2d_t brqifu_to_s1n;
- tlul_pkg::tl_d2h_t s1n_to_brqifu;
- logic [1:0] device_sel_1;
-
-// host 2 LSU
- tlul_pkg::tl_h2d_t brqlsu_to_s1n;
- tlul_pkg::tl_d2h_t s1n_to_brqlsu;
- logic [3:0] device_sel_2;
-
-// host 3 debug system bus access
- tlul_pkg::tl_h2d_t dbg_to_s1n;
- tlul_pkg::tl_d2h_t s1n_to_dbg;
- logic [3:0] device_sel_3;
-
-// Dveice connections
-
- tlul_pkg::tl_h2d_t h1_dv_i[2];
- tlul_pkg::tl_d2h_t h1_dv_o[2];
- tlul_pkg::tl_h2d_t h2_dv_i[9];
- tlul_pkg::tl_d2h_t h2_dv_o[9];
- tlul_pkg::tl_h2d_t h3_dv_i[8];
- tlul_pkg::tl_d2h_t h3_dv_o[8];
-
-// ICCM
- tlul_pkg::tl_h2d_t s1n_sm1_1[3];
- tlul_pkg::tl_d2h_t sm1_s1n_1[3];
-
-// DCCM
- tlul_pkg::tl_h2d_t s1n_sm1_2[2];
- tlul_pkg::tl_d2h_t sm1_s1n_2[2];
-
-// DEBUG ROM
- tlul_pkg::tl_h2d_t s1n_sm1_4[2];
- tlul_pkg::tl_d2h_t sm1_s1n_4[2];
-
-// TIMER
- tlul_pkg::tl_h2d_t s1n_sm1_5[2];
- tlul_pkg::tl_d2h_t sm1_s1n_5[2];
-
-// UART
- tlul_pkg::tl_h2d_t s1n_sm1_6[2];
- tlul_pkg::tl_d2h_t sm1_s1n_6[2];
-
-// SPI
- tlul_pkg::tl_h2d_t s1n_sm1_7[2];
- tlul_pkg::tl_d2h_t sm1_s1n_7[2];
-
-// PWM
- tlul_pkg::tl_h2d_t s1n_sm1_8[2];
- tlul_pkg::tl_d2h_t sm1_s1n_8[2];
-
-// GPIO
- tlul_pkg::tl_h2d_t s1n_sm1_9[2];
- tlul_pkg::tl_d2h_t sm1_s1n_9[2];
-
-// PLIC
- tlul_pkg::tl_h2d_t s1n_sm1_10[2];
- tlul_pkg::tl_d2h_t sm1_s1n_10[2];
-
-// Device 1 host connections (ICCM)
- assign h1_dv_o[0] = sm1_s1n_1[0];
- assign h3_dv_o[1] = sm1_s1n_1[1];
- assign h2_dv_o[8] = sm1_s1n_1[2];
- assign s1n_sm1_1[0] = h1_dv_i[0];
- assign s1n_sm1_1[1] = h3_dv_i[1];
- assign s1n_sm1_1[2] = h2_dv_i[8];
-
-// Device 2 host connections (DCCM)
- assign h2_dv_o[0] = sm1_s1n_2[0];
- assign h3_dv_o[0] = sm1_s1n_2[1];
- assign s1n_sm1_2[0] = h2_dv_i[0];
- assign s1n_sm1_2[1] = h3_dv_i[0];
-
-// Device 3 host connections (DEBUG ROM)
- assign h1_dv_o[1] = sm1_s1n_4[0];
- assign h2_dv_o[1] = sm1_s1n_4[1];
- assign s1n_sm1_4[0] = h1_dv_i[1];
- assign s1n_sm1_4[1] = h2_dv_i[1];
-
-// Device 4 host connections (TIMER0)
- assign h2_dv_o[2] = sm1_s1n_5[0];
- assign h3_dv_o[2] = sm1_s1n_5[1];
- assign s1n_sm1_5[0] = h2_dv_i[2];
- assign s1n_sm1_5[1] = h3_dv_i[2];
-
-// Device 5 host connections (UART)
- assign h2_dv_o[3] = sm1_s1n_6[0];
- assign h3_dv_o[3] = sm1_s1n_6[1];
- assign s1n_sm1_6[0] = h2_dv_i[3];
- assign s1n_sm1_6[1] = h3_dv_i[3];
-
-// Device 6 host connections (SPI)
- assign h2_dv_o[4] = sm1_s1n_7[0];
- assign h3_dv_o[4] = sm1_s1n_7[1];
- assign s1n_sm1_7[0] = h2_dv_i[4];
- assign s1n_sm1_7[1] = h3_dv_i[4];
-
-// Device 7 host connections (PWM)
- assign h2_dv_o[5] = sm1_s1n_8[0];
- assign h3_dv_o[5] = sm1_s1n_8[1];
- assign s1n_sm1_8[0] = h2_dv_i[5];
- assign s1n_sm1_8[1] = h3_dv_i[5];
-
-// Device 8 host connections (GPIO)
- assign h2_dv_o[6] = sm1_s1n_9[0];
- assign h3_dv_o[6] = sm1_s1n_9[1];
- assign s1n_sm1_9[0] = h2_dv_i[6];
- assign s1n_sm1_9[1] = h3_dv_i[6];
-
-// Device 9 host connections (PLIC)
- assign h2_dv_o[7] = sm1_s1n_10[0];
- assign h3_dv_o[7] = sm1_s1n_10[1];
- assign s1n_sm1_10[0] = h2_dv_i[7];
- assign s1n_sm1_10[1] = h3_dv_i[7];
-
-
-// hostv 1 connections
- assign brqifu_to_s1n = tl_brqif_i;
- assign tl_brqif_o = s1n_to_brqifu;
-// hostv 2 connections
- assign brqlsu_to_s1n = tl_brqlsu_i;
- assign tl_brqlsu_o = s1n_to_brqlsu;
-// host 3 connections
- assign dbg_to_s1n = tl_dm_sba_i;
- assign tl_dm_sba_o = s1n_to_dbg;
-
-// host 1 device selection
- always_comb begin
- device_sel_1 = 2'd2;
- if((brqifu_to_s1n.a_address & ~(ADDR_MASK_ICCM)) == ADDR_SPACE_ICCM) begin
- device_sel_1 = 2'd0;
- end else if ((brqifu_to_s1n.a_address & ~(ADDR_MASK_DEBUG_ROM)) == ADDR_SPACE_DEBUG_ROM) begin
- device_sel_1 = 2'd1;
- end
- end
-
-// host 1 socket
- tlul_socket_1n #(
- .HReqDepth (4'h0),
- .HRspDepth (4'h0),
- .DReqDepth (12'h0),
- .DRspDepth (12'h0),
- .N (2)
- ) host_1 (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (brqifu_to_s1n),
- .tl_h_o (s1n_to_brqifu),
- .tl_d_o (h1_dv_i),
- .tl_d_i (h1_dv_o),
- .dev_select_i (device_sel_1)
- );
-
-// host 2 socket
- always_comb begin
-
- device_sel_2 = 4'd9;
-
- if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_DCCM)) == ADDR_SPACE_DCCM) begin
- device_sel_2 = 4'd0;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_DEBUG_ROM)) == ADDR_SPACE_DEBUG_ROM) begin
- device_sel_2 = 4'd1;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_TIMER0)) == ADDR_SPACE_TIMER0) begin
- device_sel_2 = 4'd2;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_UART0)) == ADDR_SPACE_UART0) begin
- device_sel_2 = 4'd3;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_SPI0)) == ADDR_SPACE_SPI0) begin
- device_sel_2 = 4'd4;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_PWM)) == ADDR_SPACE_PWM) begin
- device_sel_2 = 4'd5;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_GPIO)) == ADDR_SPACE_GPIO) begin
- device_sel_2 = 4'd6;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_PLIC)) == ADDR_SPACE_PLIC) begin
- device_sel_2 = 4'd7;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_ICCM)) == ADDR_SPACE_ICCM) begin
- device_sel_2 = 4'd8;
- end
- end
-
-// host 2 socket
-
- tlul_socket_1n #(
- .HReqDepth (4'h0),
- .HRspDepth (4'h0),
- .DReqDepth (36'h0),
- .DRspDepth (36'h0),
- .N (9)
- ) host_2 (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (brqlsu_to_s1n),
- .tl_h_o (s1n_to_brqlsu),
- .tl_d_o (h2_dv_i),
- .tl_d_i (h2_dv_o),
- .dev_select_i (device_sel_2)
- );
-
-// host 3 device selection
-
- always_comb begin
-
- device_sel_3 = 4'd8;
-
- if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_DCCM)) == ADDR_SPACE_DCCM) begin
- device_sel_3 = 4'd0;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_ICCM)) == ADDR_SPACE_ICCM) begin
- device_sel_3 = 4'd1;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_TIMER0)) == ADDR_SPACE_TIMER0) begin
- device_sel_3 = 4'd2;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_UART0)) == ADDR_SPACE_UART0) begin
- device_sel_3 = 4'd3;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_SPI0)) == ADDR_SPACE_SPI0) begin
- device_sel_3 = 4'd4;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_PWM)) == ADDR_SPACE_PWM) begin
- device_sel_3 = 4'd5;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_GPIO)) == ADDR_SPACE_GPIO) begin
- device_sel_3 = 4'd6;
- end else if ((brqlsu_to_s1n.a_address & ~(ADDR_MASK_PLIC)) == ADDR_SPACE_PLIC) begin
- device_sel_3 = 4'd7;
- end
- end
-
- tlul_socket_1n #(
- .HReqDepth (4'h0),
- .HRspDepth (4'h0),
- .DReqDepth (36'h0),
- .DRspDepth (36'h0),
- .N (8)
- ) host_3 (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (dbg_to_s1n),
- .tl_h_o (s1n_to_dbg),
- .tl_d_o (h3_dv_i),
- .tl_d_i (h3_dv_o),
- .dev_select_i (device_sel_3)
- );
-
-
-// Devices
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (3)
- ) ICCM (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_1),
- .tl_h_o (sm1_s1n_1),
- .tl_d_o (tl_iccm_o),
- .tl_d_i (tl_iccm_i)
- );
-
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (2)
- ) DCCM (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_2),
- .tl_h_o (sm1_s1n_2),
- .tl_d_o (tl_dccm_o),
- .tl_d_i (tl_dccm_i)
- );
-
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (2)
- ) DEBUG_ROM (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_4),
- .tl_h_o (sm1_s1n_4),
- .tl_d_o (tl_debug_rom_o),
- .tl_d_i (tl_debug_rom_i)
- );
-
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (2)
- ) TIMER (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_5),
- .tl_h_o (sm1_s1n_5),
- .tl_d_o (tl_timer0_o),
- .tl_d_i (tl_timer0_i)
- );
-
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (2)
- ) UART (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_6),
- .tl_h_o (sm1_s1n_6),
- .tl_d_o (tl_uart_o),
- .tl_d_i (tl_uart_i)
- );
-
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (2)
- ) SPI (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_7),
- .tl_h_o (sm1_s1n_7),
- .tl_d_o (tl_spi_o),
- .tl_d_i (tl_spi_i)
- );
-
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (2)
- ) PWM (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_8),
- .tl_h_o (sm1_s1n_8),
- .tl_d_o (tl_pwm_o),
- .tl_d_i (tl_pwm_i)
- );
-
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (2)
- ) GPIO (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_9),
- .tl_h_o (sm1_s1n_9),
- .tl_d_o (tl_gpio_o),
- .tl_d_i (tl_gpio_i)
- );
-
- tlul_socket_m1 #(
- .HReqDepth (8'h0),
- .HRspDepth (8'h0),
- .DReqDepth (4'h0),
- .DRspDepth (4'h0),
- .M (2)
- ) PLIC (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (s1n_sm1_10),
- .tl_h_o (sm1_s1n_10),
- .tl_d_o (tl_plic_o),
- .tl_d_i (tl_plic_i)
- );
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/tlul_adapter_reg.sv b/verilog/rtl/tlul_adapter_reg.sv
deleted file mode 100644
index c801bc5..0000000
--- a/verilog/rtl/tlul_adapter_reg.sv
+++ /dev/null
@@ -1,125 +0,0 @@
-module tlul_adapter_reg import tlul_pkg::*; #(
- parameter int RegAw = 8,
- parameter int RegDw = 32, // Shall be matched with TL_DW
- localparam int RegBw = RegDw/8
-) (
- input clk_i,
- input rst_ni,
-
- // TL-UL interface
- input tl_h2d_t tl_i,
- output tl_d2h_t tl_o,
-
- // Register interface
- output logic re_o,
- output logic we_o,
- output logic [RegAw-1:0] addr_o,
- output logic [RegDw-1:0] wdata_o,
- output logic [RegBw-1:0] be_o,
- input [RegDw-1:0] rdata_i,
- input error_i
-);
-
- localparam int IW = $bits(tl_i.a_source);
- localparam int SZW = $bits(tl_i.a_size);
-
- logic outstanding; // Indicates current request is pending
- logic a_ack, d_ack;
-
- logic [RegDw-1:0] rdata;
- logic error, err_internal;
-
- logic addr_align_err; // Size and alignment
-// logic malformed_meta_err; // User signal format error or unsupported
- logic tl_err; // Common TL-UL error checker
-
- logic [IW-1:0] reqid;
- logic [SZW-1:0] reqsz;
- tlul_pkg::tl_d_m_op rspop;
-
- logic rd_req, wr_req;
-
- assign a_ack = tl_i.a_valid & tl_o.a_ready;
- assign d_ack = tl_o.d_valid & tl_i.d_ready;
- // Request signal
- assign wr_req = a_ack & ((tl_i.a_opcode == PutFullData) | (tl_i.a_opcode == PutPartialData));
- assign rd_req = a_ack & (tl_i.a_opcode == Get);
-
- assign we_o = wr_req & ~err_internal;
- assign re_o = rd_req & ~err_internal;
- assign addr_o = {tl_i.a_address[RegAw-1:2], 2'b00}; // generate always word-align
- assign wdata_o = tl_i.a_data;
- assign be_o = tl_i.a_mask;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) outstanding <= 1'b0;
- else if (a_ack) outstanding <= 1'b1;
- else if (d_ack) outstanding <= 1'b0;
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- reqid <= '0;
- reqsz <= '0;
- rspop <= AccessAck;
- end else if (a_ack) begin
- reqid <= tl_i.a_source;
- reqsz <= tl_i.a_size;
- // Return AccessAckData regardless of error
- rspop <= (rd_req) ? AccessAckData : AccessAck ;
- end
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rdata <= '0;
- error <= 1'b0;
- end else if (a_ack) begin
- rdata <= (err_internal) ? '1 : rdata_i;
- error <= error_i | err_internal;
- end
- end
-
- assign tl_o = '{
- a_ready: ~outstanding,
- d_valid: outstanding,
- d_opcode: rspop,
- d_param: '0,
- d_size: reqsz,
- d_source: reqid,
- d_sink: '0,
- d_data: rdata,
- d_error: error
- };
-
- ////////////////////
- // Error Handling //
- ////////////////////
- assign err_internal = addr_align_err | tl_err ;
-
- // malformed_meta_err
- // Raised if not supported feature is turned on or user signal has malformed
- // assign malformed_meta_err = (tl_i.a_user.parity_en == 1'b1);
-
- // addr_align_err
- // Raised if addr isn't aligned with the size
- // Read size error is checked in tlul_assert.sv
- // Here is it added due to the limitation of register interface.
- always_comb begin
- if (wr_req) begin
- // Only word-align is accepted based on comportability spec
- addr_align_err = |tl_i.a_address[1:0];
- end else begin
- // No request
- addr_align_err = 1'b0;
- end
- end
-
- // tl_err : separate checker
- tlul_err u_err (
- .tl_i (tl_i),
- .err_o (tl_err)
- );
-
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/tlul_err.sv b/verilog/rtl/tlul_err.sv
deleted file mode 100644
index 32d7b67..0000000
--- a/verilog/rtl/tlul_err.sv
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-module tlul_err import tlul_pkg::*; (
-
- input tl_h2d_t tl_i,
-
- output logic err_o
-);
-
- localparam int IW = $bits(tl_i.a_source);
- localparam int SZW = $bits(tl_i.a_size);
- localparam int DW = $bits(tl_i.a_data);
- localparam int MW = $bits(tl_i.a_mask);
- localparam int SubAW = $clog2(DW/8);
-
- logic opcode_allowed, a_config_allowed;
-
- logic op_full, op_partial, op_get;
- assign op_full = (tl_i.a_opcode == PutFullData);
- assign op_partial = (tl_i.a_opcode == PutPartialData);
- assign op_get = (tl_i.a_opcode == Get);
-
- // Anything that doesn't fall into the permitted category, it raises an error
- assign err_o = ~(opcode_allowed & a_config_allowed);
-
- // opcode check
- assign opcode_allowed = (tl_i.a_opcode == PutFullData)
- | (tl_i.a_opcode == PutPartialData)
- | (tl_i.a_opcode == Get);
-
- // a channel configuration check
- logic addr_sz_chk; // address and size alignment check
- logic mask_chk; // inactive lane a_mask check
- logic fulldata_chk; // PutFullData should have size match to mask
-
- logic [MW-1:0] mask;
-
- assign mask = (1 << tl_i.a_address[SubAW-1:0]);
-
- always_comb begin
- addr_sz_chk = 1'b0;
- mask_chk = 1'b0;
- fulldata_chk = 1'b0; // Only valid when opcode is PutFullData
-
- if (tl_i.a_valid) begin
- unique case (tl_i.a_size)
- 'h0: begin // 1 Byte
- addr_sz_chk = 1'b1;
- mask_chk = ~|(tl_i.a_mask & ~mask);
- fulldata_chk = |(tl_i.a_mask & mask);
- end
-
- 'h1: begin // 2 Byte
- addr_sz_chk = ~tl_i.a_address[0];
- // check inactive lanes if lower 2B, check a_mask[3:2], if uppwer 2B, a_mask[1:0]
- mask_chk = (tl_i.a_address[1]) ? ~|(tl_i.a_mask & 4'b0011)
- : ~|(tl_i.a_mask & 4'b1100);
- fulldata_chk = (tl_i.a_address[1]) ? &tl_i.a_mask[3:2] : &tl_i.a_mask[1:0] ;
- end
-
- 'h2: begin // 4 Byte
- addr_sz_chk = ~|tl_i.a_address[SubAW-1:0];
- mask_chk = 1'b1;
- fulldata_chk = &tl_i.a_mask[3:0];
- end
-
- default: begin // else
- addr_sz_chk = 1'b0;
- mask_chk = 1'b0;
- fulldata_chk = 1'b0;
- end
- endcase
- end else begin
- addr_sz_chk = 1'b0;
- mask_chk = 1'b0;
- fulldata_chk = 1'b0;
- end
- end
-
- assign a_config_allowed = addr_sz_chk
- & mask_chk
- & (op_get | op_partial | fulldata_chk) ;
-
-
-endmodule
-
diff --git a/verilog/rtl/tlul_err_resp.sv b/verilog/rtl/tlul_err_resp.sv
deleted file mode 100644
index bd5a73c..0000000
--- a/verilog/rtl/tlul_err_resp.sv
+++ /dev/null
@@ -1,56 +0,0 @@
-
-// TL-UL error responder module, used by tlul_socket_1n to help response
-// to requests to no correct address space. Responses are always one cycle
-// after request with no stalling unless response is stuck on the way out.
-//`include "/home/sajjad/Shaheen-sv/src/buraq_core_top/ibex_core/tlul_pkg.sv"
-module tlul_err_resp (
- input clk_i,
- input rst_ni,
- input tlul_pkg::tl_h2d_t tl_h_i,
- output tlul_pkg::tl_d2h_t tl_h_o
-);
- import tlul_pkg::*;
-
- tlul_pkg::tl_a_m_op err_opcode;
-// tlul_pkg::tl_a_m_op get;
- logic [$bits(tl_h_i.a_source)-1:0] err_source;
- logic [$bits(tl_h_i.a_size)-1:0] err_size;
- logic err_req_pending, err_rsp_pending;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- err_req_pending <= 1'b0;
- err_source <= {tlul_pkg::TL_AIW{1'b0}};
- err_opcode <= tlul_pkg::Get;
- err_size <= '0;
- end else if (tl_h_i.a_valid && tl_h_o.a_ready) begin
- err_req_pending <= 1'b1;
- err_source <= tl_h_i.a_source;
- err_opcode <= tl_h_i.a_opcode;
- err_size <= tl_h_i.a_size;
- end else if (!err_rsp_pending) begin
- err_req_pending <= 1'b0;
- end
- end
-
- assign tl_h_o.a_ready = ~err_rsp_pending & ~(err_req_pending & ~tl_h_i.d_ready);
- assign tl_h_o.d_valid = err_req_pending | err_rsp_pending;
- assign tl_h_o.d_data = '1; // Return all F
- assign tl_h_o.d_source = err_source;
- assign tl_h_o.d_sink = '0;
- assign tl_h_o.d_param = '0;
- assign tl_h_o.d_size = err_size;
- assign tl_h_o.d_opcode = (err_opcode == tlul_pkg::Get) ? AccessAckData : AccessAck;
- assign tl_h_o.d_error = 1'b1;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- err_rsp_pending <= 1'b0;
- end else if ((err_req_pending || err_rsp_pending) && !tl_h_i.d_ready) begin
- err_rsp_pending <= 1'b1;
- end else begin
- err_rsp_pending <= 1'b0;
- end
- end
-
-endmodule
diff --git a/verilog/rtl/tlul_fifo_sync.sv b/verilog/rtl/tlul_fifo_sync.sv
deleted file mode 100644
index 917e059..0000000
--- a/verilog/rtl/tlul_fifo_sync.sv
+++ /dev/null
@@ -1,86 +0,0 @@
-
-// TL-UL fifo, used to add elasticity or an asynchronous clock crossing
-// to an TL-UL bus. This instantiates two FIFOs, one for the request side,
-// and one for the response side.
-
-module tlul_fifo_sync #(
- parameter bit ReqPass = 1'b1,
- parameter bit RspPass = 1'b1,
- parameter int unsigned ReqDepth = 0,
- parameter int unsigned RspDepth = 0,
- parameter int unsigned SpareReqW = 1,
- parameter int unsigned SpareRspW = 1
-) (
- input clk_i,
- input rst_ni,
- input tlul_pkg::tl_h2d_t tl_h_i,
- output tlul_pkg::tl_d2h_t tl_h_o,
- output tlul_pkg::tl_h2d_t tl_d_o,
- input tlul_pkg::tl_d2h_t tl_d_i,
- input [SpareReqW-1:0] spare_req_i,
- output [SpareReqW-1:0] spare_req_o,
- input [SpareRspW-1:0] spare_rsp_i,
- output [SpareRspW-1:0] spare_rsp_o
-);
-
- // Put everything on the request side into one FIFO
- localparam int unsigned REQFIFO_WIDTH = $bits(tlul_pkg::tl_h2d_t) -2 + SpareReqW;
-
- fifo_sync #(.Width(REQFIFO_WIDTH), .Pass(ReqPass), .Depth(ReqDepth)) reqfifo (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .clr_i (1'b0 ),
- .wvalid_i (tl_h_i.a_valid),
- .wready_o (tl_h_o.a_ready),
- .wdata_i ({tl_h_i.a_opcode ,
- tl_h_i.a_param ,
- tl_h_i.a_size ,
- tl_h_i.a_source ,
- tl_h_i.a_address,
- tl_h_i.a_mask ,
- tl_h_i.a_data ,
- spare_req_i}),
- .depth_o (),
- .rvalid_o (tl_d_o.a_valid),
- .rready_i (tl_d_i.a_ready),
- .rdata_o ({tl_d_o.a_opcode ,
- tl_d_o.a_param ,
- tl_d_o.a_size ,
- tl_d_o.a_source ,
- tl_d_o.a_address,
- tl_d_o.a_mask ,
- tl_d_o.a_data ,
- spare_req_o}));
-
- // Put everything on the response side into the other FIFO
-
- localparam int unsigned RSPFIFO_WIDTH = $bits(tlul_pkg::tl_d2h_t) -2 + SpareRspW;
-
- fifo_sync #(.Width(RSPFIFO_WIDTH), .Pass(RspPass), .Depth(RspDepth)) rspfifo (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .clr_i (1'b0 ),
- .wvalid_i (tl_d_i.d_valid),
- .wready_o (tl_d_o.d_ready),
- .wdata_i ({tl_d_i.d_opcode,
- tl_d_i.d_param ,
- tl_d_i.d_size ,
- tl_d_i.d_source,
- tl_d_i.d_sink ,
- (tl_d_i.d_opcode == tlul_pkg::AccessAckData) ? tl_d_i.d_data :
- {tlul_pkg::TL_DW{1'b0}} ,
- tl_d_i.d_error ,
- spare_rsp_i}),
- .depth_o (),
- .rvalid_o (tl_h_o.d_valid),
- .rready_i (tl_h_i.d_ready),
- .rdata_o ({tl_h_o.d_opcode,
- tl_h_o.d_param ,
- tl_h_o.d_size ,
- tl_h_o.d_source,
- tl_h_o.d_sink ,
- tl_h_o.d_data ,
- tl_h_o.d_error ,
- spare_rsp_o}));
-
-endmodule
diff --git a/verilog/rtl/tlul_host_adapter.sv b/verilog/rtl/tlul_host_adapter.sv
deleted file mode 100644
index 8d18df5..0000000
--- a/verilog/rtl/tlul_host_adapter.sv
+++ /dev/null
@@ -1,95 +0,0 @@
-// tlul_adapter (Host adapter) converts basic req/grant/rvalid into TL-UL interface. If
-// MAX_REQS == 1 it is purely combinational logic. If MAX_REQS > 1 flops are required.
-//
-// The host driving the adapter is responsible for ensuring it doesn't have more requests in flight
-// than the specified MAX_REQS.
-//
-// The outgoing address is always word aligned. The access size is always the word size (as
-// specified by TL_DW). For write accesses that occupy all lanes the operation is PutFullData,
-// otherwise it is PutPartialData, mask is generated from be_i. For reads all lanes are enabled as
-// required by TL-UL (every bit in mask set).
-//
-// When MAX_REQS > 1 tlul_adapter_host does not do anything to order responses from the TL-UL
-// interface which could return them out of order. It is the host's responsibility to either only
-// have outstanding requests to an address space it knows will return responses in order or to not
-// care about out of order responses (note that if read data is returned out of order there is no
-// way to determine this).
-
-module tlul_host_adapter #(
- parameter int unsigned MAX_REQS = 1
-) (
- input clk_i,
- input rst_ni,
-// interface with host agent
- input req_i,
- output logic gnt_o,
- input logic [tlul_pkg::TL_AW-1:0] addr_i,
- input logic we_i,
- input logic [tlul_pkg::TL_DW-1:0] wdata_i,
- input logic [tlul_pkg::TL_DBW-1:0] be_i,
- output logic valid_o,
- output logic [tlul_pkg::TL_DW-1:0] rdata_o,
- output logic err_o,
-// interface with other tilelink agents or tlul interface
- output tlul_pkg::tl_h2d_t tl_h_c_a, // tilelink host channel A
- input tlul_pkg::tl_d2h_t tl_h_c_d // tilelink host channel D
-);
-
- localparam int WordSize = $clog2(tlul_pkg::TL_DBW);
-
- logic [tlul_pkg::TL_AIW-1:0] tl_source;
- logic [tlul_pkg::TL_DBW-1:0] tl_be;
-
- if(MAX_REQS == 1) begin
- assign tl_source = '0;
- end else begin
- localparam int ReqNumW = $clog2(MAX_REQS);
- logic [ReqNumW-1:0] source_d, source_q;
-
- always_ff @(posedge clk_i) begin
- if(!rst_ni) begin
- source_q <= '0;
- end else begin
- source_q <= source_d;
- end
- end
-
-
- always_comb begin
- source_d = source_q;
-
- if(req_i && gnt_o) begin
- if(source_q == MAX_REQS -1) source_d = '0;
- else source_d = source_q + 1;
- end
- end
- assign tl_source = tlul_pkg::TL_AIW'(source_q);
- end
-
-// For TL-UL Get opcode all active bytes must have their mask bit set, so all reads get all tl_be
-// bits set. For writes the supplied be_i is used as the mask.
- assign tl_be = ~we_i ? {tlul_pkg::TL_DBW{1'b1}} : be_i;
-
- assign tl_h_c_a = '{
- a_valid: req_i,
- a_opcode: (~we_i) ? tlul_pkg::Get :
- (&be_i) ? tlul_pkg::PutFullData :
- tlul_pkg::PutPartialData,
- a_param: 3'h0,
- a_size: tlul_pkg::TL_SZW'(WordSize),
- a_mask: tl_be,
- a_source: tl_source,
- a_address: {addr_i[31:WordSize], {WordSize{1'b0}}},
- a_data: wdata_i,
- d_ready: 1'b1
- };
-
- assign gnt_o = tl_h_c_d.a_ready;
- //assign rdata_0 = tl_h_c_d.d_data;
- assign err_o = tl_h_c_d.d_error;
- assign valid_o = tl_h_c_d.d_valid;
- logic [31:0] rddata;
- assign rddata = tl_h_c_d.d_data;
- assign rdata_o = rddata;
-
-endmodule
\ No newline at end of file
diff --git a/verilog/rtl/tlul_pkg.sv b/verilog/rtl/tlul_pkg.sv
deleted file mode 100644
index 9da373f..0000000
--- a/verilog/rtl/tlul_pkg.sv
+++ /dev/null
@@ -1,120 +0,0 @@
-package tlul_pkg;
-
-
- parameter ArbiterImpl = "PPC";
-function automatic integer _clog2(integer value);
- integer result;
- value = value - 1;
- for (result = 0; value > 0; result = result + 1) begin
- value = value >> 1;
- end
- return result;
- endfunction
-
-
- /**
- * Math function: Number of bits needed to address |value| items.
- *
- * 0 for value == 0
- * vbits = 1 for value == 1
- * ceil(log2(value)) for value > 1
- *
- *
- * The primary use case for this function is the definition of registers/arrays
- * which are wide enough to contain |value| items.
- *
- * This function identical to $clog2() for all input values except the value 1;
- * it could be considered an "enhanced" $clog2() function.
- *
- *
- * Example 1:
- * parameter Items = 1;
- * localparam ItemsWidth = vbits(Items); // 1
- * logic [ItemsWidth-1:0] item_register; // items_register is now [0:0]
- *
- * Example 2:
- * parameter Items = 64;
- * localparam ItemsWidth = vbits(Items); // 6
- * logic [ItemsWidth-1:0] item_register; // items_register is now [5:0]
- *
- * Note: If you want to store the number "value" inside a register, you need
- * a register with size vbits(value + 1), since you also need to store
- * the number 0.
- *
- * Example 3:
- * logic [vbits(64)-1:0] store_64_logic_values; // width is [5:0]
- * logic [vbits(64 + 1)-1:0] store_number_64; // width is [6:0]
- */
- function automatic integer vbits(integer value);
-`ifdef XCELIUM
- // The use of system functions was not allowed here in Verilog-2001, but is
- // valid since (System)Verilog-2005, which is also when $clog2() first
- // appeared.
- // Xcelium < 19.10 does not yet support the use of $clog2() here, fall back
- // to an implementation without a system function. Remove this workaround
- // if we require a newer Xcelium version.
- // See #2579 and #2597.
- return (value == 1) ? 1 : prim_util_pkg::_clog2(value);
-`else
- return (value == 1) ? 1 : $clog2(value);
-`endif
- endfunction
-
- localparam int TL_AW=32;
- localparam int TL_DW=32;
- localparam int TL_AIW=8;
- localparam int TL_DIW=1;
- localparam int TL_DBW=(TL_DW>>3);
- localparam int TL_SZW=$clog2($clog2(TL_DBW)+1);
-
-// opcodes for channel D messages/operations defined in official TileLink spec
- typedef enum logic [2:0] {
- PutFullData = 3'h0,
- PutPartialData = 3'h1,
- Get = 3'h4
- } tl_a_m_op;
-// opcodes for channel D messages/operations defined in official TileLink spec
- typedef enum logic [2:0] {
- AccessAck = 3'h0,
- AccessAckData = 3'h1
- } tl_d_m_op;
-
- typedef struct packed {
- logic a_valid;
- tl_a_m_op a_opcode;
- logic [2:0] a_param;
- logic [TL_SZW-1:0] a_size;
- logic [TL_AIW-1:0] a_source;
- logic [TL_AW-1:0] a_address;
- logic [TL_DBW-1:0] a_mask;
- logic [TL_DW-1:0] a_data;
- logic d_ready;
- } tl_h2d_t;
-
- localparam tl_h2d_t TL_H2D_DEFAULT = '{
- d_ready: 1'b1,
- a_opcode: tl_a_m_op'('0),
- default: '0
- };
-
- typedef struct packed {
- logic d_valid;
- tl_d_m_op d_opcode;
- logic [2:0] d_param;
- logic [TL_SZW-1:0] d_size;
- logic [TL_AIW-1:0] d_source;
- logic [TL_DIW-1:0] d_sink;
- logic [TL_DW-1:0] d_data;
- logic d_error;
- logic a_ready;
- } tl_d2h_t;
-
- localparam tl_d2h_t TL_D2H_DEFAULT = '{
- a_ready: 1'b1,
- d_opcode: tl_d_m_op'('0),
- default: '0
- };
-
-
-
-endpackage
diff --git a/verilog/rtl/tlul_socket_1n.sv b/verilog/rtl/tlul_socket_1n.sv
deleted file mode 100644
index 8ab6bdb..0000000
--- a/verilog/rtl/tlul_socket_1n.sv
+++ /dev/null
@@ -1,209 +0,0 @@
-
-// TL-UL socket 1:N module
-//
-// configuration settings
-// device_count: 4
-//
-// Verilog parameters
-// HReqPass: if 1 then host requests can pass through on empty fifo,
-// default 1
-// HRspPass: if 1 then host responses can pass through on empty fifo,
-// default 1
-// DReqPass: (one per device_count) if 1 then device i requests can
-// pass through on empty fifo, default 1
-// DRspPass: (one per device_count) if 1 then device i responses can
-// pass through on empty fifo, default 1
-// HReqDepth: Depth of host request FIFO, default 2
-// HRspDepth: Depth of host response FIFO, default 2
-// DReqDepth: (one per device_count) Depth of device i request FIFO,
-// default 2
-// DRspDepth: (one per device_count) Depth of device i response FIFO,
-// default 2
-//
-// Requests must stall to one device until all responses from other devices
-// have returned. Need to keep a counter of all outstanding requests and
-// wait until that counter is zero before switching devices.
-//
-// This module will return a request error if the input value of 'dev_select_i'
-// is not within the range 0..N-1. Thus the instantiator of the socket
-// can indicate error by any illegal value of dev_select_i. 4'b1111 is
-// recommended for visibility
-//
-// The maximum value of N is 15
-
-
-module tlul_socket_1n #(
- parameter int unsigned N = 4,
- parameter bit HReqPass = 1'b1,
- parameter bit HRspPass = 1'b1,
- parameter bit [N-1:0] DReqPass = {N{1'b1}},
- parameter bit [N-1:0] DRspPass = {N{1'b1}},
- parameter bit [3:0] HReqDepth = 4'h2,
- parameter bit [3:0] HRspDepth = 4'h2,
- parameter bit [N*4-1:0] DReqDepth = {N{4'h2}},
- parameter bit [N*4-1:0] DRspDepth = {N{4'h2}},
- localparam int unsigned NWD = $clog2(N+1) // derived parameter
-) (
- input clk_i,
- input rst_ni,
- input tlul_pkg::tl_h2d_t tl_h_i,
- output tlul_pkg::tl_d2h_t tl_h_o,
- output tlul_pkg::tl_h2d_t tl_d_o [N],
- input tlul_pkg::tl_d2h_t tl_d_i [N],
- input [NWD-1:0] dev_select_i
-);
-
- // Since our steering is done after potential FIFOing, we need to
- // shove our device select bits into spare bits of reqfifo
-
- // instantiate the host fifo, create intermediate bus 't'
-
- // FIFO'd version of device select
- logic [NWD-1:0] dev_select_t;
-
- tlul_pkg::tl_h2d_t tl_t_o;
- tlul_pkg::tl_d2h_t tl_t_i;
-
- tlul_fifo_sync #(
- .ReqPass(HReqPass),
- .RspPass(HRspPass),
- .ReqDepth(HReqDepth),
- .RspDepth(HRspDepth),
- .SpareReqW(NWD)
- ) fifo_h (
- .clk_i,
- .rst_ni,
- .tl_h_i,
- .tl_h_o,
- .tl_d_o (tl_t_o),
- .tl_d_i (tl_t_i),
- .spare_req_i (dev_select_i),
- .spare_req_o (dev_select_t),
- .spare_rsp_i (1'b0),
- .spare_rsp_o ());
-
-
- // We need to keep track of how many requests are outstanding,
- // and to which device. New requests are compared to this and
- // stall until that number is zero.
- localparam int MaxOutstanding = 4**tlul_pkg::TL_AIW; // Up to 256 ounstanding
- localparam int OutstandingW = $clog2(MaxOutstanding+1);
- logic [OutstandingW-1:0] num_req_outstanding;
- logic [NWD-1:0] dev_select_outstanding;
- logic hold_all_requests;
- logic accept_t_req, accept_t_rsp;
-
- assign accept_t_req = tl_t_o.a_valid & tl_t_i.a_ready;
- assign accept_t_rsp = tl_t_i.d_valid & tl_t_o.d_ready;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- num_req_outstanding <= '0;
- dev_select_outstanding <= '0;
- end else if (accept_t_req) begin
- if (!accept_t_rsp) begin
- num_req_outstanding <= num_req_outstanding + 1'b1;
- end
- dev_select_outstanding <= dev_select_t;
- end else if (accept_t_rsp) begin
- num_req_outstanding <= num_req_outstanding - 1'b1;
- end
- end
-
- assign hold_all_requests =
- (num_req_outstanding != '0) &
- (dev_select_t != dev_select_outstanding);
-
- // Make N copies of 't' request side with modified reqvalid, call
- // them 'u[0]' .. 'u[n-1]'.
-
- tlul_pkg::tl_h2d_t tl_u_o [N+1];
- tlul_pkg::tl_d2h_t tl_u_i [N+1];
-
- for (genvar i = 0 ; i < N ; i++) begin : gen_u_o
- assign tl_u_o[i].a_valid = tl_t_o.a_valid &
- (dev_select_t == NWD'(i)) &
- ~hold_all_requests;
- assign tl_u_o[i].a_opcode = tl_t_o.a_opcode;
- assign tl_u_o[i].a_param = tl_t_o.a_param;
- assign tl_u_o[i].a_size = tl_t_o.a_size;
- assign tl_u_o[i].a_source = tl_t_o.a_source;
- assign tl_u_o[i].a_address = tl_t_o.a_address;
- assign tl_u_o[i].a_mask = tl_t_o.a_mask;
- assign tl_u_o[i].a_data = tl_t_o.a_data;
- end
-
- tlul_pkg::tl_d2h_t tl_t_p ;
-
- // for the returning reqready, only look at the device we're addressing
- logic hfifo_reqready;
- always_comb begin
- hfifo_reqready = tl_u_i[N].a_ready; // default to error
- for (int idx = 0 ; idx < N ; idx++) begin
- //if (dev_select_outstanding == NWD'(idx)) hfifo_reqready = tl_u_i[idx].a_ready;
- if (dev_select_t == NWD'(idx)) hfifo_reqready = tl_u_i[idx].a_ready;
- end
- if (hold_all_requests) hfifo_reqready = 1'b0;
- end
- // Adding a_valid as a qualifier. This prevents the a_ready from having unknown value
- // when the address is unknown and the Host TL-UL FIFO is bypass mode.
- assign tl_t_i.a_ready = tl_t_o.a_valid & hfifo_reqready;
-
- always_comb begin
- tl_t_p = tl_u_i[N];
- for (int idx = 0 ; idx < N ; idx++) begin
- if (dev_select_outstanding == NWD'(idx)) tl_t_p = tl_u_i[idx];
- end
- end
- assign tl_t_i.d_valid = tl_t_p.d_valid ;
- assign tl_t_i.d_opcode = tl_t_p.d_opcode;
- assign tl_t_i.d_param = tl_t_p.d_param ;
- assign tl_t_i.d_size = tl_t_p.d_size ;
- assign tl_t_i.d_source = tl_t_p.d_source;
- assign tl_t_i.d_sink = tl_t_p.d_sink ;
- assign tl_t_i.d_data = tl_t_p.d_data ;
- assign tl_t_i.d_error = tl_t_p.d_error ;
-
-
- // accept responses from devices when selected if upstream is accepting
- for (genvar i = 0 ; i < N+1 ; i++) begin : gen_u_o_d_ready
- assign tl_u_o[i].d_ready = tl_t_o.d_ready;
- end
-
- // finally instantiate all device FIFOs and the error responder
- for (genvar i = 0 ; i < N ; i++) begin : gen_dfifo
- tlul_fifo_sync #(
- .ReqPass(DReqPass[i]),
- .RspPass(DRspPass[i]),
- .ReqDepth(DReqDepth[i*4+:4]),
- .RspDepth(DRspDepth[i*4+:4])
- ) fifo_d (
- .clk_i,
- .rst_ni,
- .tl_h_i (tl_u_o[i]),
- .tl_h_o (tl_u_i[i]),
- .tl_d_o (tl_d_o[i]),
- .tl_d_i (tl_d_i[i]),
- .spare_req_i (1'b0),
- .spare_req_o (),
- .spare_rsp_i (1'b0),
- .spare_rsp_o ());
- end
-
- assign tl_u_o[N].a_valid = tl_t_o.a_valid &
- (dev_select_t == NWD'(N)) &
- ~hold_all_requests;
- assign tl_u_o[N].a_opcode = tl_t_o.a_opcode;
- assign tl_u_o[N].a_param = tl_t_o.a_param;
- assign tl_u_o[N].a_size = tl_t_o.a_size;
- assign tl_u_o[N].a_source = tl_t_o.a_source;
- assign tl_u_o[N].a_address = tl_t_o.a_address;
- assign tl_u_o[N].a_mask = tl_t_o.a_mask;
- assign tl_u_o[N].a_data = tl_t_o.a_data;
- tlul_err_resp err_resp (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .tl_h_i (tl_u_o[N]),
- .tl_h_o (tl_u_i[N]));
-
-endmodule
diff --git a/verilog/rtl/tlul_socket_m1.sv b/verilog/rtl/tlul_socket_m1.sv
deleted file mode 100644
index c92bb49..0000000
--- a/verilog/rtl/tlul_socket_m1.sv
+++ /dev/null
@@ -1,245 +0,0 @@
-
-// TL-UL socket M:1 module
-//
-// Verilog parameters
-// M: Number of host ports.
-// HReqPass: M bit array to allow requests to pass through the host i
-// FIFO with no clock delay if the request FIFO is empty. If
-// 1'b0, at least one clock cycle of latency is created.
-// Default is 1'b1.
-// HRspPass: Same as HReqPass but for host response FIFO.
-// HReqDepth: Mx4 bit array. bit[i*4+:4] is depth of host i request FIFO.
-// Depth of zero is allowed if ReqPass is true. A maximum value
-// of 16 is allowed, default is 2.
-// HRspDepth: Same as HReqDepth but for host response FIFO.
-// DReqPass: Same as HReqPass but for device request FIFO.
-// DRspPass: Same as HReqPass but for device response FIFO.
-// DReqDepth: Same as HReqDepth but for device request FIFO.
-// DRspDepth: Same as HReqDepth but for device response FIFO.
-
-module tlul_socket_m1 #(
- parameter int unsigned M = 4,
- parameter bit [M-1:0] HReqPass = {M{1'b1}},
- parameter bit [M-1:0] HRspPass = {M{1'b1}},
- parameter bit [M*4-1:0] HReqDepth = {M{4'h2}},
- parameter bit [M*4-1:0] HRspDepth = {M{4'h2}},
- parameter bit DReqPass = 1'b1,
- parameter bit DRspPass = 1'b1,
- parameter bit [3:0] DReqDepth = 4'h2,
- parameter bit [3:0] DRspDepth = 4'h2
-) (
- input clk_i,
- input rst_ni,
-
- input tlul_pkg::tl_h2d_t tl_h_i [M],
- output tlul_pkg::tl_d2h_t tl_h_o [M],
-
- output tlul_pkg::tl_h2d_t tl_d_o,
- input tlul_pkg::tl_d2h_t tl_d_i
-);
-
- // Signals
- //
- // tl_h_i/o[0] | tl_h_i/o[1] | ... | tl_h_i/o[M-1]
- // | | |
- // u_hostfifo[0] u_hostfifo[1] u_hostfifo[M-1]
- // | | |
- // hreq_fifo_o(i) / hrsp_fifo_i(i)
- // ---------------------------------------
- // | request/grant/req_data |
- // | |
- // | PRIM_ARBITER |
- // | |
- // | arb_valid / arb_ready / arb_data |
- // ---------------------------------------
- // |
- // dreq_fifo_i / drsp_fifo_o
- // |
- // u_devicefifo
- // |
- // tl_d_o/i
- //
- // Required ID width to distinguish between host ports
- // Used in response steering
- localparam int unsigned IDW = tlul_pkg::TL_AIW;
- localparam int unsigned STIDW = $clog2(M);
-
- tlul_pkg::tl_h2d_t hreq_fifo_o [M];
- tlul_pkg::tl_d2h_t hrsp_fifo_i [M];
-
- logic [M-1:0] hrequest;
- logic [M-1:0] hgrant;
-
- tlul_pkg::tl_h2d_t dreq_fifo_i;
- tlul_pkg::tl_d2h_t drsp_fifo_o;
-
- logic arb_valid;
- logic arb_ready;
- tlul_pkg::tl_h2d_t arb_data;
-
- // Host Req/Rsp FIFO
- for (genvar i = 0 ; i < M ; i++) begin : gen_host_fifo
- tlul_pkg::tl_h2d_t hreq_fifo_i;
-
- // ID Shifting
- logic [STIDW-1:0] reqid_sub;
- logic [IDW-1:0] shifted_id;
- assign reqid_sub = i; // can cause conversion error?
- assign shifted_id = {
- tl_h_i[i].a_source[0+:(IDW-STIDW)],
- reqid_sub
- };
-
-
- // assign not connected bits to nc_* signal to make lint happy
- logic [IDW-1 : IDW-STIDW] unused_tl_h_source;
- assign unused_tl_h_source = tl_h_i[i].a_source[IDW-1 -: STIDW];
-
- // Put shifted ID
- assign hreq_fifo_i = '{
- a_valid: tl_h_i[i].a_valid,
- a_opcode: tl_h_i[i].a_opcode,
- a_param: tl_h_i[i].a_param,
- a_size: tl_h_i[i].a_size,
- a_source: shifted_id,
- a_address: tl_h_i[i].a_address,
- a_mask: tl_h_i[i].a_mask,
- a_data: tl_h_i[i].a_data,
- d_ready: tl_h_i[i].d_ready
- };
-
- tlul_fifo_sync #(
- .ReqPass (HReqPass[i]),
- .RspPass (HRspPass[i]),
- .ReqDepth (HReqDepth[i*4+:4]),
- .RspDepth (HRspDepth[i*4+:4]),
- .SpareReqW (1)
- ) u_hostfifo (
- .clk_i,
- .rst_ni,
- .tl_h_i (hreq_fifo_i),
- .tl_h_o (tl_h_o[i]),
- .tl_d_o (hreq_fifo_o[i]),
- .tl_d_i (hrsp_fifo_i[i]),
- .spare_req_i (1'b0),
- .spare_req_o (),
- .spare_rsp_i (1'b0),
- .spare_rsp_o ()
- );
- end
-
- // Device Req/Rsp FIFO
- tlul_fifo_sync #(
- .ReqPass (DReqPass),
- .RspPass (DRspPass),
- .ReqDepth (DReqDepth),
- .RspDepth (DRspDepth),
- .SpareReqW (1)
- ) u_devicefifo (
- .clk_i,
- .rst_ni,
- .tl_h_i (dreq_fifo_i),
- .tl_h_o (drsp_fifo_o),
- .tl_d_o (tl_d_o),
- .tl_d_i (tl_d_i),
- .spare_req_i (1'b0),
- .spare_req_o (),
- .spare_rsp_i (1'b0),
- .spare_rsp_o ()
- );
-
- // Request Arbiter
- for (genvar i = 0 ; i < M ; i++) begin : gen_arbreqgnt
- assign hrequest[i] = hreq_fifo_o[i].a_valid;
- end
-
- assign arb_ready = drsp_fifo_o.a_ready;
-
- if (tlul_pkg::ArbiterImpl == "PPC") begin : gen_arb_ppc
- prim_arbiter_ppc #(
- .N (M),
- .DW ($bits(tlul_pkg::tl_h2d_t)),
- .EnReqStabA (0)
- ) u_reqarb (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .req_i ( hrequest ),
- .data_i ( hreq_fifo_o ),
- .gnt_o ( hgrant ),
- .idx_o ( ),
- .valid_o ( arb_valid ),
- .data_o ( arb_data ),
- .ready_i ( arb_ready )
- );
- end else if (tlul_pkg::ArbiterImpl == "BINTREE") begin : gen_tree_arb
- prim_arbiter_tree #(
- .N (M),
- .DW ($bits(tlul_pkg::tl_h2d_t)),
- .EnReqStabA (0)
- ) u_reqarb (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .req_i ( hrequest ),
- .data_i ( hreq_fifo_o ),
- .gnt_o ( hgrant ),
- .idx_o ( ),
- .valid_o ( arb_valid ),
- .data_o ( arb_data ),
- .ready_i ( arb_ready )
- );
- end else begin : gen_unknown
-
- end
-
- logic [ M-1:0] hfifo_rspvalid;
- logic [ M-1:0] dfifo_rspready;
- logic [IDW-1:0] hfifo_rspid;
- logic dfifo_rspready_merged;
-
- // arb_data --> dreq_fifo_i
- // dreq_fifo_i.hd_rspready <= dfifo_rspready
-
- assign dfifo_rspready_merged = |dfifo_rspready;
- assign dreq_fifo_i = '{
- a_valid: arb_valid,
- a_opcode: arb_data.a_opcode,
- a_param: arb_data.a_param,
- a_size: arb_data.a_size,
- a_source: arb_data.a_source,
- a_address: arb_data.a_address,
- a_mask: arb_data.a_mask,
- a_data: arb_data.a_data,
-
- d_ready: dfifo_rspready_merged
- };
-
- // Response ID steering
- // drsp_fifo_o --> hrsp_fifo_i[i]
-
- // Response ID shifting before put into host fifo
- assign hfifo_rspid = {
- {STIDW{1'b0}},
- drsp_fifo_o.d_source[IDW-1:STIDW]
- };
- for (genvar i = 0 ; i < M ; i++) begin : gen_idrouting
- assign hfifo_rspvalid[i] = drsp_fifo_o.d_valid &
- (drsp_fifo_o.d_source[0+:STIDW] == i);
- assign dfifo_rspready[i] = hreq_fifo_o[i].d_ready &
- (drsp_fifo_o.d_source[0+:STIDW] == i) &
- drsp_fifo_o.d_valid;
-
- assign hrsp_fifo_i[i] = '{
- d_valid: hfifo_rspvalid[i],
- d_opcode: drsp_fifo_o.d_opcode,
- d_param: drsp_fifo_o.d_param,
- d_size: drsp_fifo_o.d_size,
- d_source: hfifo_rspid,
- d_sink: drsp_fifo_o.d_sink,
- d_data: drsp_fifo_o.d_data,
- d_error: drsp_fifo_o.d_error,
- a_ready: hgrant[i]
- };
- end
-
-
-endmodule
diff --git a/verilog/rtl/tlul_sram_adapter.sv b/verilog/rtl/tlul_sram_adapter.sv
deleted file mode 100644
index dc77555..0000000
--- a/verilog/rtl/tlul_sram_adapter.sv
+++ /dev/null
@@ -1,338 +0,0 @@
-/**
- * Tile-Link UL adapter for SRAM-like devices
- *
- * - Intentionally omitted BaseAddr in case of multiple memory maps are used in a SoC,
- * it means that aliasing can happen if target device size in TL-UL crossbar is bigger
- * than SRAM size
- */
-module tlul_sram_adapter #(
- parameter int SramAw = 12,
- parameter int SramDw = 32, // Must be multiple of the TL width
- parameter int Outstanding = 1, // Only one request is accepted
- parameter bit ByteAccess = 1, // 1: true, 0: false
- parameter bit ErrOnWrite = 0, // 1: Writes not allowed, automatically error
- parameter bit ErrOnRead = 0 // 1: Reads not allowed, automatically error
-) (
- input clk_i,
- input rst_ni,
-
- // TL-UL interface
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
-
- // SRAM interface
- output logic req_o,
- input gnt_i,
- output logic we_o,
- output logic [SramAw-1:0] addr_o,
- output logic [SramDw-1:0] wdata_o,
- output logic [SramDw-1:0] wmask_o,
- input [SramDw-1:0] rdata_i,
- input rvalid_i,
- input [1:0] rerror_i // 2 bit error [1]: Uncorrectable, [0]: Correctable
-);
-
- import tlul_pkg::*;
-
- localparam int SramByte = SramDw/8;
- localparam int DataBitWidth = tlul_pkg::vbits(SramByte);
- localparam int WidthMult = SramDw / tlul_pkg::TL_DW;
- localparam int WoffsetWidth = (SramByte == tlul_pkg::TL_DBW) ? 1 :
- DataBitWidth - tlul_pkg::vbits(tlul_pkg::TL_DBW);
-
- typedef struct packed {
- logic [tlul_pkg::TL_DBW-1:0] mask ; // Byte mask within the TL-UL word
- logic [WoffsetWidth-1:0] woffset ; // Offset of the TL-UL word within the SRAM word
- } sram_req_t ;
-
- typedef enum logic [1:0] {
- OpWrite,
- OpRead,
- OpUnknown
- } req_op_e ;
-
- typedef struct packed {
- req_op_e op ;
- logic error ;
- logic [tlul_pkg::TL_SZW-1:0] size ;
- logic [tlul_pkg::TL_AIW-1:0] source ;
- } req_t ;
-
- typedef struct packed {
- logic [SramDw-1:0] data ;
- logic error ;
- } rsp_t ;
-
- localparam int SramReqFifoWidth = $bits(sram_req_t) ;
- localparam int ReqFifoWidth = $bits(req_t) ;
- localparam int RspFifoWidth = $bits(rsp_t) ;
-
- // FIFO signal in case OutStand is greater than 1
- // If request is latched, {write, source} is pushed to req fifo.
- // Req fifo is popped when D channel is acknowledged (v & r)
- // D channel valid is asserted if it is write request or rsp fifo not empty if read.
- logic reqfifo_wvalid, reqfifo_wready;
- logic reqfifo_rvalid, reqfifo_rready;
- req_t reqfifo_wdata, reqfifo_rdata;
-
- logic sramreqfifo_wvalid, sramreqfifo_wready;
- logic sramreqfifo_rready;
- sram_req_t sramreqfifo_wdata, sramreqfifo_rdata;
-
- logic rspfifo_wvalid, rspfifo_wready;
- logic rspfifo_rvalid, rspfifo_rready;
- rsp_t rspfifo_wdata, rspfifo_rdata;
-
- logic error_internal; // Internal protocol error checker
- logic wr_attr_error;
- logic wr_vld_error;
- logic rd_vld_error;
- logic tlul_error; // Error from `tlul_err` module
-
- logic a_ack, d_ack, sram_ack;
- assign a_ack = tl_i.a_valid & tl_o.a_ready ;
- assign d_ack = tl_o.d_valid & tl_i.d_ready ;
- assign sram_ack = req_o & gnt_i ;
-
- // Valid handling
- logic d_valid, d_error;
- always_comb begin
- d_valid = 1'b0;
-
- if (reqfifo_rvalid) begin
- if (reqfifo_rdata.error) begin
- // Return error response. Assume no request went out to SRAM
- d_valid = 1'b1;
- end else if (reqfifo_rdata.op == OpRead) begin
- d_valid = rspfifo_rvalid;
- end else begin
- // Write without error
- d_valid = 1'b1;
- end
- end else begin
- d_valid = 1'b0;
- end
- end
-
- always_comb begin
- d_error = 1'b0;
-
- if (reqfifo_rvalid) begin
- if (reqfifo_rdata.op == OpRead) begin
- d_error = rspfifo_rdata.error | reqfifo_rdata.error;
- end else begin
- d_error = reqfifo_rdata.error;
- end
- end else begin
- d_error = 1'b0;
- end
- end
-
- assign tl_o = '{
- d_valid : d_valid ,
- d_opcode : (d_valid && reqfifo_rdata.op != OpRead) ? AccessAck : AccessAckData,
- d_param : '0,
- d_size : (d_valid) ? reqfifo_rdata.size : '0,
- d_source : (d_valid) ? reqfifo_rdata.source : '0,
- d_sink : 1'b0,
- d_data : (d_valid && rspfifo_rvalid && reqfifo_rdata.op == OpRead)
- ? rspfifo_rdata.data : '0,
- d_error : d_valid && d_error,
-
- a_ready : (gnt_i | error_internal) & reqfifo_wready & sramreqfifo_wready
- };
-
- // a_ready depends on the FIFO full condition and grant from SRAM (or SRAM arbiter)
- // assemble response, including read response, write response, and error for unsupported stuff
-
- // Output to SRAM:
- // Generate request only when no internal error occurs. If error occurs, the request should be
- // dropped and returned error response to the host. So, error to be pushed to reqfifo.
- // In this case, it is assumed the request is granted (may cause ordering issue later?)
- assign req_o = tl_i.a_valid & reqfifo_wready & ~error_internal;
- assign we_o = tl_i.a_valid & logic'(tl_i.a_opcode inside {PutFullData, PutPartialData});
- assign addr_o = (tl_i.a_valid) ? tl_i.a_address[DataBitWidth+:SramAw] : '0;
-
- // Support SRAMs wider than the TL-UL word width by mapping the parts of the
- // TL-UL address which are more fine-granular than the SRAM width to the
- // SRAM write mask.
- logic [WoffsetWidth-1:0] woffset;
- if (tlul_pkg::TL_DW != SramDw) begin : gen_wordwidthadapt
- assign woffset = tl_i.a_address[DataBitWidth-1:tlul_pkg::vbits(tlul_pkg::TL_DBW)];
- end else begin : gen_no_wordwidthadapt
- assign woffset = '0;
- end
-
- // Convert byte mask to SRAM bit mask for writes, and only forward valid data
- logic [WidthMult-1:0][tlul_pkg::TL_DW-1:0] wmask_int;
- logic [WidthMult-1:0][tlul_pkg::TL_DW-1:0] wdata_int;
-
- always_comb begin
- wmask_int = '0;
- wdata_int = '0;
-
- if (tl_i.a_valid) begin
- for (int i = 0 ; i < tlul_pkg::TL_DW/8 ; i++) begin
- wmask_int[woffset][8*i +: 8] = {8{tl_i.a_mask[i]}};
- wdata_int[woffset][8*i +: 8] = (tl_i.a_mask[i] && we_o) ? tl_i.a_data[8*i+:8] : '0;
- end
- end
- end
-
- assign wmask_o = wmask_int;
- assign wdata_o = wdata_int;
-
- // Begin: Request Error Detection
-
- // wr_attr_error: Check if the request size,mask are permitted.
- // Basic check of size, mask, addr align is done in tlul_err module.
- // Here it checks any partial write if ByteAccess isn't allowed.
- assign wr_attr_error = (tl_i.a_opcode == PutFullData || tl_i.a_opcode == PutPartialData) ?
- (ByteAccess == 0) ? (tl_i.a_mask != '1 || tl_i.a_size != 2'h2) : 1'b0 :
- 1'b0;
-
- if (ErrOnWrite == 1) begin : gen_no_writes
- assign wr_vld_error = tl_i.a_opcode != Get;
- end else begin : gen_writes_allowed
- assign wr_vld_error = 1'b0;
- end
-
- if (ErrOnRead == 1) begin: gen_no_reads
- assign rd_vld_error = tl_i.a_opcode == Get;
- end else begin : gen_reads_allowed
- assign rd_vld_error = 1'b0;
- end
-
- tlul_err u_err (
- .tl_i (tl_i),
- .err_o (tlul_error)
- );
-
- assign error_internal = wr_attr_error | wr_vld_error | rd_vld_error | tlul_error;
- // End: Request Error Detection
-
- assign reqfifo_wvalid = a_ack ; // Push to FIFO only when granted
- assign reqfifo_wdata = '{
- op: (tl_i.a_opcode != Get) ? OpWrite : OpRead, // To return AccessAck for opcode error
- error: error_internal,
- size: tl_i.a_size,
- source: tl_i.a_source
- }; // Store the request only. Doesn't have to store data
- assign reqfifo_rready = d_ack ;
-
- // push together with ReqFIFO, pop upon returning read
- assign sramreqfifo_wdata = '{
- mask : tl_i.a_mask,
- woffset : woffset
- };
- assign sramreqfifo_wvalid = sram_ack & ~we_o;
- assign sramreqfifo_rready = rspfifo_wvalid;
-
- assign rspfifo_wvalid = rvalid_i & reqfifo_rvalid;
-
- // Make sure only requested bytes are forwarded
- logic [WidthMult-1:0][tlul_pkg::TL_DW-1:0] rdata;
- logic [WidthMult-1:0][tlul_pkg::TL_DW-1:0] rmask;
- //logic [SramDw-1:0] rmask;
- logic [tlul_pkg::TL_DW-1:0] rdata_tlword;
-
- always_comb begin
- rmask = '0;
- for (int i = 0 ; i < tlul_pkg::TL_DW/8 ; i++) begin
- rmask[sramreqfifo_rdata.woffset][8*i +: 8] = {8{sramreqfifo_rdata.mask[i]}};
- end
- end
-
- assign rdata = rdata_i & rmask;
- assign rdata_tlword = rdata[sramreqfifo_rdata.woffset];
-
- assign rspfifo_wdata = '{
- data : rdata_tlword,
- error: rerror_i[1] // Only care for Uncorrectable error
- };
- assign rspfifo_rready = (reqfifo_rdata.op == OpRead & ~reqfifo_rdata.error)
- ? reqfifo_rready : 1'b0 ;
-
- // This module only cares about uncorrectable errors.
- logic unused_rerror;
- assign unused_rerror = rerror_i[0];
-
- // FIFO instance: REQ, RSP
-
- // ReqFIFO is to store the Access type to match to the Response data.
- // For instance, SRAM accepts the write request but doesn't return the
- // acknowledge. In this case, it may be hard to determine when the D
- // response for the write data should send out if reads/writes are
- // interleaved. So, to make it in-order (even TL-UL allows out-of-order
- // responses), storing the request is necessary. And if the read entry
- // is write op, it is safe to return the response right away. If it is
- // read reqeust, then D response is waiting until read data arrives.
-
- // Notes:
- // The oustanding+1 allows the reqfifo to absorb back to back transactions
- // without any wait states. Alternatively, the depth can be kept as
- // oustanding as long as the outgoing ready is qualified with the acceptance
- // of the response in the same cycle. Doing so however creates a path from
- // ready_i to ready_o, which may not be desireable.
- fifo_sync #(
- .Width (ReqFifoWidth),
- .Pass (1'b0),
- .Depth (Outstanding)
- ) u_reqfifo (
- .clk_i,
- .rst_ni,
- .clr_i (1'b0),
- .wvalid_i(reqfifo_wvalid),
- .wready_o(reqfifo_wready),
- .wdata_i (reqfifo_wdata),
- .depth_o (),
- .rvalid_o(reqfifo_rvalid),
- .rready_i(reqfifo_rready),
- .rdata_o (reqfifo_rdata)
- );
-
- // sramreqfifo:
- // While the ReqFIFO holds the request until it is sent back via TL-UL, the
- // sramreqfifo only needs to hold the mask and word offset until the read
- // data returns from memory.
- fifo_sync #(
- .Width (SramReqFifoWidth),
- .Pass (1'b0),
- .Depth (Outstanding)
- ) u_sramreqfifo (
- .clk_i,
- .rst_ni,
- .clr_i (1'b0),
- .wvalid_i(sramreqfifo_wvalid),
- .wready_o(sramreqfifo_wready),
- .wdata_i (sramreqfifo_wdata),
- .depth_o (),
- .rvalid_o(),
- .rready_i(sramreqfifo_rready),
- .rdata_o (sramreqfifo_rdata)
- );
-
- // Rationale having #Outstanding depth in response FIFO.
- // In normal case, if the host or the crossbar accepts the response data,
- // response FIFO isn't needed. But if in any case it has a chance to be
- // back pressured, the response FIFO should store the returned data not to
- // lose the data from the SRAM interface. Remember, SRAM interface doesn't
- // have back-pressure signal such as read_ready.
- fifo_sync #(
- .Width (RspFifoWidth),
- .Pass (1'b1),
- .Depth (Outstanding)
- ) u_rspfifo (
- .clk_i,
- .rst_ni,
- .clr_i (1'b0),
- .wvalid_i(rspfifo_wvalid),
- .wready_o(rspfifo_wready),
- .wdata_i (rspfifo_wdata),
- .depth_o (),
- .rvalid_o(rspfifo_rvalid),
- .rready_i(rspfifo_rready),
- .rdata_o (rspfifo_rdata)
- );
-
-endmodule
diff --git a/verilog/rtl/uart.sv b/verilog/rtl/uart.sv
deleted file mode 100644
index 090b02b..0000000
--- a/verilog/rtl/uart.sv
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Description: UART top level wrapper file
-
-// `include "prim_assert.sv"
-
-module uart (
- input clk_i,
- input rst_ni,
-
- // Bus Interface
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
-
- // Generic IO
- input cio_rx_i,
- output logic cio_tx_o,
- output logic cio_tx_en_o,
-
- // Interrupts
- output logic intr_tx_watermark_o ,
- output logic intr_rx_watermark_o ,
- output logic intr_tx_empty_o ,
- output logic intr_rx_overflow_o ,
- output logic intr_rx_frame_err_o ,
- output logic intr_rx_break_err_o ,
- output logic intr_rx_timeout_o ,
- output logic intr_rx_parity_err_o
-);
-
- import uart_reg_pkg::*;
-
- uart_reg2hw_t reg2hw;
- uart_hw2reg_t hw2reg;
-
- uart_reg_top u_reg (
- .clk_i,
- .rst_ni,
- .tl_i,
- .tl_o,
- .reg2hw,
- .hw2reg,
-
- .devmode_i (1'b1)
- );
-
- uart_core uart_core (
- .clk_i,
- .rst_ni,
- .reg2hw,
- .hw2reg,
-
- .rx (cio_rx_i ),
- .tx (cio_tx_o ),
-
- .intr_tx_watermark_o,
- .intr_rx_watermark_o,
- .intr_tx_empty_o,
- .intr_rx_overflow_o,
- .intr_rx_frame_err_o,
- .intr_rx_break_err_o,
- .intr_rx_timeout_o,
- .intr_rx_parity_err_o
- );
-
- // always enable the driving out of TX
- assign cio_tx_en_o = 1'b1;
-
- // // Assert Known for outputs
- // `ASSERT_KNOWN(txenKnown, cio_tx_en_o)
- // `ASSERT_KNOWN(txKnown, cio_tx_o, clk_i, !rst_ni || !cio_tx_en_o)
-
- // // Assert Known for interrupts
- // `ASSERT_KNOWN(txWatermarkKnown, intr_tx_watermark_o)
- // `ASSERT_KNOWN(rxWatermarkKnown, intr_rx_watermark_o)
- // `ASSERT_KNOWN(txEmptyKnown, intr_tx_empty_o)
- // `ASSERT_KNOWN(rxOverflowKnown, intr_rx_overflow_o)
- // `ASSERT_KNOWN(rxFrameErrKnown, intr_rx_frame_err_o)
- // `ASSERT_KNOWN(rxBreakErrKnown, intr_rx_break_err_o)
- // `ASSERT_KNOWN(rxTimeoutKnown, intr_rx_timeout_o)
- // `ASSERT_KNOWN(rxParityErrKnown, intr_rx_parity_err_o)
-
-endmodule
diff --git a/verilog/rtl/uart_core.sv b/verilog/rtl/uart_core.sv
deleted file mode 100644
index c205d90..0000000
--- a/verilog/rtl/uart_core.sv
+++ /dev/null
@@ -1,490 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Description: UART core module
-//
-
-module uart_core (
- input clk_i,
- input rst_ni,
-
- input uart_reg_pkg::uart_reg2hw_t reg2hw,
- output uart_reg_pkg::uart_hw2reg_t hw2reg,
-
- input rx,
- output logic tx,
-
- output logic intr_tx_watermark_o,
- output logic intr_rx_watermark_o,
- output logic intr_tx_empty_o,
- output logic intr_rx_overflow_o,
- output logic intr_rx_frame_err_o,
- output logic intr_rx_break_err_o,
- output logic intr_rx_timeout_o,
- output logic intr_rx_parity_err_o
-);
-
- import uart_reg_pkg::*;
-
- localparam int NcoWidth = $bits(reg2hw.ctrl.nco.q);
-
- logic [15:0] rx_val_q;
- logic [7:0] uart_rdata;
- logic tick_baud_x16, rx_tick_baud;
- logic [5:0] tx_fifo_depth, rx_fifo_depth;
- logic [5:0] rx_fifo_depth_prev_q;
- logic [23:0] rx_timeout_count_d, rx_timeout_count_q, uart_rxto_val;
- logic rx_fifo_depth_changed, uart_rxto_en;
- logic tx_enable, rx_enable;
- logic sys_loopback, line_loopback, rxnf_enable;
- logic uart_fifo_rxrst, uart_fifo_txrst;
- logic [2:0] uart_fifo_rxilvl;
- logic [1:0] uart_fifo_txilvl;
- logic ovrd_tx_en, ovrd_tx_val;
- logic [7:0] tx_fifo_data;
- logic tx_fifo_rready, tx_fifo_rvalid;
- logic tx_fifo_wready, tx_uart_idle;
- logic tx_out;
- logic tx_out_q;
- logic [7:0] rx_fifo_data;
- logic rx_valid, rx_fifo_wvalid, rx_fifo_rvalid;
- logic rx_fifo_wready, rx_uart_idle;
- logic rx_sync;
- logic rx_in;
- logic break_err;
- logic [4:0] allzero_cnt_d, allzero_cnt_q;
- logic allzero_err, not_allzero_char;
- logic event_tx_watermark, event_rx_watermark, event_tx_empty, event_rx_overflow;
- logic event_rx_frame_err, event_rx_break_err, event_rx_timeout, event_rx_parity_err;
- logic tx_watermark_d, tx_watermark_prev_q;
- logic rx_watermark_d, rx_watermark_prev_q;
- logic tx_uart_idle_q;
-
- assign tx_enable = reg2hw.ctrl.tx.q;
- assign rx_enable = reg2hw.ctrl.rx.q;
- assign rxnf_enable = reg2hw.ctrl.nf.q;
- assign sys_loopback = reg2hw.ctrl.slpbk.q;
- assign line_loopback = reg2hw.ctrl.llpbk.q;
-
- assign uart_fifo_rxrst = reg2hw.fifo_ctrl.rxrst.q & reg2hw.fifo_ctrl.rxrst.qe;
- assign uart_fifo_txrst = reg2hw.fifo_ctrl.txrst.q & reg2hw.fifo_ctrl.txrst.qe;
- assign uart_fifo_rxilvl = reg2hw.fifo_ctrl.rxilvl.q;
- assign uart_fifo_txilvl = reg2hw.fifo_ctrl.txilvl.q;
-
- assign ovrd_tx_en = reg2hw.ovrd.txen.q;
- assign ovrd_tx_val = reg2hw.ovrd.txval.q;
-
- typedef enum logic {
- BRK_CHK,
- BRK_WAIT
- } break_st_e ;
-
- break_st_e break_st_q;
-
- assign not_allzero_char = rx_valid & (~event_rx_frame_err | (rx_fifo_data != 8'h0));
- assign allzero_err = event_rx_frame_err & (rx_fifo_data == 8'h0);
-
-
- assign allzero_cnt_d = (break_st_q == BRK_WAIT || not_allzero_char) ? 5'h0 :
- //allzero_cnt_q[4] never be 1b without break_st_q as BRK_WAIT
- //allzero_cnt_q[4] ? allzero_cnt_q :
- allzero_err ? allzero_cnt_q + 5'd1 :
- allzero_cnt_q;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) allzero_cnt_q <= '0;
- else if (rx_enable) allzero_cnt_q <= allzero_cnt_d;
- end
-
- // break_err edges in same cycle as event_rx_frame_err edges ; that way the
- // reset-on-read works the same way for break and frame error interrupts.
-
- always_comb begin
- unique case (reg2hw.ctrl.rxblvl.q)
- 2'h0: break_err = allzero_cnt_d >= 5'd2;
- 2'h1: break_err = allzero_cnt_d >= 5'd4;
- 2'h2: break_err = allzero_cnt_d >= 5'd8;
- default: break_err = allzero_cnt_d >= 5'd16;
- endcase
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) break_st_q <= BRK_CHK;
- else begin
- unique case (break_st_q)
- BRK_CHK: begin
- if (event_rx_break_err) break_st_q <= BRK_WAIT;
- end
-
- BRK_WAIT: begin
- if (rx_in) break_st_q <= BRK_CHK;
- end
-
- // default: begin
- // break_st_q <= BRK_CHK;
- //end
- endcase
- end
- end
-
- assign hw2reg.val.d = rx_val_q;
-
- assign hw2reg.rdata.d = uart_rdata;
-
- assign hw2reg.status.rxempty.d = ~rx_fifo_rvalid;
- assign hw2reg.status.rxidle.d = rx_uart_idle;
- assign hw2reg.status.txidle.d = tx_uart_idle & ~tx_fifo_rvalid;
- assign hw2reg.status.txempty.d = ~tx_fifo_rvalid;
- assign hw2reg.status.rxfull.d = ~rx_fifo_wready;
- assign hw2reg.status.txfull.d = ~tx_fifo_wready;
-
- assign hw2reg.fifo_status.txlvl.d = tx_fifo_depth;
- assign hw2reg.fifo_status.rxlvl.d = rx_fifo_depth;
-
- // resets are self-clearing, so need to update FIFO_CTRL
- assign hw2reg.fifo_ctrl.rxilvl.de = 1'b0;
- assign hw2reg.fifo_ctrl.rxilvl.d = 3'h0;
- assign hw2reg.fifo_ctrl.txilvl.de = 1'b0;
- assign hw2reg.fifo_ctrl.txilvl.d = 2'h0;
-
- // NCO 16x Baud Generator
- // output clock rate is:
- // Fin * (NCO/2**NcoWidth)
- logic [NcoWidth:0] nco_sum_q; // extra bit to get the carry
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- nco_sum_q <= 17'h0;
- end else if (tx_enable || rx_enable) begin
- nco_sum_q <= {1'b0,nco_sum_q[NcoWidth-1:0]} + {1'b0,reg2hw.ctrl.nco.q[NcoWidth-1:0]};
- end
- end
-
- assign tick_baud_x16 = nco_sum_q[16];
-
- //////////////
- // TX Logic //
- //////////////
-
- assign tx_fifo_rready = tx_uart_idle & tx_fifo_rvalid & tx_enable;
-
- fifo_sync #(
- .Width (8),
- .Pass (1'b0),
- .Depth (32)
- ) u_uart_txfifo (
- .clk_i,
- .rst_ni,
- .clr_i (uart_fifo_txrst),
- .wvalid_i(reg2hw.wdata.qe),
- .wready_o(tx_fifo_wready),
- .wdata_i (reg2hw.wdata.q),
- .depth_o (tx_fifo_depth),
- .rvalid_o(tx_fifo_rvalid),
- .rready_i(tx_fifo_rready),
- .rdata_o (tx_fifo_data)
- );
-
- uart_tx uart_tx (
- .clk_i,
- .rst_ni,
- .tx_enable,
- .tick_baud_x16,
- .parity_enable (reg2hw.ctrl.parity_en.q),
- .wr (tx_fifo_rready),
- .wr_parity ((^tx_fifo_data) ^ reg2hw.ctrl.parity_odd.q),
- .wr_data (tx_fifo_data),
- .idle (tx_uart_idle),
- .tx (tx_out)
- );
-
- assign tx = line_loopback ? rx : tx_out_q ;
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- tx_out_q <= 1'b1;
- end else if (ovrd_tx_en) begin
- tx_out_q <= ovrd_tx_val ;
- end else if (sys_loopback) begin
- tx_out_q <= 1'b1;
- end else begin
- tx_out_q <= tx_out;
- end
- end
-
- //////////////
- // RX Logic //
- //////////////
-
- // sync the incoming data
- prim_generic_flop_2sync #(
- .Width(1),
- .ResetValue(1'b1)
- ) sync_rx (
- .clk_i,
- .rst_ni,
- .d_i(rx),
- .q_o(rx_sync)
- );
-
- // Based on: en.wikipedia.org/wiki/Repetition_code mentions the use of a majority filter
- // in UART to ignore brief noise spikes
- logic rx_sync_q1, rx_sync_q2, rx_in_mx, rx_in_maj;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rx_sync_q1 <= 1'b1;
- rx_sync_q2 <= 1'b1;
- end else begin
- rx_sync_q1 <= rx_sync;
- rx_sync_q2 <= rx_sync_q1;
- end
- end
-
- assign rx_in_maj = (rx_sync & rx_sync_q1) |
- (rx_sync & rx_sync_q2) |
- (rx_sync_q1 & rx_sync_q2);
- assign rx_in_mx = rxnf_enable ? rx_in_maj : rx_sync;
-
- assign rx_in = sys_loopback ? tx_out :
- line_loopback ? 1'b1 :
- rx_in_mx;
-
- uart_rx uart_rx (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .rx_enable (rx_enable),
- .tick_baud_x16 (tick_baud_x16),
- .parity_enable (reg2hw.ctrl.parity_en.q),
- .parity_odd (reg2hw.ctrl.parity_odd.q),
- .tick_baud (rx_tick_baud),
- .rx_valid (rx_valid),
- .rx_data (rx_fifo_data),
- .idle (rx_uart_idle),
- .frame_err (event_rx_frame_err),
- .rx (rx_in),
- .rx_parity_err (event_rx_parity_err)
- );
-
- assign rx_fifo_wvalid = rx_valid & ~event_rx_frame_err & ~event_rx_parity_err;
-
- fifo_sync #(
- .Width (8),
- .Pass (1'b0),
- .Depth (32)
- ) u_uart_rxfifo (
- .clk_i,
- .rst_ni,
- .clr_i (uart_fifo_rxrst),
- .wvalid_i(rx_fifo_wvalid),
- .wready_o(rx_fifo_wready),
- .wdata_i (rx_fifo_data),
- .depth_o (rx_fifo_depth),
- .rvalid_o(rx_fifo_rvalid),
- .rready_i(reg2hw.rdata.re),
- .rdata_o (uart_rdata)
- );
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) rx_val_q <= 16'h0;
- else if (tick_baud_x16) rx_val_q <= {rx_val_q[14:0], rx_in};
- end
-
- ////////////////////////
- // Interrupt & Status //
- ////////////////////////
-
- always_comb begin
- unique case(uart_fifo_txilvl)
- 2'h0: tx_watermark_d = (tx_fifo_depth < 6'd2);
- 2'h1: tx_watermark_d = (tx_fifo_depth < 6'd4);
- 2'h2: tx_watermark_d = (tx_fifo_depth < 6'd8);
- default: tx_watermark_d = (tx_fifo_depth < 6'd16);
- endcase
- end
-
- assign event_tx_watermark = tx_watermark_d & ~tx_watermark_prev_q;
-
- // The empty condition handling is a bit different.
- // If empty rising conditions were detected directly, then every first write of a burst
- // would trigger an empty. This is due to the fact that the uart_tx fsm immediately
- // withdraws the content and asserts "empty".
- // To guard against this false trigger, empty is qualified with idle to extend the window
- // in which software has an opportunity to deposit new data.
- // However, if software deposit speed is TOO slow, this would still be an issue.
- //
- // The alternative software fix is to disable tx_enable until it has a chance to
- // burst in the desired amount of data.
- assign event_tx_empty = ~tx_fifo_rvalid & ~tx_uart_idle_q & tx_uart_idle;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- tx_watermark_prev_q <= 1'b1; // by default watermark condition is true
- rx_watermark_prev_q <= 1'b0; // by default watermark condition is false
- tx_uart_idle_q <= 1'b1;
- end else begin
- tx_watermark_prev_q <= tx_watermark_d;
- rx_watermark_prev_q <= rx_watermark_d;
- tx_uart_idle_q <= tx_uart_idle;
- end
- end
-
- always_comb begin
- unique case(uart_fifo_rxilvl)
- 3'h0: rx_watermark_d = (rx_fifo_depth >= 6'd1);
- 3'h1: rx_watermark_d = (rx_fifo_depth >= 6'd4);
- 3'h2: rx_watermark_d = (rx_fifo_depth >= 6'd8);
- 3'h3: rx_watermark_d = (rx_fifo_depth >= 6'd16);
- 3'h4: rx_watermark_d = (rx_fifo_depth >= 6'd30);
- default: rx_watermark_d = 1'b0;
- endcase
- end
-
- assign event_rx_watermark = rx_watermark_d & ~rx_watermark_prev_q;
-
- // rx timeout interrupt
- assign uart_rxto_en = reg2hw.timeout_ctrl.en.q;
- assign uart_rxto_val = reg2hw.timeout_ctrl.val.q;
-
- assign rx_fifo_depth_changed = (rx_fifo_depth != rx_fifo_depth_prev_q);
-
- assign rx_timeout_count_d =
- // don't count if timeout feature not enabled ;
- // will never reach timeout val + lower power
- (uart_rxto_en == 1'b0) ? 24'd0 :
- // reset count if timeout interrupt is set
- event_rx_timeout ? 24'd0 :
- // reset count upon change in fifo level: covers both read and receiving a new byte
- rx_fifo_depth_changed ? 24'd0 :
- // reset count if no bytes are pending
- (rx_fifo_depth == 5'd0) ? 24'd0 :
- // stop the count at timeout value (this will set the interrupt)
- // Removed below line as when the timeout reaches the value,
- // event occured, and timeout value reset to 0h.
- //(rx_timeout_count_q == uart_rxto_val) ? rx_timeout_count_q :
- // increment if at rx baud tick
- rx_tick_baud ? (rx_timeout_count_q + 24'd1) :
- rx_timeout_count_q;
-
- assign event_rx_timeout = (rx_timeout_count_q == uart_rxto_val) & uart_rxto_en;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rx_timeout_count_q <= 24'd0;
- rx_fifo_depth_prev_q <= 6'd0;
- end else begin
- rx_timeout_count_q <= rx_timeout_count_d;
- rx_fifo_depth_prev_q <= rx_fifo_depth;
- end
- end
-
- assign event_rx_overflow = rx_fifo_wvalid & ~rx_fifo_wready;
- assign event_rx_break_err = break_err & (break_st_q == BRK_CHK);
-
- // instantiate interrupt hardware primitives
-
- prim_intr_hw #(.Width(1)) intr_hw_tx_watermark (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_tx_watermark),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.tx_watermark.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.tx_watermark.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.tx_watermark.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.tx_watermark.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.tx_watermark.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.tx_watermark.d),
- .intr_o (intr_tx_watermark_o)
- );
-
- prim_intr_hw #(.Width(1)) intr_hw_rx_watermark (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_rx_watermark),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_watermark.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.rx_watermark.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.rx_watermark.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.rx_watermark.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_watermark.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.rx_watermark.d),
- .intr_o (intr_rx_watermark_o)
- );
-
- prim_intr_hw #(.Width(1)) intr_hw_tx_empty (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_tx_empty),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.tx_empty.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.tx_empty.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.tx_empty.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.tx_empty.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.tx_empty.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.tx_empty.d),
- .intr_o (intr_tx_empty_o)
- );
-
- prim_intr_hw #(.Width(1)) intr_hw_rx_overflow (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_rx_overflow),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_overflow.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.rx_overflow.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.rx_overflow.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.rx_overflow.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_overflow.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.rx_overflow.d),
- .intr_o (intr_rx_overflow_o)
- );
-
- prim_intr_hw #(.Width(1)) intr_hw_rx_frame_err (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_rx_frame_err),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_frame_err.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.rx_frame_err.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.rx_frame_err.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.rx_frame_err.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_frame_err.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.rx_frame_err.d),
- .intr_o (intr_rx_frame_err_o)
- );
-
- prim_intr_hw #(.Width(1)) intr_hw_rx_break_err (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_rx_break_err),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_break_err.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.rx_break_err.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.rx_break_err.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.rx_break_err.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_break_err.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.rx_break_err.d),
- .intr_o (intr_rx_break_err_o)
- );
-
- prim_intr_hw #(.Width(1)) intr_hw_rx_timeout (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_rx_timeout),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_timeout.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.rx_timeout.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.rx_timeout.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.rx_timeout.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_timeout.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.rx_timeout.d),
- .intr_o (intr_rx_timeout_o)
- );
-
- prim_intr_hw #(.Width(1)) intr_hw_rx_parity_err (
- .clk_i,
- .rst_ni,
- .event_intr_i (event_rx_parity_err),
- .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rx_parity_err.q),
- .reg2hw_intr_test_q_i (reg2hw.intr_test.rx_parity_err.q),
- .reg2hw_intr_test_qe_i (reg2hw.intr_test.rx_parity_err.qe),
- .reg2hw_intr_state_q_i (reg2hw.intr_state.rx_parity_err.q),
- .hw2reg_intr_state_de_o (hw2reg.intr_state.rx_parity_err.de),
- .hw2reg_intr_state_d_o (hw2reg.intr_state.rx_parity_err.d),
- .intr_o (intr_rx_parity_err_o)
- );
-
-endmodule
diff --git a/verilog/rtl/uart_reg_pkg.sv b/verilog/rtl/uart_reg_pkg.sv
deleted file mode 100644
index 22ae7ac..0000000
--- a/verilog/rtl/uart_reg_pkg.sv
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Package auto-generated by `reggen` containing data structure
-
-package uart_reg_pkg;
-
- // Address width within the block
- parameter int BlockAw = 6;
-
- ////////////////////////////
- // Typedefs for registers //
- ////////////////////////////
- typedef struct packed {
- struct packed {
- logic q;
- } tx_watermark;
- struct packed {
- logic q;
- } rx_watermark;
- struct packed {
- logic q;
- } tx_empty;
- struct packed {
- logic q;
- } rx_overflow;
- struct packed {
- logic q;
- } rx_frame_err;
- struct packed {
- logic q;
- } rx_break_err;
- struct packed {
- logic q;
- } rx_timeout;
- struct packed {
- logic q;
- } rx_parity_err;
- } uart_reg2hw_intr_state_reg_t;
-
- typedef struct packed {
- struct packed {
- logic q;
- } tx_watermark;
- struct packed {
- logic q;
- } rx_watermark;
- struct packed {
- logic q;
- } tx_empty;
- struct packed {
- logic q;
- } rx_overflow;
- struct packed {
- logic q;
- } rx_frame_err;
- struct packed {
- logic q;
- } rx_break_err;
- struct packed {
- logic q;
- } rx_timeout;
- struct packed {
- logic q;
- } rx_parity_err;
- } uart_reg2hw_intr_enable_reg_t;
-
- typedef struct packed {
- struct packed {
- logic q;
- logic qe;
- } tx_watermark;
- struct packed {
- logic q;
- logic qe;
- } rx_watermark;
- struct packed {
- logic q;
- logic qe;
- } tx_empty;
- struct packed {
- logic q;
- logic qe;
- } rx_overflow;
- struct packed {
- logic q;
- logic qe;
- } rx_frame_err;
- struct packed {
- logic q;
- logic qe;
- } rx_break_err;
- struct packed {
- logic q;
- logic qe;
- } rx_timeout;
- struct packed {
- logic q;
- logic qe;
- } rx_parity_err;
- } uart_reg2hw_intr_test_reg_t;
-
- typedef struct packed {
- struct packed {
- logic q;
- } tx;
- struct packed {
- logic q;
- } rx;
- struct packed {
- logic q;
- } nf;
- struct packed {
- logic q;
- } slpbk;
- struct packed {
- logic q;
- } llpbk;
- struct packed {
- logic q;
- } parity_en;
- struct packed {
- logic q;
- } parity_odd;
- struct packed {
- logic [1:0] q;
- } rxblvl;
- struct packed {
- logic [15:0] q;
- } nco;
- } uart_reg2hw_ctrl_reg_t;
-
- typedef struct packed {
- struct packed {
- logic q;
- logic re;
- } txfull;
- struct packed {
- logic q;
- logic re;
- } rxfull;
- struct packed {
- logic q;
- logic re;
- } txempty;
- struct packed {
- logic q;
- logic re;
- } txidle;
- struct packed {
- logic q;
- logic re;
- } rxidle;
- struct packed {
- logic q;
- logic re;
- } rxempty;
- } uart_reg2hw_status_reg_t;
-
- typedef struct packed {
- logic [7:0] q;
- logic re;
- } uart_reg2hw_rdata_reg_t;
-
- typedef struct packed {
- logic [7:0] q;
- logic qe;
- } uart_reg2hw_wdata_reg_t;
-
- typedef struct packed {
- struct packed {
- logic q;
- logic qe;
- } rxrst;
- struct packed {
- logic q;
- logic qe;
- } txrst;
- struct packed {
- logic [2:0] q;
- logic qe;
- } rxilvl;
- struct packed {
- logic [1:0] q;
- logic qe;
- } txilvl;
- } uart_reg2hw_fifo_ctrl_reg_t;
-
- typedef struct packed {
- struct packed {
- logic q;
- } txen;
- struct packed {
- logic q;
- } txval;
- } uart_reg2hw_ovrd_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [23:0] q;
- } val;
- struct packed {
- logic q;
- } en;
- } uart_reg2hw_timeout_ctrl_reg_t;
-
-
- typedef struct packed {
- struct packed {
- logic d;
- logic de;
- } tx_watermark;
- struct packed {
- logic d;
- logic de;
- } rx_watermark;
- struct packed {
- logic d;
- logic de;
- } tx_empty;
- struct packed {
- logic d;
- logic de;
- } rx_overflow;
- struct packed {
- logic d;
- logic de;
- } rx_frame_err;
- struct packed {
- logic d;
- logic de;
- } rx_break_err;
- struct packed {
- logic d;
- logic de;
- } rx_timeout;
- struct packed {
- logic d;
- logic de;
- } rx_parity_err;
- } uart_hw2reg_intr_state_reg_t;
-
- typedef struct packed {
- struct packed {
- logic d;
- } txfull;
- struct packed {
- logic d;
- } rxfull;
- struct packed {
- logic d;
- } txempty;
- struct packed {
- logic d;
- } txidle;
- struct packed {
- logic d;
- } rxidle;
- struct packed {
- logic d;
- } rxempty;
- } uart_hw2reg_status_reg_t;
-
- typedef struct packed {
- logic [7:0] d;
- } uart_hw2reg_rdata_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [2:0] d;
- logic de;
- } rxilvl;
- struct packed {
- logic [1:0] d;
- logic de;
- } txilvl;
- } uart_hw2reg_fifo_ctrl_reg_t;
-
- typedef struct packed {
- struct packed {
- logic [5:0] d;
- } txlvl;
- struct packed {
- logic [5:0] d;
- } rxlvl;
- } uart_hw2reg_fifo_status_reg_t;
-
- typedef struct packed {
- logic [15:0] d;
- } uart_hw2reg_val_reg_t;
-
-
- ///////////////////////////////////////
- // Register to internal design logic //
- ///////////////////////////////////////
- typedef struct packed {
- uart_reg2hw_intr_state_reg_t intr_state; // [124:117]
- uart_reg2hw_intr_enable_reg_t intr_enable; // [116:109]
- uart_reg2hw_intr_test_reg_t intr_test; // [108:93]
- uart_reg2hw_ctrl_reg_t ctrl; // [92:68]
- uart_reg2hw_status_reg_t status; // [67:56]
- uart_reg2hw_rdata_reg_t rdata; // [55:47]
- uart_reg2hw_wdata_reg_t wdata; // [46:38]
- uart_reg2hw_fifo_ctrl_reg_t fifo_ctrl; // [37:27]
- uart_reg2hw_ovrd_reg_t ovrd; // [26:25]
- uart_reg2hw_timeout_ctrl_reg_t timeout_ctrl; // [24:0]
- } uart_reg2hw_t;
-
- ///////////////////////////////////////
- // Internal design logic to register //
- ///////////////////////////////////////
- typedef struct packed {
- uart_hw2reg_intr_state_reg_t intr_state; // [64:49]
- uart_hw2reg_status_reg_t status; // [48:43]
- uart_hw2reg_rdata_reg_t rdata; // [42:35]
- uart_hw2reg_fifo_ctrl_reg_t fifo_ctrl; // [34:28]
- uart_hw2reg_fifo_status_reg_t fifo_status; // [27:16]
- uart_hw2reg_val_reg_t val; // [15:0]
- } uart_hw2reg_t;
-
- // Register Address
- parameter logic [BlockAw-1:0] UART_INTR_STATE_OFFSET = 6'h 0;
- parameter logic [BlockAw-1:0] UART_INTR_ENABLE_OFFSET = 6'h 4;
- parameter logic [BlockAw-1:0] UART_INTR_TEST_OFFSET = 6'h 8;
- parameter logic [BlockAw-1:0] UART_CTRL_OFFSET = 6'h c;
- parameter logic [BlockAw-1:0] UART_STATUS_OFFSET = 6'h 10;
- parameter logic [BlockAw-1:0] UART_RDATA_OFFSET = 6'h 14;
- parameter logic [BlockAw-1:0] UART_WDATA_OFFSET = 6'h 18;
- parameter logic [BlockAw-1:0] UART_FIFO_CTRL_OFFSET = 6'h 1c;
- parameter logic [BlockAw-1:0] UART_FIFO_STATUS_OFFSET = 6'h 20;
- parameter logic [BlockAw-1:0] UART_OVRD_OFFSET = 6'h 24;
- parameter logic [BlockAw-1:0] UART_VAL_OFFSET = 6'h 28;
- parameter logic [BlockAw-1:0] UART_TIMEOUT_CTRL_OFFSET = 6'h 2c;
-
-
- // Register Index
- typedef enum int {
- UART_INTR_STATE,
- UART_INTR_ENABLE,
- UART_INTR_TEST,
- UART_CTRL,
- UART_STATUS,
- UART_RDATA,
- UART_WDATA,
- UART_FIFO_CTRL,
- UART_FIFO_STATUS,
- UART_OVRD,
- UART_VAL,
- UART_TIMEOUT_CTRL
- } uart_id_e;
-
- // Register width information to check illegal writes
- parameter logic [3:0] UART_PERMIT [12] = '{
- 4'b 0001, // index[ 0] UART_INTR_STATE
- 4'b 0001, // index[ 1] UART_INTR_ENABLE
- 4'b 0001, // index[ 2] UART_INTR_TEST
- 4'b 1111, // index[ 3] UART_CTRL
- 4'b 0001, // index[ 4] UART_STATUS
- 4'b 0001, // index[ 5] UART_RDATA
- 4'b 0001, // index[ 6] UART_WDATA
- 4'b 0001, // index[ 7] UART_FIFO_CTRL
- 4'b 0111, // index[ 8] UART_FIFO_STATUS
- 4'b 0001, // index[ 9] UART_OVRD
- 4'b 0011, // index[10] UART_VAL
- 4'b 1111 // index[11] UART_TIMEOUT_CTRL
- };
-endpackage
-
diff --git a/verilog/rtl/uart_reg_top.sv b/verilog/rtl/uart_reg_top.sv
deleted file mode 100644
index 4342e2a..0000000
--- a/verilog/rtl/uart_reg_top.sv
+++ /dev/null
@@ -1,1677 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Register Top module auto-generated by `reggen`
-
-// `include "prim_assert.sv"
-
-module uart_reg_top (
- input clk_i,
- input rst_ni,
-
- // Below Regster interface can be changed
- input tlul_pkg::tl_h2d_t tl_i,
- output tlul_pkg::tl_d2h_t tl_o,
- // To HW
- output uart_reg_pkg::uart_reg2hw_t reg2hw, // Write
- input uart_reg_pkg::uart_hw2reg_t hw2reg, // Read
-
- // Config
- input devmode_i // If 1, explicit error return for unmapped register access
-);
-
- import uart_reg_pkg::* ;
-
- localparam int AW = 6;
- localparam int DW = 32;
- localparam int DBW = DW/8; // Byte Width
-
- // register signals
- logic reg_we;
- logic reg_re;
- logic [AW-1:0] reg_addr;
- logic [DW-1:0] reg_wdata;
- logic [DBW-1:0] reg_be;
- logic [DW-1:0] reg_rdata;
- logic reg_error;
-
- logic addrmiss, wr_err;
-
- logic [DW-1:0] reg_rdata_next;
-
- tlul_pkg::tl_h2d_t tl_reg_h2d;
- tlul_pkg::tl_d2h_t tl_reg_d2h;
-
- assign tl_reg_h2d = tl_i;
- assign tl_o = tl_reg_d2h;
-
- tlul_adapter_reg #(
- .RegAw(AW),
- .RegDw(DW)
- ) u_reg_if (
- .clk_i,
- .rst_ni,
-
- .tl_i (tl_reg_h2d),
- .tl_o (tl_reg_d2h),
-
- .we_o (reg_we),
- .re_o (reg_re),
- .addr_o (reg_addr),
- .wdata_o (reg_wdata),
- .be_o (reg_be),
- .rdata_i (reg_rdata),
- .error_i (reg_error)
- );
-
- assign reg_rdata = reg_rdata_next ;
- assign reg_error = (devmode_i & addrmiss) | wr_err ;
-
- // Define SW related signals
- // Format: <reg>_<field>_{wd|we|qs}
- // or <reg>_{wd|we|qs} if field == 1 or 0
- logic intr_state_tx_watermark_qs;
- logic intr_state_tx_watermark_wd;
- logic intr_state_tx_watermark_we;
- logic intr_state_rx_watermark_qs;
- logic intr_state_rx_watermark_wd;
- logic intr_state_rx_watermark_we;
- logic intr_state_tx_empty_qs;
- logic intr_state_tx_empty_wd;
- logic intr_state_tx_empty_we;
- logic intr_state_rx_overflow_qs;
- logic intr_state_rx_overflow_wd;
- logic intr_state_rx_overflow_we;
- logic intr_state_rx_frame_err_qs;
- logic intr_state_rx_frame_err_wd;
- logic intr_state_rx_frame_err_we;
- logic intr_state_rx_break_err_qs;
- logic intr_state_rx_break_err_wd;
- logic intr_state_rx_break_err_we;
- logic intr_state_rx_timeout_qs;
- logic intr_state_rx_timeout_wd;
- logic intr_state_rx_timeout_we;
- logic intr_state_rx_parity_err_qs;
- logic intr_state_rx_parity_err_wd;
- logic intr_state_rx_parity_err_we;
- logic intr_enable_tx_watermark_qs;
- logic intr_enable_tx_watermark_wd;
- logic intr_enable_tx_watermark_we;
- logic intr_enable_rx_watermark_qs;
- logic intr_enable_rx_watermark_wd;
- logic intr_enable_rx_watermark_we;
- logic intr_enable_tx_empty_qs;
- logic intr_enable_tx_empty_wd;
- logic intr_enable_tx_empty_we;
- logic intr_enable_rx_overflow_qs;
- logic intr_enable_rx_overflow_wd;
- logic intr_enable_rx_overflow_we;
- logic intr_enable_rx_frame_err_qs;
- logic intr_enable_rx_frame_err_wd;
- logic intr_enable_rx_frame_err_we;
- logic intr_enable_rx_break_err_qs;
- logic intr_enable_rx_break_err_wd;
- logic intr_enable_rx_break_err_we;
- logic intr_enable_rx_timeout_qs;
- logic intr_enable_rx_timeout_wd;
- logic intr_enable_rx_timeout_we;
- logic intr_enable_rx_parity_err_qs;
- logic intr_enable_rx_parity_err_wd;
- logic intr_enable_rx_parity_err_we;
- logic intr_test_tx_watermark_wd;
- logic intr_test_tx_watermark_we;
- logic intr_test_rx_watermark_wd;
- logic intr_test_rx_watermark_we;
- logic intr_test_tx_empty_wd;
- logic intr_test_tx_empty_we;
- logic intr_test_rx_overflow_wd;
- logic intr_test_rx_overflow_we;
- logic intr_test_rx_frame_err_wd;
- logic intr_test_rx_frame_err_we;
- logic intr_test_rx_break_err_wd;
- logic intr_test_rx_break_err_we;
- logic intr_test_rx_timeout_wd;
- logic intr_test_rx_timeout_we;
- logic intr_test_rx_parity_err_wd;
- logic intr_test_rx_parity_err_we;
- logic ctrl_tx_qs;
- logic ctrl_tx_wd;
- logic ctrl_tx_we;
- logic ctrl_rx_qs;
- logic ctrl_rx_wd;
- logic ctrl_rx_we;
- logic ctrl_nf_qs;
- logic ctrl_nf_wd;
- logic ctrl_nf_we;
- logic ctrl_slpbk_qs;
- logic ctrl_slpbk_wd;
- logic ctrl_slpbk_we;
- logic ctrl_llpbk_qs;
- logic ctrl_llpbk_wd;
- logic ctrl_llpbk_we;
- logic ctrl_parity_en_qs;
- logic ctrl_parity_en_wd;
- logic ctrl_parity_en_we;
- logic ctrl_parity_odd_qs;
- logic ctrl_parity_odd_wd;
- logic ctrl_parity_odd_we;
- logic [1:0] ctrl_rxblvl_qs;
- logic [1:0] ctrl_rxblvl_wd;
- logic ctrl_rxblvl_we;
- logic [15:0] ctrl_nco_qs;
- logic [15:0] ctrl_nco_wd;
- logic ctrl_nco_we;
- logic status_txfull_qs;
- logic status_txfull_re;
- logic status_rxfull_qs;
- logic status_rxfull_re;
- logic status_txempty_qs;
- logic status_txempty_re;
- logic status_txidle_qs;
- logic status_txidle_re;
- logic status_rxidle_qs;
- logic status_rxidle_re;
- logic status_rxempty_qs;
- logic status_rxempty_re;
- logic [7:0] rdata_qs;
- logic rdata_re;
- logic [7:0] wdata_wd;
- logic wdata_we;
- logic fifo_ctrl_rxrst_wd;
- logic fifo_ctrl_rxrst_we;
- logic fifo_ctrl_txrst_wd;
- logic fifo_ctrl_txrst_we;
- logic [2:0] fifo_ctrl_rxilvl_qs;
- logic [2:0] fifo_ctrl_rxilvl_wd;
- logic fifo_ctrl_rxilvl_we;
- logic [1:0] fifo_ctrl_txilvl_qs;
- logic [1:0] fifo_ctrl_txilvl_wd;
- logic fifo_ctrl_txilvl_we;
- logic [5:0] fifo_status_txlvl_qs;
- logic fifo_status_txlvl_re;
- logic [5:0] fifo_status_rxlvl_qs;
- logic fifo_status_rxlvl_re;
- logic ovrd_txen_qs;
- logic ovrd_txen_wd;
- logic ovrd_txen_we;
- logic ovrd_txval_qs;
- logic ovrd_txval_wd;
- logic ovrd_txval_we;
- logic [15:0] val_qs;
- logic val_re;
- logic [23:0] timeout_ctrl_val_qs;
- logic [23:0] timeout_ctrl_val_wd;
- logic timeout_ctrl_val_we;
- logic timeout_ctrl_en_qs;
- logic timeout_ctrl_en_wd;
- logic timeout_ctrl_en_we;
-
- // Register instances
- // R[intr_state]: V(False)
-
- // F[tx_watermark]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state_tx_watermark (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_tx_watermark_we),
- .wd (intr_state_tx_watermark_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.tx_watermark.de),
- .d (hw2reg.intr_state.tx_watermark.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.tx_watermark.q ),
-
- // to register interface (read)
- .qs (intr_state_tx_watermark_qs)
- );
-
-
- // F[rx_watermark]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state_rx_watermark (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_rx_watermark_we),
- .wd (intr_state_rx_watermark_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.rx_watermark.de),
- .d (hw2reg.intr_state.rx_watermark.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.rx_watermark.q ),
-
- // to register interface (read)
- .qs (intr_state_rx_watermark_qs)
- );
-
-
- // F[tx_empty]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state_tx_empty (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_tx_empty_we),
- .wd (intr_state_tx_empty_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.tx_empty.de),
- .d (hw2reg.intr_state.tx_empty.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.tx_empty.q ),
-
- // to register interface (read)
- .qs (intr_state_tx_empty_qs)
- );
-
-
- // F[rx_overflow]: 3:3
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state_rx_overflow (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_rx_overflow_we),
- .wd (intr_state_rx_overflow_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.rx_overflow.de),
- .d (hw2reg.intr_state.rx_overflow.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.rx_overflow.q ),
-
- // to register interface (read)
- .qs (intr_state_rx_overflow_qs)
- );
-
-
- // F[rx_frame_err]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state_rx_frame_err (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_rx_frame_err_we),
- .wd (intr_state_rx_frame_err_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.rx_frame_err.de),
- .d (hw2reg.intr_state.rx_frame_err.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.rx_frame_err.q ),
-
- // to register interface (read)
- .qs (intr_state_rx_frame_err_qs)
- );
-
-
- // F[rx_break_err]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state_rx_break_err (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_rx_break_err_we),
- .wd (intr_state_rx_break_err_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.rx_break_err.de),
- .d (hw2reg.intr_state.rx_break_err.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.rx_break_err.q ),
-
- // to register interface (read)
- .qs (intr_state_rx_break_err_qs)
- );
-
-
- // F[rx_timeout]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state_rx_timeout (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_rx_timeout_we),
- .wd (intr_state_rx_timeout_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.rx_timeout.de),
- .d (hw2reg.intr_state.rx_timeout.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.rx_timeout.q ),
-
- // to register interface (read)
- .qs (intr_state_rx_timeout_qs)
- );
-
-
- // F[rx_parity_err]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("W1C"),
- .RESVAL (1'h0)
- ) u_intr_state_rx_parity_err (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_state_rx_parity_err_we),
- .wd (intr_state_rx_parity_err_wd),
-
- // from internal hardware
- .de (hw2reg.intr_state.rx_parity_err.de),
- .d (hw2reg.intr_state.rx_parity_err.d ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_state.rx_parity_err.q ),
-
- // to register interface (read)
- .qs (intr_state_rx_parity_err_qs)
- );
-
-
- // R[intr_enable]: V(False)
-
- // F[tx_watermark]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable_tx_watermark (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_tx_watermark_we),
- .wd (intr_enable_tx_watermark_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.tx_watermark.q ),
-
- // to register interface (read)
- .qs (intr_enable_tx_watermark_qs)
- );
-
-
- // F[rx_watermark]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable_rx_watermark (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_rx_watermark_we),
- .wd (intr_enable_rx_watermark_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.rx_watermark.q ),
-
- // to register interface (read)
- .qs (intr_enable_rx_watermark_qs)
- );
-
-
- // F[tx_empty]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable_tx_empty (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_tx_empty_we),
- .wd (intr_enable_tx_empty_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.tx_empty.q ),
-
- // to register interface (read)
- .qs (intr_enable_tx_empty_qs)
- );
-
-
- // F[rx_overflow]: 3:3
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable_rx_overflow (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_rx_overflow_we),
- .wd (intr_enable_rx_overflow_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.rx_overflow.q ),
-
- // to register interface (read)
- .qs (intr_enable_rx_overflow_qs)
- );
-
-
- // F[rx_frame_err]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable_rx_frame_err (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_rx_frame_err_we),
- .wd (intr_enable_rx_frame_err_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.rx_frame_err.q ),
-
- // to register interface (read)
- .qs (intr_enable_rx_frame_err_qs)
- );
-
-
- // F[rx_break_err]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable_rx_break_err (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_rx_break_err_we),
- .wd (intr_enable_rx_break_err_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.rx_break_err.q ),
-
- // to register interface (read)
- .qs (intr_enable_rx_break_err_qs)
- );
-
-
- // F[rx_timeout]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable_rx_timeout (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_rx_timeout_we),
- .wd (intr_enable_rx_timeout_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.rx_timeout.q ),
-
- // to register interface (read)
- .qs (intr_enable_rx_timeout_qs)
- );
-
-
- // F[rx_parity_err]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_intr_enable_rx_parity_err (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (intr_enable_rx_parity_err_we),
- .wd (intr_enable_rx_parity_err_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.intr_enable.rx_parity_err.q ),
-
- // to register interface (read)
- .qs (intr_enable_rx_parity_err_qs)
- );
-
-
- // R[intr_test]: V(True)
-
- // F[tx_watermark]: 0:0
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test_tx_watermark (
- .re (1'b0),
- .we (intr_test_tx_watermark_we),
- .wd (intr_test_tx_watermark_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.tx_watermark.qe),
- .q (reg2hw.intr_test.tx_watermark.q ),
- .qs ()
- );
-
-
- // F[rx_watermark]: 1:1
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test_rx_watermark (
- .re (1'b0),
- .we (intr_test_rx_watermark_we),
- .wd (intr_test_rx_watermark_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.rx_watermark.qe),
- .q (reg2hw.intr_test.rx_watermark.q ),
- .qs ()
- );
-
-
- // F[tx_empty]: 2:2
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test_tx_empty (
- .re (1'b0),
- .we (intr_test_tx_empty_we),
- .wd (intr_test_tx_empty_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.tx_empty.qe),
- .q (reg2hw.intr_test.tx_empty.q ),
- .qs ()
- );
-
-
- // F[rx_overflow]: 3:3
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test_rx_overflow (
- .re (1'b0),
- .we (intr_test_rx_overflow_we),
- .wd (intr_test_rx_overflow_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.rx_overflow.qe),
- .q (reg2hw.intr_test.rx_overflow.q ),
- .qs ()
- );
-
-
- // F[rx_frame_err]: 4:4
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test_rx_frame_err (
- .re (1'b0),
- .we (intr_test_rx_frame_err_we),
- .wd (intr_test_rx_frame_err_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.rx_frame_err.qe),
- .q (reg2hw.intr_test.rx_frame_err.q ),
- .qs ()
- );
-
-
- // F[rx_break_err]: 5:5
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test_rx_break_err (
- .re (1'b0),
- .we (intr_test_rx_break_err_we),
- .wd (intr_test_rx_break_err_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.rx_break_err.qe),
- .q (reg2hw.intr_test.rx_break_err.q ),
- .qs ()
- );
-
-
- // F[rx_timeout]: 6:6
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test_rx_timeout (
- .re (1'b0),
- .we (intr_test_rx_timeout_we),
- .wd (intr_test_rx_timeout_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.rx_timeout.qe),
- .q (reg2hw.intr_test.rx_timeout.q ),
- .qs ()
- );
-
-
- // F[rx_parity_err]: 7:7
- prim_subreg_ext #(
- .DW (1)
- ) u_intr_test_rx_parity_err (
- .re (1'b0),
- .we (intr_test_rx_parity_err_we),
- .wd (intr_test_rx_parity_err_wd),
- .d ('0),
- .qre (),
- .qe (reg2hw.intr_test.rx_parity_err.qe),
- .q (reg2hw.intr_test.rx_parity_err.q ),
- .qs ()
- );
-
-
- // R[ctrl]: V(False)
-
- // F[tx]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ctrl_tx (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_tx_we),
- .wd (ctrl_tx_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.tx.q ),
-
- // to register interface (read)
- .qs (ctrl_tx_qs)
- );
-
-
- // F[rx]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ctrl_rx (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_rx_we),
- .wd (ctrl_rx_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.rx.q ),
-
- // to register interface (read)
- .qs (ctrl_rx_qs)
- );
-
-
- // F[nf]: 2:2
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ctrl_nf (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_nf_we),
- .wd (ctrl_nf_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.nf.q ),
-
- // to register interface (read)
- .qs (ctrl_nf_qs)
- );
-
-
- // F[slpbk]: 4:4
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ctrl_slpbk (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_slpbk_we),
- .wd (ctrl_slpbk_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.slpbk.q ),
-
- // to register interface (read)
- .qs (ctrl_slpbk_qs)
- );
-
-
- // F[llpbk]: 5:5
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ctrl_llpbk (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_llpbk_we),
- .wd (ctrl_llpbk_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.llpbk.q ),
-
- // to register interface (read)
- .qs (ctrl_llpbk_qs)
- );
-
-
- // F[parity_en]: 6:6
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ctrl_parity_en (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_parity_en_we),
- .wd (ctrl_parity_en_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.parity_en.q ),
-
- // to register interface (read)
- .qs (ctrl_parity_en_qs)
- );
-
-
- // F[parity_odd]: 7:7
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ctrl_parity_odd (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_parity_odd_we),
- .wd (ctrl_parity_odd_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.parity_odd.q ),
-
- // to register interface (read)
- .qs (ctrl_parity_odd_qs)
- );
-
-
- // F[rxblvl]: 9:8
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_ctrl_rxblvl (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_rxblvl_we),
- .wd (ctrl_rxblvl_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.rxblvl.q ),
-
- // to register interface (read)
- .qs (ctrl_rxblvl_qs)
- );
-
-
- // F[nco]: 31:16
- prim_subreg #(
- .DW (16),
- .SWACCESS("RW"),
- .RESVAL (16'h0)
- ) u_ctrl_nco (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ctrl_nco_we),
- .wd (ctrl_nco_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ctrl.nco.q ),
-
- // to register interface (read)
- .qs (ctrl_nco_qs)
- );
-
-
- // R[status]: V(True)
-
- // F[txfull]: 0:0
- prim_subreg_ext #(
- .DW (1)
- ) u_status_txfull (
- .re (status_txfull_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.status.txfull.d),
- .qre (reg2hw.status.txfull.re),
- .qe (),
- .q (reg2hw.status.txfull.q ),
- .qs (status_txfull_qs)
- );
-
-
- // F[rxfull]: 1:1
- prim_subreg_ext #(
- .DW (1)
- ) u_status_rxfull (
- .re (status_rxfull_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.status.rxfull.d),
- .qre (reg2hw.status.rxfull.re),
- .qe (),
- .q (reg2hw.status.rxfull.q ),
- .qs (status_rxfull_qs)
- );
-
-
- // F[txempty]: 2:2
- prim_subreg_ext #(
- .DW (1)
- ) u_status_txempty (
- .re (status_txempty_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.status.txempty.d),
- .qre (reg2hw.status.txempty.re),
- .qe (),
- .q (reg2hw.status.txempty.q ),
- .qs (status_txempty_qs)
- );
-
-
- // F[txidle]: 3:3
- prim_subreg_ext #(
- .DW (1)
- ) u_status_txidle (
- .re (status_txidle_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.status.txidle.d),
- .qre (reg2hw.status.txidle.re),
- .qe (),
- .q (reg2hw.status.txidle.q ),
- .qs (status_txidle_qs)
- );
-
-
- // F[rxidle]: 4:4
- prim_subreg_ext #(
- .DW (1)
- ) u_status_rxidle (
- .re (status_rxidle_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.status.rxidle.d),
- .qre (reg2hw.status.rxidle.re),
- .qe (),
- .q (reg2hw.status.rxidle.q ),
- .qs (status_rxidle_qs)
- );
-
-
- // F[rxempty]: 5:5
- prim_subreg_ext #(
- .DW (1)
- ) u_status_rxempty (
- .re (status_rxempty_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.status.rxempty.d),
- .qre (reg2hw.status.rxempty.re),
- .qe (),
- .q (reg2hw.status.rxempty.q ),
- .qs (status_rxempty_qs)
- );
-
-
- // R[rdata]: V(True)
-
- prim_subreg_ext #(
- .DW (8)
- ) u_rdata (
- .re (rdata_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.rdata.d),
- .qre (reg2hw.rdata.re),
- .qe (),
- .q (reg2hw.rdata.q ),
- .qs (rdata_qs)
- );
-
-
- // R[wdata]: V(False)
-
- prim_subreg #(
- .DW (8),
- .SWACCESS("WO"),
- .RESVAL (8'h0)
- ) u_wdata (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (wdata_we),
- .wd (wdata_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (reg2hw.wdata.qe),
- .q (reg2hw.wdata.q ),
-
- .qs ()
- );
-
-
- // R[fifo_ctrl]: V(False)
-
- // F[rxrst]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("WO"),
- .RESVAL (1'h0)
- ) u_fifo_ctrl_rxrst (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (fifo_ctrl_rxrst_we),
- .wd (fifo_ctrl_rxrst_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (reg2hw.fifo_ctrl.rxrst.qe),
- .q (reg2hw.fifo_ctrl.rxrst.q ),
-
- .qs ()
- );
-
-
- // F[txrst]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("WO"),
- .RESVAL (1'h0)
- ) u_fifo_ctrl_txrst (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (fifo_ctrl_txrst_we),
- .wd (fifo_ctrl_txrst_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (reg2hw.fifo_ctrl.txrst.qe),
- .q (reg2hw.fifo_ctrl.txrst.q ),
-
- .qs ()
- );
-
-
- // F[rxilvl]: 4:2
- prim_subreg #(
- .DW (3),
- .SWACCESS("RW"),
- .RESVAL (3'h0)
- ) u_fifo_ctrl_rxilvl (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (fifo_ctrl_rxilvl_we),
- .wd (fifo_ctrl_rxilvl_wd),
-
- // from internal hardware
- .de (hw2reg.fifo_ctrl.rxilvl.de),
- .d (hw2reg.fifo_ctrl.rxilvl.d ),
-
- // to internal hardware
- .qe (reg2hw.fifo_ctrl.rxilvl.qe),
- .q (reg2hw.fifo_ctrl.rxilvl.q ),
-
- // to register interface (read)
- .qs (fifo_ctrl_rxilvl_qs)
- );
-
-
- // F[txilvl]: 6:5
- prim_subreg #(
- .DW (2),
- .SWACCESS("RW"),
- .RESVAL (2'h0)
- ) u_fifo_ctrl_txilvl (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (fifo_ctrl_txilvl_we),
- .wd (fifo_ctrl_txilvl_wd),
-
- // from internal hardware
- .de (hw2reg.fifo_ctrl.txilvl.de),
- .d (hw2reg.fifo_ctrl.txilvl.d ),
-
- // to internal hardware
- .qe (reg2hw.fifo_ctrl.txilvl.qe),
- .q (reg2hw.fifo_ctrl.txilvl.q ),
-
- // to register interface (read)
- .qs (fifo_ctrl_txilvl_qs)
- );
-
-
- // R[fifo_status]: V(True)
-
- // F[txlvl]: 5:0
- prim_subreg_ext #(
- .DW (6)
- ) u_fifo_status_txlvl (
- .re (fifo_status_txlvl_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.fifo_status.txlvl.d),
- .qre (),
- .qe (),
- .q (),
- .qs (fifo_status_txlvl_qs)
- );
-
-
- // F[rxlvl]: 21:16
- prim_subreg_ext #(
- .DW (6)
- ) u_fifo_status_rxlvl (
- .re (fifo_status_rxlvl_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.fifo_status.rxlvl.d),
- .qre (),
- .qe (),
- .q (),
- .qs (fifo_status_rxlvl_qs)
- );
-
-
- // R[ovrd]: V(False)
-
- // F[txen]: 0:0
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ovrd_txen (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ovrd_txen_we),
- .wd (ovrd_txen_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ovrd.txen.q ),
-
- // to register interface (read)
- .qs (ovrd_txen_qs)
- );
-
-
- // F[txval]: 1:1
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_ovrd_txval (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (ovrd_txval_we),
- .wd (ovrd_txval_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.ovrd.txval.q ),
-
- // to register interface (read)
- .qs (ovrd_txval_qs)
- );
-
-
- // R[val]: V(True)
-
- prim_subreg_ext #(
- .DW (16)
- ) u_val (
- .re (val_re),
- .we (1'b0),
- .wd ('0),
- .d (hw2reg.val.d),
- .qre (),
- .qe (),
- .q (),
- .qs (val_qs)
- );
-
-
- // R[timeout_ctrl]: V(False)
-
- // F[val]: 23:0
- prim_subreg #(
- .DW (24),
- .SWACCESS("RW"),
- .RESVAL (24'h0)
- ) u_timeout_ctrl_val (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (timeout_ctrl_val_we),
- .wd (timeout_ctrl_val_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.timeout_ctrl.val.q ),
-
- // to register interface (read)
- .qs (timeout_ctrl_val_qs)
- );
-
-
- // F[en]: 31:31
- prim_subreg #(
- .DW (1),
- .SWACCESS("RW"),
- .RESVAL (1'h0)
- ) u_timeout_ctrl_en (
- .clk_i (clk_i ),
- .rst_ni (rst_ni ),
-
- // from register interface
- .we (timeout_ctrl_en_we),
- .wd (timeout_ctrl_en_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0 ),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.timeout_ctrl.en.q ),
-
- // to register interface (read)
- .qs (timeout_ctrl_en_qs)
- );
-
-
-
-
- logic [11:0] addr_hit;
- always_comb begin
- addr_hit = '0;
- addr_hit[ 0] = (reg_addr == UART_INTR_STATE_OFFSET);
- addr_hit[ 1] = (reg_addr == UART_INTR_ENABLE_OFFSET);
- addr_hit[ 2] = (reg_addr == UART_INTR_TEST_OFFSET);
- addr_hit[ 3] = (reg_addr == UART_CTRL_OFFSET);
- addr_hit[ 4] = (reg_addr == UART_STATUS_OFFSET);
- addr_hit[ 5] = (reg_addr == UART_RDATA_OFFSET);
- addr_hit[ 6] = (reg_addr == UART_WDATA_OFFSET);
- addr_hit[ 7] = (reg_addr == UART_FIFO_CTRL_OFFSET);
- addr_hit[ 8] = (reg_addr == UART_FIFO_STATUS_OFFSET);
- addr_hit[ 9] = (reg_addr == UART_OVRD_OFFSET);
- addr_hit[10] = (reg_addr == UART_VAL_OFFSET);
- addr_hit[11] = (reg_addr == UART_TIMEOUT_CTRL_OFFSET);
- end
-
- assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
-
- // Check sub-word write is permitted
- always_comb begin
- wr_err = 1'b0;
- if (addr_hit[ 0] && reg_we && (UART_PERMIT[ 0] != (UART_PERMIT[ 0] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 1] && reg_we && (UART_PERMIT[ 1] != (UART_PERMIT[ 1] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 2] && reg_we && (UART_PERMIT[ 2] != (UART_PERMIT[ 2] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 3] && reg_we && (UART_PERMIT[ 3] != (UART_PERMIT[ 3] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 4] && reg_we && (UART_PERMIT[ 4] != (UART_PERMIT[ 4] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 5] && reg_we && (UART_PERMIT[ 5] != (UART_PERMIT[ 5] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 6] && reg_we && (UART_PERMIT[ 6] != (UART_PERMIT[ 6] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 7] && reg_we && (UART_PERMIT[ 7] != (UART_PERMIT[ 7] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 8] && reg_we && (UART_PERMIT[ 8] != (UART_PERMIT[ 8] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[ 9] && reg_we && (UART_PERMIT[ 9] != (UART_PERMIT[ 9] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[10] && reg_we && (UART_PERMIT[10] != (UART_PERMIT[10] & reg_be))) wr_err = 1'b1 ;
- if (addr_hit[11] && reg_we && (UART_PERMIT[11] != (UART_PERMIT[11] & reg_be))) wr_err = 1'b1 ;
- end
-
- assign intr_state_tx_watermark_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_tx_watermark_wd = reg_wdata[0];
-
- assign intr_state_rx_watermark_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_rx_watermark_wd = reg_wdata[1];
-
- assign intr_state_tx_empty_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_tx_empty_wd = reg_wdata[2];
-
- assign intr_state_rx_overflow_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_rx_overflow_wd = reg_wdata[3];
-
- assign intr_state_rx_frame_err_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_rx_frame_err_wd = reg_wdata[4];
-
- assign intr_state_rx_break_err_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_rx_break_err_wd = reg_wdata[5];
-
- assign intr_state_rx_timeout_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_rx_timeout_wd = reg_wdata[6];
-
- assign intr_state_rx_parity_err_we = addr_hit[0] & reg_we & ~wr_err;
- assign intr_state_rx_parity_err_wd = reg_wdata[7];
-
- assign intr_enable_tx_watermark_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_tx_watermark_wd = reg_wdata[0];
-
- assign intr_enable_rx_watermark_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_rx_watermark_wd = reg_wdata[1];
-
- assign intr_enable_tx_empty_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_tx_empty_wd = reg_wdata[2];
-
- assign intr_enable_rx_overflow_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_rx_overflow_wd = reg_wdata[3];
-
- assign intr_enable_rx_frame_err_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_rx_frame_err_wd = reg_wdata[4];
-
- assign intr_enable_rx_break_err_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_rx_break_err_wd = reg_wdata[5];
-
- assign intr_enable_rx_timeout_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_rx_timeout_wd = reg_wdata[6];
-
- assign intr_enable_rx_parity_err_we = addr_hit[1] & reg_we & ~wr_err;
- assign intr_enable_rx_parity_err_wd = reg_wdata[7];
-
- assign intr_test_tx_watermark_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_tx_watermark_wd = reg_wdata[0];
-
- assign intr_test_rx_watermark_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_rx_watermark_wd = reg_wdata[1];
-
- assign intr_test_tx_empty_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_tx_empty_wd = reg_wdata[2];
-
- assign intr_test_rx_overflow_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_rx_overflow_wd = reg_wdata[3];
-
- assign intr_test_rx_frame_err_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_rx_frame_err_wd = reg_wdata[4];
-
- assign intr_test_rx_break_err_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_rx_break_err_wd = reg_wdata[5];
-
- assign intr_test_rx_timeout_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_rx_timeout_wd = reg_wdata[6];
-
- assign intr_test_rx_parity_err_we = addr_hit[2] & reg_we & ~wr_err;
- assign intr_test_rx_parity_err_wd = reg_wdata[7];
-
- assign ctrl_tx_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_tx_wd = reg_wdata[0];
-
- assign ctrl_rx_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_rx_wd = reg_wdata[1];
-
- assign ctrl_nf_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_nf_wd = reg_wdata[2];
-
- assign ctrl_slpbk_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_slpbk_wd = reg_wdata[4];
-
- assign ctrl_llpbk_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_llpbk_wd = reg_wdata[5];
-
- assign ctrl_parity_en_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_parity_en_wd = reg_wdata[6];
-
- assign ctrl_parity_odd_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_parity_odd_wd = reg_wdata[7];
-
- assign ctrl_rxblvl_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_rxblvl_wd = reg_wdata[9:8];
-
- assign ctrl_nco_we = addr_hit[3] & reg_we & ~wr_err;
- assign ctrl_nco_wd = reg_wdata[31:16];
-
- assign status_txfull_re = addr_hit[4] && reg_re;
-
- assign status_rxfull_re = addr_hit[4] && reg_re;
-
- assign status_txempty_re = addr_hit[4] && reg_re;
-
- assign status_txidle_re = addr_hit[4] && reg_re;
-
- assign status_rxidle_re = addr_hit[4] && reg_re;
-
- assign status_rxempty_re = addr_hit[4] && reg_re;
-
- assign rdata_re = addr_hit[5] && reg_re;
-
- assign wdata_we = addr_hit[6] & reg_we & ~wr_err;
- assign wdata_wd = reg_wdata[7:0];
-
- assign fifo_ctrl_rxrst_we = addr_hit[7] & reg_we & ~wr_err;
- assign fifo_ctrl_rxrst_wd = reg_wdata[0];
-
- assign fifo_ctrl_txrst_we = addr_hit[7] & reg_we & ~wr_err;
- assign fifo_ctrl_txrst_wd = reg_wdata[1];
-
- assign fifo_ctrl_rxilvl_we = addr_hit[7] & reg_we & ~wr_err;
- assign fifo_ctrl_rxilvl_wd = reg_wdata[4:2];
-
- assign fifo_ctrl_txilvl_we = addr_hit[7] & reg_we & ~wr_err;
- assign fifo_ctrl_txilvl_wd = reg_wdata[6:5];
-
- assign fifo_status_txlvl_re = addr_hit[8] && reg_re;
-
- assign fifo_status_rxlvl_re = addr_hit[8] && reg_re;
-
- assign ovrd_txen_we = addr_hit[9] & reg_we & ~wr_err;
- assign ovrd_txen_wd = reg_wdata[0];
-
- assign ovrd_txval_we = addr_hit[9] & reg_we & ~wr_err;
- assign ovrd_txval_wd = reg_wdata[1];
-
- assign val_re = addr_hit[10] && reg_re;
-
- assign timeout_ctrl_val_we = addr_hit[11] & reg_we & ~wr_err;
- assign timeout_ctrl_val_wd = reg_wdata[23:0];
-
- assign timeout_ctrl_en_we = addr_hit[11] & reg_we & ~wr_err;
- assign timeout_ctrl_en_wd = reg_wdata[31];
-
- // Read data return
- always_comb begin
- reg_rdata_next = '0;
- unique case (1'b1)
- addr_hit[0]: begin
- reg_rdata_next[0] = intr_state_tx_watermark_qs;
- reg_rdata_next[1] = intr_state_rx_watermark_qs;
- reg_rdata_next[2] = intr_state_tx_empty_qs;
- reg_rdata_next[3] = intr_state_rx_overflow_qs;
- reg_rdata_next[4] = intr_state_rx_frame_err_qs;
- reg_rdata_next[5] = intr_state_rx_break_err_qs;
- reg_rdata_next[6] = intr_state_rx_timeout_qs;
- reg_rdata_next[7] = intr_state_rx_parity_err_qs;
- end
-
- addr_hit[1]: begin
- reg_rdata_next[0] = intr_enable_tx_watermark_qs;
- reg_rdata_next[1] = intr_enable_rx_watermark_qs;
- reg_rdata_next[2] = intr_enable_tx_empty_qs;
- reg_rdata_next[3] = intr_enable_rx_overflow_qs;
- reg_rdata_next[4] = intr_enable_rx_frame_err_qs;
- reg_rdata_next[5] = intr_enable_rx_break_err_qs;
- reg_rdata_next[6] = intr_enable_rx_timeout_qs;
- reg_rdata_next[7] = intr_enable_rx_parity_err_qs;
- end
-
- addr_hit[2]: begin
- reg_rdata_next[0] = '0;
- reg_rdata_next[1] = '0;
- reg_rdata_next[2] = '0;
- reg_rdata_next[3] = '0;
- reg_rdata_next[4] = '0;
- reg_rdata_next[5] = '0;
- reg_rdata_next[6] = '0;
- reg_rdata_next[7] = '0;
- end
-
- addr_hit[3]: begin
- reg_rdata_next[0] = ctrl_tx_qs;
- reg_rdata_next[1] = ctrl_rx_qs;
- reg_rdata_next[2] = ctrl_nf_qs;
- reg_rdata_next[4] = ctrl_slpbk_qs;
- reg_rdata_next[5] = ctrl_llpbk_qs;
- reg_rdata_next[6] = ctrl_parity_en_qs;
- reg_rdata_next[7] = ctrl_parity_odd_qs;
- reg_rdata_next[9:8] = ctrl_rxblvl_qs;
- reg_rdata_next[31:16] = ctrl_nco_qs;
- end
-
- addr_hit[4]: begin
- reg_rdata_next[0] = status_txfull_qs;
- reg_rdata_next[1] = status_rxfull_qs;
- reg_rdata_next[2] = status_txempty_qs;
- reg_rdata_next[3] = status_txidle_qs;
- reg_rdata_next[4] = status_rxidle_qs;
- reg_rdata_next[5] = status_rxempty_qs;
- end
-
- addr_hit[5]: begin
- reg_rdata_next[7:0] = rdata_qs;
- end
-
- addr_hit[6]: begin
- reg_rdata_next[7:0] = '0;
- end
-
- addr_hit[7]: begin
- reg_rdata_next[0] = '0;
- reg_rdata_next[1] = '0;
- reg_rdata_next[4:2] = fifo_ctrl_rxilvl_qs;
- reg_rdata_next[6:5] = fifo_ctrl_txilvl_qs;
- end
-
- addr_hit[8]: begin
- reg_rdata_next[5:0] = fifo_status_txlvl_qs;
- reg_rdata_next[21:16] = fifo_status_rxlvl_qs;
- end
-
- addr_hit[9]: begin
- reg_rdata_next[0] = ovrd_txen_qs;
- reg_rdata_next[1] = ovrd_txval_qs;
- end
-
- addr_hit[10]: begin
- reg_rdata_next[15:0] = val_qs;
- end
-
- addr_hit[11]: begin
- reg_rdata_next[23:0] = timeout_ctrl_val_qs;
- reg_rdata_next[31] = timeout_ctrl_en_qs;
- end
-
- default: begin
- reg_rdata_next = '1;
- end
- endcase
- end
-
- // // Assertions for Register Interface
- // `ASSERT_PULSE(wePulse, reg_we)
- // `ASSERT_PULSE(rePulse, reg_re)
-
- // `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
-
- // `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
-
- // // this is formulated as an assumption such that the FPV testbenches do disprove this
- // // property by mistake
- // `ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.parity_en == 1'b0)
-
-endmodule
diff --git a/verilog/rtl/uart_rx.sv b/verilog/rtl/uart_rx.sv
deleted file mode 100644
index 829895a..0000000
--- a/verilog/rtl/uart_rx.sv
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Description: UART Receive Module
-//
-
-module uart_rx (
- input clk_i,
- input rst_ni,
-
- input rx_enable,
- input tick_baud_x16,
- input parity_enable,
- input parity_odd,
-
- output logic tick_baud,
- output logic rx_valid,
- output [7:0] rx_data,
- output logic idle,
- output frame_err,
- output rx_parity_err,
-
- input rx
-);
-
- logic rx_valid_q;
- logic [10:0] sreg_q, sreg_d;
- logic [3:0] bit_cnt_q, bit_cnt_d;
- logic [3:0] baud_div_q, baud_div_d;
- logic tick_baud_d, tick_baud_q;
- logic idle_d, idle_q;
-
- assign tick_baud = tick_baud_q;
- assign idle = idle_q;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- sreg_q <= 11'h0;
- bit_cnt_q <= 4'h0;
- baud_div_q <= 4'h0;
- tick_baud_q <= 1'b0;
- idle_q <= 1'b1;
- end else begin
- sreg_q <= sreg_d;
- bit_cnt_q <= bit_cnt_d;
- baud_div_q <= baud_div_d;
- tick_baud_q <= tick_baud_d;
- idle_q <= idle_d;
- end
- end
-
- always_comb begin
- if (!rx_enable) begin
- sreg_d = 11'h0;
- bit_cnt_d = 4'h0;
- baud_div_d = 4'h0;
- tick_baud_d = 1'b0;
- idle_d = 1'b1;
- end else begin
- tick_baud_d = 1'b0;
- sreg_d = sreg_q;
- bit_cnt_d = bit_cnt_q;
- baud_div_d = baud_div_q;
- idle_d = idle_q;
- if (tick_baud_x16) begin
- {tick_baud_d, baud_div_d} = {1'b0,baud_div_q} + 5'h1;
- end
-
- if (idle_q && !rx) begin
- // start of char, sample in the middle of the bit time
- baud_div_d = 4'd8;
- tick_baud_d = 1'b0;
- bit_cnt_d = (parity_enable ? 4'd11 : 4'd10);
- sreg_d = 11'h0;
- idle_d = 1'b0;
- end else if (!idle_q && tick_baud_q) begin
- if ((bit_cnt_q == (parity_enable ? 4'd11 : 4'd10)) && rx) begin
- // must have been a glitch on the input, start bit is not set
- // in the middle of the bit time, abort
- idle_d = 1'b1;
- bit_cnt_d = 4'h0;
- end else begin
- sreg_d = {rx, sreg_q[10:1]};
- bit_cnt_d = bit_cnt_q - 4'h1;
- idle_d = (bit_cnt_q == 4'h1);
- end
- end
- end
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) rx_valid_q <= 1'b0;
- else rx_valid_q <= tick_baud_q & (bit_cnt_q == 4'h1);
-
- end
-
- assign rx_valid = rx_valid_q;
- assign rx_data = parity_enable ? sreg_q[8:1] : sreg_q[9:2];
- // (rx_parity = sreg_q[9])
- assign frame_err = rx_valid_q & ~sreg_q[10];
- assign rx_parity_err = parity_enable & rx_valid_q &
- (^{sreg_q[9:1],parity_odd});
-
-endmodule
diff --git a/verilog/rtl/uart_rx_prog.v b/verilog/rtl/uart_rx_prog.v
deleted file mode 100644
index 83c3e95..0000000
--- a/verilog/rtl/uart_rx_prog.v
+++ /dev/null
@@ -1,156 +0,0 @@
-`timescale 1ns / 1ps
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-// Set Parameter CLKS_PER_BIT as follows:
-// CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
-// Example: 10 MHz Clock, 115200 baud UART
-// (10000000)/(115200) = 87
-
-module uart_rx_prog (
- input clk_i,
- input rst_ni,
- input i_Rx_Serial,
- input [15:0] CLKS_PER_BIT,
- output o_Rx_DV,
- output [7:0] o_Rx_Byte
- );
-
- parameter s_IDLE = 3'b000;
- parameter s_RX_START_BIT = 3'b001;
- parameter s_RX_DATA_BITS = 3'b010;
- parameter s_RX_STOP_BIT = 3'b011;
- parameter s_CLEANUP = 3'b100;
-
- reg r_Rx_Data_R ;
- reg r_Rx_Data ;
-
- reg [15:0] r_Clock_Count ;
- reg [2:0] r_Bit_Index ; //8 bits total
- reg [7:0] r_Rx_Byte ;
- reg r_Rx_DV ;
- reg [2:0] r_SM_Main ;
-
- // Purpose: Double-register the incoming data.
- // This allows it to be used in the UART RX Clock Domain.
- // (It removes problems caused by metastability)
- always @(posedge clk_i)
- begin
- if (~rst_ni) begin
- r_Rx_Data_R <= 1'b1;
- r_Rx_Data <= 1'b1;
- end else begin
- r_Rx_Data_R <= i_Rx_Serial;
- r_Rx_Data <= r_Rx_Data_R;
- end
- end
-
-
- // Purpose: Control RX state machine
- always @(posedge clk_i or negedge rst_ni)
- begin
- if (~rst_ni) begin
- r_SM_Main <= s_IDLE;
- r_Rx_DV <= 1'b0;
- r_Clock_Count <= 0;
- r_Bit_Index <= 0;
- end else begin
- case (r_SM_Main)
- s_IDLE :
- begin
- r_Rx_DV <= 1'b0;
- r_Clock_Count <= 0;
- r_Bit_Index <= 0;
-
- if (r_Rx_Data == 1'b0) // Start bit detected
- r_SM_Main <= s_RX_START_BIT;
- else
- r_SM_Main <= s_IDLE;
- end
-
- // Check middle of start bit to make sure it's still low
- s_RX_START_BIT :
- begin
- if (r_Clock_Count == ((CLKS_PER_BIT-1)>>1))
- begin
- if (r_Rx_Data == 1'b0)
- begin
- r_Clock_Count <= 0; // reset counter, found the middle
- r_SM_Main <= s_RX_DATA_BITS;
- end
- else
- r_SM_Main <= s_IDLE;
- end
- else
- begin
- r_Clock_Count <= r_Clock_Count + 1;
- r_SM_Main <= s_RX_START_BIT;
- end
- end // case: s_RX_START_BIT
-
-
- // Wait CLKS_PER_BIT-1 clock cycles to sample serial data
- s_RX_DATA_BITS :
- begin
- if (r_Clock_Count < CLKS_PER_BIT-1)
- begin
- r_Clock_Count <= r_Clock_Count + 1;
- r_SM_Main <= s_RX_DATA_BITS;
- end
- else
- begin
- r_Clock_Count <= 0;
- r_Rx_Byte[r_Bit_Index] <= r_Rx_Data;
-
- // Check if we have received all bits
- if (r_Bit_Index < 7)
- begin
- r_Bit_Index <= r_Bit_Index + 1;
- r_SM_Main <= s_RX_DATA_BITS;
- end
- else
- begin
- r_Bit_Index <= 0;
- r_SM_Main <= s_RX_STOP_BIT;
- end
- end
- end // case: s_RX_DATA_BITS
-
-
- // Receive Stop bit. Stop bit = 1
- s_RX_STOP_BIT :
- begin
- // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
- if (r_Clock_Count < CLKS_PER_BIT-1)
- begin
- r_Clock_Count <= r_Clock_Count + 1;
- r_SM_Main <= s_RX_STOP_BIT;
- end
- else
- begin
- r_Rx_DV <= 1'b1;
- r_Clock_Count <= 0;
- r_SM_Main <= s_CLEANUP;
- end
- end // case: s_RX_STOP_BIT
-
-
- // Stay here 1 clock
- s_CLEANUP :
- begin
- r_SM_Main <= s_IDLE;
- r_Rx_DV <= 1'b0;
- end
-
-
- default :
- r_SM_Main <= s_IDLE;
-
- endcase
- end
- end
-
- assign o_Rx_DV = r_Rx_DV;
- assign o_Rx_Byte = r_Rx_Byte;
-
-endmodule // uart_rx
\ No newline at end of file
diff --git a/verilog/rtl/uart_tx.sv b/verilog/rtl/uart_tx.sv
deleted file mode 100644
index d10d16a..0000000
--- a/verilog/rtl/uart_tx.sv
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-//
-// Description: UART Transmit Module
-//
-
-module uart_tx (
- input clk_i,
- input rst_ni,
-
- input tx_enable,
- input tick_baud_x16,
- input logic parity_enable,
-
- input wr,
- input logic wr_parity,
- input [7:0] wr_data,
- output idle,
-
- output logic tx
-);
-
-
- logic [3:0] baud_div_q;
- logic tick_baud_q;
-
- logic [3:0] bit_cnt_q, bit_cnt_d;
- logic [10:0] sreg_q, sreg_d;
- logic tx_q, tx_d;
-
- assign tx = tx_q;
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- baud_div_q <= 4'h0;
- tick_baud_q <= 1'b0;
- end else if (tick_baud_x16) begin
- {tick_baud_q, baud_div_q} <= {1'b0,baud_div_q} + 5'h1;
- end else begin
- tick_baud_q <= 1'b0;
- end
- end
-
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- bit_cnt_q <= 4'h0;
- sreg_q <= 11'h7ff;
- tx_q <= 1'b1;
- end else begin
- bit_cnt_q <= bit_cnt_d;
- sreg_q <= sreg_d;
- tx_q <= tx_d;
- end
- end
-
- always_comb begin
- if (!tx_enable) begin
- bit_cnt_d = 4'h0;
- sreg_d = 11'h7ff;
- tx_d = 1'b1;
- end else begin
- bit_cnt_d = bit_cnt_q;
- sreg_d = sreg_q;
- tx_d = tx_q;
- if (wr) begin
- sreg_d = {1'b1, (parity_enable ? wr_parity : 1'b1), wr_data, 1'b0};
- bit_cnt_d = (parity_enable ? 4'd11 : 4'd10);
- end else if (tick_baud_q && (bit_cnt_q != 4'h0)) begin
- sreg_d = {1'b1, sreg_q[10:1]};
- tx_d = sreg_q[0];
- bit_cnt_d = bit_cnt_q - 4'h1;
- end
- end
- end
-
- assign idle = (tx_enable) ? (bit_cnt_q == 4'h0) : 1'b1;
-
-endmodule
diff --git a/verilog/rtl/user_proj_example.v b/verilog/rtl/user_proj_example.v
deleted file mode 100644
index b33e032..0000000
--- a/verilog/rtl/user_proj_example.v
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-FileCopyrightText: 2020 Efabless Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the 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.
-// SPDX-License-Identifier: Apache-2.0
-
-`default_nettype none
-/*
- *-------------------------------------------------------------
- *
- * user_proj_example
- *
- * This is an example of a (trivially simple) user project,
- * showing how the user project can connect to the logic
- * analyzer, the wishbone bus, and the I/O pads.
- *
- * This project generates an integer count, which is output
- * on the user area GPIO pads (digital output only). The
- * wishbone connection allows the project to be controlled
- * (start and stop) from the management SoC program.
- *
- * See the testbenches in directory "mprj_counter" for the
- * example programs that drive this user project. The three
- * testbenches are "io_ports", "la_test1", and "la_test2".
- *
- *-------------------------------------------------------------
- */
-
-module user_proj_example #(
- parameter BITS = 32
-)(
-`ifdef USE_POWER_PINS
- inout vdda1, // User area 1 3.3V supply
- inout vdda2, // User area 2 3.3V supply
- inout vssa1, // User area 1 analog ground
- inout vssa2, // User area 2 analog ground
- inout vccd1, // User area 1 1.8V supply
- inout vccd2, // User area 2 1.8v supply
- inout vssd1, // User area 1 digital ground
- inout vssd2, // User area 2 digital ground
-`endif
-
- // Wishbone Slave ports (WB MI A)
- input wb_clk_i,
- input wb_rst_i,
- input wbs_stb_i,
- input wbs_cyc_i,
- input wbs_we_i,
- input [3:0] wbs_sel_i,
- input [31:0] wbs_dat_i,
- input [31:0] wbs_adr_i,
- output wbs_ack_o,
- output [31:0] wbs_dat_o,
-
- // Logic Analyzer Signals
- input [127:0] la_data_in,
- output [127:0] la_data_out,
- input [127:0] la_oenb,
-
- // IOs
- input [`MPRJ_IO_PADS-1:0] io_in,
- output [`MPRJ_IO_PADS-1:0] io_out,
- output [`MPRJ_IO_PADS-1:0] io_oeb,
-
- // IRQ
- output [2:0] irq
-);
- wire clk;
- wire rst;
-
- wire [`MPRJ_IO_PADS-1:0] io_in;
- wire [`MPRJ_IO_PADS-1:0] io_out;
- wire [`MPRJ_IO_PADS-1:0] io_oeb;
-
- wire [31:0] rdata;
- wire [31:0] wdata;
- wire [BITS-1:0] count;
-
- wire valid;
- wire [3:0] wstrb;
- wire [31:0] la_write;
-
- // WB MI A
- assign valid = wbs_cyc_i && wbs_stb_i;
- assign wstrb = wbs_sel_i & {4{wbs_we_i}};
- assign wbs_dat_o = rdata;
- assign wdata = wbs_dat_i;
-
- // IO
- assign io_out = count;
- assign io_oeb = {(`MPRJ_IO_PADS-1){rst}};
-
- // IRQ
- assign irq = 3'b000; // Unused
-
- // LA
- assign la_data_out = {{(127-BITS){1'b0}}, count};
- // Assuming LA probes [63:32] are for controlling the count register
- assign la_write = ~la_oenb[63:32] & ~{BITS{valid}};
- // Assuming LA probes [65:64] are for controlling the count clk & reset
- assign clk = (~la_oenb[64]) ? la_data_in[64]: wb_clk_i;
- assign rst = (~la_oenb[65]) ? la_data_in[65]: wb_rst_i;
-
- counter #(
- .BITS(BITS)
- ) counter(
- .clk(clk),
- .reset(rst),
- .ready(wbs_ack_o),
- .valid(valid),
- .rdata(rdata),
- .wdata(wbs_dat_i),
- .wstrb(wstrb),
- .la_write(la_write),
- .la_input(la_data_in[63:32]),
- .count(count)
- );
-
-endmodule
-
-module counter #(
- parameter BITS = 32
-)(
- input clk,
- input reset,
- input valid,
- input [3:0] wstrb,
- input [BITS-1:0] wdata,
- input [BITS-1:0] la_write,
- input [BITS-1:0] la_input,
- output ready,
- output [BITS-1:0] rdata,
- output [BITS-1:0] count
-);
- reg ready;
- reg [BITS-1:0] count;
- reg [BITS-1:0] rdata;
-
- always @(posedge clk) begin
- if (reset) begin
- count <= 0;
- ready <= 0;
- end else begin
- ready <= 1'b0;
- if (~|la_write) begin
- count <= count + 1;
- end
- if (valid && !ready) begin
- ready <= 1'b1;
- rdata <= count;
- if (wstrb[0]) count[7:0] <= wdata[7:0];
- if (wstrb[1]) count[15:8] <= wdata[15:8];
- if (wstrb[2]) count[23:16] <= wdata[23:16];
- if (wstrb[3]) count[31:24] <= wdata[31:24];
- end else if (|la_write) begin
- count <= la_write & la_input;
- end
- end
- end
-
-endmodule
-`default_nettype wire
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 524b489..976f670 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -1,58 +1,31 @@
-// SPDX-FileCopyrightText: 2020 Efabless Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the 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.
-// SPDX-License-Identifier: Apache-2.0
-
-`default_nettype none
-/*
- *-------------------------------------------------------------
- *
- * user_project_wrapper
- *
- * This wrapper enumerates all of the pins available to the
- * user for the user project.
- *
- * An example user project is provided in this wrapper. The
- * example should be removed and replaced with the actual
- * user project.
- *
- *-------------------------------------------------------------
- */
+// Designed by a Team at Micro Electronics Research Lab, Usman Institute of Technology.
+// https://www.merledupk.org
+`default_nettype wire
module user_project_wrapper #(
parameter BITS = 32
) (
-`ifdef USE_POWER_PINS
- inout vdda1, // User area 1 3.3V supply
- inout vdda2, // User area 2 3.3V supply
- inout vssa1, // User area 1 analog ground
- inout vssa2, // User area 2 analog ground
- inout vccd1, // User area 1 1.8V supply
- inout vccd2, // User area 2 1.8v supply
- inout vssd1, // User area 1 digital ground
- inout vssd2, // User area 2 digital ground
-`endif
+ `ifdef USE_POWER_PINS
+ inout vdda1, // User area 1 3.3V supply
+ inout vdda2, // User area 2 3.3V supply
+ inout vssa1, // User area 1 analog ground
+ inout vssa2, // User area 2 analog ground
+ inout vccd1, // User area 1 1.8V supply
+ inout vccd2, // User area 2 1.8v supply
+ inout vssd1, // User area 1 digital ground
+ inout vssd2, // User area 2 digital ground
+ `endif
// Wishbone Slave ports (WB MI A)
- input wb_clk_i,
- input wb_rst_i,
- input wbs_stb_i,
- input wbs_cyc_i,
- input wbs_we_i,
- input [3:0] wbs_sel_i,
- input [31:0] wbs_dat_i,
- input [31:0] wbs_adr_i,
- output wbs_ack_o,
+ input wb_clk_i,
+ input wb_rst_i,
+ input wbs_stb_i,
+ input wbs_cyc_i,
+ input wbs_we_i,
+ input [3:0] wbs_sel_i,
+ input [31:0] wbs_dat_i,
+ input [31:0] wbs_adr_i,
+ output wbs_ack_o,
output [31:0] wbs_dat_o,
// Logic Analyzer Signals
@@ -60,8 +33,8 @@
output [127:0] la_data_out,
input [127:0] la_oenb,
- // IOs
- input [`MPRJ_IO_PADS-1:0] io_in,
+ // IOs, MPRJ_IO_PADS = 38
+ input [`MPRJ_IO_PADS-1:0] io_in,
output [`MPRJ_IO_PADS-1:0] io_out,
output [`MPRJ_IO_PADS-1:0] io_oeb,
@@ -78,52 +51,168 @@
output [2:0] user_irq
);
-/*--------------------------------------*/
-/* User project is instantiated here */
-/*--------------------------------------*/
+ wire clk_i;
+ wire rst_ni;
+ wire prog;
+
+ // Clocks per bit
+ wire [15:0] clks_per_bit;
-azadi_soc_top_caravel mprj (
- `ifdef USE_POWER_PINS
- .vdda1(vdda1), // User area 1 3.3V power
- .vdda2(vdda2), // User area 2 3.3V power
- .vssa1(vssa1), // User area 1 analog ground
- .vssa2(vssa2), // User area 2 analog ground
- .vccd1(vccd1), // User area 1 1.8V power
- .vccd2(vccd2), // User area 2 1.8V power
- .vssd1(vssd1), // User area 1 digital ground
- .vssd2(vssd2), // User area 2 digital ground
- `endif
+ // gpios interface
+ wire [31:0] gpio_i;
+ wire [31:0] gpio_o;
+ wire [31:0] gpio_oe;
- .wb_clk_i(wb_clk_i),
- .wb_rst_i(wb_rst_i),
+ // jtag interface
+ wire jtag_tck;
+ wire jtag_tms;
+ wire jtag_trst;
+ wire jtag_tdi;
+ wire jtag_tdo;
+ wire jtag_tdo_oe;
- // MGMT SoC Wishbone Slave
+ // uart-periph interface
+ wire uart_tx;
+ wire uart_rx;
- .wbs_cyc_i(wbs_cyc_i),
- .wbs_stb_i(wbs_stb_i),
- .wbs_we_i(wbs_we_i),
- .wbs_sel_i(wbs_sel_i),
- .wbs_adr_i(wbs_adr_i),
- .wbs_dat_i(wbs_dat_i),
- .wbs_ack_o(wbs_ack_o),
- .wbs_dat_o(wbs_dat_o),
+ // PWM interface
+ wire pwm_o_1;
+ wire pwm_o_2;
+ wire pwm1_oe;
+ wire pwm2_oe;
- // Logic Analyzer
+ // SPI interface
+ wire [3:0] ss_o;
+ wire sclk_o;
+ wire sd_o;
+ wire sd_oe;
+ wire sd_i;
- .la_data_in(la_data_in),
- .la_data_out(la_data_out),
- .la_oenb (la_oenb),
+ // Note: Output enable is active low for IO pads
+ assign io_oeb[0] = ~jtag_tdo_oe;
+ assign jtag_tdi = io_in[0];
+ assign io_out[0] = jtag_tdo;
- // IO Pads
+ // SPI 0
+ assign io_oeb[1] = ~(sd_oe | gpio_oe[30]);
+ assign io_out[1] = sd_oe ? sd_o : gpio_o[30];
+ assign gpio_i[30] = io_in[1];
- .io_in (io_in),
- .io_out(io_out),
- .io_oeb(io_oeb),
+ assign io_oeb[2] = 1'b1;
+ assign io_out[2] = 1'b0;
+ assign sd_i = io_in[2];
- // IRQ
- .irq(user_irq)
-);
+ assign io_oeb[3] = ~(sd_oe | gpio_oe[31]);
+ assign io_out[3] = sd_oe ? ss_o[0] : gpio_o[31];
+ assign gpio_i[31] = io_in[3];
-endmodule // user_project_wrapper
+ assign io_oeb[4] = 1'b0;
+ assign io_out[4] = sclk_o;
-`default_nettype wire
+ // UART
+ assign io_oeb[5] = 1'b0;
+ assign io_out[5] = uart_tx;
+
+ assign io_oeb[6] = 1'b1;
+ assign uart_rx = io_in[6];
+
+ // Programming Button
+ assign io_oeb[7] = 1'b1;
+ assign prog = io_in[7];
+
+ // GPIO 0-18
+ assign io_oeb[25:8] = ~gpio_oe[18:0];
+ assign gpio_i[18:0] = io_in [25:8];
+ assign io_out[25:8] = gpio_o [18:0];
+
+ // GPIO 19-21, SPI SS
+ assign io_oeb[27] = ~(sd_oe | gpio_oe[19]);
+ assign io_out[27] = sd_oe ? ss_o[1] : gpio_o [19]; // SPI slave sel[1]
+ assign gpio_i[19] = io_in[27];
+
+ assign io_oeb[28] = ~(sd_oe | gpio_oe[20]);
+ assign io_out[28] = sd_oe ? ss_o[2] : gpio_o [20]; // SPI slave sel[2]
+ assign gpio_i[20] = io_in[28];
+
+ assign io_oeb[29] = ~(sd_oe | gpio_oe[21]);
+ assign io_out[29] = sd_oe ? ss_o[3] : gpio_o [21]; // SPI slave sel[3]
+ assign gpio_i[21] = io_in[29];
+
+ // GPIO 22-24, JTAG in
+ assign io_oeb[30] = ~gpio_oe[22];
+ assign io_out[30] = gpio_o [22];
+ assign gpio_i[22] = io_in[30];
+ assign jtag_tck = io_in[30]; // JTAG TCK
+
+ assign io_oeb[31] = ~gpio_oe[23];
+ assign io_out[31] = gpio_o [23];
+ assign gpio_i[23] = io_in[31];
+ assign jtag_tms = io_in[31]; // JTAG TMS
+
+ assign io_oeb[32] = ~gpio_oe[24];
+ assign io_out[32] = gpio_o [24];
+ assign gpio_i[24] = io_in[32];
+ assign jtag_trst = io_in[32]; // JTAG TRST
+
+ // GPIO 25-26, PWM 1, 2
+ assign io_oeb[33] = ~(pwm1_oe | gpio_oe[25]); // PWM1
+ assign io_out[33] = pwm1_oe ? pwm_o_1 : gpio_o [25];
+ assign gpio_i[25] = io_in[33];
+
+ assign io_oeb[34] = ~(pwm2_oe | gpio_oe[26]); // PWM2
+ assign io_out[34] = pwm2_oe ? pwm_o_2 : gpio_o [26];
+ assign gpio_i[26] = io_in[34];
+
+ // GPIO 27-29
+ assign io_oeb[37:35] = ~gpio_oe[29:27];
+ assign gpio_i[29:27] = io_in [37:35];
+ assign io_out[37:35] = gpio_o [29:27];
+
+ // Logic Analyzer ports
+ assign la_oenb[15:0] = 16'hffff;
+ assign clks_per_bit = la_data_in[15:0];
+
+ azadi_soc_top mprj(
+ `ifdef USE_POWER_PINS
+ .VPWR(vccd1),
+ .VGND(vssd1),
+ `endif
+ .clk_i(wb_clk_i),
+ .rst_ni(wb_rst_i),
+ .prog(prog),
+
+ // Clocks per bits
+ .clks_per_bit(clks_per_bit),
+
+ // gpios interface
+ .gpio_i(gpio_i),
+ .gpio_o(gpio_o),
+ .gpio_oe(gpio_oe),
+
+ // jtag interface
+ .jtag_tck_i(jtag_tck),
+ .jtag_tms_i(jtag_tms),
+ .jtag_trst_ni(jtag_trst),
+ .jtag_tdi_i(jtag_tdi),
+ .jtag_tdo_o(jtag_tdo),
+ .jtag_tdo_oe_o(jtag_tdo_oe),
+
+ // uart-periph interface
+ .uart_tx(uart_tx), // output
+ .uart_rx(uart_rx), // input
+
+ // PWM interface
+ .pwm_o(pwm_o_1),
+ .pwm_o_2(pwm_o_2),
+ .pwm1_oe(pwm1_oe),
+ .pwm2_oe(pwm2_oe),
+
+ // SPI interface
+ .ss_o(ss_o), // [3:0]
+ .sclk_o(sclk_o),
+ .sd_o(sd_o),
+ .sd_oe(sd_oe),
+ .sd_i(sd_i)
+ );
+
+endmodule
diff --git a/verilog/rtl/utils.vh b/verilog/rtl/utils.vh
deleted file mode 100644
index 6a8c518..0000000
--- a/verilog/rtl/utils.vh
+++ /dev/null
@@ -1,113 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2013, University of British Columbia (UBC); All rights reserved. //
-// //
-// Redistribution and use in source and binary forms, with or without //
-// modification, are permitted provided that the following conditions are met: //
-// * Redistributions of source code must retain the above copyright //
-// notice, this list of conditions and the following disclaimer. //
-// * Redistributions in binary form must reproduce the above copyright //
-// notice, this list of conditions and the following disclaimer in the //
-// documentation and/or other materials provided with the distribution. //
-// * Neither the name of the University of British Columbia (UBC) nor the names //
-// of its contributors may be used to endorse or promote products //
-// derived from this software without specific prior written permission. //
-// //
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" //
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE //
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
-// DISCLAIMED. IN NO EVENT SHALL University of British Columbia (UBC) BE LIABLE //
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL //
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR //
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER //
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
-////////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////////
-// utils.vh: Design utilities (pre-compile) //
-// //
-// Author: Ameer M. Abdelhadi (ameer@ece.ubc.ca, ameer.abdelhadi@gmail.com) //
-// SRAM-based Multi-ported RAMs; University of British Columbia (UBC), March 2013 //
-////////////////////////////////////////////////////////////////////////////////////
-
-`ifndef __UTILS_VH__
-`define __UTILS_VH__
-
-`define DEBUG_MODE // debug mode, comment this line for other modes
-`define VERBOSE // verbose debug, comment this line for other modes
-
-// Initiate Array structure - use once before calling packing/unpacking modules
-`define ARRINIT integer _i_,_j_
-// pack/unpack 1D/2D/3D arrays; use in "always @*" if combinatorial
-`define ARR2D1D(D1W,D2W, SRC,DST) for(_i_=1;_i_<=(D1W);_i_=_i_+1) DST[((D2W)*_i_-1)-:D2W] = SRC[_i_-1]
-`define ARR1D2D(D1W,D2W, SRC,DST) for(_i_=1;_i_<=(D1W);_i_=_i_+1) DST[_i_-1] = SRC[((D2W)*_i_-1)-:D2W]
-`define ARR2D3D(D1W,D2W,D3W,SRC,DST) for(_i_=0;_i_< (D1W);_i_=_i_+1) for(_j_=1;_j_<=(D2W);_j_=_j_+1) DST[_i_][_j_-1] = SRC[_i_][((D3W)*_j_-1)-:D3W]
-`define ARR3D2D(D1W,D2W,D3W,SRC,DST) for(_i_=0;_i_< (D1W);_i_=_i_+1) for(_j_=1;_j_<=(D2W);_j_=_j_+1) DST[_i_][((D3W)*_j_-1)-:D3W] = SRC[_i_][_j_-1]
-
-// print a 2-D array in a comma-delimited list
-`define ARRPRN(ARRLEN,PRNSRC) for (_i_=(ARRLEN)-1;_i_>=0;_i_=_i_-1) $write("%c%h%c",(_i_==(ARRLEN)-1)?"[":"",PRNSRC[_i_],!_i_?"]":",")
-// Initialize a vector with a specific width random number; extra bits are zero padded
-`define GETRAND(RAND,RANDW) RAND=0; repeat ((RANDW)/32) RAND=(RAND<<32)|{$random}; RAND=(RAND<<((RANDW)%32))|({$random}>>(32-(RANDW)%32))
-
-// factorial (n!)
-`define fact(n) ( ( ((n) >= 2 ) ? 2 : 1) * \
- ( ((n) >= 3 ) ? 3 : 1) * \
- ( ((n) >= 4 ) ? 4 : 1) * \
- ( ((n) >= 5 ) ? 5 : 1) * \
- ( ((n) >= 6 ) ? 6 : 1) * \
- ( ((n) >= 7 ) ? 7 : 1) * \
- ( ((n) >= 8 ) ? 8 : 1) * \
- ( ((n) >= 9 ) ? 9 : 1) * \
- ( ((n) >= 10 ) ? 10 : 1) )
-
-// ceiling of log2
-`define log2(x) ( ( ((x) > 1 ) ? 1 : 0) + \
- ( ((x) > 2 ) ? 1 : 0) + \
- ( ((x) > 4 ) ? 1 : 0) + \
- ( ((x) > 8 ) ? 1 : 0) + \
- ( ((x) > 16 ) ? 1 : 0) + \
- ( ((x) > 32 ) ? 1 : 0) + \
- ( ((x) > 64 ) ? 1 : 0) + \
- ( ((x) > 128 ) ? 1 : 0) + \
- ( ((x) > 256 ) ? 1 : 0) + \
- ( ((x) > 512 ) ? 1 : 0) + \
- ( ((x) > 1024 ) ? 1 : 0) + \
- ( ((x) > 2048 ) ? 1 : 0) + \
- ( ((x) > 4096 ) ? 1 : 0) + \
- ( ((x) > 8192 ) ? 1 : 0) + \
- ( ((x) > 16384 ) ? 1 : 0) + \
- ( ((x) > 32768 ) ? 1 : 0) + \
- ( ((x) > 65536 ) ? 1 : 0) + \
- ( ((x) > 131072 ) ? 1 : 0) + \
- ( ((x) > 262144 ) ? 1 : 0) + \
- ( ((x) > 524288 ) ? 1 : 0) + \
- ( ((x) > 1048576) ? 1 : 0) + \
- ( ((x) > 2097152) ? 1 : 0) + \
- ( ((x) > 4194304) ? 1 : 0) )
-
-// floor of log2
-`define log2f(x) ( ( ((x) >= 2 ) ? 1 : 0) + \
- ( ((x) >= 4 ) ? 1 : 0) + \
- ( ((x) >= 8 ) ? 1 : 0) + \
- ( ((x) >= 16 ) ? 1 : 0) + \
- ( ((x) >= 32 ) ? 1 : 0) + \
- ( ((x) >= 64 ) ? 1 : 0) + \
- ( ((x) >= 128 ) ? 1 : 0) + \
- ( ((x) >= 256 ) ? 1 : 0) + \
- ( ((x) >= 512 ) ? 1 : 0) + \
- ( ((x) >= 1024 ) ? 1 : 0) + \
- ( ((x) >= 2048 ) ? 1 : 0) + \
- ( ((x) >= 4096 ) ? 1 : 0) + \
- ( ((x) >= 8192 ) ? 1 : 0) + \
- ( ((x) >= 16384 ) ? 1 : 0) + \
- ( ((x) >= 32768 ) ? 1 : 0) + \
- ( ((x) >= 65536 ) ? 1 : 0) + \
- ( ((x) >= 131072 ) ? 1 : 0) + \
- ( ((x) >= 262144 ) ? 1 : 0) + \
- ( ((x) >= 524288 ) ? 1 : 0) + \
- ( ((x) >= 1048576) ? 1 : 0) + \
- ( ((x) >= 2097152) ? 1 : 0) + \
- ( ((x) >= 4194304) ? 1 : 0) )
-
-`endif //__UTILS_VH__