mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-06-28 01:29:10 -04:00
add X-IF 1.0 (#284)
* Core-V eXtension Interface (CV-X-IF) integration (#277) * minor fixes (#283) * minor fix again * Changes to make the X_if addition compatible with the golden version of the core, minus the rf_we line (#289) * Fix remaining sec inconsistency regarding the X-IF addition (#291) * Changes to make the X_if addition compatible with the golden version of the core, minus the rf_we line * [rt][sec][xif] Made the length of the cve2_id_stage's rf_wdata_sel dependent on the whether the X-IF is present * [rtl][sec][xif] Made the length of the cve2_id_stage's rf_wdata_sel dependent on the whether the X-IF is present * Clean Verilator warning about X-IF addition while keeping the RTL SEC-safe (#292) * Changes to make the X_if addition compatible with the golden version of the core, minus the rf_we line * [rt][sec][xif] Made the length of the cve2_id_stage's rf_wdata_sel dependent on the whether the X-IF is present * [rtl][sec][xif] Made the length of the cve2_id_stage's rf_wdata_sel dependent on the whether the X-IF is present * [rtl][xif][verilator] Clean warnings about enum-logic[] width mismatch on Verilator, while keeping the design logically equivalent. This is due to the cve2_decoder's rf_wdata_sel_o signal, which has its width dependent of the X-IF. * fix xif --------- Co-authored-by: FrancescoDeMalde-synthara <167969440+FrancescoDeMalde-synthara@users.noreply.github.com> Co-authored-by: Cairo Caplan <cairo.caplan@eclipse-foundation.org>
This commit is contained in:
parent
44393eb863
commit
468b3595cd
7 changed files with 401 additions and 92 deletions
|
@ -22,7 +22,8 @@ module cve2_core import cve2_pkg::*; #(
|
||||||
parameter rv32m_e RV32M = RV32MFast,
|
parameter rv32m_e RV32M = RV32MFast,
|
||||||
parameter rv32b_e RV32B = RV32BNone,
|
parameter rv32b_e RV32B = RV32BNone,
|
||||||
parameter bit DbgTriggerEn = 1'b0,
|
parameter bit DbgTriggerEn = 1'b0,
|
||||||
parameter int unsigned DbgHwBreakNum = 1
|
parameter int unsigned DbgHwBreakNum = 1,
|
||||||
|
parameter bit XInterface = 1'b0
|
||||||
) (
|
) (
|
||||||
// Clock and Reset
|
// Clock and Reset
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -52,6 +53,25 @@ module cve2_core import cve2_pkg::*; #(
|
||||||
input logic [31:0] data_rdata_i,
|
input logic [31:0] data_rdata_i,
|
||||||
input logic data_err_i,
|
input logic data_err_i,
|
||||||
|
|
||||||
|
// Core-V Extension Interface (CV-X-IF)
|
||||||
|
// Issue Interface
|
||||||
|
output logic x_issue_valid_o,
|
||||||
|
input logic x_issue_ready_i,
|
||||||
|
output x_issue_req_t x_issue_req_o,
|
||||||
|
input x_issue_resp_t x_issue_resp_i,
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
output x_register_t x_register_o,
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
output logic x_commit_valid_o,
|
||||||
|
output x_commit_t x_commit_o,
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
input logic x_result_valid_i,
|
||||||
|
output logic x_result_ready_o,
|
||||||
|
input x_result_t x_result_i,
|
||||||
|
|
||||||
// Interrupt inputs
|
// Interrupt inputs
|
||||||
input logic irq_software_i,
|
input logic irq_software_i,
|
||||||
input logic irq_timer_i,
|
input logic irq_timer_i,
|
||||||
|
@ -355,7 +375,8 @@ module cve2_core import cve2_pkg::*; #(
|
||||||
cve2_id_stage #(
|
cve2_id_stage #(
|
||||||
.RV32E (RV32E),
|
.RV32E (RV32E),
|
||||||
.RV32M (RV32M),
|
.RV32M (RV32M),
|
||||||
.RV32B (RV32B)
|
.RV32B (RV32B),
|
||||||
|
.XInterface (XInterface)
|
||||||
) id_stage_i (
|
) id_stage_i (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_ni(rst_ni),
|
.rst_ni(rst_ni),
|
||||||
|
@ -439,6 +460,25 @@ module cve2_core import cve2_pkg::*; #(
|
||||||
.lsu_load_err_i (lsu_load_err),
|
.lsu_load_err_i (lsu_load_err),
|
||||||
.lsu_store_err_i(lsu_store_err),
|
.lsu_store_err_i(lsu_store_err),
|
||||||
|
|
||||||
|
// Core-V Extension Interface (CV-X-IF)
|
||||||
|
// Issue Interface
|
||||||
|
.x_issue_valid_o(x_issue_valid_o),
|
||||||
|
.x_issue_ready_i(x_issue_ready_i),
|
||||||
|
.x_issue_req_o(x_issue_req_o),
|
||||||
|
.x_issue_resp_i(x_issue_resp_i),
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
.x_register_o(x_register_o),
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
.x_commit_valid_o(x_commit_valid_o),
|
||||||
|
.x_commit_o(x_commit_o),
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
.x_result_valid_i(x_result_valid_i),
|
||||||
|
.x_result_ready_o(x_result_ready_o),
|
||||||
|
.x_result_i(x_result_i),
|
||||||
|
|
||||||
// Interrupt Signals
|
// Interrupt Signals
|
||||||
.csr_mstatus_mie_i(csr_mstatus_mie),
|
.csr_mstatus_mie_i(csr_mstatus_mie),
|
||||||
.irq_pending_i (irq_pending_o),
|
.irq_pending_i (irq_pending_o),
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
module cve2_decoder #(
|
module cve2_decoder #(
|
||||||
parameter bit RV32E = 0,
|
parameter bit RV32E = 0,
|
||||||
parameter cve2_pkg::rv32m_e RV32M = cve2_pkg::RV32MFast,
|
parameter cve2_pkg::rv32m_e RV32M = cve2_pkg::RV32MFast,
|
||||||
parameter cve2_pkg::rv32b_e RV32B = cve2_pkg::RV32BNone
|
parameter cve2_pkg::rv32b_e RV32B = cve2_pkg::RV32BNone,
|
||||||
|
parameter bit XInterface = 1'b0
|
||||||
) (
|
) (
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input logic rst_ni,
|
input logic rst_ni,
|
||||||
|
@ -50,46 +51,50 @@ module cve2_decoder #(
|
||||||
output logic [31:0] zimm_rs1_type_o,
|
output logic [31:0] zimm_rs1_type_o,
|
||||||
|
|
||||||
// register file
|
// register file
|
||||||
output cve2_pkg::rf_wd_sel_e rf_wdata_sel_o, // RF write data selection
|
output logic [XInterface:0] rf_wdata_sel_o, // RF write data selection
|
||||||
output logic rf_we_o, // write enable for regfile
|
output logic rf_we_o, // write enable for regfile
|
||||||
output logic [4:0] rf_raddr_a_o,
|
output logic [4:0] rf_raddr_a_o,
|
||||||
output logic [4:0] rf_raddr_b_o,
|
output logic [4:0] rf_raddr_b_o,
|
||||||
output logic [4:0] rf_waddr_o,
|
output logic [4:0] rf_waddr_o,
|
||||||
output logic rf_ren_a_o, // Instruction reads from RF addr A
|
output logic rf_ren_a_o, // Instruction reads from RF addr A
|
||||||
output logic rf_ren_b_o, // Instruction reads from RF addr B
|
output logic rf_ren_b_o, // Instruction reads from RF addr B
|
||||||
|
|
||||||
// ALU
|
// ALU
|
||||||
output cve2_pkg::alu_op_e alu_operator_o, // ALU operation selection
|
output cve2_pkg::alu_op_e alu_operator_o, // ALU operation selection
|
||||||
output cve2_pkg::op_a_sel_e alu_op_a_mux_sel_o, // operand a selection: reg value, PC,
|
output cve2_pkg::op_a_sel_e alu_op_a_mux_sel_o, // operand a selection: reg value, PC,
|
||||||
// immediate or zero
|
// immediate or zero
|
||||||
output cve2_pkg::op_b_sel_e alu_op_b_mux_sel_o, // operand b selection: reg value or
|
output cve2_pkg::op_b_sel_e alu_op_b_mux_sel_o, // operand b selection: reg value or
|
||||||
// immediate
|
// immediate
|
||||||
output logic alu_multicycle_o, // ternary bitmanip instruction
|
output logic alu_multicycle_o, // ternary bitmanip instruction
|
||||||
|
|
||||||
// MULT & DIV
|
// MULT & DIV
|
||||||
output logic mult_en_o, // perform integer multiplication
|
output logic mult_en_o, // perform integer multiplication
|
||||||
output logic div_en_o, // perform integer division or remainder
|
output logic div_en_o, // perform integer division or remainder
|
||||||
output logic mult_sel_o, // as above but static, for data muxes
|
output logic mult_sel_o, // as above but static, for data muxes
|
||||||
output logic div_sel_o, // as above but static, for data muxes
|
output logic div_sel_o, // as above but static, for data muxes
|
||||||
|
|
||||||
output cve2_pkg::md_op_e multdiv_operator_o,
|
output cve2_pkg::md_op_e multdiv_operator_o,
|
||||||
output logic [1:0] multdiv_signed_mode_o,
|
output logic [1:0] multdiv_signed_mode_o,
|
||||||
|
|
||||||
// CSRs
|
// CSRs
|
||||||
output logic csr_access_o, // access to CSR
|
output logic csr_access_o, // access to CSR
|
||||||
output cve2_pkg::csr_op_e csr_op_o, // operation to perform on CSR
|
output cve2_pkg::csr_op_e csr_op_o, // operation to perform on CSR
|
||||||
|
|
||||||
// LSU
|
// LSU
|
||||||
output logic data_req_o, // start transaction to data memory
|
output logic data_req_o, // start transaction to data memory
|
||||||
output logic data_we_o, // write enable
|
output logic data_we_o, // write enable
|
||||||
output logic [1:0] data_type_o, // size of transaction: byte, half
|
output logic [1:0] data_type_o, // size of transaction: byte, half
|
||||||
// word or word
|
// word or word
|
||||||
output logic data_sign_extension_o, // sign extension for data read from
|
output logic data_sign_extension_o, // sign extension for data read from
|
||||||
// memory
|
// memory
|
||||||
|
|
||||||
|
// Core-V eXtension interface (CV-X-IF)
|
||||||
|
input cve2_pkg::readregflags_t x_issue_resp_register_read_i,
|
||||||
|
input cve2_pkg::writeregflags_t x_issue_resp_writeback_i,
|
||||||
|
|
||||||
// jump/branches
|
// jump/branches
|
||||||
output logic jump_in_dec_o, // jump is being calculated in ALU
|
output logic jump_in_dec_o, // jump is being calculated in ALU
|
||||||
output logic branch_in_dec_o
|
output logic branch_in_dec_o
|
||||||
);
|
);
|
||||||
|
|
||||||
import cve2_pkg::*;
|
import cve2_pkg::*;
|
||||||
|
@ -205,7 +210,7 @@ module cve2_decoder #(
|
||||||
multdiv_operator_o = MD_OP_MULL;
|
multdiv_operator_o = MD_OP_MULL;
|
||||||
multdiv_signed_mode_o = 2'b00;
|
multdiv_signed_mode_o = 2'b00;
|
||||||
|
|
||||||
rf_wdata_sel_o = RF_WD_EX;
|
rf_wdata_sel_o = $bits(rf_wdata_sel_o)'({RF_WD_EX});
|
||||||
rf_we = 1'b0;
|
rf_we = 1'b0;
|
||||||
rf_ren_a_o = 1'b0;
|
rf_ren_a_o = 1'b0;
|
||||||
rf_ren_b_o = 1'b0;
|
rf_ren_b_o = 1'b0;
|
||||||
|
@ -612,7 +617,7 @@ module cve2_decoder #(
|
||||||
end else begin
|
end else begin
|
||||||
// instruction to read/modify CSR
|
// instruction to read/modify CSR
|
||||||
csr_access_o = 1'b1;
|
csr_access_o = 1'b1;
|
||||||
rf_wdata_sel_o = RF_WD_CSR;
|
rf_wdata_sel_o = $bits(rf_wdata_sel_o)'({RF_WD_CSR});
|
||||||
rf_we = 1'b1;
|
rf_we = 1'b1;
|
||||||
|
|
||||||
if (~instr[14]) begin
|
if (~instr[14]) begin
|
||||||
|
@ -653,6 +658,13 @@ module cve2_decoder #(
|
||||||
jump_set_o = 1'b0;
|
jump_set_o = 1'b0;
|
||||||
branch_in_dec_o = 1'b0;
|
branch_in_dec_o = 1'b0;
|
||||||
csr_access_o = 1'b0;
|
csr_access_o = 1'b0;
|
||||||
|
// CV-X-IF
|
||||||
|
if(XInterface) begin
|
||||||
|
rf_ren_a_o = x_issue_resp_register_read_i[0];
|
||||||
|
rf_ren_b_o = x_issue_resp_register_read_i[1];
|
||||||
|
rf_we = x_issue_resp_writeback_i;
|
||||||
|
rf_wdata_sel_o = $bits(rf_wdata_sel_o)'({RF_WD_COPROC});
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
module cve2_id_stage #(
|
module cve2_id_stage #(
|
||||||
parameter bit RV32E = 0,
|
parameter bit RV32E = 0,
|
||||||
parameter cve2_pkg::rv32m_e RV32M = cve2_pkg::RV32MFast,
|
parameter cve2_pkg::rv32m_e RV32M = cve2_pkg::RV32MFast,
|
||||||
parameter cve2_pkg::rv32b_e RV32B = cve2_pkg::RV32BNone
|
parameter cve2_pkg::rv32b_e RV32B = cve2_pkg::RV32BNone,
|
||||||
|
parameter bit XInterface = 1'b0
|
||||||
) (
|
) (
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input logic rst_ni,
|
input logic rst_ni,
|
||||||
|
@ -102,6 +103,25 @@ module cve2_id_stage #(
|
||||||
input logic lsu_addr_incr_req_i,
|
input logic lsu_addr_incr_req_i,
|
||||||
input logic [31:0] lsu_addr_last_i,
|
input logic [31:0] lsu_addr_last_i,
|
||||||
|
|
||||||
|
// Core-V eXtension Interface (CV-X-IF)
|
||||||
|
// Issue Interface
|
||||||
|
output logic x_issue_valid_o,
|
||||||
|
input logic x_issue_ready_i,
|
||||||
|
output cve2_pkg::x_issue_req_t x_issue_req_o,
|
||||||
|
input cve2_pkg::x_issue_resp_t x_issue_resp_i,
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
output cve2_pkg::x_register_t x_register_o,
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
output logic x_commit_valid_o,
|
||||||
|
output cve2_pkg::x_commit_t x_commit_o,
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
input logic x_result_valid_i,
|
||||||
|
output logic x_result_ready_o,
|
||||||
|
input cve2_pkg::x_result_t x_result_i,
|
||||||
|
|
||||||
// Interrupt signals
|
// Interrupt signals
|
||||||
input logic csr_mstatus_mie_i,
|
input logic csr_mstatus_mie_i,
|
||||||
input logic irq_pending_i,
|
input logic irq_pending_i,
|
||||||
|
@ -196,10 +216,10 @@ module cve2_id_stage #(
|
||||||
|
|
||||||
// Register file interface
|
// Register file interface
|
||||||
|
|
||||||
rf_wd_sel_e rf_wdata_sel;
|
logic [XInterface:0] rf_wdata_sel;
|
||||||
logic rf_we_dec, rf_we_raw;
|
logic rf_we_dec, rf_we_raw;
|
||||||
logic rf_ren_a, rf_ren_b;
|
logic rf_ren_a, rf_ren_b;
|
||||||
logic rf_ren_a_dec, rf_ren_b_dec;
|
logic rf_ren_a_dec, rf_ren_b_dec;
|
||||||
|
|
||||||
// Read enables should only be asserted for valid and legal instructions
|
// Read enables should only be asserted for valid and legal instructions
|
||||||
assign rf_ren_a = instr_valid_i & ~instr_fetch_err_i & ~illegal_insn_o & rf_ren_a_dec;
|
assign rf_ren_a = instr_valid_i & ~instr_fetch_err_i & ~illegal_insn_o & rf_ren_a_dec;
|
||||||
|
@ -243,6 +263,81 @@ module cve2_id_stage #(
|
||||||
logic [31:0] alu_operand_a;
|
logic [31:0] alu_operand_a;
|
||||||
logic [31:0] alu_operand_b;
|
logic [31:0] alu_operand_b;
|
||||||
|
|
||||||
|
// CV-X-IF
|
||||||
|
logic stall_coproc;
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// ID-EX FSM //
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
typedef enum logic { FIRST_CYCLE, MULTI_CYCLE } id_fsm_e;
|
||||||
|
id_fsm_e id_fsm_q, id_fsm_d;
|
||||||
|
|
||||||
|
always_ff @(posedge clk_i or negedge rst_ni) begin : id_pipeline_reg
|
||||||
|
if (!rst_ni) begin
|
||||||
|
id_fsm_q <= FIRST_CYCLE;
|
||||||
|
end else if (instr_executing) begin
|
||||||
|
id_fsm_q <= id_fsm_d;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// CV-X-IF
|
||||||
|
if (XInterface) begin: gen_xif
|
||||||
|
|
||||||
|
logic coproc_done;
|
||||||
|
assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : (illegal_insn_dec ? coproc_done : ex_valid_i);
|
||||||
|
|
||||||
|
assign coproc_done = (x_issue_valid_o & x_issue_ready_i & ~x_issue_resp_i.writeback) | (x_result_valid_i & x_result_i.we);
|
||||||
|
|
||||||
|
// Issue Interface
|
||||||
|
assign x_issue_valid_o = instr_executing & illegal_insn_dec & (id_fsm_q == FIRST_CYCLE);
|
||||||
|
assign x_issue_req_o.instr = instr_rdata_i;
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
assign x_register_o.rs[0] = rf_rdata_a_fwd;
|
||||||
|
assign x_register_o.rs[1] = rf_rdata_b_fwd;
|
||||||
|
assign x_register_o.rs_valid = '1;
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
assign x_commit_valid_o = 1'b1;
|
||||||
|
assign x_commit_o.commit_kill = 1'b0;
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
assign x_result_ready_o = 1'b1;
|
||||||
|
|
||||||
|
assign illegal_insn_o = instr_valid_i & (illegal_csr_insn_i | (x_issue_valid_o & x_issue_ready_i & ~x_issue_resp_i.accept));
|
||||||
|
end
|
||||||
|
|
||||||
|
else begin: no_gen_xif
|
||||||
|
logic unused_x_issue_ready;
|
||||||
|
x_issue_resp_t unused_x_issue_resp;
|
||||||
|
logic unused_x_result_valid;
|
||||||
|
x_result_t unused_x_result;
|
||||||
|
|
||||||
|
|
||||||
|
assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i;
|
||||||
|
|
||||||
|
// Issue Interface
|
||||||
|
assign x_issue_valid_o = 1'b0;
|
||||||
|
assign unused_x_issue_ready = x_issue_ready_i;
|
||||||
|
assign x_issue_req_o = '0;
|
||||||
|
assign unused_x_issue_resp = x_issue_resp_i;
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
assign x_register_o = '0;
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
assign x_commit_valid_o = 1'b0;
|
||||||
|
assign x_commit_o = '0;
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
assign x_result_ready_o = 1'b0;
|
||||||
|
assign unused_x_result_valid = x_result_valid_i;
|
||||||
|
assign unused_x_result = x_result_i;
|
||||||
|
|
||||||
|
assign illegal_insn_o = instr_valid_i & (illegal_csr_insn_i | illegal_insn_dec);
|
||||||
|
end
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// LSU Mux //
|
// LSU Mux //
|
||||||
/////////////
|
/////////////
|
||||||
|
@ -323,10 +418,11 @@ module cve2_id_stage #(
|
||||||
|
|
||||||
// Register file write data mux
|
// Register file write data mux
|
||||||
always_comb begin : rf_wdata_id_mux
|
always_comb begin : rf_wdata_id_mux
|
||||||
unique case (rf_wdata_sel)
|
unique case ($bits(rf_wd_sel_e)'({rf_wdata_sel}))
|
||||||
RF_WD_EX: rf_wdata_id_o = result_ex_i;
|
RF_WD_EX: rf_wdata_id_o = result_ex_i;
|
||||||
RF_WD_CSR: rf_wdata_id_o = csr_rdata_i;
|
RF_WD_CSR: rf_wdata_id_o = csr_rdata_i;
|
||||||
default: rf_wdata_id_o = result_ex_i;
|
RF_WD_COPROC: rf_wdata_id_o = XInterface? x_result_i.data : result_ex_i;
|
||||||
|
default: rf_wdata_id_o = result_ex_i;
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -337,7 +433,8 @@ module cve2_id_stage #(
|
||||||
cve2_decoder #(
|
cve2_decoder #(
|
||||||
.RV32E (RV32E),
|
.RV32E (RV32E),
|
||||||
.RV32M (RV32M),
|
.RV32M (RV32M),
|
||||||
.RV32B (RV32B)
|
.RV32B (RV32B),
|
||||||
|
.XInterface (XInterface)
|
||||||
) decoder_i (
|
) decoder_i (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_ni(rst_ni),
|
.rst_ni(rst_ni),
|
||||||
|
@ -402,6 +499,10 @@ module cve2_id_stage #(
|
||||||
.data_type_o (lsu_type),
|
.data_type_o (lsu_type),
|
||||||
.data_sign_extension_o(lsu_sign_ext),
|
.data_sign_extension_o(lsu_sign_ext),
|
||||||
|
|
||||||
|
// Core-V eXtension Interface (CV-X-IF)
|
||||||
|
.x_issue_resp_register_read_i(x_issue_resp_i.register_read),
|
||||||
|
.x_issue_resp_writeback_i(x_issue_resp_i.writeback),
|
||||||
|
|
||||||
// jump/branches
|
// jump/branches
|
||||||
.jump_in_dec_o (jump_in_dec),
|
.jump_in_dec_o (jump_in_dec),
|
||||||
.branch_in_dec_o(branch_in_dec)
|
.branch_in_dec_o(branch_in_dec)
|
||||||
|
@ -442,8 +543,6 @@ module cve2_id_stage #(
|
||||||
// Controller //
|
// Controller //
|
||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
assign illegal_insn_o = instr_valid_i & (illegal_insn_dec | illegal_csr_insn_i);
|
|
||||||
|
|
||||||
cve2_controller #(
|
cve2_controller #(
|
||||||
) controller_i (
|
) controller_i (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
|
@ -599,21 +698,6 @@ module cve2_id_stage #(
|
||||||
assign jump_set = jump_set_raw & ~branch_jump_set_done_q;
|
assign jump_set = jump_set_raw & ~branch_jump_set_done_q;
|
||||||
assign branch_set = branch_set_raw & ~branch_jump_set_done_q;
|
assign branch_set = branch_set_raw & ~branch_jump_set_done_q;
|
||||||
|
|
||||||
///////////////
|
|
||||||
// ID-EX FSM //
|
|
||||||
///////////////
|
|
||||||
|
|
||||||
typedef enum logic { FIRST_CYCLE, MULTI_CYCLE } id_fsm_e;
|
|
||||||
id_fsm_e id_fsm_q, id_fsm_d;
|
|
||||||
|
|
||||||
always_ff @(posedge clk_i or negedge rst_ni) begin : id_pipeline_reg
|
|
||||||
if (!rst_ni) begin
|
|
||||||
id_fsm_q <= FIRST_CYCLE;
|
|
||||||
end else if (instr_executing) begin
|
|
||||||
id_fsm_q <= id_fsm_d;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// ID/EX stage can be in two states, FIRST_CYCLE and MULTI_CYCLE. An instruction enters
|
// ID/EX stage can be in two states, FIRST_CYCLE and MULTI_CYCLE. An instruction enters
|
||||||
// MULTI_CYCLE if it requires multiple cycles to complete regardless of stalls and other
|
// MULTI_CYCLE if it requires multiple cycles to complete regardless of stalls and other
|
||||||
// considerations. An instruction may be held in FIRST_CYCLE if it's unable to begin executing
|
// considerations. An instruction may be held in FIRST_CYCLE if it's unable to begin executing
|
||||||
|
@ -626,6 +710,7 @@ module cve2_id_stage #(
|
||||||
stall_jump = 1'b0;
|
stall_jump = 1'b0;
|
||||||
stall_branch = 1'b0;
|
stall_branch = 1'b0;
|
||||||
stall_alu = 1'b0;
|
stall_alu = 1'b0;
|
||||||
|
stall_coproc = 1'b0;
|
||||||
branch_set_raw_d = 1'b0;
|
branch_set_raw_d = 1'b0;
|
||||||
jump_set_raw = 1'b0;
|
jump_set_raw = 1'b0;
|
||||||
perf_branch_o = 1'b0;
|
perf_branch_o = 1'b0;
|
||||||
|
@ -673,6 +758,30 @@ module cve2_id_stage #(
|
||||||
id_fsm_d = MULTI_CYCLE;
|
id_fsm_d = MULTI_CYCLE;
|
||||||
rf_we_raw = 1'b0;
|
rf_we_raw = 1'b0;
|
||||||
end
|
end
|
||||||
|
illegal_insn_dec: begin
|
||||||
|
|
||||||
|
// CV-X-IF
|
||||||
|
if(XInterface) begin
|
||||||
|
if(x_issue_valid_o && x_issue_ready_i) begin
|
||||||
|
if(x_issue_resp_i.accept && x_issue_resp_i.writeback) begin
|
||||||
|
id_fsm_d = MULTI_CYCLE;
|
||||||
|
stall_coproc = 1'b1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
id_fsm_d = FIRST_CYCLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
stall_coproc = 1'b1;
|
||||||
|
id_fsm_d = FIRST_CYCLE;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
id_fsm_d = FIRST_CYCLE;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
default: begin
|
default: begin
|
||||||
id_fsm_d = FIRST_CYCLE;
|
id_fsm_d = FIRST_CYCLE;
|
||||||
end
|
end
|
||||||
|
@ -690,6 +799,7 @@ module cve2_id_stage #(
|
||||||
stall_multdiv = multdiv_en_dec;
|
stall_multdiv = multdiv_en_dec;
|
||||||
stall_branch = branch_in_dec;
|
stall_branch = branch_in_dec;
|
||||||
stall_jump = jump_in_dec;
|
stall_jump = jump_in_dec;
|
||||||
|
stall_coproc = XInterface & illegal_insn_dec;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -700,13 +810,16 @@ module cve2_id_stage #(
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
`ASSERT(StallIDIfMulticycle, (id_fsm_q == FIRST_CYCLE) & (id_fsm_d == MULTI_CYCLE) |-> stall_id)
|
`ASSERT(StallIDIfMulticycle, (id_fsm_q == FIRST_CYCLE) & (id_fsm_d == MULTI_CYCLE) |-> stall_id)
|
||||||
|
|
||||||
|
|
||||||
// Stall ID/EX stage for reason that relates to instruction in ID/EX, update assertion below if
|
// Stall ID/EX stage for reason that relates to instruction in ID/EX, update assertion below if
|
||||||
// modifying this.
|
// modifying this.
|
||||||
assign stall_id = stall_mem | stall_multdiv | stall_jump | stall_branch |
|
assign stall_id = stall_mem | stall_multdiv | stall_jump | stall_branch |
|
||||||
stall_alu;
|
stall_alu | (XInterface & stall_coproc);
|
||||||
|
|
||||||
// Generally illegal instructions have no reason to stall, however they must still stall waiting
|
// Generally illegal instructions have no reason to stall, however they must still stall waiting
|
||||||
// for outstanding memory requests so exceptions related to them take priority over the illegal
|
// for outstanding memory requests so exceptions related to them take priority over the illegal
|
||||||
|
@ -723,34 +836,32 @@ module cve2_id_stage #(
|
||||||
// Used by ALU to access RS3 if ternary instruction.
|
// Used by ALU to access RS3 if ternary instruction.
|
||||||
assign instr_first_cycle_id_o = instr_first_cycle;
|
assign instr_first_cycle_id_o = instr_first_cycle;
|
||||||
|
|
||||||
assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i;
|
assign data_req_allowed = instr_first_cycle;
|
||||||
|
|
||||||
assign data_req_allowed = instr_first_cycle;
|
// Without Writeback Stage always stall the first cycle of a load/store.
|
||||||
|
// Then stall until it is complete
|
||||||
|
assign stall_mem = instr_valid_i & (lsu_req_dec & (~lsu_resp_valid_i | instr_first_cycle));
|
||||||
|
|
||||||
// Without Writeback Stage always stall the first cycle of a load/store.
|
// Without writeback stage any valid instruction that hasn't seen an error will execute
|
||||||
// Then stall until it is complete
|
assign instr_executing_spec = instr_valid_i & ~instr_fetch_err_i & controller_run;
|
||||||
assign stall_mem = instr_valid_i & (lsu_req_dec & (~lsu_resp_valid_i | instr_first_cycle));
|
assign instr_executing = instr_executing_spec;
|
||||||
|
|
||||||
// Without writeback stage any valid instruction that hasn't seen an error will execute
|
`ASSERT(IbexStallIfValidInstrNotExecuting,
|
||||||
assign instr_executing_spec = instr_valid_i & ~instr_fetch_err_i & controller_run;
|
instr_valid_i & ~instr_fetch_err_i & ~instr_executing & controller_run |-> stall_id)
|
||||||
assign instr_executing = instr_executing_spec;
|
|
||||||
|
|
||||||
`ASSERT(IbexStallIfValidInstrNotExecuting,
|
// No data forwarding without writeback stage so always take source register data direct from
|
||||||
instr_valid_i & ~instr_fetch_err_i & ~instr_executing & controller_run |-> stall_id)
|
// register file
|
||||||
|
assign rf_rdata_a_fwd = rf_rdata_a_i;
|
||||||
|
assign rf_rdata_b_fwd = rf_rdata_b_i;
|
||||||
|
|
||||||
// No data forwarding without writeback stage so always take source register data direct from
|
// Unused Writeback stage only IO & wiring
|
||||||
// register file
|
// Assign inputs and internal wiring to unused signals to satisfy lint checks
|
||||||
assign rf_rdata_a_fwd = rf_rdata_a_i;
|
// Tie-off outputs to constant values
|
||||||
assign rf_rdata_b_fwd = rf_rdata_b_i;
|
logic unused_data_req_done_ex;
|
||||||
|
|
||||||
// Unused Writeback stage only IO & wiring
|
assign perf_dside_wait_o = instr_executing & lsu_req_dec & ~lsu_resp_valid_i;
|
||||||
// Assign inputs and internal wiring to unused signals to satisfy lint checks
|
|
||||||
// Tie-off outputs to constant values
|
|
||||||
logic unused_data_req_done_ex;
|
|
||||||
|
|
||||||
assign perf_dside_wait_o = instr_executing & lsu_req_dec & ~lsu_resp_valid_i;
|
assign instr_id_done_o = instr_done;
|
||||||
|
|
||||||
assign instr_id_done_o = instr_done;
|
|
||||||
|
|
||||||
// Signal which instructions to count as retired in minstret, all traps along with ebrk and
|
// Signal which instructions to count as retired in minstret, all traps along with ebrk and
|
||||||
// ecall instructions are not counted.
|
// ecall instructions are not counted.
|
||||||
|
@ -784,9 +895,17 @@ module cve2_id_stage #(
|
||||||
OP_A_FWD,
|
OP_A_FWD,
|
||||||
OP_A_CURRPC,
|
OP_A_CURRPC,
|
||||||
OP_A_IMM})
|
OP_A_IMM})
|
||||||
`ASSERT(IbexRegfileWdataSelValid, instr_valid_i |-> rf_wdata_sel inside {
|
if (XInterface) begin: gen_asserts_xif
|
||||||
RF_WD_EX,
|
`ASSERT(IbexRegfileWdataSelValid, instr_valid_i |-> rf_wdata_sel inside {
|
||||||
RF_WD_CSR})
|
RF_WD_EX,
|
||||||
|
RF_WD_CSR,
|
||||||
|
RF_WD_COPROC})
|
||||||
|
end
|
||||||
|
else begin : no_gen_asserts_xif
|
||||||
|
`ASSERT(IbexRegfileWdataSelValid, instr_valid_i |-> rf_wdata_sel inside {
|
||||||
|
RF_WD_EX,
|
||||||
|
RF_WD_CSR})
|
||||||
|
end
|
||||||
`ASSERT_KNOWN(IbexWbStateKnown, id_fsm_q)
|
`ASSERT_KNOWN(IbexWbStateKnown, id_fsm_q)
|
||||||
|
|
||||||
// Branch decision must be valid when jumping.
|
// Branch decision must be valid when jumping.
|
||||||
|
@ -803,7 +922,7 @@ module cve2_id_stage #(
|
||||||
|
|
||||||
// Multicycle enable signals must be unique.
|
// Multicycle enable signals must be unique.
|
||||||
`ASSERT(IbexMulticycleEnableUnique,
|
`ASSERT(IbexMulticycleEnableUnique,
|
||||||
$onehot0({lsu_req_dec, multdiv_en_dec, branch_in_dec, jump_in_dec}))
|
$onehot0({lsu_req_dec, multdiv_en_dec, branch_in_dec, jump_in_dec, illegal_insn_dec}))
|
||||||
|
|
||||||
// Duplicated instruction flops must match
|
// Duplicated instruction flops must match
|
||||||
// === as DV environment can produce instructions with Xs in, so must use precise match that
|
// === as DV environment can produce instructions with Xs in, so must use precise match that
|
||||||
|
|
|
@ -260,9 +260,10 @@ package cve2_pkg;
|
||||||
} imm_b_sel_e;
|
} imm_b_sel_e;
|
||||||
|
|
||||||
// Regfile write data selection
|
// Regfile write data selection
|
||||||
typedef enum logic {
|
typedef enum {
|
||||||
RF_WD_EX,
|
RF_WD_EX,
|
||||||
RF_WD_CSR
|
RF_WD_CSR,
|
||||||
|
RF_WD_COPROC // Only used when XInterface = 1
|
||||||
} rf_wd_sel_e;
|
} rf_wd_sel_e;
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
|
@ -654,5 +655,57 @@ package cve2_pkg;
|
||||||
rvfi_csr_elmt_t pmpaddr15;
|
rvfi_csr_elmt_t pmpaddr15;
|
||||||
} rvfi_csr_t;
|
} rvfi_csr_t;
|
||||||
|
|
||||||
|
// CV-X-IF
|
||||||
|
parameter int unsigned X_NUM_RS = 2;
|
||||||
|
parameter int unsigned X_ID_WIDTH = 4;
|
||||||
|
parameter int unsigned X_RFR_WIDTH = 32;
|
||||||
|
parameter int unsigned X_RFW_WIDTH = 32;
|
||||||
|
parameter int unsigned X_HARTID_WIDTH = 1;
|
||||||
|
parameter int unsigned X_DUAL_READ = 0;
|
||||||
|
parameter int unsigned X_DUAL_WRITE = 0;
|
||||||
|
|
||||||
|
typedef logic [X_NUM_RS+X_DUAL_READ-1:0] readregflags_t;
|
||||||
|
typedef logic [X_DUAL_WRITE:0] writeregflags_t;
|
||||||
|
typedef logic [X_ID_WIDTH-1:0] id_t;
|
||||||
|
typedef logic [X_HARTID_WIDTH-1:0] hartid_t;
|
||||||
|
|
||||||
|
// Issue Interface
|
||||||
|
typedef struct packed {
|
||||||
|
logic [31:0] instr;
|
||||||
|
hartid_t hartid;
|
||||||
|
id_t id;
|
||||||
|
} x_issue_req_t;
|
||||||
|
|
||||||
|
typedef struct packed {
|
||||||
|
logic accept;
|
||||||
|
writeregflags_t writeback;
|
||||||
|
readregflags_t register_read;
|
||||||
|
} x_issue_resp_t;
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
typedef struct packed {
|
||||||
|
hartid_t hartid;
|
||||||
|
id_t id;
|
||||||
|
logic [X_NUM_RS-1:0][X_RFR_WIDTH-1:0] rs;
|
||||||
|
readregflags_t rs_valid;
|
||||||
|
} x_register_t;
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
typedef struct packed {
|
||||||
|
hartid_t hartid;
|
||||||
|
id_t id;
|
||||||
|
logic commit_kill;
|
||||||
|
} x_commit_t;
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
typedef struct packed {
|
||||||
|
hartid_t hartid;
|
||||||
|
id_t id;
|
||||||
|
logic [X_RFW_WIDTH-1:0] data;
|
||||||
|
logic [4:0] rd;
|
||||||
|
writeregflags_t we;
|
||||||
|
} x_result_t;
|
||||||
|
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,8 @@ module cve2_top import cve2_pkg::*; #(
|
||||||
parameter int unsigned MHPMCounterNum = 10,
|
parameter int unsigned MHPMCounterNum = 10,
|
||||||
parameter int unsigned MHPMCounterWidth = 40,
|
parameter int unsigned MHPMCounterWidth = 40,
|
||||||
parameter bit RV32E = 1'b0,
|
parameter bit RV32E = 1'b0,
|
||||||
parameter rv32m_e RV32M = RV32MFast
|
parameter rv32m_e RV32M = RV32MFast,
|
||||||
|
parameter bit XInterface = 1'b0
|
||||||
) (
|
) (
|
||||||
// Clock and Reset
|
// Clock and Reset
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -48,6 +49,25 @@ module cve2_top import cve2_pkg::*; #(
|
||||||
input logic [31:0] data_rdata_i,
|
input logic [31:0] data_rdata_i,
|
||||||
input logic data_err_i,
|
input logic data_err_i,
|
||||||
|
|
||||||
|
// Core-V Extension Interface (CV-X-IF)
|
||||||
|
// Issue Interface
|
||||||
|
output logic x_issue_valid_o,
|
||||||
|
input logic x_issue_ready_i,
|
||||||
|
output x_issue_req_t x_issue_req_o,
|
||||||
|
input x_issue_resp_t x_issue_resp_i,
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
output x_register_t x_register_o,
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
output logic x_commit_valid_o,
|
||||||
|
output x_commit_t x_commit_o,
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
input logic x_result_valid_i,
|
||||||
|
output logic x_result_ready_o,
|
||||||
|
input x_result_t x_result_i,
|
||||||
|
|
||||||
// Interrupt inputs
|
// Interrupt inputs
|
||||||
input logic irq_software_i,
|
input logic irq_software_i,
|
||||||
input logic irq_timer_i,
|
input logic irq_timer_i,
|
||||||
|
@ -161,7 +181,8 @@ module cve2_top import cve2_pkg::*; #(
|
||||||
.RV32M (RV32M),
|
.RV32M (RV32M),
|
||||||
.RV32B (RV32B),
|
.RV32B (RV32B),
|
||||||
.DbgTriggerEn (DbgTriggerEn),
|
.DbgTriggerEn (DbgTriggerEn),
|
||||||
.DbgHwBreakNum (DbgHwBreakNum)
|
.DbgHwBreakNum (DbgHwBreakNum),
|
||||||
|
.XInterface (XInterface)
|
||||||
) u_cve2_core (
|
) u_cve2_core (
|
||||||
.clk_i(clk),
|
.clk_i(clk),
|
||||||
.rst_ni,
|
.rst_ni,
|
||||||
|
@ -187,6 +208,25 @@ module cve2_top import cve2_pkg::*; #(
|
||||||
.data_rdata_i,
|
.data_rdata_i,
|
||||||
.data_err_i,
|
.data_err_i,
|
||||||
|
|
||||||
|
// Core-V Extension Interface (CV-X-IF)
|
||||||
|
// Issue Interface
|
||||||
|
.x_issue_valid_o,
|
||||||
|
.x_issue_ready_i,
|
||||||
|
.x_issue_req_o,
|
||||||
|
.x_issue_resp_i,
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
.x_register_o,
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
.x_commit_valid_o,
|
||||||
|
.x_commit_o,
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
.x_result_valid_i,
|
||||||
|
.x_result_ready_o,
|
||||||
|
.x_result_i,
|
||||||
|
|
||||||
.irq_software_i,
|
.irq_software_i,
|
||||||
.irq_timer_i,
|
.irq_timer_i,
|
||||||
.irq_external_i,
|
.irq_external_i,
|
||||||
|
@ -268,7 +308,6 @@ module cve2_top import cve2_pkg::*; #(
|
||||||
|
|
||||||
`ASSERT_KNOWN(IbexDataGntX, data_gnt_i)
|
`ASSERT_KNOWN(IbexDataGntX, data_gnt_i)
|
||||||
`ASSERT_KNOWN(IbexDataRValidX, data_rvalid_i)
|
`ASSERT_KNOWN(IbexDataRValidX, data_rvalid_i)
|
||||||
`ASSERT_KNOWN_IF(IbexDataRPayloadX, {data_rdata_i, data_err_i}, data_rvalid_i)
|
|
||||||
|
|
||||||
`ASSERT_KNOWN(IbexIrqX, {irq_software_i, irq_timer_i, irq_external_i, irq_fast_i, irq_nm_i})
|
`ASSERT_KNOWN(IbexIrqX, {irq_software_i, irq_timer_i, irq_external_i, irq_fast_i, irq_nm_i})
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,25 @@ module cve2_top_tracing import cve2_pkg::*; #(
|
||||||
input logic [31:0] data_rdata_i,
|
input logic [31:0] data_rdata_i,
|
||||||
input logic data_err_i,
|
input logic data_err_i,
|
||||||
|
|
||||||
|
// Core-V Extension Interface (CV-X-IF)
|
||||||
|
// Issue Interface
|
||||||
|
output logic x_issue_valid_o,
|
||||||
|
input logic x_issue_ready_i,
|
||||||
|
output x_issue_req_t x_issue_req_o,
|
||||||
|
input x_issue_resp_t x_issue_resp_i,
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
output x_register_t x_register_o,
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
output logic x_commit_valid_o,
|
||||||
|
output x_commit_t x_commit_o,
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
input logic x_result_valid_i,
|
||||||
|
output logic x_result_ready_o,
|
||||||
|
input x_result_t x_result_i,
|
||||||
|
|
||||||
// Interrupt inputs
|
// Interrupt inputs
|
||||||
input logic irq_software_i,
|
input logic irq_software_i,
|
||||||
input logic irq_timer_i,
|
input logic irq_timer_i,
|
||||||
|
@ -140,6 +159,25 @@ module cve2_top_tracing import cve2_pkg::*; #(
|
||||||
.data_rdata_i,
|
.data_rdata_i,
|
||||||
.data_err_i,
|
.data_err_i,
|
||||||
|
|
||||||
|
// Core-V Extension Interface (CV-X-IF)
|
||||||
|
// Issue Interface
|
||||||
|
.x_issue_valid_o,
|
||||||
|
.x_issue_ready_i,
|
||||||
|
.x_issue_req_o,
|
||||||
|
.x_issue_resp_i,
|
||||||
|
|
||||||
|
// Register Interface
|
||||||
|
.x_register_o,
|
||||||
|
|
||||||
|
// Commit Interface
|
||||||
|
.x_commit_valid_o,
|
||||||
|
.x_commit_o,
|
||||||
|
|
||||||
|
// Result Interface
|
||||||
|
.x_result_valid_i,
|
||||||
|
.x_result_ready_o,
|
||||||
|
.x_result_i,
|
||||||
|
|
||||||
.irq_software_i,
|
.irq_software_i,
|
||||||
.irq_timer_i,
|
.irq_timer_i,
|
||||||
.irq_external_i,
|
.irq_external_i,
|
||||||
|
|
|
@ -100,13 +100,21 @@ elif [[ "${target_tool}" == "mentor" ]]; then
|
||||||
|
|
||||||
elif [[ "${target_tool}" == "yosys" ]]; then
|
elif [[ "${target_tool}" == "yosys" ]]; then
|
||||||
echo "Using Yosys EQY"
|
echo "Using Yosys EQY"
|
||||||
eqy -f yosys/sec.eqy -j $(($(nproc)/2)) -d ${report_dir} &> ${report_dir}/output.yosys.log
|
|
||||||
|
if ! [ -x "$(command -v eqy)" ]; then
|
||||||
|
echo "Yosys EQY (eqy) could not be found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
eqy -f yosys/sec.eqy -j $(($(nproc)/2)) -d ${report_dir} &> /dev/null
|
||||||
|
mv ${report_dir}/logfile.txt ${report_dir}/output.yosys.log
|
||||||
rm yosys/golden_io.txt
|
rm yosys/golden_io.txt
|
||||||
|
|
||||||
if [ -f "${report_dir}/PASS" ]; then
|
if [ -f "${report_dir}/PASS" ]; then
|
||||||
RESULT=0
|
RESULT=0
|
||||||
elif [ -f "${report_dir}/FAIL" ]; then
|
elif [ -f "${report_dir}/FAIL" ]; then
|
||||||
RESULT=1
|
RESULT=1
|
||||||
|
echo "Check ${report_dir}/output.yosys.log"
|
||||||
else
|
else
|
||||||
echo "Failed to run Yosys EQY"
|
echo "Failed to run Yosys EQY"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue