mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 21:27:10 -04:00
Fixes issue #7
This commit is contained in:
parent
b3dec48368
commit
30edf32c98
6 changed files with 147 additions and 114 deletions
75
ariane.sv
75
ariane.sv
|
@ -10,7 +10,7 @@ import ariane_pkg::*;
|
|||
|
||||
module ariane
|
||||
#(
|
||||
parameter N_EXT_PERF_COUNTERS = 0
|
||||
parameter N_EXT_PERF_COUNTERS = 0
|
||||
)
|
||||
(
|
||||
input logic clk_i,
|
||||
|
@ -60,9 +60,9 @@ module ariane
|
|||
logic [4:0] waddr_a_i;
|
||||
logic [63:0] wdata_a_i;
|
||||
logic we_a_i;
|
||||
logic [4:0] alu_trans_id, trans_id_o;
|
||||
logic [TRANS_ID_BITS-1:0] alu_trans_id, lsu_trans_id, trans_id_o;
|
||||
logic alu_valid_o;
|
||||
logic [63:0] alu_result;
|
||||
logic [63:0] alu_result, lsu_result;
|
||||
// synth stuff
|
||||
assign flush_i = 1'b0;
|
||||
|
||||
|
@ -102,7 +102,7 @@ module ariane
|
|||
logic lsu_req_i;
|
||||
logic lsu_gnt_o;
|
||||
logic lsu_we_i;
|
||||
logic [3:0] lsu_be_i;
|
||||
logic [7:0] lsu_be_i;
|
||||
logic lsu_err_o;
|
||||
logic [63:0] lsu_vaddr_i;
|
||||
priv_lvl_t priv_lvl_i;
|
||||
|
@ -144,38 +144,39 @@ module ariane
|
|||
|
||||
id_stage
|
||||
#(
|
||||
.NR_WB_PORTS ( 1 )
|
||||
.NR_ENTRIES ( NR_SB_ENTRIES ),
|
||||
.NR_WB_PORTS ( NR_WB_PORTS )
|
||||
)
|
||||
id_stage_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_n ),
|
||||
.test_en_i ( test_en_i ),
|
||||
.flush_i ( flush_i ),
|
||||
.instruction_i ( instr_rdata_id_o ),
|
||||
.instruction_valid_i ( instr_valid_id_o ),
|
||||
.pc_if_i ( pc_if_o ), // PC from if
|
||||
.ex_i ( exception_if ), // exception from if
|
||||
.ready_o ( ready_o ),
|
||||
.operator_o ( operator_o ),
|
||||
.operand_a_o ( operand_a_o ),
|
||||
.operand_b_o ( operand_b_o ),
|
||||
.trans_id_o ( trans_id_o ),
|
||||
.alu_ready_i ( alu_ready_i ),
|
||||
.alu_valid_o ( alu_valid_i ),
|
||||
.lsu_ready_i ( ),
|
||||
.lsu_valid_o ( ),
|
||||
.mult_ready_i ( ),
|
||||
.mult_valid_o ( ),
|
||||
.trans_id_i ( {alu_trans_id} ),
|
||||
.wdata_i ( {alu_result} ),
|
||||
.wb_valid_i ( {alu_valid_o} ),
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_n ),
|
||||
.test_en_i ( test_en_i ),
|
||||
.flush_i ( flush_i ),
|
||||
.instruction_i ( instr_rdata_id_o ),
|
||||
.instruction_valid_i ( instr_valid_id_o ),
|
||||
.pc_if_i ( pc_if_o ), // PC from if
|
||||
.ex_i ( exception_if ), // exception from if
|
||||
.ready_o ( ready_o ),
|
||||
.operator_o ( operator_o ),
|
||||
.operand_a_o ( operand_a_o ),
|
||||
.operand_b_o ( operand_b_o ),
|
||||
.trans_id_o ( trans_id_o ),
|
||||
.alu_ready_i ( alu_ready_i ),
|
||||
.alu_valid_o ( alu_valid_i ),
|
||||
.lsu_ready_i ( ),
|
||||
.lsu_valid_o ( ),
|
||||
.mult_ready_i ( ),
|
||||
.mult_valid_o ( ),
|
||||
.trans_id_i ( {alu_trans_id, lsu_trans_id} ),
|
||||
.wdata_i ( {alu_result, lsu_result} ),
|
||||
.wb_valid_i ( {alu_valid_o, l su_valid_o} ),
|
||||
|
||||
.waddr_a_i ( waddr_a_i ),
|
||||
.wdata_a_i ( wdata_a_i ),
|
||||
.we_a_i ( we_a_i ),
|
||||
.waddr_a_i ( waddr_a_i ),
|
||||
.wdata_a_i ( wdata_a_i ),
|
||||
.we_a_i ( we_a_i ),
|
||||
|
||||
.commit_instr_o ( commit_instr_o ),
|
||||
.commit_ack_i ( commit_ack_i )
|
||||
.commit_instr_o ( commit_instr_o ),
|
||||
.commit_ack_i ( commit_ack_i )
|
||||
);
|
||||
|
||||
ex_stage ex_stage_i (
|
||||
|
@ -186,6 +187,7 @@ module ariane
|
|||
.operand_b_i ( operand_b_o ),
|
||||
.trans_id_i ( trans_id_o ),
|
||||
.comparison_result_o ( comparison_result_o ),
|
||||
|
||||
.alu_ready_o ( alu_ready_i ),
|
||||
.alu_valid_i ( alu_valid_i ),
|
||||
.alu_result_o ( alu_result ),
|
||||
|
@ -194,12 +196,15 @@ module ariane
|
|||
|
||||
.lsu_ready_o ( lsu_ready_o ),
|
||||
.lsu_valid_i ( lsu_valid_i ),
|
||||
.lsu_result_o ( lsu_result ),
|
||||
.lsu_trans_id_o ( lsu_trans_id ),
|
||||
.lsu_valid_o ( lsu_valid_o ),
|
||||
|
||||
.mult_ready_o ( mult_ready_o ),
|
||||
.mult_valid_i ( mult_valid_i )
|
||||
);
|
||||
|
||||
commit_stage i_commit_stage (
|
||||
commit_stage commit_stage (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_n ),
|
||||
.priv_lvl_o ( priv_lvl_o ),
|
||||
|
@ -211,7 +216,7 @@ module ariane
|
|||
.we_a_o ( we_a_i )
|
||||
);
|
||||
|
||||
mmu i_mmu (
|
||||
mmu mmu_i (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_n ),
|
||||
.enable_translation_i ( enable_translation_i ),
|
||||
|
@ -223,7 +228,7 @@ module ariane
|
|||
.fetch_rdata_o ( fetch_rdata_o ),
|
||||
.lsu_req_i ( lsu_req_i ),
|
||||
.lsu_gnt_o ( lsu_gnt_o ),
|
||||
.lsu_valid_o ( lsu_valid_o ),
|
||||
.lsu_valid_o ( ),
|
||||
.lsu_we_i ( lsu_we_i ),
|
||||
.lsu_be_i ( lsu_be_i ),
|
||||
.lsu_err_o ( lsu_err_o ),
|
||||
|
|
24
ex_stage.sv
24
ex_stage.sv
|
@ -7,18 +7,21 @@ module ex_stage (
|
|||
input fu_op operator_i,
|
||||
input logic [63:0] operand_a_i,
|
||||
input logic [63:0] operand_b_i,
|
||||
input logic [4:0] trans_id_i,
|
||||
input logic [TRANS_ID_BITS-1:0] trans_id_i,
|
||||
|
||||
// ALU 1
|
||||
output logic alu_ready_o, // FU is ready
|
||||
input logic alu_valid_i, // Output is valid
|
||||
output logic alu_valid_o, // ALU result is valid
|
||||
output logic [63:0] alu_result_o,
|
||||
output logic [4:0] alu_trans_id_o, // ID of scoreboard entry at which to write back
|
||||
output logic [TRANS_ID_BITS-1:0] alu_trans_id_o, // ID of scoreboard entry at which to write back
|
||||
output logic comparison_result_o,
|
||||
// LSU
|
||||
output logic lsu_ready_o, // FU is ready
|
||||
input logic lsu_valid_i, // Output is valid
|
||||
input logic lsu_valid_i, // Input is valid
|
||||
output logic lsu_valid_o, // Output is valid
|
||||
output logic [63:0] lsu_result_o,
|
||||
output logic [TRANS_ID_BITS-1:0] lsu_trans_id_o,
|
||||
// MULT
|
||||
output logic mult_ready_o, // FU is ready
|
||||
input logic mult_valid_i // Output is valid
|
||||
|
@ -45,6 +48,21 @@ alu alu_i (
|
|||
|
||||
// Load-Store Unit
|
||||
|
||||
assign lsu_valid_o = 1'b0;
|
||||
assign lsu_trans_id_o = trans_id_i;
|
||||
logic rst_n;
|
||||
logic data_req_o;
|
||||
logic data_gnt_i;
|
||||
logic data_rvalid_i;
|
||||
logic data_err_i;
|
||||
logic [63:0] data_addr_o;
|
||||
logic data_we_o;
|
||||
logic [7:0] data_be_o;
|
||||
logic [63:0] data_wdata_o;
|
||||
logic [63:0] data_rdata_i;
|
||||
logic lsu_trans_id_i;
|
||||
exception lsu_exception_o;
|
||||
|
||||
// pass through
|
||||
|
||||
|
||||
|
|
54
id_stage.sv
54
id_stage.sv
|
@ -14,41 +14,41 @@ module id_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 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_i,
|
||||
// from IF
|
||||
input logic [31:0] instruction_i,
|
||||
input logic instruction_valid_i,
|
||||
input logic [63:0] pc_if_i,
|
||||
input exception ex_i,
|
||||
output logic ready_o, // id is ready
|
||||
output fu_op operator_o,
|
||||
output logic [63:0] operand_a_o,
|
||||
output logic [63:0] operand_b_o,
|
||||
output logic [4:0] trans_id_o,
|
||||
input logic [31:0] instruction_i,
|
||||
input logic instruction_valid_i,
|
||||
input logic [63:0] pc_if_i,
|
||||
input exception ex_i,
|
||||
output logic ready_o, // id is ready
|
||||
output fu_op operator_o,
|
||||
output logic [63:0] operand_a_o,
|
||||
output logic [63:0] operand_b_o,
|
||||
output logic [TRANS_ID_BITS-1:0] trans_id_o,
|
||||
|
||||
input logic alu_ready_i,
|
||||
output logic alu_valid_o,
|
||||
input logic alu_ready_i,
|
||||
output logic alu_valid_o,
|
||||
|
||||
input logic lsu_ready_i,
|
||||
output logic lsu_valid_o,
|
||||
input logic lsu_ready_i,
|
||||
output logic lsu_valid_o,
|
||||
|
||||
input logic mult_ready_i,
|
||||
output logic mult_valid_o,
|
||||
input logic mult_ready_i,
|
||||
output logic mult_valid_o,
|
||||
// write back port
|
||||
input logic [NR_WB_PORTS-1:0][4:0] trans_id_i,
|
||||
input logic [NR_WB_PORTS-1:0][63:0] wdata_i,
|
||||
input logic [NR_WB_PORTS-1:0] wb_valid_i,
|
||||
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 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,
|
||||
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
|
||||
output scoreboard_entry commit_instr_o,
|
||||
input logic commit_ack_i
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,13 @@
|
|||
* in one package.
|
||||
*/
|
||||
package ariane_pkg;
|
||||
|
||||
// ---------------
|
||||
// Global Config
|
||||
// ---------------
|
||||
localparam NR_SB_ENTRIES = 4; // number of scoreboard entries
|
||||
localparam TRANS_ID_BITS = $clog2(NR_SB_ENTRIES); // depending on the number of scoreboard entries we need that many bits
|
||||
// to uniquely identify the entry in the scoreboard
|
||||
localparam NR_WB_PORTS = 2;
|
||||
// ---------------
|
||||
// Fetch Stage
|
||||
// ---------------
|
||||
|
@ -41,7 +47,7 @@ package ariane_pkg;
|
|||
} misspredict;
|
||||
|
||||
typedef enum logic[3:0] {
|
||||
NONE, ALU, MULT, LSU, CSR
|
||||
NONE, LSU, ALU, MULT, CSR
|
||||
} fu_t;
|
||||
|
||||
localparam EXC_OFF_RST = 8'h80;
|
||||
|
@ -62,18 +68,18 @@ package ariane_pkg;
|
|||
// ID/EX/WB Stage
|
||||
// ---------------
|
||||
typedef struct packed {
|
||||
logic [4:0] trans_id; // this can potentially be simplified, we could index the scoreboard entry with the transaction id
|
||||
// in any case make the width more generic
|
||||
fu_t fu; // functional unit to use
|
||||
fu_op op; // operation to perform in each functional unit
|
||||
logic [4:0] rs1; // register source address 1
|
||||
logic [4:0] rs2; // register source address 2
|
||||
logic [4:0] rd; // register destination address
|
||||
logic [63:0] result; // for unfinished instructions this field also holds the immediate
|
||||
logic valid; // is the result valid
|
||||
logic use_imm; // should we use the immediate as operand b?
|
||||
logic use_pc; // set if we need to use the PC as operand A, PC from exception
|
||||
exception ex; // exception has occurred
|
||||
logic [TRANS_ID_BITS-1:0] trans_id; // this can potentially be simplified, we could index the scoreboard entry
|
||||
// with the transaction id in any case make the width more generic
|
||||
fu_t fu; // functional unit to use
|
||||
fu_op op; // operation to perform in each functional unit
|
||||
logic [4:0] rs1; // register source address 1
|
||||
logic [4:0] rs2; // register source address 2
|
||||
logic [4:0] rd; // register destination address
|
||||
logic [63:0] result; // for unfinished instructions this field also holds the immediate
|
||||
logic valid; // is the result valid
|
||||
logic use_imm; // should we use the immediate as operand b?
|
||||
logic use_pc; // set if we need to use the PC as operand A, PC from exception
|
||||
exception ex; // exception has occurred
|
||||
} scoreboard_entry;
|
||||
|
||||
// --------------------
|
||||
|
|
|
@ -30,10 +30,10 @@ module issue_read_operands (
|
|||
// get clobber input
|
||||
input logic [31:0][$bits(fu_t)-1:0] rd_clobber_i,
|
||||
// To FU, just single issue for now
|
||||
output fu_op operator_o,
|
||||
output fu_op operator_o,
|
||||
output logic [63:0] operand_a_o,
|
||||
output logic [63:0] operand_b_o,
|
||||
output logic [4:0] trans_id_o,
|
||||
output logic [TRANS_ID_BITS-1:0] trans_id_o,
|
||||
// ALU 1
|
||||
input logic alu_ready_i, // FU is ready
|
||||
output logic alu_valid_o, // Output is valid
|
||||
|
@ -57,7 +57,7 @@ module issue_read_operands (
|
|||
// output flipflop (ID <-> EX)
|
||||
logic [63:0] operand_a_n, operand_a_q, operand_b_n, operand_b_q;
|
||||
logic alu_valid_n, alu_valid_q;
|
||||
logic [4:0] trans_id_n, trans_id_q;
|
||||
logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q;
|
||||
fu_op operator_n, operator_q;
|
||||
|
||||
// forwarding signals
|
||||
|
|
|
@ -8,45 +8,45 @@
|
|||
import ariane_pkg::*;
|
||||
|
||||
module scoreboard #(
|
||||
parameter int NR_ENTRIES = 8,
|
||||
parameter int NR_ENTRIES = 8,
|
||||
parameter int NR_WB_PORTS = 1,
|
||||
parameter type dtype = scoreboard_entry
|
||||
parameter type dtype = scoreboard_entry
|
||||
)
|
||||
(
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
output logic full_o, // We can't take anymore data
|
||||
input logic flush_i,
|
||||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
output logic full_o, // We can't take anymore data
|
||||
input logic flush_i,
|
||||
// list of clobbered registers to issue stage
|
||||
output logic [31:0][$bits(fu_t)-1:0] rd_clobber_o,
|
||||
output logic [31:0][$bits(fu_t)-1:0] rd_clobber_o,
|
||||
|
||||
// regfile like interface to operand read stage
|
||||
input logic [4:0] rs1_i,
|
||||
output logic [63:0] rs1_o,
|
||||
output logic rs1_valid_o,
|
||||
input logic [4:0] rs1_i,
|
||||
output logic [63:0] rs1_o,
|
||||
output logic rs1_valid_o,
|
||||
|
||||
input logic [4:0] rs2_i,
|
||||
output logic [63:0] rs2_o,
|
||||
output logic rs2_valid_o,
|
||||
input logic [4:0] rs2_i,
|
||||
output logic [63:0] rs2_o,
|
||||
output logic rs2_valid_o,
|
||||
|
||||
// advertise instruction to commit stage, if commit_ack_i is asserted advance the commit pointer
|
||||
output dtype commit_instr_o,
|
||||
input logic commit_ack_i,
|
||||
output dtype commit_instr_o,
|
||||
input logic commit_ack_i,
|
||||
|
||||
// instruction to put on top of scoreboard e.g.: top pointer
|
||||
// we can always put this instruction to the top unless we signal with asserted full_o
|
||||
input dtype decoded_instr_i,
|
||||
input logic decoded_instr_valid_i,
|
||||
// instruction to put on top of scoreboard e.g. : top pointer
|
||||
// we can always put this instruction to the to p unless we signal with asserted full_o
|
||||
input dtype decoded_instr_i,
|
||||
input logic decoded_instr_valid_i,
|
||||
|
||||
// instruction to issue logic, if issue_instr_valid and issue_ready is asserted, advance the issue pointer
|
||||
output dtype issue_instr_o,
|
||||
output logic issue_instr_valid_o,
|
||||
input logic issue_ack_i,
|
||||
output dtype issue_instr_o,
|
||||
output logic issue_instr_valid_o,
|
||||
input logic issue_ack_i,
|
||||
|
||||
// write-back port
|
||||
input logic [NR_WB_PORTS-1:0][4:0] trans_id_i, // transaction ID at which to write the result back
|
||||
input logic [NR_WB_PORTS-1:0][63:0] wdata_i, // write data in
|
||||
input logic [NR_WB_PORTS-1:0] wb_valid_i // data in is valid
|
||||
input logic [NR_WB_PORTS-1:0][TRANS_ID_BITS-1:0] trans_id_i, // transaction ID at which to write the result back
|
||||
input logic [NR_WB_PORTS-1:0][63:0] wdata_i, // write data in
|
||||
input logic [NR_WB_PORTS-1:0] wb_valid_i // data in is valid
|
||||
);
|
||||
localparam BITS_ENTRIES = $clog2(NR_ENTRIES);
|
||||
|
||||
|
@ -135,13 +135,17 @@ always_comb begin : read_operands
|
|||
end
|
||||
|
||||
// provide a direct combinational path from WB a.k.a forwarding
|
||||
if (mem_q[trans_id_i].rd == rs1_i && wb_valid_i) begin
|
||||
rs1_o = wdata_i;
|
||||
rs1_valid_o = wb_valid_i;
|
||||
end
|
||||
if (mem_q[trans_id_i].rd == rs2_i && wb_valid_i) begin
|
||||
rs2_o = wdata_i;
|
||||
rs2_valid_o = wb_valid_i;
|
||||
for (int j = 0; j < NR_WB_PORTS; j++) begin
|
||||
if (mem_q[trans_id_i[j]].rd == rs1_i && wb_valid_i[j]) begin
|
||||
rs1_o = wdata_i[j];
|
||||
rs1_valid_o = wb_valid_i[j];
|
||||
break;
|
||||
end
|
||||
if (mem_q[trans_id_i[j]].rd == rs2_i && wb_valid_i[j]) begin
|
||||
rs2_o = wdata_i[j];
|
||||
rs2_valid_o = wb_valid_i[j];
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
// make sure we didn't read the zero register
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue