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__