Skip to content

Commit

Permalink
fixup! [FIXME] id_stage: Work around simulator elab issue
Browse files Browse the repository at this point in the history
  • Loading branch information
paulsc96 committed Oct 18, 2024
1 parent f3ec356 commit 0493347
Show file tree
Hide file tree
Showing 2 changed files with 351 additions and 3 deletions.
348 changes: 348 additions & 0 deletions bla.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
// Author: Florian Zaruba, ETH Zurich
// Date: 15.04.2017
// Description: Instruction decode, contains the logic for decode,
// issue and read operands.

module id_stage #(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter type branchpredict_sbe_t = logic,
parameter type exception_t = logic,
parameter type fetch_entry_t = logic,
parameter type irq_ctrl_t = logic,
parameter type scoreboard_entry_t = logic,
parameter type interrupts_t = logic,
parameter interrupts_t INTERRUPTS = '0,
parameter type x_compressed_req_t = logic,
parameter type x_compressed_resp_t = logic
) (
// Subsystem Clock - SUBSYSTEM
input logic clk_i,
// Asynchronous reset active low - SUBSYSTEM
input logic rst_ni,
// Fetch flush request - CONTROLLER
input logic flush_i,
// Debug (async) request - SUBSYSTEM
input logic debug_req_i,
// Handshake's data between fetch and decode - FRONTEND
input fetch_entry_t [CVA6Cfg.NrIssuePorts-1:0] fetch_entry_i,
// Handshake's valid between fetch and decode - FRONTEND
input logic [CVA6Cfg.NrIssuePorts-1:0] fetch_entry_valid_i,
// Handshake's ready between fetch and decode - FRONTEND
output logic [CVA6Cfg.NrIssuePorts-1:0] fetch_entry_ready_o,
// Handshake's data between decode and issue - ISSUE
output scoreboard_entry_t [CVA6Cfg.NrIssuePorts-1:0] issue_entry_o,
// Instruction value - ISSUE
output logic [CVA6Cfg.NrIssuePorts-1:0][31:0] orig_instr_o,
// Handshake's valid between decode and issue - ISSUE
output logic [CVA6Cfg.NrIssuePorts-1:0] issue_entry_valid_o,
// Report if instruction is a control flow instruction - ISSUE
output logic [CVA6Cfg.NrIssuePorts-1:0] is_ctrl_flow_o,
// Handshake's acknowlege between decode and issue - ISSUE
input logic [CVA6Cfg.NrIssuePorts-1:0] issue_instr_ack_i,
// Information dedicated to RVFI - RVFI
output logic [CVA6Cfg.NrIssuePorts-1:0] rvfi_is_compressed_o,
// Current privilege level - CSR_REGFILE
input riscv::priv_lvl_t priv_lvl_i,
// Current virtualization mode - CSR_REGFILE
input logic v_i,
// Floating point extension status - CSR_REGFILE
input riscv::xs_t fs_i,
// Floating point extension virtual status - CSR_REGFILE
input riscv::xs_t vfs_i,
// Floating point dynamic rounding mode - CSR_REGFILE
input logic [2:0] frm_i,
// Vector extension status - CSR_REGFILE
input riscv::xs_t vs_i,
// Level sensitive (async) interrupts - SUBSYSTEM
input logic [1:0] irq_i,
// Interrupt control status - CSR_REGFILE
input irq_ctrl_t irq_ctrl_i,
// Is current mode debug ? - CSR_REGFILE
input logic debug_mode_i,
// Trap virtual memory - CSR_REGFILE
input logic tvm_i,
// Timeout wait - CSR_REGFILE
input logic tw_i,
// Virtual timeout wait - CSR_REGFILE
input logic vtw_i,
// Trap sret - CSR_REGFILE
input logic tsr_i,
// Hypervisor user mode - CSR_REGFILE
input logic hu_i,
// CVXIF Compressed interface
input logic [CVA6Cfg.XLEN-1:0] hart_id_i,
input logic compressed_ready_i,
input x_compressed_resp_t compressed_resp_i,
output logic compressed_valid_o,
output x_compressed_req_t compressed_req_o
);
// ID/ISSUE register stage
typedef struct packed {
logic valid;
logic [$bits(scoreboard_entry_t)-1:0] sbe;
logic [31:0] orig_instr;
logic is_ctrl_flow;
} issue_struct_t;
issue_struct_t [CVA6Cfg.NrIssuePorts-1:0] issue_n, issue_q;

logic [CVA6Cfg.NrIssuePorts-1:0] is_control_flow_instr;
scoreboard_entry_t [CVA6Cfg.NrIssuePorts-1:0] decoded_instruction;
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] orig_instr;

logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal;
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cmp;
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cvxif;
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction;
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] compressed_instr;
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_cvxif;
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed;
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cmp;
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cvxif;

logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr_i;
logic stall_instr_fetch;
logic stall_macro_deco;
logic is_last_macro_instr_o;
logic is_double_rd_macro_instr_o;

if (CVA6Cfg.RVC) begin
// ---------------------------------------------------------
// 1. Check if they are compressed and expand in case they are
// ---------------------------------------------------------
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
compressed_decoder #(
.CVA6Cfg(CVA6Cfg)
) compressed_decoder_i (
.instr_i (fetch_entry_i[i].instruction),
.instr_o (compressed_instr[i]),
.illegal_instr_o (is_illegal[i]),
.is_compressed_o (is_compressed[i]),
.is_macro_instr_o(is_macro_instr_i[i])
);
end
if (CVA6Cfg.RVZCMP) begin
//sequencial decoder
macro_decoder #(
.CVA6Cfg(CVA6Cfg)
) macro_decoder_i (
.instr_i (compressed_instr[0]),
.is_macro_instr_i (is_macro_instr_i[0]),
.clk_i (clk_i),
.rst_ni (rst_ni),
.instr_o (instruction_cvxif[0]),
.illegal_instr_i (is_illegal[0]),
.is_compressed_i (is_compressed[0]),
.issue_ack_i (issue_instr_ack_i[0]),
.illegal_instr_o (is_illegal_cvxif[0]),
.is_compressed_o (is_compressed_cvxif[0]),
.fetch_stall_o (stall_macro_deco),
.is_last_macro_instr_o (is_last_macro_instr_o),
.is_double_rd_macro_instr_o(is_double_rd_macro_instr_o)
);
if (CVA6Cfg.SuperscalarEn) begin
assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
assign is_illegal_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
assign is_compressed_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
end
cvxif_compressed_if_driver #(
.CVA6Cfg(CVA6Cfg),
.x_compressed_req_t(x_compressed_req_t),
.x_compressed_resp_t(x_compressed_resp_t)
) i_cvxif_compressed_if_driver_i (
.clk_i (clk_i),
.rst_ni (rst_ni),
.hart_id_i (hart_id_i),
.is_compressed_i (is_compressed_cvxif),
.is_illegal_i (is_illegal_cvxif),
.instruction_i (instruction_cvxif),
.is_compressed_o (is_compressed_cmp),
.is_illegal_o (is_illegal_cmp),
.instruction_o (instruction),
.stall_i (stall_macro_deco),
.stall_o (stall_instr_fetch),
.compressed_ready_i(compressed_ready_i),
.compressed_resp_i (compressed_resp_i),
.compressed_valid_o(compressed_valid_o),
.compressed_req_o (compressed_req_o)
);
end else begin
cvxif_compressed_if_driver #(
.CVA6Cfg(CVA6Cfg),
.x_compressed_req_t(x_compressed_req_t),
.x_compressed_resp_t(x_compressed_resp_t)
) i_cvxif_compressed_if_driver_i (
.clk_i (clk_i),
.rst_ni (rst_ni),
.hart_id_i (hart_id_i),
.is_compressed_i (is_compressed),
.is_illegal_i (is_illegal),
.instruction_i (compressed_instr),
.is_compressed_o (is_compressed_cmp),
.is_illegal_o (is_illegal_cmp),
.instruction_o (instruction),
.stall_i (1'b0),
.stall_o (stall_instr_fetch),
.compressed_ready_i(compressed_ready_i),
.compressed_resp_i (compressed_resp_i),
.compressed_valid_o(compressed_valid_o),
.compressed_req_o (compressed_req_o)
);
assign is_last_macro_instr_o = '0;
assign is_double_rd_macro_instr_o = '0;
end
end else begin
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
assign instruction[i] = fetch_entry_i[i].instruction;
end
assign is_illegal_cmp = '0;
assign is_compressed_cmp = '0;
assign is_macro_instr_i = '0;
assign is_last_macro_instr_o = '0;
assign is_double_rd_macro_instr_o = '0;
if (CVA6Cfg.CvxifEn) begin
assign compressed_valid_o = '0;
assign compressed_req_o.instr = '0;
assign compressed_req_o.hartid = hart_id_i;
end // TODO Add else to map x_compressed_if outputs to '0 ?
end

assign rvfi_is_compressed_o = is_compressed_cmp;
// ---------------------------------------------------------
// 2. Decode and emit instruction to issue stage
// ---------------------------------------------------------
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
decoder #(
.CVA6Cfg(CVA6Cfg),
.branchpredict_sbe_t(branchpredict_sbe_t),
.exception_t(exception_t),
.irq_ctrl_t(irq_ctrl_t),
.scoreboard_entry_t(scoreboard_entry_t),
.interrupts_t(interrupts_t),
.INTERRUPTS(INTERRUPTS)
) decoder_i (
.debug_req_i,
.irq_ctrl_i,
.irq_i,
.pc_i (fetch_entry_i[i].address),
.is_compressed_i (is_compressed_cmp[i]),
.is_macro_instr_i (is_macro_instr_i[i]),
.is_last_macro_instr_i (is_last_macro_instr_o),
.is_double_rd_macro_instr_i(is_double_rd_macro_instr_o),
.is_illegal_i (is_illegal_cmp[i]),
.instruction_i (instruction[i]),
.compressed_instr_i (fetch_entry_i[i].instruction[15:0]),
.branch_predict_i (fetch_entry_i[i].branch_predict),
.ex_i (fetch_entry_i[i].ex),
.priv_lvl_i (priv_lvl_i),
.v_i (v_i),
.debug_mode_i (debug_mode_i),
.fs_i,
.vfs_i,
.frm_i,
.vs_i,
.tvm_i,
.tw_i,
.vtw_i,
.tsr_i,
.hu_i,
.instruction_o (decoded_instruction[i]),
.orig_instr_o (orig_instr[i]),
.is_control_flow_instr_o (is_control_flow_instr[i])
);
end

