This commit is contained in:
Florian Zaruba 2017-06-02 10:56:16 +02:00
parent 602116f2e7
commit 72b842eaf8
8 changed files with 35 additions and 23 deletions

View file

@ -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;

View file

@ -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 ),

View file

@ -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
// ---------

View file

@ -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;

View file

@ -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,

View file

@ -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,

View file

@ -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;

View file

@ -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;