mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 05:37:16 -04:00
Fix issue #39
This commit is contained in:
parent
602116f2e7
commit
72b842eaf8
8 changed files with 35 additions and 23 deletions
|
@ -65,7 +65,7 @@ package ariane_pkg;
|
|||
} branchpredict_sbe;
|
||||
|
||||
typedef enum logic[3:0] {
|
||||
NONE, LSU, ALU, CTRL_FLOW, MULT, CSR
|
||||
NONE, LOAD, STORE, ALU, CTRL_FLOW, MULT, CSR
|
||||
} fu_t;
|
||||
|
||||
localparam EXC_OFF_RST = 8'h80;
|
||||
|
|
|
@ -118,6 +118,7 @@ module ariane
|
|||
// --------------
|
||||
logic [63:0] imm_id_ex;
|
||||
logic [TRANS_ID_BITS-1:0] trans_id_id_ex;
|
||||
fu_t fu_id_ex;
|
||||
fu_op operator_id_ex;
|
||||
logic [63:0] operand_a_id_ex;
|
||||
logic [63:0] operand_b_id_ex;
|
||||
|
@ -275,6 +276,7 @@ module ariane
|
|||
.ready_o ( ready_id_if ),
|
||||
.priv_lvl_i ( priv_lvl ),
|
||||
// Functional Units
|
||||
.fu_o ( fu_id_ex ),
|
||||
.operator_o ( operator_id_ex ),
|
||||
.operand_a_o ( operand_a_id_ex ),
|
||||
.operand_b_o ( operand_b_id_ex ),
|
||||
|
@ -319,6 +321,7 @@ module ariane
|
|||
// ---------
|
||||
ex_stage ex_stage_i (
|
||||
.flush_i ( flush_ctrl_ex ),
|
||||
.fu_i ( fu_id_ex ),
|
||||
.operator_i ( operator_id_ex ),
|
||||
.operand_a_i ( operand_a_id_ex ),
|
||||
.operand_b_i ( operand_b_id_ex ),
|
||||
|
|
|
@ -76,7 +76,7 @@ module commit_stage (
|
|||
we_a_o = 1'b1;
|
||||
commit_ack_o = 1'b1;
|
||||
// check whether the instruction we retire was a store
|
||||
if (commit_instr_i.op inside {SD, SW, SH, SB}) begin
|
||||
if (commit_instr_i.fu == STORE) begin
|
||||
commit_lsu_o = 1'b1;
|
||||
end
|
||||
// ---------
|
||||
|
|
|
@ -291,7 +291,7 @@ module decoder (
|
|||
end
|
||||
|
||||
OPCODE_STORE: begin
|
||||
instruction_o.fu = LSU;
|
||||
instruction_o.fu = STORE;
|
||||
imm_select = SIMM;
|
||||
instruction_o.rs1 = instr.stype.rs1;
|
||||
instruction_o.rs2 = instr.stype.rs2;
|
||||
|
@ -311,7 +311,7 @@ module decoder (
|
|||
end
|
||||
|
||||
OPCODE_LOAD: begin
|
||||
instruction_o.fu = LSU;
|
||||
instruction_o.fu = LOAD;
|
||||
imm_select = IIMM;
|
||||
instruction_o.rs1 = instr.itype.rs1;
|
||||
instruction_o.rd = instr.itype.rd;
|
||||
|
|
|
@ -26,6 +26,7 @@ module ex_stage #(
|
|||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic flush_i,
|
||||
|
||||
input fu_t fu_i,
|
||||
input fu_op operator_i,
|
||||
input logic [63:0] operand_a_i,
|
||||
input logic [63:0] operand_b_i,
|
||||
|
|
|
@ -38,6 +38,7 @@ module id_stage #(
|
|||
input priv_lvl_t priv_lvl_i, // current privilege level
|
||||
|
||||
output logic ready_o, // id is ready
|
||||
output fu_t fu_o,
|
||||
output fu_op operator_o,
|
||||
output logic [63:0] operand_a_o,
|
||||
output logic [63:0] operand_b_o,
|
||||
|
|
|
@ -39,6 +39,7 @@ module issue_read_operands (
|
|||
// get clobber input
|
||||
input fu_t [31:0] rd_clobber_i,
|
||||
// To FU, just single issue for now
|
||||
output fu_t fu_o,
|
||||
output fu_op operator_o,
|
||||
output logic [63:0] operand_a_o,
|
||||
output logic [63:0] operand_b_o,
|
||||
|
@ -84,7 +85,8 @@ module issue_read_operands (
|
|||
logic branch_valid_n, branch_valid_q;
|
||||
|
||||
logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q;
|
||||
fu_op operator_n, operator_q;
|
||||
fu_op operator_n, operator_q; // operation to perform
|
||||
fu_t fu_n, fu_q; // functional unit to use
|
||||
|
||||
// forwarding signals
|
||||
logic forward_rs1, forward_rs2;
|
||||
|
@ -92,6 +94,7 @@ module issue_read_operands (
|
|||
assign operand_a_o = operand_a_q;
|
||||
assign operand_b_o = operand_b_q;
|
||||
assign operand_c_o = operand_c_q;
|
||||
assign fu_o = fu_q;
|
||||
assign operator_o = operator_q;
|
||||
assign alu_valid_o = alu_valid_q;
|
||||
assign branch_valid_o = branch_valid_q;
|
||||
|
@ -150,7 +153,7 @@ module issue_read_operands (
|
|||
fu_busy = ~alu_ready_i;
|
||||
MULT:
|
||||
fu_busy = ~mult_ready_i;
|
||||
LSU:
|
||||
LOAD, STORE:
|
||||
fu_busy = ~lsu_ready_i;
|
||||
CSR:
|
||||
fu_busy = ~csr_ready_i;
|
||||
|
@ -203,8 +206,8 @@ module issue_read_operands (
|
|||
// immediates are the third operands in the store case
|
||||
imm_n = issue_instr_i.result;
|
||||
trans_id_n = issue_instr_i.trans_id;
|
||||
fu_n = issue_instr_i.fu;
|
||||
operator_n = issue_instr_i.op;
|
||||
|
||||
// or should we forward
|
||||
if (forward_rs1) begin
|
||||
operand_a_n = rs1_i;
|
||||
|
@ -225,7 +228,7 @@ module issue_read_operands (
|
|||
operand_a_n = {52'b0, issue_instr_i.rs1};
|
||||
end
|
||||
// or is it an immediate (including PC), this is not the case for a store
|
||||
if (issue_instr_i.use_imm && ~(issue_instr_i.op inside {SD, SW, SH, SB})) begin
|
||||
if (issue_instr_i.use_imm && (issue_instr_i.fu != STORE)) begin
|
||||
operand_b_n = issue_instr_i.result;
|
||||
end
|
||||
// special assignments in the JAL and JALR case
|
||||
|
@ -269,7 +272,7 @@ module issue_read_operands (
|
|||
alu_valid_n = 1'b1;
|
||||
MULT:
|
||||
mult_valid_n = 1'b1;
|
||||
LSU:
|
||||
LOAD, STORE:
|
||||
lsu_valid_n = 1'b1;
|
||||
CSR:
|
||||
csr_valid_n = 1'b1;
|
||||
|
@ -330,6 +333,7 @@ module issue_read_operands (
|
|||
mult_valid_q <= 1'b0;
|
||||
lsu_valid_q <= 1'b0;
|
||||
csr_valid_q <= 1'b0;
|
||||
fu_q <= NONE;
|
||||
operator_q <= ADD;
|
||||
trans_id_q <= 5'b0;
|
||||
pc_o <= 64'b0;
|
||||
|
@ -345,6 +349,7 @@ module issue_read_operands (
|
|||
mult_valid_q <= mult_valid_n;
|
||||
lsu_valid_q <= lsu_valid_n;
|
||||
csr_valid_q <= csr_valid_n;
|
||||
fu_q <= fu_n;
|
||||
operator_q <= operator_n;
|
||||
trans_id_q <= trans_id_n;
|
||||
pc_o <= issue_instr_i.pc;
|
||||
|
|
30
src/lsu.sv
30
src/lsu.sv
|
@ -25,6 +25,7 @@ module lsu #(
|
|||
input logic rst_ni,
|
||||
input logic flush_i,
|
||||
|
||||
input fu_t fu_i,
|
||||
input fu_op operator_i,
|
||||
input logic [63:0] operand_a_i,
|
||||
input logic [63:0] operand_b_i,
|
||||
|
@ -85,11 +86,13 @@ module lsu #(
|
|||
logic [63:0] vaddr;
|
||||
logic [63:0] data;
|
||||
logic [7:0] be;
|
||||
fu_t fu;
|
||||
fu_op operator;
|
||||
logic [TRANS_ID_BITS-1:0] trans_id;
|
||||
// registered address in case of a necessary stall
|
||||
logic [63:0] vaddr_n, vaddr_q;
|
||||
logic [63:0] data_n, data_q;
|
||||
fu_t fu_n, fu_q;
|
||||
fu_op operator_n, operator_q;
|
||||
logic [TRANS_ID_BITS-1:0] trans_id_n, trans_id_q;
|
||||
logic [7:0] be_n, be_q;
|
||||
|
@ -100,6 +103,7 @@ module lsu #(
|
|||
// virtual address as calculated by the AGU in the first cycle
|
||||
logic [63:0] vaddr_i;
|
||||
logic [7:0] be_i;
|
||||
|
||||
assign vaddr_i = $signed(imm_i) + $signed(operand_a_i);
|
||||
|
||||
logic st_valid_i;
|
||||
|
@ -325,8 +329,6 @@ module lsu #(
|
|||
end
|
||||
end
|
||||
|
||||
enum logic {LD_OP, ST_OP} op;
|
||||
|
||||
// determine whether this is a load or store
|
||||
always_comb begin : which_op
|
||||
|
||||
|
@ -334,20 +336,14 @@ module lsu #(
|
|||
st_valid_i = 1'b0;
|
||||
|
||||
// only activate one of the units if we didn't got an misaligned exception
|
||||
// we can directly output an misaligned exception and do not need to process it any further
|
||||
// we can directly output a misaligned exception and do not need to process it any further
|
||||
if (!data_misaligned) begin
|
||||
// check the operator to activate the right functional unit accordingly
|
||||
unique case (operator)
|
||||
unique case (fu)
|
||||
// all loads go here
|
||||
LD, LW, LWU, LH, LHU, LB, LBU: begin
|
||||
ld_valid_i = 1'b1;
|
||||
op = LD_OP;
|
||||
end
|
||||
LOAD: ld_valid_i = 1'b1;
|
||||
// all stores go here
|
||||
SD, SW, SH, SB: begin
|
||||
st_valid_i = 1'b1;
|
||||
op = ST_OP;
|
||||
end
|
||||
STORE: st_valid_i = 1'b1;
|
||||
// not relevant for the LSU
|
||||
default: ;
|
||||
endcase
|
||||
|
@ -444,14 +440,14 @@ module lsu #(
|
|||
|
||||
if (data_misaligned) begin
|
||||
|
||||
if (op == LD_OP) begin
|
||||
if (fu == LOAD) begin
|
||||
misaligned_exception = {
|
||||
64'b0,
|
||||
LD_ADDR_MISALIGNED,
|
||||
1'b1
|
||||
};
|
||||
|
||||
end else if (op == ST_OP) begin
|
||||
end else if (fu == STORE) begin
|
||||
misaligned_exception = {
|
||||
64'b0,
|
||||
ST_ADDR_MISALIGNED,
|
||||
|
@ -468,12 +464,14 @@ module lsu #(
|
|||
if (stall_q) begin
|
||||
vaddr = vaddr_q;
|
||||
data = data_q;
|
||||
fu = fu_q;
|
||||
operator = operator_q;
|
||||
trans_id = trans_id_q;
|
||||
be = be_q;
|
||||
end else begin // otherwise bypass them
|
||||
vaddr = vaddr_i;
|
||||
data = operand_b_i;
|
||||
fu = fu_i;
|
||||
operator = operator_i;
|
||||
trans_id = trans_id_i;
|
||||
be = be_i;
|
||||
|
@ -483,6 +481,7 @@ module lsu #(
|
|||
always_comb begin : register_stage
|
||||
vaddr_n = vaddr_q;
|
||||
data_n = data_q;
|
||||
fu_n = fu_q;
|
||||
operator_n = operator_q;
|
||||
trans_id_n = trans_id_q;
|
||||
be_n = be_q;
|
||||
|
@ -490,6 +489,7 @@ module lsu #(
|
|||
if (lsu_valid_i) begin
|
||||
vaddr_n = vaddr_i;
|
||||
data_n = operand_b_i;
|
||||
fu_n = fu_i;
|
||||
operator_n = operator_i;
|
||||
trans_id_n = trans_id_i;
|
||||
be_n = be_i;
|
||||
|
@ -508,6 +508,7 @@ module lsu #(
|
|||
// 1st LSU stage
|
||||
vaddr_q <= 64'b0;
|
||||
data_q <= 64'b0;
|
||||
fu_q <= NONE;
|
||||
operator_q <= ADD;
|
||||
trans_id_q <= '{default: 0};
|
||||
be_q <= 8'b0;
|
||||
|
@ -516,6 +517,7 @@ module lsu #(
|
|||
// 1st LSU stage
|
||||
vaddr_q <= vaddr_n;
|
||||
data_q <= data_n;
|
||||
fu_q <= fu_n;
|
||||
operator_q <= operator_n;
|
||||
trans_id_q <= trans_id_n;
|
||||
be_q <= be_n;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue