mirror of
https://github.com/lowRISC/ibex.git
synced 2025-06-27 17:00:41 -04:00
Here's a high-level overview of what this commit does: - Compiles Sail into SystemVerilog including patchin compiler bugs - Create a TCL file that tells JasperGold what to prove and assume - Check memory operations modelling the LSU Most of these properties now prove without time-bound on the response from memory due to alternative LSUs - Check memory even with Smepmp errors: Continues on top of https://github.com/riscv/sail-riscv/pull/196 - CSR verification - Checks for instruction types such as B-Type, I-Type, R-Type - Check illegal instructions and WFI instructions - Using psgen language for proof generation - Documentation on how to use the setup - Wrap around proof that proves instructions executed in a row still match the specification. - Liveness proof to guarantee instructions will retire within a upper bound of cycles. All of these proofs make heavy use of the concept of k-induction. All the different properties and steps are necessary to help the tool get the useful properties it needs to prove the next step. The instruction correctness, wrap-around and liveness all give us increased confidence that Ibex is trace-equivalent to Sail. Throughout this process an issue was found in Ibex where the pipeline was not flushing properly on changing PMP registers using clear: #2193 Alternative LSUs: This makes all top level memory properties prove quickly and at a low proof effort (1 or 2-induction). Three 'alternative LSUs' representing three stages of memory instructions: 1. Before the first response is received, in the EX stage 2. After the first response is received, but not the second grant, also in the EX stage 3. Before the last response is received in the WB stage. In each case we ask 'if the response came now, would the result be correct?'. Similar is applied for CSRs/PC though less directly. This is particularly interesting (read: ugly) in the case of a PMP error wbexc_exists makes Wrap properties fast to prove. The bottleneck becomes SpecPastNoWbexcPC, which fails only due to a bug. See the comment in riscv.proof. Co-authored-by: Marno van der Maas <mvdmaas+git@lowrisc.org> Signed-off-by: Louis-Emile Ploix <louis-emile.ploix@lowrisc.org>
486 lines
17 KiB
Systemverilog
486 lines
17 KiB
Systemverilog
// Copyright lowRISC contributors.
|
|
// Copyright 2024 University of Oxford, see also CREDITS.md.
|
|
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
|
// Original author: Louis-Emile Ploix
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
/*
|
|
This is the top module. Everything else in check/* will be included into this file.
|
|
This module contains the ibex instance, the specification instance and the assertions
|
|
(included via the built psgen file), most of the non assertion code is setting up
|
|
infrastructure for those assertions.
|
|
|
|
It has the same ports as the ibex top.
|
|
*/
|
|
|
|
// Preprocessor decoding of instructions. Could be replaced with internal signals of the Sail one day
|
|
`include "encodings.sv"
|
|
|
|
`define CR ibex_top_i.u_ibex_core
|
|
`define CSR `CR.cs_registers_i
|
|
`define CSRG `CSR.gen_scr
|
|
`define CSRP `CSR.g_pmp_registers
|
|
`define LSU `CR.load_store_unit_i
|
|
`define ID `CR.id_stage_i
|
|
`define IDG `ID.gen_stall_mem
|
|
`define IDC `ID.controller_i
|
|
`define WB `CR.wb_stage_i
|
|
`define WBG `WB.g_writeback_stage
|
|
`define RF ibex_top_i.gen_regfile_ff.register_file_i
|
|
`define IF `CR.if_stage_i
|
|
`define IFP `IF.gen_prefetch_buffer.prefetch_buffer_i
|
|
`define MULT `CR.ex_block_i.gen_multdiv_fast.multdiv_i
|
|
`define MULTG `MULT.gen_mult_fast
|
|
|
|
module top import ibex_pkg::*; #(
|
|
parameter int unsigned DmHaltAddr = 32'h1A110800,
|
|
parameter int unsigned DmExceptionAddr = 32'h1A110808,
|
|
parameter bit SecureIbex = 1'b0,
|
|
parameter bit WritebackStage = 1'b1,
|
|
parameter bit RV32E = 1'b0,
|
|
parameter int unsigned PMPNumRegions = 4
|
|
) (
|
|
// Clock and Reset
|
|
input logic clk_i,
|
|
input logic rst_ni,
|
|
|
|
input logic test_en_i, // enable all clock gates for testing
|
|
input prim_ram_1p_pkg::ram_1p_cfg_t ram_cfg_i,
|
|
|
|
input logic [31:0] hart_id_i,
|
|
input logic [31:0] boot_addr_i,
|
|
|
|
// Instruction memory interface
|
|
output logic instr_req_o,
|
|
input logic instr_gnt_i,
|
|
input logic instr_rvalid_i,
|
|
output logic [31:0] instr_addr_o,
|
|
input logic [31:0] instr_rdata_i,
|
|
input logic [6:0] instr_rdata_intg_i,
|
|
input logic instr_err_i,
|
|
|
|
// Data memory interface
|
|
output logic data_req_o,
|
|
output logic data_is_cap_o,
|
|
input logic data_gnt_i,
|
|
input logic data_rvalid_i,
|
|
output logic data_we_o,
|
|
output logic [3:0] data_be_o,
|
|
output logic [31:0] data_addr_o,
|
|
output logic [31:0] data_wdata_o,
|
|
output logic [6:0] data_wdata_intg_o,
|
|
input logic [31:0] data_rdata_i,
|
|
input logic [6:0] data_rdata_intg_i,
|
|
input logic data_err_i,
|
|
|
|
// Interrupt inputs
|
|
input logic irq_software_i,
|
|
input logic irq_timer_i,
|
|
input logic irq_external_i,
|
|
input logic [14:0] irq_fast_i,
|
|
input logic irq_nm_i, // non-maskeable interrupt
|
|
|
|
// Scrambling Interface
|
|
input logic scramble_key_valid_i,
|
|
input logic [SCRAMBLE_KEY_W-1:0] scramble_key_i,
|
|
input logic [SCRAMBLE_NONCE_W-1:0] scramble_nonce_i,
|
|
output logic scramble_req_o,
|
|
|
|
// Debug Interface
|
|
input logic debug_req_i,
|
|
output crash_dump_t crash_dump_o,
|
|
output logic double_fault_seen_o,
|
|
|
|
// CPU Control Signals
|
|
input ibex_mubi_t fetch_enable_i,
|
|
output logic core_sleep_o,
|
|
output logic alert_minor_o,
|
|
output logic alert_major_internal_o,
|
|
output logic alert_major_bus_o,
|
|
|
|
|
|
// DFT bypass controls
|
|
input logic scan_rst_ni
|
|
);
|
|
|
|
default clocking @(posedge clk_i); endclocking
|
|
|
|
ibex_top #(
|
|
.DmHaltAddr(DmHaltAddr),
|
|
.DmExceptionAddr(DmExceptionAddr),
|
|
.SecureIbex(SecureIbex),
|
|
.WritebackStage(WritebackStage),
|
|
.RV32E(RV32E),
|
|
.BranchTargetALU(1'b1),
|
|
.PMPEnable(1'b1),
|
|
.PMPNumRegions(PMPNumRegions)
|
|
) ibex_top_i(.*);
|
|
|
|
// Core constraints
|
|
// 1. We do not allow going into debug mode
|
|
NotDebug: assume property (!ibex_top_i.u_ibex_core.debug_mode & !debug_req_i);
|
|
// 2. The boot address is constant
|
|
ConstantBoot: assume property (boot_addr_i == $past(boot_addr_i));
|
|
// 3. Always fetch enable
|
|
FetchEnable: assume property (fetch_enable_i == IbexMuBiOn);
|
|
// 4. Never try to sleep if we couldn't ever wake up
|
|
WFIStart: assume property (`IDC.ctrl_fsm_cs == SLEEP |-> (
|
|
`CSR.mie_q.irq_software |
|
|
`CSR.mie_q.irq_timer |
|
|
`CSR.mie_q.irq_external
|
|
));
|
|
// 5. Disable clock gating
|
|
TestEn: assume property (test_en_i);
|
|
// See protocol/* for further assumptions
|
|
|
|
///////////////////////////////// Declarations /////////////////////////////////
|
|
|
|
// Helpful macros to define each relevant, checked CSR and their types.
|
|
// Some CSRs are not checked or tracked, see ex_is_checkable_csr below.
|
|
`define X_EACH_CSR \
|
|
`ifndef X_DISABLE_PC `X(pc) `endif \
|
|
`X(priv) \
|
|
`X(mstatus) \
|
|
`X(mie) \
|
|
`X(mcause) \
|
|
`X(mtval) \
|
|
`X(mtvec) \
|
|
`X(mscratch) \
|
|
`X(mepc) \
|
|
`X(mcounteren) \
|
|
`X(pmp_cfg) \
|
|
`X(pmp_addr) \
|
|
`X(mseccfg)
|
|
|
|
`define X_EACH_CSR_TYPED \
|
|
logic [31:0] `X(pc); \
|
|
t_Privilege `X(priv); \
|
|
mstatus_t `X(mstatus); \
|
|
logic [31:0] `X(mie); \
|
|
logic [31:0] `X(mcause); \
|
|
logic [31:0] `X(mtval); \
|
|
logic [31:0] `X(mtvec); \
|
|
logic [31:0] `X(mscratch); \
|
|
logic [31:0] `X(mepc); \
|
|
logic [63:0] `X(mcycle); \
|
|
logic [31:0] `X(mshwmb); \
|
|
logic [31:0] `X(mshwm); \
|
|
logic [31:0] `X(mcounteren); \
|
|
logic [7:0] `X(pmp_cfg)[PMPNumRegions]; \
|
|
logic [31:0] `X(pmp_addr)[PMPNumRegions]; \
|
|
logic [31:0] `X(mseccfg);
|
|
|
|
////////////////////// Abstract State //////////////////////
|
|
|
|
// Pre state is the architectural state of Ibex at the start of the cycle
|
|
logic [31:0] pre_regs[32];
|
|
logic [31:0] pre_nextpc;
|
|
logic [31:0] pre_mip;
|
|
|
|
`define X(n) pre_``n
|
|
`X_EACH_CSR_TYPED
|
|
`undef X
|
|
|
|
// Post state is the architectural state of Ibex at the end of this cycle, or the start of the next
|
|
`define X(n) post_``n
|
|
`X_EACH_CSR_TYPED
|
|
`undef X
|
|
|
|
////////////////////// Following //////////////////////
|
|
// Generally:
|
|
// - ex_P is 1 if P is true for the instruction in the ID/EX stage.
|
|
// - wbexc_P is 1 if P is true for the instruction in the WB/EXC (exception) stage.
|
|
|
|
logic ex_is_wfi, ex_is_rtype, ex_is_div;
|
|
logic ex_is_pres_btype, ex_is_pres_jump;
|
|
logic ex_is_mem_instr, ex_is_load_instr, ex_is_store_instr;
|
|
logic ex_is_pres_mem_instr, ex_is_pres_load_instr, ex_is_pres_store_instr;
|
|
|
|
// Have we branched, or are we branching in this cycle?
|
|
logic ex_has_branched_d, ex_has_branched_q;
|
|
logic [31:0] ex_branch_dst;
|
|
assign ex_branch_dst = `CR.branch_decision ? `CR.branch_target_ex : pre_nextpc;
|
|
|
|
logic outstanding_mem;
|
|
assign outstanding_mem = `ID.outstanding_load_wb_i || `ID.outstanding_store_wb_i;
|
|
|
|
logic has_resp_waiting_q, has_resp_waiting_d;
|
|
assign has_resp_waiting_q = data_mem_assume.outstanding_reqs_q != 8'h0;
|
|
assign has_resp_waiting_d = data_mem_assume.outstanding_reqs != 8'h0;
|
|
|
|
logic has_one_resp_waiting_q, has_one_resp_waiting_d;
|
|
assign has_one_resp_waiting_q = data_mem_assume.outstanding_reqs_q == 8'h1;
|
|
assign has_one_resp_waiting_d = data_mem_assume.outstanding_reqs == 8'h1;
|
|
|
|
logic has_two_resp_waiting_q, has_two_resp_waiting_d;
|
|
assign has_two_resp_waiting_q = data_mem_assume.outstanding_reqs_q == 8'h2;
|
|
assign has_two_resp_waiting_d = data_mem_assume.outstanding_reqs == 8'h2;
|
|
|
|
logic wbexc_is_pres_load_instr, wbexc_is_pres_store_instr;
|
|
logic wbexc_is_load_instr, wbexc_is_store_instr;
|
|
logic wbexc_is_pres_mem_instr, wbexc_is_mem_instr;
|
|
logic wbexc_is_wfi;
|
|
|
|
logic [31:0] ex_compressed_instr;
|
|
logic ex_has_compressed_instr;
|
|
|
|
// Stored specification post state
|
|
logic wbexc_post_int_err; // Spec had an internal error
|
|
|
|
logic [31:0] wbexc_post_wX;
|
|
logic [5:0] wbexc_post_wX_addr;
|
|
logic wbexc_post_wX_en;
|
|
|
|
`define X(n) wbexc_post_``n
|
|
`X_EACH_CSR_TYPED
|
|
`undef X
|
|
|
|
// Stored predetermined memory responses, see check/peek/mem.sv
|
|
logic [31:0] wbexc_spec_mem_read_fst_rdata;
|
|
logic [31:0] wbexc_spec_mem_read_snd_rdata;
|
|
|
|
// Store DUT CSR post state
|
|
`define X(n) wbexc_dut_post_``n
|
|
`X_EACH_CSR_TYPED
|
|
`undef X
|
|
|
|
logic [31:0] wbexc_instr; // original potentially compressed
|
|
logic [31:0] wbexc_decompressed_instr; // post decompression
|
|
logic wbexc_is_compressed;
|
|
|
|
logic [31:0] wbexc_pc;
|
|
|
|
logic mem_gnt_fst_d; // We are having or have had the first gnt
|
|
logic mem_gnt_fst_q; // We have had the first gnt before now
|
|
logic mem_gnt_snd_d; // We are having or have had the second gnt
|
|
logic mem_gnt_snd_q; // We have had the second gnt before now
|
|
|
|
logic mem_req_fst_d; // We are having the first req
|
|
logic mem_req_snd_d; // We are having the second req
|
|
|
|
logic wbexc_mem_had_snd_req; // During ID/EX there was a second request
|
|
|
|
logic lsu_had_first_resp;
|
|
assign lsu_had_first_resp = `LSU.ls_fsm_cs == `LSU.WAIT_GNT && `LSU.split_misaligned_access;
|
|
|
|
////////////////////// Wrap signals //////////////////////
|
|
|
|
logic spec_en; // The specification is being queried in this cycle
|
|
logic has_spec_past; // There is a previous step to compare against.
|
|
// Will become 0 on uncheckable CSRs and at reset.
|
|
|
|
// The previous specification output to be compared with the new input
|
|
logic [31:0] spec_past_regs[32];
|
|
logic [31:0] spec_past_has_reg; // Registers will have past values only when they are written to.
|
|
`define X(n) spec_past_``n
|
|
`X_EACH_CSR_TYPED
|
|
`undef X
|
|
|
|
////////////////////// Pipeline signals //////////////////////
|
|
|
|
logic ex_success; // Execute stage succeeding
|
|
logic ex_err; // Execute stage erroring
|
|
logic ex_kill; // Execute stage killed
|
|
logic exc_finishing; // Exception finishing
|
|
logic wb_finishing; // WB finishing
|
|
logic wbexc_finishing; // WB/EXC finishing
|
|
logic wbexc_exists; // Instruction in WB/EXC
|
|
logic wbexc_ex_err; // EXC has an execute error
|
|
logic wbexc_fetch_err; // EXC has a fetch error
|
|
logic wbexc_illegal; // EXC has an illegal instruction
|
|
logic wbexc_compressed_illegal; // EXC has an illegal instruction
|
|
logic wbexc_err; // EXC has an error
|
|
logic instr_will_progress; // Instruction will finish EX
|
|
logic wfi_will_finish; // WFI instruction retire by flushing the pipeline,
|
|
// but that isn't an exception.
|
|
logic wbexc_csr_pipe_flush; // The pipeline is being flushed due to a CSR write
|
|
logic wbexc_handling_irq; // Check the results of handling an IRQ
|
|
|
|
////////////////////// CSR selection //////////////////////
|
|
// Decide whether to compare wbexc_post_* and wbexc_dut_post_* or to use live versions.
|
|
|
|
// WBEXC CSR dut post state
|
|
`define X(n) wbexc_dut_cmp_post_``n
|
|
`X_EACH_CSR_TYPED
|
|
`undef X
|
|
|
|
// WBEXC CSR spec post state
|
|
`define X(n) wbexc_spec_cmp_post_``n
|
|
`X_EACH_CSR_TYPED
|
|
`undef X
|
|
|
|
////////////////////// Spec Post //////////////////////
|
|
|
|
// These cause combinational cycles, but not severe ones. The problem is fixed in CherIoT-Ibex
|
|
logic spec_rx_a_en;
|
|
logic [4:0] spec_rx_a_addr;
|
|
logic [31:0] spec_rx_a;
|
|
assign spec_rx_a = pre_regs[spec_rx_a_addr];
|
|
|
|
logic spec_rx_b_en;
|
|
logic [4:0] spec_rx_b_addr;
|
|
logic [31:0] spec_rx_b;
|
|
assign spec_rx_b = pre_regs[spec_rx_b_addr];
|
|
|
|
logic [31:0] spec_post_wX;
|
|
logic [4:0] spec_post_wX_addr;
|
|
logic spec_post_wX_en;
|
|
|
|
`define X(n) spec_post_``n
|
|
`X_EACH_CSR_TYPED
|
|
`undef X
|
|
|
|
logic spec_int_err;
|
|
|
|
logic spec_fetch_err; // The specification has experienced a fetch error,
|
|
// regardless of whether or not it was told to.
|
|
assign spec_fetch_err =
|
|
(main_mode == MAIN_IFERR && spec_api_i.main_result == MAINRES_OK) ||
|
|
spec_api_i.main_result == MAINRES_IFERR_1 || spec_api_i.main_result == MAINRES_IFERR_2;
|
|
|
|
logic spec_mem_read;
|
|
logic spec_mem_read_snd;
|
|
logic [31:0] spec_mem_read_fst_addr;
|
|
logic [31:0] spec_mem_read_snd_addr;
|
|
logic [31:0] spec_mem_read_fst_rdata; // Undriven
|
|
logic [31:0] spec_mem_read_snd_rdata; // Undriven
|
|
|
|
logic spec_mem_write;
|
|
logic spec_mem_write_snd;
|
|
logic [31:0] spec_mem_write_fst_addr;
|
|
logic [31:0] spec_mem_write_snd_addr;
|
|
logic [31:0] spec_mem_write_fst_wdata;
|
|
logic [31:0] spec_mem_write_snd_wdata;
|
|
logic [3:0] spec_mem_write_fst_be;
|
|
logic [3:0] spec_mem_write_snd_be;
|
|
|
|
logic spec_mem_en;
|
|
logic spec_mem_en_snd;
|
|
logic [31:0] spec_mem_fst_addr;
|
|
logic [31:0] spec_mem_snd_addr;
|
|
logic spec_has_pmp_err;
|
|
|
|
assign spec_mem_en = spec_mem_read | spec_mem_write;
|
|
assign spec_mem_en_snd = spec_mem_read_snd | spec_mem_write_snd;
|
|
assign spec_mem_fst_addr = spec_mem_read ? spec_mem_read_fst_addr : spec_mem_write_fst_addr;
|
|
assign spec_mem_snd_addr = spec_mem_read ? spec_mem_read_snd_addr : spec_mem_write_snd_addr;
|
|
assign spec_has_pmp_err = ~spec_mem_en || (`LSU.split_misaligned_access && ~spec_mem_en_snd);
|
|
|
|
logic [31:0] fst_mask, snd_mask;
|
|
assign fst_mask = {
|
|
{8{spec_mem_write_fst_be[3]}}, {8{spec_mem_write_fst_be[2]}},
|
|
{8{spec_mem_write_fst_be[1]}}, {8{spec_mem_write_fst_be[0]}}
|
|
};
|
|
assign snd_mask = {
|
|
{8{spec_mem_write_snd_be[3]}}, {8{spec_mem_write_snd_be[2]}},
|
|
{8{spec_mem_write_snd_be[1]}}, {8{spec_mem_write_snd_be[0]}}
|
|
};
|
|
|
|
logic fst_mem_cmp; // Condition for the first outgoing request to be spec conformant
|
|
assign fst_mem_cmp = (spec_mem_write == data_we_o) && (spec_mem_read == ~data_we_o) &&
|
|
(data_addr_o == spec_mem_fst_addr) &&
|
|
(data_we_o ->
|
|
(data_wdata_o & fst_mask) == (spec_mem_write_fst_wdata & fst_mask));
|
|
logic snd_mem_cmp; // Condition for the second outgoing request to be spec conformant
|
|
assign snd_mem_cmp = (spec_mem_write_snd == data_we_o) && (spec_mem_read_snd == ~data_we_o) &&
|
|
(data_addr_o == spec_mem_snd_addr) &&
|
|
(data_we_o ->
|
|
(data_wdata_o & snd_mask) == (spec_mem_write_snd_wdata & snd_mask));
|
|
|
|
logic lsu_waiting_for_misal;
|
|
assign lsu_waiting_for_misal =
|
|
((`LSU.data_type_q == 2'b00) && (`LSU.rdata_offset_q != 2'b00)) ||
|
|
((`LSU.data_type_q == 2'b01) && (`LSU.rdata_offset_q == 2'b11));
|
|
|
|
logic addr_last_matches;
|
|
assign addr_last_matches = `ID.rf_rdata_a_fwd +
|
|
(ex_is_store_instr? `ID.imm_s_type : `ID.imm_i_type) ==
|
|
`LSU.addr_last_q;
|
|
|
|
logic addr_last_d_matches;
|
|
assign addr_last_d_matches = `ID.rf_rdata_a_fwd +
|
|
(ex_is_store_instr? `ID.imm_s_type : `ID.imm_i_type) ==
|
|
`LSU.addr_last_d;
|
|
|
|
////////////////////// Compare //////////////////////
|
|
|
|
logic addr_match; // Register write index match
|
|
logic data_match; // Register write data match
|
|
logic csrs_match;
|
|
logic ex_csrs_match;
|
|
logic csrs_match_non_exc;
|
|
logic ex_csrs_match_non_exc;
|
|
logic pc_match;
|
|
logic finishing_executed; // Finishing normal case
|
|
|
|
`define INSTR `CR.instr_rdata_id
|
|
|
|
logic wbexc_is_checkable_csr;
|
|
logic ex_is_checkable_csr;
|
|
assign ex_is_checkable_csr = ~(
|
|
((CSR_MHPMCOUNTER3H <= `CSR_ADDR) && (`CSR_ADDR <= CSR_MHPMCOUNTER31H)) |
|
|
((CSR_MHPMCOUNTER3 <= `CSR_ADDR) && (`CSR_ADDR <= CSR_MHPMCOUNTER31)) |
|
|
((CSR_MHPMEVENT3 <= `CSR_ADDR) && (`CSR_ADDR <= CSR_MHPMEVENT31)) |
|
|
(`CSR_ADDR == CSR_CPUCTRLSTS) | (`CSR_ADDR == CSR_SECURESEED) |
|
|
(`CSR_ADDR == CSR_MIE) |
|
|
(`CSR_ADDR == CSR_MCYCLE) | (`CSR_ADDR == CSR_MCYCLEH) |
|
|
|
|
// TODO:
|
|
(`CSR_ADDR == CSR_MINSTRET) | (`CSR_ADDR == CSR_MINSTRETH) |
|
|
(`CSR_ADDR == CSR_MCOUNTINHIBIT)
|
|
);
|
|
|
|
`undef INSTR
|
|
`define INSTR wbexc_decompressed_instr
|
|
|
|
// Illegal instructions arent checkable unless the relevant specifications are present.
|
|
logic can_check_illegal;
|
|
assign can_check_illegal = `SPEC_ILLEGAL & `SPEC_CSR & `SPEC_MRET & `SPEC_WFI;
|
|
|
|
`undef INSTR
|
|
|
|
////////////////////// Decompression Invariant Defs //////////////////////
|
|
// These will be used to show that the decompressed instruction stored is in fact the decompressed version of the compressed instruction.
|
|
|
|
logic [31:0] decompressed_instr;
|
|
logic decompressed_instr_illegal;
|
|
ibex_compressed_decoder decompression_assertion_decoder(
|
|
.clk_i,
|
|
.rst_ni,
|
|
.valid_i(1'b1),
|
|
.instr_i(ex_compressed_instr),
|
|
.instr_o(decompressed_instr),
|
|
.is_compressed_o(),
|
|
.illegal_instr_o(decompressed_instr_illegal)
|
|
);
|
|
|
|
logic [31:0] decompressed_instr_2;
|
|
logic decompressed_instr_illegal_2;
|
|
ibex_compressed_decoder decompression_assertion_decoder_2(
|
|
.clk_i,
|
|
.rst_ni,
|
|
.valid_i(1'b1),
|
|
.instr_i(wbexc_instr),
|
|
.instr_o(decompressed_instr_2),
|
|
.is_compressed_o(wbexc_is_compressed),
|
|
.illegal_instr_o(decompressed_instr_illegal_2)
|
|
);
|
|
|
|
////////////////////// IRQ + Memory Protocols //////////////////////
|
|
`include "protocol/irqs.sv"
|
|
`include "protocol/mem.sv"
|
|
|
|
////////////////////// Following //////////////////////
|
|
`include "peek/abs.sv" // Abstract state
|
|
`include "peek/mem.sv" // Memory tracking
|
|
`include "peek/follower.sv" // Pipeline follower
|
|
`include "spec_instance.sv" // Instantiate the specification
|
|
|
|
////////////////////// Proof helpers ///////////////////////
|
|
`include "peek/compare_helper.sv"
|
|
|
|
////////////////////// Proof //////////////////////
|
|
`define INSTR wbexc_decompressed_instr
|
|
`include "../build/psgen.sv"
|
|
|
|
endmodule
|