data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv
1: b'%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:13: Cannot find include file: prim_assert.sv\n`include "prim_assert.sv" \n         ^~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl,data/full_repos/permissive/509468557/prim_assert.sv\n             data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl,data/full_repos/permissive/509468557/prim_assert.sv.v\n             data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl,data/full_repos/permissive/509468557/prim_assert.sv.sv\n             prim_assert.sv\n             prim_assert.sv.v\n             prim_assert.sv.sv\n             obj_dir/prim_assert.sv\n             obj_dir/prim_assert.sv.v\n             obj_dir/prim_assert.sv.sv\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:15: syntax error, unexpected IDENTIFIER, expecting PACKAGE-IDENTIFIER\nmodule ibex_if_stage import ibex_pkg::*; #(\n                            ^~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:17: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter int unsigned DmExceptionAddr   = 32\'h1A110808,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:18: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter bit          DummyInstructions = 1\'b0,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:19: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter bit          ICache            = 1\'b0,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:20: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter bit          ICacheECC         = 1\'b0,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:21: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter int unsigned BusSizeECC        = BUS_SIZE,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:22: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter int unsigned TagSizeECC        = IC_TAG_SIZE,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:23: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter int unsigned LineSizeECC       = IC_LINE_SIZE,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:24: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter bit          PCIncrCheck       = 1\'b0,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:25: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter bit          ResetAll          = 1\'b0,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:26: syntax error, unexpected parameter, expecting IDENTIFIER\n    parameter lfsr_seed_t  RndCnstLfsrSeed   = RndCnstLfsrSeedDefault,\n    ^~~~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:29: syntax error, unexpected \')\', expecting \';\'\n) (\n^\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:31: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                         rst_ni,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:33: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic [31:0]                  boot_addr_i,               \n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:34: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                         req_i,                     \n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:37: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        instr_req_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:38: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [31:0]                 instr_addr_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:39: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                        instr_gnt_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:40: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                        instr_rvalid_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:41: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic [31:0]                 instr_rdata_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:42: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                        instr_err_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:43: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                        instr_pmp_err_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:46: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [IC_NUM_WAYS-1:0]      ic_tag_req_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:47: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        ic_tag_write_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:48: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [IC_INDEX_W-1:0]       ic_tag_addr_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:49: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [TagSizeECC-1:0]       ic_tag_wdata_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:50: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic [TagSizeECC-1:0]       ic_tag_rdata_i [IC_NUM_WAYS],\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:51: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [IC_NUM_WAYS-1:0]      ic_data_req_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:52: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        ic_data_write_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:53: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [IC_INDEX_W-1:0]       ic_data_addr_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:54: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [LineSizeECC-1:0]      ic_data_wdata_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:55: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic [LineSizeECC-1:0]      ic_data_rdata_i [IC_NUM_WAYS],\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:58: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        instr_valid_id_o,          \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:59: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        instr_new_id_o,            \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:60: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [31:0]                 instr_rdata_id_o,          \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:61: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [31:0]                 instr_rdata_alu_id_o,      \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:63: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [15:0]                 instr_rdata_c_id_o,        \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:66: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        instr_is_compressed_id_o,  \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:68: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        instr_bp_taken_o,          \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:70: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        instr_fetch_err_o,         \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:71: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        instr_fetch_err_plus2_o,   \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:72: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        illegal_c_insn_id_o,       \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:74: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic                        dummy_instr_id_o,          \n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:75: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [31:0]                 pc_if_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:76: syntax error, unexpected output, expecting IDENTIFIER or \'=\' or do or final\n    output logic [31:0]                 pc_id_o,\n    ^~~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:79: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                        instr_valid_clear_i,       \n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:80: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                        pc_set_i,                  \n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:81: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  logic                        pc_set_spec_i,\n    ^~~~~\n%Error: data/full_repos/permissive/509468557/generators/ibex/src/main/resources/vsrc/ibex/rtl/ibex_if_stage.sv:82: syntax error, unexpected input, expecting IDENTIFIER or \'=\' or do or final\n    input  pc_sel_e                     pc_mux_i,                  \n    ^~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module ibex_if_stage import ibex_pkg::*; #(
    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 int unsigned BusSizeECC        = BUS_SIZE,
    parameter int unsigned TagSizeECC        = IC_TAG_SIZE,
    parameter int unsigned LineSizeECC       = IC_LINE_SIZE,
    parameter bit          PCIncrCheck       = 1'b0,
    parameter bit          ResetAll          = 1'b0,
    parameter lfsr_seed_t  RndCnstLfsrSeed   = RndCnstLfsrSeedDefault,
    parameter lfsr_perm_t  RndCnstLfsrPerm   = RndCnstLfsrPermDefault,
    parameter bit          BranchPredictor   = 1'b0
) (
    input  logic                         clk_i,
    input  logic                         rst_ni,

    input  logic [31:0]                  boot_addr_i,
    input  logic                         req_i,


    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 logic [IC_NUM_WAYS-1:0]      ic_tag_req_o,
    output logic                        ic_tag_write_o,
    output logic [IC_INDEX_W-1:0]       ic_tag_addr_o,
    output logic [TagSizeECC-1:0]       ic_tag_wdata_o,
    input  logic [TagSizeECC-1:0]       ic_tag_rdata_i [IC_NUM_WAYS],
    output logic [IC_NUM_WAYS-1:0]      ic_data_req_o,
    output logic                        ic_data_write_o,
    output logic [IC_INDEX_W-1:0]       ic_data_addr_o,
    output logic [LineSizeECC-1:0]      ic_data_wdata_o,
    input  logic [LineSizeECC-1:0]      ic_data_rdata_i [IC_NUM_WAYS],


    output logic                        instr_valid_id_o,
    output logic                        instr_new_id_o,
    output logic [31:0]                 instr_rdata_id_o,
    output logic [31:0]                 instr_rdata_alu_id_o,

    output logic [15:0]                 instr_rdata_c_id_o,


    output logic                        instr_is_compressed_id_o,

    output logic                        instr_bp_taken_o,

    output logic                        instr_fetch_err_o,
    output logic                        instr_fetch_err_plus2_o,
    output logic                        illegal_c_insn_id_o,

    output logic                        dummy_instr_id_o,
    output logic [31:0]                 pc_if_o,
    output logic [31:0]                 pc_id_o,


    input  logic                        instr_valid_clear_i,
    input  logic                        pc_set_i,
    input  logic                        pc_set_spec_i,
    input  pc_sel_e                     pc_mux_i,
    input  logic                        nt_branch_mispredict_i,

    input  exc_pc_sel_e                 exc_pc_mux_i,
    input  exc_cause_e                  exc_cause,

    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,
    input logic                         icache_enable_i,
    input logic                         icache_inval_i,


    input  logic [31:0]                 branch_target_ex_i,


    input  logic [31:0]                 csr_mepc_i,

    input  logic [31:0]                 csr_depc_i,

    input  logic [31:0]                 csr_mtvec_i,
    output logic                        csr_mtvec_init_o,


    input  logic                        id_in_ready_i,


    output logic                        pc_mismatch_alert_o,
    output logic                        if_busy_o
);

  logic              instr_valid_id_d, instr_valid_id_q;
  logic              instr_new_id_d, instr_new_id_q;


  logic              prefetch_busy;
  logic              branch_req;
  logic              branch_spec;
  logic              predicted_branch;
  logic       [31:0] fetch_addr_n;
  logic              unused_fetch_addr_n0;

  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        [5:0] irq_id;
  logic              unused_irq_bit;

  logic              if_id_pipe_reg_we;


  logic              stall_dummy_instr;
  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;

  ibex_pkg::pc_sel_e pc_mux_internal;

  logic        [7:0] unused_boot_addr;
  logic        [7:0] unused_csr_mtvec;

  assign unused_boot_addr = boot_addr_i[7:0];
  assign unused_csr_mtvec = csr_mtvec_i[7:0];


  assign irq_id         = {exc_cause};
  assign unused_irq_bit = irq_id[5];


  always_comb begin : exc_pc_mux
    unique case (exc_pc_mux_i)
      EXC_PC_EXC:     exc_pc = { csr_mtvec_i[31:8], 8'h00                    };
      EXC_PC_IRQ:     exc_pc = { csr_mtvec_i[31:8], 1'b0, irq_id[4:0], 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



  assign pc_mux_internal =
    (BranchPredictor && predict_branch_taken && !pc_set_i) ? PC_BP : pc_mux_i;


  always_comb begin : fetch_addr_mux
    unique case (pc_mux_internal)
      PC_BOOT: fetch_addr_n = { boot_addr_i[31:8], 8'h80 };
      PC_JUMP: fetch_addr_n = branch_target_ex_i;
      PC_EXC:  fetch_addr_n = exc_pc;
      PC_ERET: fetch_addr_n = csr_mepc_i;
      PC_DRET: fetch_addr_n = csr_depc_i;


      PC_BP:   fetch_addr_n = BranchPredictor ? predict_branch_pc : { boot_addr_i[31:8], 8'h80 };
      default: fetch_addr_n = { boot_addr_i[31:8], 8'h80 };
    endcase
  end


  assign csr_mtvec_init_o = (pc_mux_i == PC_BOOT) & pc_set_i;

  if (ICache) begin : gen_icache

    ibex_icache #(
      .BranchPredictor (BranchPredictor),
      .ICacheECC       (ICacheECC),
      .ResetAll        (ResetAll),
      .BusSizeECC      (BusSizeECC),
      .TagSizeECC      (TagSizeECC),
      .LineSizeECC     (LineSizeECC)
    ) icache_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            ),

        .ic_tag_req_o        ( ic_tag_req_o               ),
        .ic_tag_write_o      ( ic_tag_write_o             ),
        .ic_tag_addr_o       ( ic_tag_addr_o              ),
        .ic_tag_wdata_o      ( ic_tag_wdata_o             ),
        .ic_tag_rdata_i      ( ic_tag_rdata_i             ),
        .ic_data_req_o       ( ic_data_req_o              ),
        .ic_data_write_o     ( ic_data_write_o            ),
        .ic_data_addr_o      ( ic_data_addr_o             ),
        .ic_data_wdata_o     ( ic_data_wdata_o            ),
        .ic_data_rdata_i     ( ic_data_rdata_i            ),

        .icache_enable_i     ( icache_enable_i            ),
        .icache_inval_i      ( icache_inval_i             ),
        .busy_o              ( prefetch_busy              )
    );
  end else begin : gen_prefetch_buffer

    ibex_prefetch_buffer #(
      .BranchPredictor (BranchPredictor),
      .ResetAll        (ResetAll)
    ) 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              )
    );

    logic                   unused_icen, unused_icinv;
    logic [TagSizeECC-1:0]  unused_tag_ram_input [IC_NUM_WAYS];
    logic [LineSizeECC-1:0] unused_data_ram_input [IC_NUM_WAYS];
    assign unused_icen           = icache_enable_i;
    assign unused_icinv          = icache_inval_i;
    assign unused_tag_ram_input  = ic_tag_rdata_i;
    assign unused_data_ram_input = ic_data_rdata_i;
    assign ic_tag_req_o          = 'b0;
    assign ic_tag_write_o        = 'b0;
    assign ic_tag_addr_o         = 'b0;
    assign ic_tag_wdata_o        = 'b0;
    assign ic_data_req_o         = 'b0;
    assign ic_data_write_o       = 'b0;
    assign ic_data_addr_o        = 'b0;
    assign ic_data_wdata_o       = 'b0;
  end

  assign unused_fetch_addr_n0 = fetch_addr_n[0];

  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;






  logic [31:0] instr_decompressed;
  logic        illegal_c_insn;
  logic        instr_is_compressed;

  ibex_compressed_decoder compressed_decoder_i (
      .clk_i           ( clk_i                    ),
      .rst_ni          ( rst_ni                   ),
      .valid_i         ( fetch_valid & ~fetch_err ),
      .instr_i         ( if_instr_rdata           ),
      .instr_o         ( instr_decompressed       ),
      .is_compressed_o ( instr_is_compressed      ),
      .illegal_instr_o ( illegal_c_insn           )
  );


  if (DummyInstructions) begin : gen_dummy_instr
    logic        insert_dummy_instr;
    logic [31:0] dummy_instr_data;

    ibex_dummy_instr #(
      .RndCnstLfsrSeed (RndCnstLfsrSeed),
      .RndCnstLfsrPerm (RndCnstLfsrPerm)
    ) dummy_instr_i (
      .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 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 : if_instr_err;




    assign stall_dummy_instr = insert_dummy_instr;


    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        dummy_instr_id_o <= 1'b0;
      end else if (if_id_pipe_reg_we) begin
        dummy_instr_id_o <= insert_dummy_instr;
      end
    end

  end else begin : gen_no_dummy_instr
    logic        unused_dummy_en;
    logic [2:0]  unused_dummy_mask;
    logic        unused_dummy_seed_en;
    logic [31:0] unused_dummy_seed;

    assign unused_dummy_en         = dummy_instr_en_i;
    assign unused_dummy_mask       = dummy_instr_mask_i;
    assign unused_dummy_seed_en    = dummy_instr_seed_en_i;
    assign unused_dummy_seed       = dummy_instr_seed_i;
    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 stall_dummy_instr       = 1'b0;
    assign dummy_instr_id_o        = 1'b0;
  end




  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;

  assign instr_new_id_o   = instr_new_id_q;


  assign if_id_pipe_reg_we = instr_new_id_d;

  if (ResetAll) begin : g_instr_rdata_ra
    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        instr_rdata_id_o         <= '0;
        instr_rdata_alu_id_o     <= '0;
        instr_fetch_err_o        <= '0;
        instr_fetch_err_plus2_o  <= '0;
        instr_rdata_c_id_o       <= '0;
        instr_is_compressed_id_o <= '0;
        illegal_c_insn_id_o      <= '0;
        pc_id_o                  <= '0;
      end else 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
    end
  end else begin : g_instr_rdata_nr
    always_ff @(posedge clk_i) begin
      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
    end
  end


  if (PCIncrCheck) begin : g_secure_pc
    logic [31:0] prev_instr_addr_incr;
    logic        prev_instr_seq_q, prev_instr_seq_d;



    assign prev_instr_seq_d = (prev_instr_seq_q | instr_new_id_d) &
        ~branch_req & ~stall_dummy_instr;

    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        prev_instr_seq_q <= 1'b0;
      end else begin
        prev_instr_seq_q <= prev_instr_seq_d;
      end
    end

    assign prev_instr_addr_incr = pc_id_o + ((instr_is_compressed_id_o && !instr_fetch_err_o) ?
                                             32'd2 : 32'd4);


    assign pc_mismatch_alert_o = prev_instr_seq_q & (pc_if_o != prev_instr_addr_incr);

  end else begin : g_no_secure_pc
    assign pc_mismatch_alert_o = 1'b0;
  end

  if (BranchPredictor) begin : g_branch_predictor
    logic [31:0] instr_skid_data_q;
    logic [31:0] instr_skid_addr_q;
    logic        instr_skid_bp_taken_q;
    logic        instr_skid_valid_q, instr_skid_valid_d;
    logic        instr_skid_en;
    logic        instr_bp_taken_q, instr_bp_taken_d;

    logic        predict_branch_taken_raw;


    if (ResetAll) begin : g_bp_taken_ra
      always_ff @(posedge clk_i or negedge rst_ni) begin
        if (!rst_ni) begin
          instr_bp_taken_q <= '0;
        end else if (if_id_pipe_reg_we) begin
          instr_bp_taken_q <= instr_bp_taken_d;
        end
      end
    end else begin : g_bp_taken_nr
      always_ff @(posedge clk_i) begin
        if (if_id_pipe_reg_we) begin
          instr_bp_taken_q <= instr_bp_taken_d;
        end
      end
    end









    assign instr_skid_en = predicted_branch & ~id_in_ready_i & ~instr_skid_valid_q;

    assign instr_skid_valid_d = (instr_skid_valid_q & ~id_in_ready_i & ~stall_dummy_instr) |
                                instr_skid_en;

    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        instr_skid_valid_q <= 1'b0;
      end else begin
        instr_skid_valid_q <= instr_skid_valid_d;
      end
    end

    if (ResetAll) begin : g_instr_skid_ra
      always_ff @(posedge clk_i or negedge rst_ni) begin
        if (!rst_ni) begin
          instr_skid_bp_taken_q <= '0;
          instr_skid_data_q     <= '0;
          instr_skid_addr_q     <= '0;
        end else if (instr_skid_en) begin
          instr_skid_bp_taken_q <= predict_branch_taken;
          instr_skid_data_q     <= fetch_rdata;
          instr_skid_addr_q     <= fetch_addr;
        end
      end
    end else begin : g_instr_skid_nr
      always_ff @(posedge clk_i) begin
        if (instr_skid_en) begin
          instr_skid_bp_taken_q <= predict_branch_taken;
          instr_skid_data_q     <= fetch_rdata;
          instr_skid_addr_q     <= fetch_addr;
        end
      end
    end

    ibex_branch_predict branch_predict_i (
      .clk_i                  ( clk_i                    ),
      .rst_ni                 ( rst_ni                   ),
      .fetch_rdata_i          ( fetch_rdata              ),
      .fetch_pc_i             ( fetch_addr               ),
      .fetch_valid_i          ( fetch_valid              ),

      .predict_branch_taken_o ( predict_branch_taken_raw ),
      .predict_branch_pc_o    ( predict_branch_pc        )
    );





    assign predict_branch_taken = predict_branch_taken_raw & ~instr_skid_valid_q & ~fetch_err;


    assign predicted_branch = predict_branch_taken & ~pc_set_i;

    assign if_instr_valid   = fetch_valid | instr_skid_valid_q;
    assign if_instr_rdata   = instr_skid_valid_q ? instr_skid_data_q : fetch_rdata;
    assign if_instr_addr    = instr_skid_valid_q ? instr_skid_addr_q : fetch_addr;



    assign if_instr_err     = ~instr_skid_valid_q & fetch_err;
    assign instr_bp_taken_d = instr_skid_valid_q ? instr_skid_bp_taken_q : predict_branch_taken;

    assign fetch_ready = id_in_ready_i & ~stall_dummy_instr & ~instr_skid_valid_q;

    assign instr_bp_taken_o = instr_bp_taken_q;

    `ASSERT(NoPredictSkid, instr_skid_valid_q |-> ~predict_branch_taken)
    `ASSERT(NoPredictIllegal, predict_branch_taken |-> ~illegal_c_insn)
  end else begin : g_no_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






  `ASSERT_KNOWN(IbexExcPcMuxKnown, exc_pc_mux_i)

  if (BranchPredictor) begin : g_branch_predictor_asserts
    `ASSERT_IF(IbexPcMuxValid, pc_mux_internal inside {
        PC_BOOT,
        PC_JUMP,
        PC_EXC,
        PC_ERET,
        PC_DRET,
        PC_BP},
      pc_set_i)

`ifdef INC_ASSERT

    logic        predicted_branch_live_q, predicted_branch_live_d;
    logic [31:0] predicted_branch_nt_pc_q, predicted_branch_nt_pc_d;
    logic [31:0] awaiting_instr_after_mispredict_q, awaiting_instr_after_mispredict_d;
    logic [31:0] next_pc;

    logic mispredicted, mispredicted_d, mispredicted_q;

    assign next_pc = fetch_addr + (instr_is_compressed_out ? 32'd2 : 32'd4);

    always_comb begin
      predicted_branch_live_d = predicted_branch_live_q;
      mispredicted_d          = mispredicted_q;

      if (branch_req & predicted_branch) begin
        predicted_branch_live_d = 1'b1;
        mispredicted_d          = 1'b0;
      end else if (predicted_branch_live_q) begin
        if (fetch_valid & fetch_ready) begin
          predicted_branch_live_d = 1'b0;
        end else if (nt_branch_mispredict_i) begin
          mispredicted_d = 1'b1;
        end
      end
    end

    always @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        predicted_branch_live_q <= 1'b0;
        mispredicted_q          <= 1'b0;
      end else begin
        predicted_branch_live_q <= predicted_branch_live_d;
        mispredicted_q          <= mispredicted_d;
      end
    end

    always @(posedge clk_i) begin
      if (branch_req & predicted_branch) begin
        predicted_branch_nt_pc_q <= next_pc;
      end
    end



    `ASSERT(MispredictOnlyImmediatelyAfterPredictedBranch,
      nt_branch_mispredict_i |-> predicted_branch_live_q)


    `ASSERT(CorrectPCOnMispredict,
      predicted_branch_live_q & mispredicted_d & fetch_valid |->
      fetch_addr == predicted_branch_nt_pc_q)




    `ASSERT(MispredictSingleCycle,
      nt_branch_mispredict_i & ~(fetch_valid & fetch_ready) |=> ~nt_branch_mispredict_i)


    `ASSERT(NoMispredBranch, nt_branch_mispredict_i |-> ~branch_req)
`endif

  end else begin : g_no_branch_predictor_asserts
    `ASSERT_IF(IbexPcMuxValid, pc_mux_internal inside {
        PC_BOOT,
        PC_JUMP,
        PC_EXC,
        PC_ERET,
        PC_DRET},
      pc_set_i)
  end


  `ASSERT(IbexBootAddrUnaligned, boot_addr_i[7:0] == 8'h00)


  `ASSERT(IbexInstrAddrUnknown, instr_req_o |-> !$isunknown(instr_addr_o))


  `ASSERT(IbexInstrAddrUnaligned, instr_req_o |-> (instr_addr_o[1:0] == 2'b00))

endmodule
module ibex_if_stage import ibex_pkg::*;
 #(
    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 int unsigned BusSizeECC        = BUS_SIZE,
    parameter int unsigned TagSizeECC        = IC_TAG_SIZE,
    parameter int unsigned LineSizeECC       = IC_LINE_SIZE,
    parameter bit          PCIncrCheck       = 1'b0,
    parameter bit          ResetAll          = 1'b0,
    parameter lfsr_seed_t  RndCnstLfsrSeed   = RndCnstLfsrSeedDefault,
    parameter lfsr_perm_t  RndCnstLfsrPerm   = RndCnstLfsrPermDefault,
    parameter bit          BranchPredictor   = 1'b0
) (
    input  logic                         clk_i,
    input  logic                         rst_ni,

    input  logic [31:0]                  boot_addr_i,
    input  logic                         req_i,


    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 logic [IC_NUM_WAYS-1:0]      ic_tag_req_o,
    output logic                        ic_tag_write_o,
    output logic [IC_INDEX_W-1:0]       ic_tag_addr_o,
    output logic [TagSizeECC-1:0]       ic_tag_wdata_o,
    input  logic [TagSizeECC-1:0]       ic_tag_rdata_i [IC_NUM_WAYS],
    output logic [IC_NUM_WAYS-1:0]      ic_data_req_o,
    output logic                        ic_data_write_o,
    output logic [IC_INDEX_W-1:0]       ic_data_addr_o,
    output logic [LineSizeECC-1:0]      ic_data_wdata_o,
    input  logic [LineSizeECC-1:0]      ic_data_rdata_i [IC_NUM_WAYS],


    output logic                        instr_valid_id_o,
    output logic                        instr_new_id_o,
    output logic [31:0]                 instr_rdata_id_o,
    output logic [31:0]                 instr_rdata_alu_id_o,

    output logic [15:0]                 instr_rdata_c_id_o,


    output logic                        instr_is_compressed_id_o,

    output logic                        instr_bp_taken_o,

    output logic                        instr_fetch_err_o,
    output logic                        instr_fetch_err_plus2_o,
    output logic                        illegal_c_insn_id_o,

    output logic                        dummy_instr_id_o,
    output logic [31:0]                 pc_if_o,
    output logic [31:0]                 pc_id_o,


    input  logic                        instr_valid_clear_i,
    input  logic                        pc_set_i,
    input  logic                        pc_set_spec_i,
    input  pc_sel_e                     pc_mux_i,
    input  logic                        nt_branch_mispredict_i,

    input  exc_pc_sel_e                 exc_pc_mux_i,
    input  exc_cause_e                  exc_cause,

    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,
    input logic                         icache_enable_i,
    input logic                         icache_inval_i,


    input  logic [31:0]                 branch_target_ex_i,


    input  logic [31:0]                 csr_mepc_i,

    input  logic [31:0]                 csr_depc_i,

    input  logic [31:0]                 csr_mtvec_i,
    output logic                        csr_mtvec_init_o,


    input  logic                        id_in_ready_i,


    output logic                        pc_mismatch_alert_o,
    output logic                        if_busy_o
);

  logic              instr_valid_id_d, instr_valid_id_q;
  logic              instr_new_id_d, instr_new_id_q;


  logic              prefetch_busy;
  logic              branch_req;
  logic              branch_spec;
  logic              predicted_branch;
  logic       [31:0] fetch_addr_n;
  logic              unused_fetch_addr_n0;

  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        [5:0] irq_id;
  logic              unused_irq_bit;

  logic              if_id_pipe_reg_we;


  logic              stall_dummy_instr;
  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;

  ibex_pkg::pc_sel_e pc_mux_internal;

  logic        [7:0] unused_boot_addr;
  logic        [7:0] unused_csr_mtvec;

  assign unused_boot_addr = boot_addr_i[7:0];
  assign unused_csr_mtvec = csr_mtvec_i[7:0];


  assign irq_id         = {exc_cause};
  assign unused_irq_bit = irq_id[5];


  always_comb begin : exc_pc_mux
    unique case (exc_pc_mux_i)
      EXC_PC_EXC:     exc_pc = { csr_mtvec_i[31:8], 8'h00                    };
      EXC_PC_IRQ:     exc_pc = { csr_mtvec_i[31:8], 1'b0, irq_id[4:0], 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



  assign pc_mux_internal =
    (BranchPredictor && predict_branch_taken && !pc_set_i) ? PC_BP : pc_mux_i;


  always_comb begin : fetch_addr_mux
    unique case (pc_mux_internal)
      PC_BOOT: fetch_addr_n = { boot_addr_i[31:8], 8'h80 };
      PC_JUMP: fetch_addr_n = branch_target_ex_i;
      PC_EXC:  fetch_addr_n = exc_pc;
      PC_ERET: fetch_addr_n = csr_mepc_i;
      PC_DRET: fetch_addr_n = csr_depc_i;


      PC_BP:   fetch_addr_n = BranchPredictor ? predict_branch_pc : { boot_addr_i[31:8], 8'h80 };
      default: fetch_addr_n = { boot_addr_i[31:8], 8'h80 };
    endcase
  end


  assign csr_mtvec_init_o = (pc_mux_i == PC_BOOT) & pc_set_i;

  if (ICache) begin : gen_icache

    ibex_icache #(
      .BranchPredictor (BranchPredictor),
      .ICacheECC       (ICacheECC),
      .ResetAll        (ResetAll),
      .BusSizeECC      (BusSizeECC),
      .TagSizeECC      (TagSizeECC),
      .LineSizeECC     (LineSizeECC)
    ) icache_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            ),

        .ic_tag_req_o        ( ic_tag_req_o               ),
        .ic_tag_write_o      ( ic_tag_write_o             ),
        .ic_tag_addr_o       ( ic_tag_addr_o              ),
        .ic_tag_wdata_o      ( ic_tag_wdata_o             ),
        .ic_tag_rdata_i      ( ic_tag_rdata_i             ),
        .ic_data_req_o       ( ic_data_req_o              ),
        .ic_data_write_o     ( ic_data_write_o            ),
        .ic_data_addr_o      ( ic_data_addr_o             ),
        .ic_data_wdata_o     ( ic_data_wdata_o            ),
        .ic_data_rdata_i     ( ic_data_rdata_i            ),

        .icache_enable_i     ( icache_enable_i            ),
        .icache_inval_i      ( icache_inval_i             ),
        .busy_o              ( prefetch_busy              )
    );
  end else begin : gen_prefetch_buffer

    ibex_prefetch_buffer #(
      .BranchPredictor (BranchPredictor),
      .ResetAll        (ResetAll)
    ) 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              )
    );

    logic                   unused_icen, unused_icinv;
    logic [TagSizeECC-1:0]  unused_tag_ram_input [IC_NUM_WAYS];
    logic [LineSizeECC-1:0] unused_data_ram_input [IC_NUM_WAYS];
    assign unused_icen           = icache_enable_i;
    assign unused_icinv          = icache_inval_i;
    assign unused_tag_ram_input  = ic_tag_rdata_i;
    assign unused_data_ram_input = ic_data_rdata_i;
    assign ic_tag_req_o          = 'b0;
    assign ic_tag_write_o        = 'b0;
    assign ic_tag_addr_o         = 'b0;
    assign ic_tag_wdata_o        = 'b0;
    assign ic_data_req_o         = 'b0;
    assign ic_data_write_o       = 'b0;
    assign ic_data_addr_o        = 'b0;
    assign ic_data_wdata_o       = 'b0;
  end

  assign unused_fetch_addr_n0 = fetch_addr_n[0];

  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;






  logic [31:0] instr_decompressed;
  logic        illegal_c_insn;
  logic        instr_is_compressed;

  ibex_compressed_decoder compressed_decoder_i (
      .clk_i           ( clk_i                    ),
      .rst_ni          ( rst_ni                   ),
      .valid_i         ( fetch_valid & ~fetch_err ),
      .instr_i         ( if_instr_rdata           ),
      .instr_o         ( instr_decompressed       ),
      .is_compressed_o ( instr_is_compressed      ),
      .illegal_instr_o ( illegal_c_insn           )
  );


  if (DummyInstructions) begin : gen_dummy_instr
    logic        insert_dummy_instr;
    logic [31:0] dummy_instr_data;

    ibex_dummy_instr #(
      .RndCnstLfsrSeed (RndCnstLfsrSeed),
      .RndCnstLfsrPerm (RndCnstLfsrPerm)
    ) dummy_instr_i (
      .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 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 : if_instr_err;




    assign stall_dummy_instr = insert_dummy_instr;


    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        dummy_instr_id_o <= 1'b0;
      end else if (if_id_pipe_reg_we) begin
        dummy_instr_id_o <= insert_dummy_instr;
      end
    end

  end else begin : gen_no_dummy_instr
    logic        unused_dummy_en;
    logic [2:0]  unused_dummy_mask;
    logic        unused_dummy_seed_en;
    logic [31:0] unused_dummy_seed;

    assign unused_dummy_en         = dummy_instr_en_i;
    assign unused_dummy_mask       = dummy_instr_mask_i;
    assign unused_dummy_seed_en    = dummy_instr_seed_en_i;
    assign unused_dummy_seed       = dummy_instr_seed_i;
    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 stall_dummy_instr       = 1'b0;
    assign dummy_instr_id_o        = 1'b0;
  end




  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;

  assign instr_new_id_o   = instr_new_id_q;


  assign if_id_pipe_reg_we = instr_new_id_d;

  if (ResetAll) begin : g_instr_rdata_ra
    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        instr_rdata_id_o         <= '0;
        instr_rdata_alu_id_o     <= '0;
        instr_fetch_err_o        <= '0;
        instr_fetch_err_plus2_o  <= '0;
        instr_rdata_c_id_o       <= '0;
        instr_is_compressed_id_o <= '0;
        illegal_c_insn_id_o      <= '0;
        pc_id_o                  <= '0;
      end else 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
    end
  end else begin : g_instr_rdata_nr
    always_ff @(posedge clk_i) begin
      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
    end
  end


  if (PCIncrCheck) begin : g_secure_pc
    logic [31:0] prev_instr_addr_incr;
    logic        prev_instr_seq_q, prev_instr_seq_d;



    assign prev_instr_seq_d = (prev_instr_seq_q | instr_new_id_d) &
        ~branch_req & ~stall_dummy_instr;

    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        prev_instr_seq_q <= 1'b0;
      end else begin
        prev_instr_seq_q <= prev_instr_seq_d;
      end
    end

    assign prev_instr_addr_incr = pc_id_o + ((instr_is_compressed_id_o && !instr_fetch_err_o) ?
                                             32'd2 : 32'd4);


    assign pc_mismatch_alert_o = prev_instr_seq_q & (pc_if_o != prev_instr_addr_incr);

  end else begin : g_no_secure_pc
    assign pc_mismatch_alert_o = 1'b0;
  end

  if (BranchPredictor) begin : g_branch_predictor
    logic [31:0] instr_skid_data_q;
    logic [31:0] instr_skid_addr_q;
    logic        instr_skid_bp_taken_q;
    logic        instr_skid_valid_q, instr_skid_valid_d;
    logic        instr_skid_en;
    logic        instr_bp_taken_q, instr_bp_taken_d;

    logic        predict_branch_taken_raw;


    if (ResetAll) begin : g_bp_taken_ra
      always_ff @(posedge clk_i or negedge rst_ni) begin
        if (!rst_ni) begin
          instr_bp_taken_q <= '0;
        end else if (if_id_pipe_reg_we) begin
          instr_bp_taken_q <= instr_bp_taken_d;
        end
      end
    end else begin : g_bp_taken_nr
      always_ff @(posedge clk_i) begin
        if (if_id_pipe_reg_we) begin
          instr_bp_taken_q <= instr_bp_taken_d;
        end
      end
    end









    assign instr_skid_en = predicted_branch & ~id_in_ready_i & ~instr_skid_valid_q;

    assign instr_skid_valid_d = (instr_skid_valid_q & ~id_in_ready_i & ~stall_dummy_instr) |
                                instr_skid_en;

    always_ff @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        instr_skid_valid_q <= 1'b0;
      end else begin
        instr_skid_valid_q <= instr_skid_valid_d;
      end
    end

    if (ResetAll) begin : g_instr_skid_ra
      always_ff @(posedge clk_i or negedge rst_ni) begin
        if (!rst_ni) begin
          instr_skid_bp_taken_q <= '0;
          instr_skid_data_q     <= '0;
          instr_skid_addr_q     <= '0;
        end else if (instr_skid_en) begin
          instr_skid_bp_taken_q <= predict_branch_taken;
          instr_skid_data_q     <= fetch_rdata;
          instr_skid_addr_q     <= fetch_addr;
        end
      end
    end else begin : g_instr_skid_nr
      always_ff @(posedge clk_i) begin
        if (instr_skid_en) begin
          instr_skid_bp_taken_q <= predict_branch_taken;
          instr_skid_data_q     <= fetch_rdata;
          instr_skid_addr_q     <= fetch_addr;
        end
      end
    end

    ibex_branch_predict branch_predict_i (
      .clk_i                  ( clk_i                    ),
      .rst_ni                 ( rst_ni                   ),
      .fetch_rdata_i          ( fetch_rdata              ),
      .fetch_pc_i             ( fetch_addr               ),
      .fetch_valid_i          ( fetch_valid              ),

      .predict_branch_taken_o ( predict_branch_taken_raw ),
      .predict_branch_pc_o    ( predict_branch_pc        )
    );





    assign predict_branch_taken = predict_branch_taken_raw & ~instr_skid_valid_q & ~fetch_err;


    assign predicted_branch = predict_branch_taken & ~pc_set_i;

    assign if_instr_valid   = fetch_valid | instr_skid_valid_q;
    assign if_instr_rdata   = instr_skid_valid_q ? instr_skid_data_q : fetch_rdata;
    assign if_instr_addr    = instr_skid_valid_q ? instr_skid_addr_q : fetch_addr;



    assign if_instr_err     = ~instr_skid_valid_q & fetch_err;
    assign instr_bp_taken_d = instr_skid_valid_q ? instr_skid_bp_taken_q : predict_branch_taken;

    assign fetch_ready = id_in_ready_i & ~stall_dummy_instr & ~instr_skid_valid_q;

    assign instr_bp_taken_o = instr_bp_taken_q;

    `ASSERT(NoPredictSkid, instr_skid_valid_q |-> ~predict_branch_taken)
    `ASSERT(NoPredictIllegal, predict_branch_taken |-> ~illegal_c_insn)
  end else begin : g_no_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






  `ASSERT_KNOWN(IbexExcPcMuxKnown, exc_pc_mux_i)

  if (BranchPredictor) begin : g_branch_predictor_asserts
    `ASSERT_IF(IbexPcMuxValid, pc_mux_internal inside {
        PC_BOOT,
        PC_JUMP,
        PC_EXC,
        PC_ERET,
        PC_DRET,
        PC_BP},
      pc_set_i)

`ifdef INC_ASSERT

    logic        predicted_branch_live_q, predicted_branch_live_d;
    logic [31:0] predicted_branch_nt_pc_q, predicted_branch_nt_pc_d;
    logic [31:0] awaiting_instr_after_mispredict_q, awaiting_instr_after_mispredict_d;
    logic [31:0] next_pc;

    logic mispredicted, mispredicted_d, mispredicted_q;

    assign next_pc = fetch_addr + (instr_is_compressed_out ? 32'd2 : 32'd4);

    always_comb begin
      predicted_branch_live_d = predicted_branch_live_q;
      mispredicted_d          = mispredicted_q;

      if (branch_req & predicted_branch) begin
        predicted_branch_live_d = 1'b1;
        mispredicted_d          = 1'b0;
      end else if (predicted_branch_live_q) begin
        if (fetch_valid & fetch_ready) begin
          predicted_branch_live_d = 1'b0;
        end else if (nt_branch_mispredict_i) begin
          mispredicted_d = 1'b1;
        end
      end
    end

    always @(posedge clk_i or negedge rst_ni) begin
      if (!rst_ni) begin
        predicted_branch_live_q <= 1'b0;
        mispredicted_q          <= 1'b0;
      end else begin
        predicted_branch_live_q <= predicted_branch_live_d;
        mispredicted_q          <= mispredicted_d;
      end
    end

    always @(posedge clk_i) begin
      if (branch_req & predicted_branch) begin
        predicted_branch_nt_pc_q <= next_pc;
      end
    end



    `ASSERT(MispredictOnlyImmediatelyAfterPredictedBranch,
      nt_branch_mispredict_i |-> predicted_branch_live_q)


    `ASSERT(CorrectPCOnMispredict,
      predicted_branch_live_q & mispredicted_d & fetch_valid |->
      fetch_addr == predicted_branch_nt_pc_q)




    `ASSERT(MispredictSingleCycle,
      nt_branch_mispredict_i & ~(fetch_valid & fetch_ready) |=> ~nt_branch_mispredict_i)


    `ASSERT(NoMispredBranch, nt_branch_mispredict_i |-> ~branch_req)
`endif

  end else begin : g_no_branch_predictor_asserts
    `ASSERT_IF(IbexPcMuxValid, pc_mux_internal inside {
        PC_BOOT,
        PC_JUMP,
        PC_EXC,
        PC_ERET,
        PC_DRET},
      pc_set_i)
  end


  `ASSERT(IbexBootAddrUnaligned, boot_addr_i[7:0] == 8'h00)


  `ASSERT(IbexInstrAddrUnknown, instr_req_o |-> !$isunknown(instr_addr_o))


  `ASSERT(IbexInstrAddrUnaligned, instr_req_o |-> (instr_addr_o[1:0] == 2'b00))

endmodule