mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 05:07:21 -04:00
i✂️ Add separate issue stage
This commit is contained in:
parent
a6711fd330
commit
f6f33eafaf
5 changed files with 281 additions and 193 deletions
|
@ -118,8 +118,17 @@ module ariane
|
|||
logic fetch_valid_if_id;
|
||||
logic decode_ack_id_if;
|
||||
exception exception_if_id;
|
||||
|
||||
// --------------
|
||||
// ID <-> EX
|
||||
// ID <-> ISSUE
|
||||
// --------------
|
||||
scoreboard_entry issue_entry_id_issue;
|
||||
logic issue_entry_valid_id_issue;
|
||||
logic is_ctrl_fow_id_issue;
|
||||
logic issue_instr_issue_id;
|
||||
|
||||
// --------------
|
||||
// ISSUE <-> EX
|
||||
// --------------
|
||||
logic [63:0] imm_id_ex;
|
||||
logic [TRANS_ID_BITS-1:0] trans_id_id_ex;
|
||||
|
@ -266,22 +275,42 @@ module ariane
|
|||
// ---------
|
||||
// ID
|
||||
// ---------
|
||||
id_stage
|
||||
id_stage id_stage_i (
|
||||
.flush_i ( flush_ctrl_id ),
|
||||
.fetch_entry_i ( fetch_entry_if_id ),
|
||||
.fetch_entry_valid_i ( fetch_valid_if_id ),
|
||||
.decoded_instr_ack_o ( decode_ack_id_if ),
|
||||
|
||||
.issue_entry_o ( issue_entry_id_issue ),
|
||||
.issue_entry_valid_o ( issue_entry_valid_id_issue ),
|
||||
.is_ctrl_flow_o ( is_ctrl_fow_id_issue ),
|
||||
.issue_instr_ack_i ( issue_instr_issue_id ),
|
||||
|
||||
.priv_lvl_i ( priv_lvl ),
|
||||
.tvm_i ( tvm_csr_id ),
|
||||
.tw_i ( tw_csr_id ),
|
||||
.tsr_i ( tsr_csr_id ),
|
||||
|
||||
.*
|
||||
);
|
||||
|
||||
// ---------
|
||||
// Issue
|
||||
// ---------
|
||||
issue_stage
|
||||
#(
|
||||
.NR_ENTRIES ( NR_SB_ENTRIES ),
|
||||
.NR_WB_PORTS ( NR_WB_PORTS )
|
||||
.NR_ENTRIES ( NR_SB_ENTRIES ),
|
||||
.NR_WB_PORTS ( NR_WB_PORTS )
|
||||
)
|
||||
id_stage_i (
|
||||
.test_en_i ( test_en_i ),
|
||||
issue_stage_i (
|
||||
.flush_unissued_instr_i ( flush_unissued_instr_i ),
|
||||
.flush_i ( flush_ctrl_id ),
|
||||
.flush_unissued_instr_i ( flush_unissued_instr_ctrl_id ),
|
||||
.fetch_entry_i ( fetch_entry_if_id ),
|
||||
.fetch_entry_valid_i ( fetch_valid_if_id ),
|
||||
.decoded_instr_ack_o ( decode_ack_id_if ),
|
||||
.priv_lvl_i ( priv_lvl ),
|
||||
.tvm_i ( tvm_csr_id ),
|
||||
.tw_i ( tw_csr_id ),
|
||||
.tsr_i ( tsr_csr_id ),
|
||||
|
||||
.decoded_instr_i ( issue_entry_id_issue ),
|
||||
.decoded_instr_valid_i ( issue_entry_valid_id_issue ),
|
||||
.is_ctrl_flow_i ( is_ctrl_fow_id_issue ),
|
||||
.decoded_instr_ack_o ( issue_instr_issue_id ),
|
||||
|
||||
// Functional Units
|
||||
.fu_o ( fu_id_ex ),
|
||||
.operator_o ( operator_id_ex ),
|
||||
|
@ -485,8 +514,8 @@ module ariane
|
|||
assign tracer_if.fetch_valid = fetch_valid_if_id;
|
||||
assign tracer_if.fetch_ack = decode_ack_id_if;
|
||||
// Issue
|
||||
assign tracer_if.issue_ack = id_stage_i.scoreboard_i.issue_ack_i;
|
||||
assign tracer_if.issue_sbe = id_stage_i.scoreboard_i.issue_instr_o;
|
||||
assign tracer_if.issue_ack = issue_stage_i.scoreboard_i.issue_ack_i;
|
||||
assign tracer_if.issue_sbe = issue_stage_i.scoreboard_i.issue_instr_o;
|
||||
// write-back
|
||||
assign tracer_if.waddr = waddr_a_commit_id;
|
||||
assign tracer_if.wdata = wdata_a_commit_id;
|
||||
|
|
198
src/id_stage.sv
198
src/id_stage.sv
|
@ -19,121 +19,37 @@
|
|||
//
|
||||
import ariane_pkg::*;
|
||||
|
||||
module id_stage #(
|
||||
parameter int NR_ENTRIES = 4,
|
||||
parameter int NR_WB_PORTS = 4
|
||||
)(
|
||||
module id_stage (
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic test_en_i, // Test Enable
|
||||
|
||||
input logic flush_i,
|
||||
input logic flush_unissued_instr_i,
|
||||
// from IF
|
||||
input fetch_entry fetch_entry_i,
|
||||
input logic fetch_entry_valid_i,
|
||||
output logic decoded_instr_ack_o,
|
||||
output logic decoded_instr_ack_o, // acknowledge the instruction (fetch entry)
|
||||
|
||||
// to ID
|
||||
output scoreboard_entry issue_entry_o, // a decoded instruction
|
||||
output logic issue_entry_valid_o, // issue entry is valid
|
||||
output logic is_ctrl_flow_o, // the instruction we issue is a ctrl flow instructions
|
||||
input logic issue_instr_ack_i, // issue stage acknowledged sampling of instructions
|
||||
// from CSR file
|
||||
input priv_lvl_t priv_lvl_i, // current privilege level
|
||||
input priv_lvl_t priv_lvl_i, // current privilege level
|
||||
input logic tvm_i,
|
||||
input logic tw_i,
|
||||
input logic tsr_i,
|
||||
|
||||
output fu_t fu_o,
|
||||
output fu_op operator_o,
|
||||
output logic [63:0] operand_a_o,
|
||||
output logic [63:0] operand_b_o,
|
||||
output logic [63:0] imm_o,
|
||||
output logic [TRANS_ID_BITS-1:0] trans_id_o,
|
||||
output logic [63:0] pc_o,
|
||||
output logic is_compressed_instr_o,
|
||||
|
||||
input logic alu_ready_i,
|
||||
output logic alu_valid_o,
|
||||
// ex just resolved our predicted branch, we are ready to accept new requests
|
||||
input logic resolve_branch_i,
|
||||
|
||||
input logic lsu_ready_i,
|
||||
output logic lsu_valid_o,
|
||||
// branch prediction
|
||||
input logic branch_ready_i,
|
||||
output logic branch_valid_o, // use branch prediction unit
|
||||
output branchpredict_sbe branch_predict_o,
|
||||
|
||||
input logic mult_ready_i,
|
||||
output logic mult_valid_o, // Branch predict Out
|
||||
|
||||
input logic csr_ready_i,
|
||||
output logic csr_valid_o,
|
||||
|
||||
// write back port
|
||||
input logic [NR_WB_PORTS-1:0][TRANS_ID_BITS-1:0] trans_id_i,
|
||||
input logic [NR_WB_PORTS-1:0][63:0] wdata_i,
|
||||
input exception [NR_WB_PORTS-1:0] ex_ex_i, // exception from execute stage
|
||||
input logic [NR_WB_PORTS-1:0] wb_valid_i,
|
||||
// commit port
|
||||
input logic[4:0] waddr_a_i,
|
||||
input logic[63:0] wdata_a_i,
|
||||
input logic we_a_i,
|
||||
|
||||
output scoreboard_entry commit_instr_o,
|
||||
input logic commit_ack_i
|
||||
input logic tsr_i
|
||||
);
|
||||
// ---------------------------------------------------
|
||||
// Global signals
|
||||
// ---------------------------------------------------
|
||||
logic full;
|
||||
logic decode_instr_ack;
|
||||
// ---------------------------------------------------
|
||||
// Scoreboard (SB) <-> Issue and Read Operands (iro)
|
||||
// ---------------------------------------------------
|
||||
fu_t [31:0] rd_clobber_sb_iro;
|
||||
logic [4:0] rs1_iro_sb;
|
||||
logic [63:0] rs1_sb_iro;
|
||||
logic rs1_valid_sb_iro;
|
||||
logic [4:0] rs2_iro_sb;
|
||||
logic [63:0] rs2_sb_iro;
|
||||
logic rs2_valid_iro_sb;
|
||||
scoreboard_entry issue_instr_sb_iro;
|
||||
logic issue_instr_valid_sb_iro;
|
||||
logic issue_ack_iro_sb;
|
||||
// ---------------------------------------------------
|
||||
// Decoder (DC) <-> Scoreboard (SB)
|
||||
// ---------------------------------------------------
|
||||
scoreboard_entry decoded_instr_dc_sb;
|
||||
// ---------------------------------------------------
|
||||
// Decoder (DC) <-> Branch Logic
|
||||
// ---------------------------------------------------
|
||||
// register stage
|
||||
struct packed {
|
||||
logic valid;
|
||||
scoreboard_entry sbe;
|
||||
logic is_ctrl_flow;
|
||||
|
||||
} issue_n, issue_q;
|
||||
|
||||
logic is_control_flow_instr;
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Branch (resolve) logic
|
||||
// ---------------------------------------------------
|
||||
// This should basically prevent the scoreboard from accepting
|
||||
// instructions past a branch. We need to resolve the branch beforehand.
|
||||
// This limitation is in place to ease the backtracking of mis-predicted branches as they
|
||||
// can simply be in the front-end of the processor.
|
||||
logic unresolved_branch_n, unresolved_branch_q;
|
||||
|
||||
always_comb begin : unresolved_branch
|
||||
unresolved_branch_n = unresolved_branch_q;
|
||||
// we just resolved the branch
|
||||
if (resolve_branch_i) begin
|
||||
unresolved_branch_n = 1'b0;
|
||||
end
|
||||
// if the instruction is valid and it is a control flow instruction
|
||||
if (fetch_entry_valid_i && is_control_flow_instr) begin
|
||||
unresolved_branch_n = 1'b1;
|
||||
end
|
||||
// if we are requested to flush also flush the unresolved branch flag because either the flush
|
||||
// was requested by a branch or an exception. In any case: any unresolved branch will get evicted
|
||||
if (flush_unissued_instr_i || flush_i) begin
|
||||
unresolved_branch_n = 1'b0;
|
||||
end
|
||||
end
|
||||
// we are ready if we are not full and don't have any unresolved branches, but it can be
|
||||
// the case that we have an unresolved branch which is cleared in that cycle (resolved_branch_i.valid == 1)
|
||||
assign decoded_instr_ack_o = decode_instr_ack && !unresolved_branch_q;
|
||||
scoreboard_entry decoded_instruction;
|
||||
|
||||
decoder decoder_i (
|
||||
.pc_i ( fetch_entry_i.address ),
|
||||
|
@ -142,59 +58,47 @@ module id_stage #(
|
|||
.branch_predict_i ( fetch_entry_i.branch_predict ),
|
||||
.is_illegal_i ( fetch_entry_i.is_illegal ),
|
||||
.ex_i ( fetch_entry_i.ex ),
|
||||
.instruction_o ( decoded_instr_dc_sb ),
|
||||
.instruction_o ( decoded_instruction ),
|
||||
.is_control_flow_instr_o ( is_control_flow_instr ),
|
||||
.*
|
||||
);
|
||||
|
||||
scoreboard #(
|
||||
.NR_ENTRIES ( NR_ENTRIES ),
|
||||
.NR_WB_PORTS ( NR_WB_PORTS )
|
||||
)
|
||||
scoreboard_i
|
||||
(
|
||||
.full_o ( full ),
|
||||
.rd_clobber_o ( rd_clobber_sb_iro ),
|
||||
.rs1_i ( rs1_iro_sb ),
|
||||
.rs1_o ( rs1_sb_iro ),
|
||||
.rs1_valid_o ( rs1_valid_sb_iro ),
|
||||
.rs2_i ( rs2_iro_sb ),
|
||||
.rs2_o ( rs2_sb_iro ),
|
||||
.rs2_valid_o ( rs2_valid_iro_sb ),
|
||||
.commit_instr_o ( commit_instr_o ),
|
||||
.commit_ack_i ( commit_ack_i ),
|
||||
.decoded_instr_ack_o ( decode_instr_ack ),
|
||||
.decoded_instr_i ( decoded_instr_dc_sb ),
|
||||
.decoded_instr_valid_i ( fetch_entry_valid_i ),
|
||||
.issue_instr_o ( issue_instr_sb_iro ),
|
||||
.issue_instr_valid_o ( issue_instr_valid_sb_iro ),
|
||||
.issue_ack_i ( issue_ack_iro_sb ),
|
||||
.trans_id_i ( trans_id_i ),
|
||||
.wdata_i ( wdata_i ),
|
||||
.ex_i ( ex_ex_i ),
|
||||
.*
|
||||
);
|
||||
// ------------------
|
||||
// Output Registers
|
||||
// ------------------
|
||||
assign issue_entry_o = issue_q.sbe;
|
||||
assign issue_entry_valid_o = issue_q.valid;
|
||||
assign is_ctrl_flow_o = issue_q.is_ctrl_flow;
|
||||
|
||||
always_comb begin
|
||||
issue_n = issue_q;
|
||||
decoded_instr_ack_o = 1'b0;
|
||||
|
||||
issue_read_operands issue_read_operands_i (
|
||||
.issue_instr_i ( issue_instr_sb_iro ),
|
||||
.issue_instr_valid_i ( issue_instr_valid_sb_iro ),
|
||||
.issue_ack_o ( issue_ack_iro_sb ),
|
||||
.rs1_o ( rs1_iro_sb ),
|
||||
.rs1_i ( rs1_sb_iro ),
|
||||
.rs1_valid_i ( rs1_valid_sb_iro ),
|
||||
.rs2_o ( rs2_iro_sb ),
|
||||
.rs2_i ( rs2_sb_iro ),
|
||||
.rs2_valid_i ( rs2_valid_iro_sb ),
|
||||
.rd_clobber_i ( rd_clobber_sb_iro ),
|
||||
.*
|
||||
);
|
||||
// if we have a space in the register and the fetch is valid, go get it
|
||||
if (!issue_q.valid && fetch_entry_valid_i) begin
|
||||
decoded_instr_ack_o = 1'b1;
|
||||
issue_n = { 1'b1, decoded_instruction, is_control_flow_instr};
|
||||
issue_n.valid = 1'b1;
|
||||
end
|
||||
|
||||
// we have something in the register but issue stage already acknowledged
|
||||
if (issue_q.valid && issue_instr_ack_i) begin
|
||||
decoded_instr_ack_o = 1'b1;
|
||||
issue_n = { 1'b1, decoded_instruction, is_control_flow_instr};
|
||||
end
|
||||
|
||||
// invalidate on a flush
|
||||
if (flush_i)
|
||||
issue_n.valid = 1'b0;
|
||||
end
|
||||
// -------------------------
|
||||
// Registers (ID <-> Issue)
|
||||
// -------------------------
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
unresolved_branch_q <= 1'b0;
|
||||
if(~rst_ni) begin
|
||||
issue_q <= '0;
|
||||
end else begin
|
||||
unresolved_branch_q <= unresolved_branch_n;
|
||||
issue_q <= issue_n;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
180
src/issue_stage.sv
Executable file
180
src/issue_stage.sv
Executable file
|
@ -0,0 +1,180 @@
|
|||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 21.05.2017
|
||||
// Description: Issue stage dispatches instructions to the FUs
|
||||
//
|
||||
//
|
||||
// Copyright (C) 2017 ETH Zurich, University of Bologna
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is under development and not yet released to the public.
|
||||
// Until it is released, the code is under the copyright of ETH Zurich and
|
||||
// the University of Bologna, and may contain confidential and/or unpublished
|
||||
// work. Any reuse/redistribution is strictly forbidden without written
|
||||
// permission from ETH Zurich.
|
||||
//
|
||||
// Bug fixes and contributions will eventually be released under the
|
||||
// SolderPad open hardware license in the context of the PULP platform
|
||||
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
|
||||
// University of Bologna.
|
||||
//
|
||||
|
||||
import ariane_pkg::*;
|
||||
|
||||
module issue_stage #(
|
||||
parameter int NR_ENTRIES = 4,
|
||||
parameter int NR_WB_PORTS = 4
|
||||
)(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic test_en_i, // Test Enable
|
||||
|
||||
input logic flush_unissued_instr_i,
|
||||
input logic flush_i,
|
||||
// from ID
|
||||
input scoreboard_entry decoded_instr_i,
|
||||
input logic decoded_instr_valid_i,
|
||||
input logic is_ctrl_flow_i,
|
||||
output logic decoded_instr_ack_o,
|
||||
// to EX
|
||||
output fu_t fu_o,
|
||||
output fu_op operator_o,
|
||||
output logic [63:0] operand_a_o,
|
||||
output logic [63:0] operand_b_o,
|
||||
output logic [63:0] imm_o,
|
||||
output logic [TRANS_ID_BITS-1:0] trans_id_o,
|
||||
output logic [63:0] pc_o,
|
||||
output logic is_compressed_instr_o,
|
||||
|
||||
input logic alu_ready_i,
|
||||
output logic alu_valid_o,
|
||||
// ex just resolved our predicted branch, we are ready to accept new requests
|
||||
input logic resolve_branch_i,
|
||||
|
||||
input logic lsu_ready_i,
|
||||
output logic lsu_valid_o,
|
||||
// branch prediction
|
||||
input logic branch_ready_i,
|
||||
output logic branch_valid_o, // use branch prediction unit
|
||||
output branchpredict_sbe branch_predict_o,
|
||||
|
||||
input logic mult_ready_i,
|
||||
output logic mult_valid_o, // Branch predict Out
|
||||
|
||||
input logic csr_ready_i,
|
||||
output logic csr_valid_o,
|
||||
|
||||
// write back port
|
||||
input logic [NR_WB_PORTS-1:0][TRANS_ID_BITS-1:0] trans_id_i,
|
||||
input logic [NR_WB_PORTS-1:0][63:0] wdata_i,
|
||||
input exception [NR_WB_PORTS-1:0] ex_ex_i, // exception from execute stage
|
||||
input logic [NR_WB_PORTS-1:0] wb_valid_i,
|
||||
|
||||
// commit port
|
||||
input logic[4:0] waddr_a_i,
|
||||
input logic[63:0] wdata_a_i,
|
||||
input logic we_a_i,
|
||||
|
||||
output scoreboard_entry commit_instr_o,
|
||||
input logic commit_ack_i
|
||||
);
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Global signals
|
||||
// ---------------------------------------------------
|
||||
logic full;
|
||||
logic decoded_instr_ack;
|
||||
// ---------------------------------------------------
|
||||
// Scoreboard (SB) <-> Issue and Read Operands (IRO)
|
||||
// ---------------------------------------------------
|
||||
fu_t [31:0] rd_clobber_sb_iro;
|
||||
logic [4:0] rs1_iro_sb;
|
||||
logic [63:0] rs1_sb_iro;
|
||||
logic rs1_valid_sb_iro;
|
||||
logic [4:0] rs2_iro_sb;
|
||||
logic [63:0] rs2_sb_iro;
|
||||
logic rs2_valid_iro_sb;
|
||||
scoreboard_entry issue_instr_sb_iro;
|
||||
logic issue_instr_valid_sb_iro;
|
||||
logic issue_ack_iro_sb;
|
||||
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Branch (resolve) logic
|
||||
// ---------------------------------------------------
|
||||
// This should basically prevent the scoreboard from accepting
|
||||
// instructions past a branch. We need to resolve the branch beforehand.
|
||||
// This limitation is in place to ease the backtracking of mis-predicted branches as they
|
||||
// can simply be in the front-end of the processor.
|
||||
logic unresolved_branch_n, unresolved_branch_q;
|
||||
|
||||
always_comb begin : unresolved_branch
|
||||
unresolved_branch_n = unresolved_branch_q;
|
||||
// we just resolved the branch
|
||||
if (resolve_branch_i) begin
|
||||
unresolved_branch_n = 1'b0;
|
||||
end
|
||||
// if the instruction is valid and it is a control flow instruction
|
||||
if (decoded_instr_valid_i && is_ctrl_flow_i) begin
|
||||
unresolved_branch_n = 1'b1;
|
||||
end
|
||||
// if we are requested to flush also flush the unresolved branch flag because either the flush
|
||||
// was requested by a branch or an exception. In any case: any unresolved branch will get evicted
|
||||
if (flush_unissued_instr_i || flush_i) begin
|
||||
unresolved_branch_n = 1'b0;
|
||||
end
|
||||
end
|
||||
// we are ready if we are not full and don't have any unresolved branches, but it can be
|
||||
// the case that we have an unresolved branch which is cleared in that cycle (resolved_branch_i == 1)
|
||||
assign decoded_instr_ack_o = ~full && (~unresolved_branch_q) && decoded_instr_ack;
|
||||
|
||||
issue_read_operands issue_read_operands_i (
|
||||
.flush_i ( flush_unissued_instr_i ),
|
||||
.issue_instr_i ( issue_instr_sb_iro ),
|
||||
.issue_instr_valid_i ( issue_instr_valid_sb_iro ),
|
||||
.issue_ack_o ( issue_ack_iro_sb ),
|
||||
.rs1_o ( rs1_iro_sb ),
|
||||
.rs1_i ( rs1_sb_iro ),
|
||||
.rs1_valid_i ( rs1_valid_sb_iro ),
|
||||
.rs2_o ( rs2_iro_sb ),
|
||||
.rs2_i ( rs2_sb_iro ),
|
||||
.rs2_valid_i ( rs2_valid_iro_sb ),
|
||||
.rd_clobber_i ( rd_clobber_sb_iro ),
|
||||
.*
|
||||
);
|
||||
|
||||
scoreboard #(
|
||||
.NR_ENTRIES ( NR_ENTRIES ),
|
||||
.NR_WB_PORTS ( NR_WB_PORTS )
|
||||
)
|
||||
scoreboard_i
|
||||
(
|
||||
.full_o ( full ),
|
||||
.rd_clobber_o ( rd_clobber_sb_iro ),
|
||||
.rs1_i ( rs1_iro_sb ),
|
||||
.rs1_o ( rs1_sb_iro ),
|
||||
.rs1_valid_o ( rs1_valid_sb_iro ),
|
||||
.rs2_i ( rs2_iro_sb ),
|
||||
.rs2_o ( rs2_sb_iro ),
|
||||
.rs2_valid_o ( rs2_valid_iro_sb ),
|
||||
|
||||
.decoded_instr_ack_o ( decoded_instr_ack ),
|
||||
|
||||
.issue_instr_o ( issue_instr_sb_iro ),
|
||||
.issue_instr_valid_o ( issue_instr_valid_sb_iro ),
|
||||
.issue_ack_i ( issue_ack_iro_sb ),
|
||||
|
||||
.trans_id_i ( trans_id_i ),
|
||||
.wdata_i ( wdata_i ),
|
||||
.ex_i ( ex_ex_i ),
|
||||
.*
|
||||
);
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (~rst_ni) begin
|
||||
unresolved_branch_q <= 1'b0;
|
||||
end else begin
|
||||
unresolved_branch_q <= unresolved_branch_n;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -76,13 +76,6 @@ module scoreboard #(
|
|||
logic [$clog2(NR_ENTRIES)-1:0] commit_pointer_n, commit_pointer_q;
|
||||
logic issue_full;
|
||||
|
||||
struct packed {
|
||||
logic valid;
|
||||
scoreboard_entry sbe;
|
||||
} decoded_instr_n, decoded_instr_q;
|
||||
|
||||
logic decoded_instr_ack;
|
||||
|
||||
// the issue queue is full don't issue any new instructions
|
||||
assign issue_full = (issue_cnt_q == NR_ENTRIES-1);
|
||||
assign full_o = issue_full;
|
||||
|
@ -91,29 +84,13 @@ module scoreboard #(
|
|||
|
||||
// an instruction is ready for issue if we have place in the issue FIFO and it the decoder says it is valid
|
||||
always_comb begin
|
||||
issue_instr_o = decoded_instr_q;
|
||||
issue_instr_o = decoded_instr_i;
|
||||
// make sure we assign the correct trans ID
|
||||
issue_instr_o.trans_id = issue_pointer_q;
|
||||
issue_instr_valid_o = decoded_instr_q.valid;
|
||||
decoded_instr_ack_o = decoded_instr_ack;
|
||||
issue_instr_valid_o = decoded_instr_valid_i;
|
||||
decoded_instr_ack_o = issue_ack_i;
|
||||
end
|
||||
always_comb begin : decode_if
|
||||
decoded_instr_ack = 1'b0;
|
||||
decoded_instr_n = decoded_instr_q;
|
||||
|
||||
if (issue_ack_i)
|
||||
decoded_instr_n.valid = 1'b0;
|
||||
|
||||
if (!decoded_instr_q.valid && decoded_instr_valid_i) begin
|
||||
decoded_instr_ack = 1'b1;
|
||||
decoded_instr_n = {1'b1, decoded_instr_i};
|
||||
end
|
||||
|
||||
if (decoded_instr_q.valid && !issue_full && issue_ack_i) begin
|
||||
decoded_instr_ack = 1'b1;
|
||||
decoded_instr_n = {1'b1, decoded_instr_i};
|
||||
end
|
||||
end
|
||||
// maintain a FIFO with issued instructions
|
||||
// keep track of all issued instructions
|
||||
always_comb begin : issue_fifo
|
||||
|
@ -254,13 +231,11 @@ module scoreboard #(
|
|||
issue_cnt_q <= '0;
|
||||
commit_pointer_q <= '0;
|
||||
issue_pointer_q <= '0;
|
||||
decoded_instr_q <= '0;
|
||||
end else begin
|
||||
mem_q <= mem_n;
|
||||
issue_cnt_q <= issue_cnt_n;
|
||||
commit_pointer_q <= commit_pointer_n;
|
||||
issue_pointer_q <= issue_pointer_n;
|
||||
decoded_instr_q <= decoded_instr_n;
|
||||
end
|
||||
end
|
||||
`ifndef SYNTHESIS
|
||||
|
|
|
@ -3,9 +3,9 @@ add wave -noupdate -group pcgen_stage -group btb /core_tb/dut/pcgen_i/btb_i/*
|
|||
add wave -noupdate -group pcgen_stage /core_tb/dut/pcgen_i/*
|
||||
add wave -noupdate -group if_stage -group fetch_fifo /core_tb/dut/if_stage_i/fetch_fifo_i/*
|
||||
add wave -noupdate -group if_stage /core_tb/dut/if_stage_i/*
|
||||
add wave -noupdate -group id_stage -group scoreboard /core_tb/dut/id_stage_i/scoreboard_i/*
|
||||
add wave -noupdate -group id_stage -group decoder /core_tb/dut/id_stage_i/decoder_i/*
|
||||
add wave -noupdate -group id_stage -group issue_read_operands /core_tb/dut/id_stage_i/issue_read_operands_i/*
|
||||
add wave -noupdate -group issue_stage -group scoreboard /core_tb/dut/issue_stage_i/scoreboard_i/*
|
||||
add wave -noupdate -group issue_stage -group issue_read_operands /core_tb/dut/issue_stage_i/issue_read_operands_i/*
|
||||
add wave -noupdate -group id_stage /core_tb/dut/id_stage_i/*
|
||||
add wave -noupdate -group ex_stage -group alu /core_tb/dut/ex_stage_i/alu_i/*
|
||||
add wave -noupdate -group ex_stage -group lsu -group mmu /core_tb/dut/ex_stage_i/lsu_i/mmu_i/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue