Overall Coverage: 97.2%
All Uncovered:
.I (clk_i),
.CE (en_i | test_en_i),
.O (clk_o)
end
////////////////
endmodule
// to be the full bit mask.
// Xilinx FPGA specific Dual-port RAM coding style
// using always instead of always_ff to avoid 'ICPD - illegal combination of drivers' error
);
end
// using always instead of always_ff to avoid 'ICPD - illegal combination of drivers' error
// thrown when using $readmemh system task to backdoor load an image
end
end
if (AsyncOn) begin : gen_async
state_e state_d, state_q;
logic diff_p_edge, diff_n_edge, diff_check_ok, level;
logic diff_pq, diff_nq, diff_pd, diff_nd;
prim_flop_2sync #(
.Width(1),
.ResetValue(0)
.clk_i,
.rst_ni,
.d(diff_pi),
.q(diff_pd)
prim_flop_2sync #(
.Width(1),
.ResetValue(1)
.clk_i,
.rst_ni,
.d(diff_ni),
.q(diff_nd)
assign diff_p_edge = diff_pq ^ diff_pd;
assign diff_n_edge = diff_nq ^ diff_nd;
assign diff_check_ok = diff_pd ^ diff_nd;
assign level = diff_pd;
assign level_o = level_d;
assign event_o = rise_o | fall_o;
always_comb begin : p_diff_fsm
state_d = state_q;
level_d = level_q;
rise_o = 1'b0;
fall_o = 1'b0;
sigint_o = 1'b0;
unique case (state_q)
IsStd: begin
if (diff_check_ok) begin
level_d = level;
if (diff_p_edge && diff_n_edge) begin
if (level) begin
rise_o = 1'b1;
end else begin
fall_o = 1'b1;
end else begin
if (diff_p_edge || diff_n_edge) begin
state_d = IsSkewed;
end else begin
state_d = SigInt;
sigint_o = 1'b1;
IsSkewed: begin
if (diff_check_ok) begin
state_d = IsStd;
level_d = level;
if (level) rise_o = 1'b1;
else fall_o = 1'b1;
end else begin
state_d = SigInt;
sigint_o = 1'b1;
SigInt: begin
sigint_o = 1'b1;
if (diff_check_ok) begin
state_d = IsStd;
sigint_o = 1'b0;
default : ;
always_ff @(posedge clk_i or negedge rst_ni) begin : p_sync_reg
if (!rst_ni) begin
state_q <= IsStd;
diff_pq <= 1'b0;
diff_nq <= 1'b1;
level_q <= 1'b0;
end else begin
state_q <= state_d;
diff_pq <= diff_pd;
diff_nq <= diff_nd;
level_q <= level_d;
if (AsyncOn) begin : gen_async_assert
// |
};
end else if (tlul_pkg::ArbiterImpl == "BINTREE") begin : gen_tree_arb
prim_arbiter_tree #(
.N (M),
.DW ($bits(tlul_pkg::tl_h2d_t))
.clk_i,
.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 )
if (BusWidth == 64) begin : gen_word_mux64
assign rdata_o = word_mux;
}; // Store the request only. Doesn't have to store data
end else if (SBoxImpl == "canright") begin : gen_sbox_canright
.op_i,
.data_i,
.data_o
end else begin : gen_sbox_masked
logic [7:0] in_data_m, out_data_m;
logic [7:0] in_mask, out_mask;
assign in_mask = 8'hAA;
assign out_mask = 8'h55;
assign in_data_m = data_i ^ in_mask;
if (SBoxImpl == "canright_masked_noreuse") begin : gen_sbox_canright_masked_noreuse
.op_i,
.data_i ( in_data_m ),
.in_mask_i ( in_mask ),
.out_mask_i ( out_mask ),
.data_o ( out_data_m )
end else if (SBoxImpl == "canright_masked") begin : gen_sbox_canright_masked
.op_i,
.data_i ( in_data_m ),
.in_mask_i ( in_mask ),
.out_mask_i ( out_mask ),
.data_o ( out_data_m )
assign data_o = out_data_m ^ out_mask;
};
typedef enum {
#(
import "DPI-C" function
chandle spidpi_create(input string name, input int mode, input int loglevel);
import "DPI-C" function
void spidpi_close(input chandle ctx);
import "DPI-C" function
byte spidpi_tick(input chandle ctx_void, input [1:0] d2p_data);
#(
import "DPI-C" function
chandle gpiodpi_create(input string name, input int n_bits);
import "DPI-C" function
void gpiodpi_device_to_host(input chandle ctx, input [N_GPIO-1:0] gpio_d2p,
input [N_GPIO-1:0] gpio_en_d2p);
import "DPI-C" function
void gpiodpi_close(input chandle ctx);
import "DPI-C" function
int gpiodpi_host_to_device_tick(input chandle ctx,
input [N_GPIO-1:0] gpio_en_d2p);
import "DPI-C" function
chandle uartdpi_create(input string name);
import "DPI-C" function
byte uartdpi_read(input chandle ctx);
import "DPI-C" function
int uartdpi_can_read(input chandle ctx);
import "DPI-C" function
void uartdpi_write(input chandle ctx, int data);
import "DPI-C" function
chandle usbdpi_create(input string name, input int loglevel);
import "DPI-C" function
void usbdpi_device_to_host(input chandle ctx, input bit [4:0] d2p);
import "DPI-C" function
void usbdpi_close(input chandle ctx);
import "DPI-C" function
byte usbdpi_host_to_device(input chandle ctx, input bit [4:0] d2p);
generate
for (genvar i = 0; i < Width; i++) begin : each_pin
import "DPI-C"
function chandle dmidpi_create(input string name, input int listen_port);
import "DPI-C"
function void dmidpi_tick(input chandle ctx, output bit dmi_req_valid,
input bit dmi_req_ready, output bit [6:0] dmi_req_addr,
output bit [1:0] dmi_req_op, output bit [31:0] dmi_req_data,
input bit dmi_rsp_valid, output bit dmi_rsp_ready,
input bit [31:0] dmi_rsp_data, input bit [1:0] dmi_rsp_resp,
output bit dmi_rst_n);
import "DPI-C"
function void dmidpi_close(input chandle ctx);
import "DPI-C"
function chandle jtagdpi_create(input string name, input int listen_port);
import "DPI-C"
function void jtagdpi_tick(input chandle ctx, output bit tck, output bit tms,
output bit tdi, output bit trst_n,
output bit srst_n, input bit tdo);
import "DPI-C"
function void jtagdpi_close(input chandle ctx);
.S ( sel_i ),
.I0 ( clk0_i ),
.I1 ( clk1_i ),
.O ( clk_o )
.T(oe_n),
.I(out),
.O(in),
.IO(inout_io)
#(
if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
.*
#(
if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
.*
#(
if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
prim_xilinx_pad_wrapper #(
.AttrDw(AttrDw)
.*
#(
#(
#(
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;
if (Lock) begin : gen_lock
logic [N-1:0] mask_d, mask_q;
assign mask_d = (valid_o && (!ready_i)) ? req : {N{1'b1}};
assign req = mask_q & req_i;
always_ff @(posedge clk_i) begin : p_lock_regs
if (!rst_ni) begin
mask_q <= {N{1'b1}};
end else begin
mask_q <= mask_d;
end else begin : gen_tie_off
assign req_tree[Pa] = '0;
assign idx_tree[Pa] = '0;
assign data_tree[Pa] = '0;
end : gen_tree
if (Lock) begin : gen_lock_assertion
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_nodatapath
assign data_o = '1;
#(
if (AsyncOn) begin : gen_async_assert
#(
if (AsyncOn) begin : gen_async_assert
end else begin : gen_noscan
logic unused_scanmode;
assign unused_scanmode = scanmode_i;
assign clk_no = ~clk_i;
end else if (ArbiterImpl == "BINTREE") begin : gen_tree_arb
prim_arbiter_arb #(
.N (N),
.DW(ARB_DW)
.clk_i,
.rst_ni,
.req_i ( req ),
.data_i ( req_packed ),
.gnt_o ( gnt ),
.idx_o ( ),
.valid_o ( sram_req ),
.data_o ( sram_packed ),
.ready_i ( 1'b1 )
if (ICacheECC) begin : gen_ecc_wdata
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];
.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]};
.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;
for (genvar way = 0; way < NumWays; way++) begin : gen_rams
prim_ram_1p #(
.Width (TAG_SIZE_ECC),
.Depth (NUM_LINES),
.DataBitsPerMask (TAG_SIZE_ECC)
.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])
prim_ram_1p #(
.Width (LINE_SIZE_ECC),
.Depth (NUM_LINES),
.DataBitsPerMask (LINE_SIZE_ECC)
.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])
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];
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];
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;
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;
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]};
.in (tag_rdata_padded_ic1),
.d_o (),
.syndrome_o (),
.err_o (tag_err_bank_ic1)
assign tag_err_ic1[way] = |tag_err_bank_ic1;
.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));
assign ecc_correction_ways_d = 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;
always_ff @(posedge clk_i) begin
if (lookup_grant_ic0) begin
lookup_index_ic1 <= lookup_addr_ic0[INDEX_HI-:INDEX_W];
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;
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;
if (BranchCache) begin : gen_caching_logic
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;
assign fill_cache_new = (branch_i | (|cache_cnt_q)) & icache_enable_i &
~icache_inval_i & ~inval_prog_q;
end else begin : gen_cache_all
assign fill_cache_new = icache_enable_i & ~start_inval & ~inval_prog_q;
for (genvar fb = 0; fb < NUM_FB; fb++) begin : gen_fbs
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]);
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]);
assign fill_older_d[fb] = (fill_alloc[fb] ? fill_busy_q : fill_older_q[fb]) & ~fill_done;
assign fill_done[fb] = (fill_ram_done_q[fb] | fill_hit_q[fb] | ~fill_cache_q[fb] |
(|fill_err_q[fb])) &
(fill_out_done[fb] | fill_stale_q[fb] | branch_i) &
fill_rvd_done[fb];
assign fill_stale_d[fb] = fill_busy_q[fb] & (branch_i | fill_stale_q[fb]);
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);
assign fill_hit_ic1[fb] = lookup_valid_ic1 & fill_in_ic1[fb] & tag_hit_ic1;
assign fill_hit_d[fb] = (fill_hit_ic1[fb] & ~ecc_err_ic1) |
(fill_hit_q[fb] & fill_busy_q[fb]);
assign fill_ext_req[fb] = fill_busy_q[fb] & ~fill_ext_done[fb];
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});
assign fill_ext_hold_d[fb] = (fill_alloc[fb] & fill_spec_hold) |
(fill_ext_arb[fb] & ~gnt_or_pmp_err);
assign fill_ext_done[fb] = (fill_ext_cnt_q[fb][LINE_BEATS_W] |
(fill_hit_ic1[fb] & ~ecc_err_ic1) | fill_hit_q[fb] |
fill_err_q[fb][fill_ext_off[fb]] |
(~fill_cache_q[fb] & (branch_i | fill_stale_q[fb]))) &
~fill_ext_hold_q[fb];
assign fill_rvd_exp[fb] = fill_busy_q[fb] & ~fill_rvd_done[fb];
assign fill_rvd_cnt_d[fb] = fill_alloc[fb] ? '0 :
(fill_rvd_cnt_q[fb] +
{{LINE_BEATS_W{1'b0}},fill_rvd_arb[fb]});
assign fill_rvd_done[fb] = fill_ext_done[fb] & (fill_rvd_cnt_q[fb] == fill_ext_cnt_q[fb]);
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]);
assign fill_out_grant[fb] = fill_out_arb[fb] & output_ready & ~ecc_err_ic1;
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]});
assign fill_out_done[fb] = fill_out_cnt_q[fb][LINE_BEATS_W];
assign fill_ram_req[fb] = fill_busy_q[fb] & fill_rvd_cnt_q[fb][LINE_BEATS_W] &
~fill_hit_q[fb] & fill_cache_q[fb] & ~|fill_err_q[fb] &
~fill_ram_done_q[fb];
assign fill_ram_done_d[fb] = fill_ram_arb[fb] | (fill_ram_done_q[fb] & fill_busy_q[fb]);
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_ext_off[fb] = fill_addr_q[fb][LINE_W-1:BUS_W] +
fill_ext_cnt_q[fb][LINE_BEATS_W-1:0];
assign fill_rvd_off[fb] = fill_rvd_beat[fb][LINE_BEATS_W-1:0];
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]);
assign fill_data_sel[fb] = ~|(fill_busy_q & ~fill_out_done & ~fill_stale_q &
fill_older_q[fb]);
assign fill_out_arb[fb] = fill_out_req[fb] & fill_data_sel[fb];
assign fill_rvd_arb[fb] = instr_rvalid_i & fill_rvd_exp[fb] & ~|(fill_rvd_exp & fill_older_q[fb]);
assign fill_data_reg[fb] = fill_busy_q[fb] & ~fill_stale_q[fb] &
~fill_out_done[fb] & fill_data_sel[fb] &
((fill_rvd_beat[fb] > fill_out_cnt_q[fb]) | fill_hit_q[fb] |
(|fill_err_q[fb]));
assign fill_data_hit[fb] = fill_busy_q[fb] & fill_hit_ic1[fb] & fill_data_sel[fb];
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] &
(fill_rvd_beat[fb] == fill_out_cnt_q[fb]) & fill_data_sel[fb];
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_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_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];
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;
always_ff @(posedge clk_i) begin
if (fill_way_en[fb]) begin
fill_way_q[fb] <= sel_way_ic1;
assign fill_data_d[fb] = (fill_hit_ic1[fb] & ~ecc_err_ic1) ? hit_data_ic1[LineSize-1:0] :
{LINE_BEATS{instr_rdata_i}};
for (genvar b = 0; b < LINE_BEATS; b++) begin : gen_data_buf
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])) |
(instr_pmp_err_i & fill_ext_arb[fb] &
(fill_ext_off[fb] == b[LINE_BEATS_W-1:0])) |
(fill_rvd_arb[fb] & instr_err_i &
(fill_rvd_off[fb] == b[LINE_BEATS_W-1:0])) |
(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];
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 else begin : gen_no_output_zero
assign rdata = rdata_int;
if (ICache) begin : gen_icache
ibex_icache #(
.ICacheECC (ICacheECC)
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.req_i ( req_i ),
.branch_i ( branch_req ),
.branch_spec_i ( pc_set_spec_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 ),
.icache_enable_i ( icache_enable_i ),
.icache_inval_i ( icache_inval_i ),
.busy_o ( prefetch_busy )
if (DummyInstructions) begin : gen_dummy_instr
logic insert_dummy_instr;
logic [31:0] dummy_instr_data;
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.dummy_instr_en_i ( dummy_instr_en_i ),
.dummy_instr_mask_i ( dummy_instr_mask_i ),
.dummy_instr_seed_en_i ( dummy_instr_seed_en_i ),
.dummy_instr_seed_i ( dummy_instr_seed_i ),
.fetch_valid_i ( fetch_valid ),
.id_in_ready_i ( id_in_ready_i ),
.insert_dummy_instr_o ( insert_dummy_instr ),
.dummy_instr_data_o ( dummy_instr_data )
assign fetch_valid_out = insert_dummy_instr | fetch_valid;
assign instr_out = insert_dummy_instr ? dummy_instr_data : instr_decompressed;
assign instr_is_compressed_out = insert_dummy_instr ? 1'b0 : instr_is_compressed;
assign illegal_c_instr_out = insert_dummy_instr ? 1'b0 : illegal_c_insn;
assign instr_err_out = insert_dummy_instr ? 1'b0 : fetch_err;
assign stall_dummy_instr = insert_dummy_instr;
dummy_instr_id_o <= 1'b0;
end else if (if_id_pipe_reg_we) begin
end else begin : gen_multdiv_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_state_q, 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_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;
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
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;
ALBH: begin
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];
accum = {18'b0, imd_val_q_i[31:16]};
if (operator_i == MD_OP_MULL) begin
mac_res_d = {2'b0, mac_res[`OP_L], imd_val_q_i[`OP_L]};
end else begin
mac_res_d = mac_res;
mult_state_d = AHBL;
AHBL: begin
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[31:16]};
mac_res_d = {2'b0, mac_res[15:0], imd_val_q_i[15:0]};
mult_valid = 1'b1;
mult_state_d = ALBL;
mult_hold = ~multdiv_ready_id_i;
end else begin
accum = imd_val_q_i;
mac_res_d = mac_res;
mult_state_d = AHBH;
AHBH: begin
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[33:16];
accum[33:18] = {16{signed_mult & imd_val_q_i[33]}};
mac_res_d = mac_res;
mult_valid = 1'b1;
mult_state_d = ALBL;
mult_hold = ~multdiv_ready_id_i;
default: begin
mult_state_d = ALBL;
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 else begin : g_no_pmp
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;
assign pmp_req_err[PMP_I] = 1'b0;
assign pmp_req_err[PMP_D] = 1'b0;
assign rvfi_stage_valid_d[0] = instr_id_done & ~dummy_instr_id;
assign rvfi_instr_new_wb = instr_new_id;
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 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];
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 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 ready_wb_o = 1'b1;
logic unused_clk;
logic unused_rst;
logic unused_en_wb;
wb_instr_type_e unused_instr_type_wb;
logic [31:0] unused_pc_id;
logic unused_lsu_resp_valid;
assign unused_clk = clk_i;
assign unused_rst = rst_ni;
assign unused_en_wb = en_wb_i;
assign unused_instr_type_wb = instr_type_wb_i;
assign unused_pc_id = pc_id_i;
assign unused_lsu_resp_valid = lsu_resp_valid_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;
prim_lfsr #(
.LfsrDw ( 32 ),
.StateOutDw ( LFSR_OUT_W )
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.seed_en_i ( dummy_instr_seed_en_i ),
.seed_i ( dummy_instr_seed_i ),
.lfsr_en_i ( lfsr_en ),
.entropy_i ( '0 ),
.state_o ( lfsr_state )
if (DummyInstructions) begin : g_dummy_r0
logic we_r0_dummy;
logic [31:0] rf_r0;
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 <= '0;
end else if (we_r0_dummy) begin
rf_r0 <= wdata_a_i;
assign rf_reg[0] = dummy_instr_id_i ? rf_r0 : '0;
if (Offset == 0) begin : gen_offset0
assign rho_data[x][y][W-1:0] = theta_data[x][y][W-1:0];
if (CustomCoeffs > 0) begin : gen_custom
assign coeffs = CustomCoeffs[LfsrDw-1:0];
end else if (64'(LfsrType) == "FIB_XNOR") begin : gen_fib_xnor
if (CustomCoeffs > 0) begin : gen_custom
assign coeffs = CustomCoeffs[LfsrDw-1:0];
end else begin : gen_lut
assign coeffs = FIB_XNOR_COEFFS[LfsrDw-FIB_XNOR_LUT_OFF][LfsrDw-1:0];
assign next_lfsr_state = LfsrDw'(entropy_i) ^ {lfsr_q[LfsrDw-2:0], ~(^(lfsr_q & coeffs))};
assign lockup = &lfsr_q;
end else begin : gen_stored_out
assign stored_data_next = {{(OutW-InW){1'b0}}, concat_data[OutW+:InW]};
assign stored_mask_next = {{(OutW-InW){1'b0}}, concat_mask[OutW+:InW]};
if (Decrypt) begin : gen_dec
if (DataWidth == 64) begin : gen_d64
assign data_state_sbox = prim_cipher_pkg::perm_64bit(data_state_xor,
prim_cipher_pkg::PRESENT_PERM64_INV);
assign data_state[k+1] = prim_cipher_pkg::sbox4_64bit(data_state_sbox,
prim_cipher_pkg::PRESENT_SBOX4_INV);
end else begin : gen_d32
assign data_state_sbox = prim_cipher_pkg::perm_32bit(data_state_xor,
prim_cipher_pkg::PRESENT_PERM32_INV);
assign data_state[k+1] = prim_cipher_pkg::sbox4_32bit(data_state_sbox,
prim_cipher_pkg::PRESENT_SBOX4_INV);
if (KeyWidth == 128) begin : gen_k128
assign round_key[k+1] = prim_cipher_pkg::present_inv_update_key128(round_key[k],
5'(k + 1),
5'(NumRounds));
end else if (KeyWidth == 80) begin : gen_k80
assign round_key[k+1] = prim_cipher_pkg::present_inv_update_key80(round_key[k],
5'(k + 1),
5'(NumRounds));
end else begin : gen_k64
assign round_key[k+1] = prim_cipher_pkg::present_inv_update_key64(round_key[k],
5'(k + 1),
5'(NumRounds));
end else begin : gen_d32
assign data_state_sbox = prim_cipher_pkg::sbox4_32bit(data_state_xor,
prim_cipher_pkg::PRESENT_SBOX4);
assign data_state[k+1] = prim_cipher_pkg::perm_32bit(data_state_sbox,
prim_cipher_pkg::PRESENT_PERM32);
end else if (KeyWidth == 80) begin : gen_k80
assign round_key[k+1] = prim_cipher_pkg::present_update_key80(round_key[k], 5'(k + 1));
end else begin : gen_k64
assign round_key[k+1] = prim_cipher_pkg::present_update_key64(round_key[k], 5'(k + 1));
if (UseOldKeySched) begin : gen_legacy_keyschedule
assign k0_new = k1;
prim_cipher_pkg::PRINCE_SBOX4);
end else begin : gen_fwd_d32
always_comb begin : p_fwd_d32
data_state_round = prim_cipher_pkg::sbox4_32bit(data_state[k-1],
prim_cipher_pkg::PRINCE_SBOX4);
data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round);
data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round,
prim_cipher_pkg::PRINCE_SHIFT_ROWS64);
prim_cipher_pkg::PRINCE_SBOX4);
prim_cipher_pkg::PRINCE_SBOX4_INV);
end else begin : gen_middle_d32
always_comb begin : p_middle_d32
data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf],
prim_cipher_pkg::PRINCE_SBOX4);
data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle);
data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle,
prim_cipher_pkg::PRINCE_SBOX4_INV);
end else begin : gen_bwd_d32
always_comb begin : p_bwd_d32
data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1,
prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV);
data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd);
data_state[NumRoundsHalf+k+1] = prim_cipher_pkg::sbox4_32bit(data_state_bwd,
prim_cipher_pkg::PRINCE_SBOX4_INV);
end else if (SWACCESS == "RO") begin : gen_ro
end else if (SWACCESS == "W1S") begin : gen_w1s
assign wr_en = we | de ;
assign wr_data = (de ? d : q) | (we ? wd : '0);
end else if (SWACCESS == "W1C") begin : gen_w1c
end else if (SWACCESS == "W0C") begin : gen_w0c
end else if (SWACCESS == "RC") begin : gen_rc
assign wr_en = we | de ;
assign wr_data = (de ? d : q) & (we ? '0 : '1);
end else begin : gen_hw
assign wr_en = de ;
assign wr_data = d ;
if (EnableParity == 0 && EnableECC) begin : gen_secded
assign wmask_d = {TotalWidth{1'b1}};
if (Width == 32) begin : gen_secded_39_32
.in (rdata_sram),
.d_o (rdata_d[0+:Width]),
.syndrome_o ( ),
.err_o (rerror_d)
end else if (EnableParity) begin : gen_byte_parity
always_comb begin : p_parity
rerror_d = '0;
wmask_d[0+:Width] = wmask_i;
wdata_d[0+:Width] = wdata_i;
for (int i = 0; i < Width/8; i ++) begin
wdata_d[Width + i] = ~(^wdata_i[i*8 +: 8]);
wmask_d[Width + i] = &wmask_i[i*8 +: 8];
rerror_d[1] |= ~(^{rdata_sram[i*8 +: 8], rdata_sram[Width + i]});
rerror_d &= {2{rvalid_sram}};
assign rdata_d = rdata_sram[0+:Width];
if (EnableInputPipeline) begin : gen_regslice_input
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
req_q <= '0;
write_q <= '0;
addr_q <= '0;
wdata_q <= '0;
wmask_q <= '0;
end else begin
req_q <= req_d;
write_q <= write_d;
addr_q <= addr_d;
wdata_q <= wdata_d;
wmask_q <= wmask_d;
if (EnableOutputPipeline) begin : gen_regslice_output
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
rvalid_q <= '0;
rdata_q <= '0;
rerror_q <= '0;
end else begin
rvalid_q <= rvalid_d;
rdata_q <= rdata_d;
rerror_q <= rerror_d;
end else if (EnableParity) begin : gen_byte_parity
always_comb begin : p_parity
a_rerror_d = '0;
b_rerror_d = '0;
a_wmask_d[0+:Width] = a_wmask_i;
b_wmask_d[0+:Width] = b_wmask_i;
a_wdata_d[0+:Width] = a_wdata_i;
b_wdata_d[0+:Width] = b_wdata_i;
for (int i = 0; i < Width/8; i ++) begin
a_wdata_d[Width + i] = ~(^a_wdata_i[i*8 +: 8]);
b_wdata_d[Width + i] = ~(^b_wdata_i[i*8 +: 8]);
a_wmask_d[Width + i] = &a_wmask_i[i*8 +: 8];
b_wmask_d[Width + i] = &b_wmask_i[i*8 +: 8];
a_rerror_d[1] |= ~(^{a_rdata_sram[i*8 +: 8], a_rdata_sram[Width + i]});
b_rerror_d[1] |= ~(^{b_rdata_sram[i*8 +: 8], b_rdata_sram[Width + i]});
a_rerror_d &= {2{a_rvalid_sram}};
b_rerror_d &= {2{b_rvalid_sram}};
assign a_rdata_d = a_rdata_sram[0+:Width];
assign b_rdata_d = b_rdata_sram[0+:Width];
if (EnableInputPipeline) begin : gen_regslice_input
always_ff @(posedge clk_a_i or negedge rst_a_ni) begin
if (!rst_a_ni) begin
a_req_q <= '0;
a_write_q <= '0;
a_addr_q <= '0;
a_wdata_q <= '0;
a_wmask_q <= '0;
end else begin
a_req_q <= a_req_d;
a_write_q <= a_write_d;
a_addr_q <= a_addr_d;
a_wdata_q <= a_wdata_d;
a_wmask_q <= a_wmask_d;
always_ff @(posedge clk_b_i or negedge rst_b_ni) begin
if (!rst_b_ni) begin
b_req_q <= '0;
b_write_q <= '0;
b_addr_q <= '0;
b_wdata_q <= '0;
b_wmask_q <= '0;
end else begin
b_req_q <= b_req_d;
b_write_q <= b_write_d;
b_addr_q <= b_addr_d;
b_wdata_q <= b_wdata_d;
b_wmask_q <= b_wmask_d;
if (EnableOutputPipeline) begin : gen_regslice_output
always_ff @(posedge clk_a_i or negedge rst_a_ni) begin
if (!rst_a_ni) begin
a_rvalid_q <= '0;
a_rdata_q <= '0;
a_rerror_q <= '0;
end else begin
a_rvalid_q <= a_rvalid_d;
a_rdata_q <= a_rdata_d;
a_rerror_q <= a_rerror_d;
always_ff @(posedge clk_b_i or negedge rst_b_ni) begin
if (!rst_b_ni) begin
b_rvalid_q <= '0;
b_rdata_q <= '0;
b_rerror_q <= '0;
end else begin
b_rvalid_q <= b_rvalid_d;
b_rdata_q <= b_rdata_d;
b_rerror_q <= b_rerror_d;
IMM_B_S,
IMM_B_U,
IMM_B_INCR_PC,
end else begin : g_nobtalu
op_a_sel_e unused_a_mux_sel;
imm_b_sel_e unused_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;
// Register file write data mux
// (condition pass/fail used same cycle as generated instruction request)
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;
end
// Use the speculative branch signal when BTALU is enabled
assign branch_set_spec = (BranchTargetALU && !data_ind_timing_i) ? branch_spec : branch_set_q;
// 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;
branch_taken_q <= 1'b0;
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 lsu_req_in_id = 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;
logic unused_data_req_done_ex;
logic unused_lsu_load;
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 unused_rf_ren_a, unused_rf_ren_b;
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_ren_a = rf_ren_a;
assign unused_rf_ren_b = rf_ren_b;
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 en_wb_o = 1'b0;
assign instr_id_done_o = instr_done;
end else begin : gen_multdiv_no_m
assign multdiv_sel = 1'b0;
end else begin : g_no_branch_target_alu
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;
if (MultiplierImplementation == "slow") begin : gen_multdiv_slow
.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 (MultiplierImplementation == "fast") begin : gen_multdiv_fast
ibex_multdiv_fast # (
.SingleCycleMultiply (0)
.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 else if (MultiplierImplementation == "single-cycle") begin: gen_multdiv_single_cycle
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));
if (RV32B) begin : g_alu_rvb
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];
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];
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;
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
always_comb begin
bitcnt_partial = '{default: '0};
for (int unsigned i=1; i<32; i+=2) begin
bitcnt_partial[i] = {5'h0, bitcnt_bits[i]} + {5'h0, bitcnt_bits[i-1]};
for (int unsigned i=3; i<32; i+=4) begin
bitcnt_partial[i] = bitcnt_partial[i-2] + bitcnt_partial[i];
for (int unsigned i=7; i<32; i+=8) begin
bitcnt_partial[i] = bitcnt_partial[i-4] + bitcnt_partial[i];
for (int unsigned i=15; i <32; i+=16) begin
bitcnt_partial[i] = bitcnt_partial[i-8] + bitcnt_partial[i];
bitcnt_partial[31] = bitcnt_partial[15] + bitcnt_partial[31];
bitcnt_partial[23] = bitcnt_partial[15] + bitcnt_partial[23];
for (int unsigned i=11; i<32; i+=8) begin
bitcnt_partial[i] = bitcnt_partial[i-4] + bitcnt_partial[i];
for (int unsigned i=5; i<32; i+=4) begin
bitcnt_partial[i] = bitcnt_partial[i-2] + bitcnt_partial[i];
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]};
assign zbe_op = (operator_i == ALU_BEXT) | (operator_i == ALU_BDEP);
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
logic [31:0] butterfly_zbe_mask_l[5];
logic [31:0] butterfly_zbe_mask_r[5];
logic [31:0] butterfly_zbe_mask_not[5];
logic [31:0] butterfly_zbp_mask_l[5];
logic [31:0] butterfly_zbp_mask_r[5];
logic [31:0] butterfly_zbp_mask_not[5];
logic grev_op;
logic gorc_op;
logic zbp_op;
{{`_N(stg){1'b0}},{`_N(stg){1'b1}}} <<
bitcnt_partial[`_N(stg)*(2*seg+1)-1][$clog2(`_N(stg)):0];
= ~lrotc_stage[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_zbe_mask_r[stg][`_N(stg)*(2*seg+2)-1 : `_N(stg)*(2*seg+1)] = '0;
end
~(butterfly_zbe_mask_l[stg] | butterfly_zbe_mask_r[stg]);
end
assign butterfly_zbp_mask_r[0] = shift_amt[4] ? 32'h0000_ffff : 32'h0000_0000;
assign butterfly_zbp_mask_not[0] =
!shift_amt[4] || (shift_amt[4] && gorc_op) ? 32'hffff_ffff : 32'h0000_0000;
assign butterfly_zbp_mask_r[1] = shift_amt[3] ? 32'h00ff_00ff : 32'h0000_0000;
assign butterfly_zbp_mask_not[1] =
!shift_amt[3] || (shift_amt[3] && gorc_op) ? 32'hffff_ffff : 32'h0000_0000;
assign butterfly_zbp_mask_r[2] = shift_amt[2] ? 32'h0f0f_0f0f : 32'h0000_0000;
assign butterfly_zbp_mask_not[2] =
!shift_amt[2] || (shift_amt[2] && gorc_op) ? 32'hffff_ffff : 32'h0000_0000;
assign butterfly_zbp_mask_r[3] = shift_amt[1] ? 32'h3333_3333 : 32'h0000_0000;
assign butterfly_zbp_mask_not[3] =
!shift_amt[1] || (shift_amt[1] && gorc_op) ? 32'hffff_ffff : 32'h0000_0000;
assign butterfly_zbp_mask_r[4] = shift_amt[0] ? 32'h5555_5555 : 32'h0000_0000;
assign butterfly_zbp_mask_not[4] =
!shift_amt[0] || (shift_amt[0] && gorc_op) ? 32'hffff_ffff : 32'h0000_0000;
assign gorc_op = RV32B ? (operator_i == ALU_GORC) : 1'b0;
assign zbp_op = grev_op | gorc_op;
assign butterfly_mask_r = zbp_op ? butterfly_zbp_mask_r : butterfly_zbe_mask_r;
assign butterfly_mask_not = zbp_op ? butterfly_zbp_mask_not : butterfly_zbe_mask_not;
butterfly_result = operand_a_i;
((butterfly_result & butterfly_mask_l[0]) >> 16)|
((butterfly_result & butterfly_mask_r[0]) << 16);
((butterfly_result & butterfly_mask_l[1]) >> 8)|
((butterfly_result & butterfly_mask_r[1]) << 8);
((butterfly_result & butterfly_mask_l[2]) >> 4)|
((butterfly_result & butterfly_mask_r[2]) << 4);
((butterfly_result & butterfly_mask_l[3]) >> 2)|
((butterfly_result & butterfly_mask_r[3]) << 2);
((butterfly_result & butterfly_mask_l[4]) >> 1)|
((butterfly_result & butterfly_mask_r[4]) << 1);
butterfly_result = butterfly_result & operand_b_i;
end
invbutterfly_result = operand_a_i & operand_b_i;
((invbutterfly_result & butterfly_mask_l[4]) >> 1)|
((invbutterfly_result & butterfly_mask_r[4]) << 1);
((invbutterfly_result & butterfly_mask_l[3]) >> 2)|
((invbutterfly_result & butterfly_mask_r[3]) << 2);
((invbutterfly_result & butterfly_mask_l[2]) >> 4)|
((invbutterfly_result & butterfly_mask_r[2]) << 4);
((invbutterfly_result & butterfly_mask_l[1]) >> 8)|
((invbutterfly_result & butterfly_mask_r[1]) << 8);
((invbutterfly_result & butterfly_mask_l[0]) >> 16)|
((invbutterfly_result & butterfly_mask_r[0]) << 16);
end
'{32'h00ff_0000, 32'h0f00_0f00, 32'h3030_3030, 32'h4444_4444};
localparam logic [31:0] SHUFFLE_MASK_R [0:3] =
'{32'h0000_ff00, 32'h00f0_00f0, 32'h0c0c_0c0c, 32'h2222_2222};
'{32'h2200_1100, 32'h0044_0000, 32'h4411_0000, 32'h1100_0000};
localparam logic [31:0] FLIP_MASK_R [0:3] =
'{32'h0088_0044, 32'h0000_2200, 32'h0000_8822, 32'h0000_0088};
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
assign shuffle_flip = operator_i == ALU_UNSHFL;
shuffle_result = operand_a_i;
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
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
shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[0]) |
(((shuffle_result << 8) & SHUFFLE_MASK_L[0]) |
((shuffle_result >> 8) & SHUFFLE_MASK_R[0]));
end
shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[1]) |
(((shuffle_result << 4) & SHUFFLE_MASK_L[1]) |
((shuffle_result >> 4) & SHUFFLE_MASK_R[1]));
end
shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[2]) |
(((shuffle_result << 2) & SHUFFLE_MASK_L[2]) |
((shuffle_result >> 2) & SHUFFLE_MASK_R[2]));
end
shuffle_result = (shuffle_result & SHUFFLE_MASK_NOT[3]) |
(((shuffle_result << 1) & SHUFFLE_MASK_L[3]) |
((shuffle_result >> 1) & SHUFFLE_MASK_R[3]));
end
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
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_rev;
assign operand_b_rev[i] = operand_b_i[31-i];
end
assign clmul_hmode = operator_i == ALU_CLMULH;
localparam logic [31:0] CRC32_MU_REV = 32'hf701_1641;
localparam logic [31:0] CRC32C_MU_REV = 32'hdea7_13f1;
logic crc_hmode;
logic crc_bmode;
logic [31:0] crc_poly;
logic [31:0] crc_mu_rev;
(operator_i == ALU_CRC32C_H) | (operator_i == ALU_CRC32_H) |
(operator_i == ALU_CRC32C_B) | (operator_i == ALU_CRC32_B);
(operator_i == ALU_CRC32C_H) |
(operator_i == ALU_CRC32C_B);
assign crc_bmode = (operator_i == ALU_CRC32_B) | (operator_i == ALU_CRC32C_B);
assign crc_mu_rev = crc_cpoly ? CRC32C_MU_REV : CRC32_MU_REV;
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
if (crc_op) begin
clmul_op_a = instr_first_cycle_i ? crc_operand : imd_val_q_i;
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
assign clmul_and_stage[i] = clmul_op_b[i] ? clmul_op_a << i : '0;
end
assign clmul_xor_stage1[i] = clmul_and_stage[2*i] ^ clmul_and_stage[2*i+1];
end
assign clmul_xor_stage2[i] = clmul_xor_stage1[2*i] ^ clmul_xor_stage1[2*i+1];
end
assign clmul_xor_stage3[i] = clmul_xor_stage2[2*i] ^ clmul_xor_stage2[2*i+1];
end
assign clmul_xor_stage4[i] = clmul_xor_stage3[2*i] ^ clmul_xor_stage3[2*i+1];
end
assign clmul_result_rev[i] = clmul_result_raw[31-i];
end
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
unique case (operator_i)
ALU_CMOV: begin
imd_val_d_o = operand_a_i;
multicycle_result = (operand_b_i == 32'h0) ? operand_a_i : imd_val_q_i;
if (instr_first_cycle_i) begin
imd_val_we_o = 1'b1;
end else begin
imd_val_we_o = 1'b0;
end
multicycle_result = imd_val_q_i | bwlogic_and_result;
imd_val_d_o = bwlogic_and_result;
if (instr_first_cycle_i) begin
imd_val_we_o = 1'b1;
end else begin
imd_val_we_o = 1'b0;
end
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;
end else begin
multicycle_result = imd_val_q_i | shift_result;
end
if (instr_first_cycle_i) begin
imd_val_we_o = 1'b1;
end else begin
imd_val_we_o = 1'b0;
end
ALU_CRC32_H, ALU_CRC32C_H,
ALU_CRC32_B, ALU_CRC32C_B: begin
imd_val_d_o = clmul_result_rev;
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_we_o = 1'b1;
end else begin
imd_val_we_o = 1'b0;
end
imd_val_d_o = operand_a_i;
imd_val_we_o = 1'b0;
multicycle_result = operand_a_i;
end
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
logic packh;
assign packu = operator_i == ALU_PACKU;
assign packh = operator_i == ALU_PACKH;
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
{ {24{operand_a_i[7]}}, operand_a_i[7:0]} : { {16{operand_a_i[15]}}, operand_a_i[15:0]};
end else if (PMPGranularity == 1) begin : g_pmp_g1
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 else begin : g_pmp_g2
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 else if (pmp_cfg[i].mode == PMP_MODE_NAPOT) begin
pmp_addr_rdata[i][PMPGranularity-2:0] = '1;
end else begin : g_other_regions
assign pmp_cfg_rdata[i] = '0;
assign pmp_addr_rdata[i] = '0;
end else begin : g_no_pmp_tieoffs
for (genvar i = 0; i < PMP_MAX_REGIONS; i++) begin : g_rdata
assign pmp_addr_rdata[i] = '0;
assign pmp_cfg_rdata[i] = '0;
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 else begin : g_mcountinhibit_full
assign mcountinhibit = mcountinhibit_q;
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;
if (DataIndTiming) begin : gen_dit
logic data_ind_timing_d, data_ind_timing_q;
assign data_ind_timing_d = (csr_we_int && (csr_addr == CSR_CPUCTRL)) ?
cpuctrl_wdata.data_ind_timing : data_ind_timing_q;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
data_ind_timing_q <= 1'b0; // disabled on reset
end else begin
data_ind_timing_q <= data_ind_timing_d;
assign cpuctrl_rdata.data_ind_timing = data_ind_timing_q;
if (DummyInstructions) begin : gen_dummy
logic dummy_instr_en_d, dummy_instr_en_q;
logic [2:0] dummy_instr_mask_d, dummy_instr_mask_q;
assign dummy_instr_en_d = (csr_we_int && (csr_addr == CSR_CPUCTRL)) ?
cpuctrl_wdata.dummy_instr_en : dummy_instr_en_q;
assign dummy_instr_mask_d = (csr_we_int && (csr_addr == CSR_CPUCTRL)) ?
cpuctrl_wdata.dummy_instr_mask : dummy_instr_mask_q;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
dummy_instr_en_q <= 1'b0; // disabled on reset
dummy_instr_mask_q <= 3'b000;
end else begin
dummy_instr_en_q <= dummy_instr_en_d;
dummy_instr_mask_q <= dummy_instr_mask_d;
assign cpuctrl_rdata.dummy_instr_en = dummy_instr_en_q;
assign cpuctrl_rdata.dummy_instr_mask = dummy_instr_mask_q;
assign dummy_instr_seed_en_o = csr_we_int && (csr_addr == CSR_SECURESEED);
assign dummy_instr_seed_o = csr_wdata_int;
if (ICache) begin : gen_icache_enable
logic icache_enable_d, icache_enable_q;
assign icache_enable_d = (csr_we_int & (csr_addr == CSR_CPUCTRL)) ?
cpuctrl_wdata.icache_enable : icache_enable_q;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
icache_enable_q <= 1'b0; // disabled on reset
end else begin
icache_enable_q <= icache_enable_d;
assign cpuctrl_rdata.icache_enable = icache_enable_q;
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;
assign wb_exception_o = 1'b0;
#(
if (WidthMultiple == 1) begin : gen_single_prog_data
assign prog_data = prog_data_i;
if (WidthMultiple == 1) begin : gen_single_word_sel
assign rsp_fifo_wdata.word_sel = '0;
if (WidthMultiple == 1) begin : gen_width_one_rd
logic unused_word_sel;
assign data_o = |buf_rsp_match ? buf_rsp_data : data_i;
assign unused_word_sel = rsp_fifo_rdata.word_sel;
end : fill_w
end : compress_round
end : gen_alert_tx
#(
end : gen_esc_sev
end else if (ConnectMioOut[k]) begin : gen_mio_output
prim_pad_wrapper #(
.AttrDw(AttrDw)
.inout_io ( mio_pad_io[k] ),
.in_o ( ),
.out_i ( mio_out_i[k] ),
.oe_i ( mio_oe_i[k] ),
.attr_i ( mio_attr_i[k] )
assign mio_in_o[k] = 1'b0;
end else if (ConnectMioIn[k]) begin : gen_mio_input
prim_pad_wrapper #(
.AttrDw(AttrDw)
.inout_io ( mio_pad_io[k] ),
.in_o ( mio_in_o[k] ),
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( mio_attr_i[k] )
logic unused_out, unused_oe;
assign unused_out = mio_out_i[k];
assign unused_oe = mio_oe_i[k];
end else begin : gen_mio_tie_off
logic unused_out, unused_oe;
logic [AttrDw-1:0] unused_attr;
assign mio_pad_io[k] = 1'bz;
assign unused_out = mio_out_i[k];
assign unused_oe = mio_oe_i[k];
assign unused_attr = mio_attr_i[k];
assign mio_in_o[k] = 1'b0;
end else if (ConnectDioOut[k]) begin : gen_dio_output
prim_pad_wrapper #(
.AttrDw(AttrDw)
.inout_io ( dio_pad_io[k] ),
.in_o ( ),
.out_i ( dio_out_i[k] ),
.oe_i ( dio_oe_i[k] ),
.attr_i ( dio_attr_i[k] )
assign dio_in_o[k] = 1'b0;
end else if (ConnectDioIn[k]) begin : gen_dio_input
prim_pad_wrapper #(
.AttrDw(AttrDw)
.inout_io ( dio_pad_io[k] ),
.in_o ( dio_in_o[k] ),
.out_i ( 1'b0 ),
.oe_i ( 1'b0 ),
.attr_i ( dio_attr_i[k] )
logic unused_out, unused_oe;
assign unused_out = dio_out_i[k];
assign unused_oe = dio_oe_i[k];
end else begin : gen_dio_tie_off
logic unused_out, unused_oe;
logic [AttrDw-1:0] unused_attr;
assign dio_pad_io[k] = 1'bz;
assign unused_out = dio_out_i[k];
assign unused_oe = dio_oe_i[k];
assign unused_attr = dio_attr_i[k];
assign dio_in_o[k] = 1'b0;
end else if (Impl == prim_pkg::ImplXilinx) begin : gen_xilinx
assign warl_mask = AttrDw'(2'h3);
end else begin : gen_others
assign warl_mask = AttrDw'(6'h3F);
if (DioPeriphHasSleepMode[k]) begin : gen_sleep
assign dio_out_o[k] = (sleep_en_q) ? dio_out_sleep_q[k] : periph_to_dio_i[k];
assign dio_oe_o[k] = (sleep_en_q) ? dio_oe_sleep_q[k] : periph_to_dio_oe_i[k];
if (DioPeriphHasWkup[k]) begin : gen_dio_wkup_connect
assign dio_data_mux[k] = dio_in_i[k];
for (genvar k = NDioPads; k < AlignedMuxSize; k++) begin : gen_dio_data_mux_tie_off
assign dio_data_mux[k] = 1'b0;
for (genvar k = 0; k < NStraps; k++) begin : gen_strap_taps
assign lc_strap_taps[k] = mio_in_i[MioStrapPos[k]];
end else begin : gen_tie_off
assign is_tree[Pa] = '0;
assign id_tree[Pa] = '0;
assign max_tree[Pa] = '0;
end : gen_level
end : gen_tree