// ------------------
// Pipeline Register
// ------------------
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
assign issue_entry_o[i] = issue_q[i].sbe;
assign issue_entry_valid_o[i] = issue_q[i].valid;
assign is_ctrl_flow_o[i] = issue_q[i].is_ctrl_flow;
assign orig_instr_o[i] = issue_q[i].orig_instr;
end

if (CVA6Cfg.SuperscalarEn) begin
always_comb begin
issue_n = issue_q;
fetch_entry_ready_o = '0;

// Clear the valid flag if issue has acknowledged the instruction
if (issue_instr_ack_i[0]) begin
issue_n[0].valid = 1'b0;
end
if (issue_instr_ack_i[1]) begin
issue_n[1].valid = 1'b0;
end

if (!issue_n[0].valid) begin
if (issue_n[1].valid) begin
issue_n[0] = issue_n[1];
issue_n[1].valid = 1'b0;
end else if (fetch_entry_valid_i[0]) begin
fetch_entry_ready_o[0] = 1'b1;
issue_n[0] = '{1'b1, decoded_instruction[0], orig_instr[0], is_control_flow_instr[0]};
end
end

if (!issue_n[1].valid) begin
if (fetch_entry_ready_o[0]) begin
if (fetch_entry_valid_i[1]) begin
fetch_entry_ready_o[1] = 1'b1;
issue_n[1] = '{1'b1, decoded_instruction[1], orig_instr[1], is_control_flow_instr[1]};
end
end else if (fetch_entry_valid_i[0]) begin
fetch_entry_ready_o[0] = 1'b1;
issue_n[1] = '{1'b1, decoded_instruction[0], orig_instr[0], is_control_flow_instr[0]};
end
end

if (flush_i) begin
issue_n[0].valid = 1'b0;
issue_n[1].valid = 1'b0;
end
end
end else begin
always_comb begin
issue_n = issue_q;
fetch_entry_ready_o = '0;

// Clear the valid flag if issue has acknowledged the instruction
if (issue_instr_ack_i[0]) issue_n[0].valid = 1'b0;

// if we have a space in the register and the fetch is valid, go get it
// or the issue stage is currently acknowledging an instruction, which means that we will have space
// for a new instruction
if ((!issue_q[0].valid || issue_instr_ack_i[0]) && fetch_entry_valid_i[0]) begin
if (stall_instr_fetch) begin
fetch_entry_ready_o[0] = 1'b0;
end else begin
fetch_entry_ready_o[0] = 1'b1;
end
issue_n[0] = '{1'b1, decoded_instruction[0], orig_instr[0], is_control_flow_instr[0]};
end

// invalidate the pipeline register on a flush
if (flush_i) issue_n[0].valid = 1'b0;
end
end
// -------------------------
// Registers (ID <-> Issue)
// -------------------------
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
issue_q <= '0;
end else begin
issue_q <= issue_n;
end
end
endmodule
6 changes: 3 additions & 3 deletions core/id_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ module id_stage #(
);
// ID/ISSUE register stage
typedef struct packed {
logic valid;
logic valid;
logic [$bits(scoreboard_entry_t)-1:0] sbe;
logic [31:0] orig_instr;
logic is_ctrl_flow;
logic [31:0] orig_instr;
logic is_ctrl_flow;
} issue_struct_t;
issue_struct_t [CVA6Cfg.NrIssuePorts-1:0] issue_n, issue_q;

Expand Down

0 comments on commit 0493347

Please sign in to comment.