mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 12:07:53 -04:00
alu writeback changes and writeback frequency improvements
This commit is contained in:
parent
e41fb648be
commit
1ac97a8872
15 changed files with 148 additions and 178 deletions
|
@ -41,6 +41,8 @@ module alu_unit(
|
|||
logic[XLEN:0] adder_in2;
|
||||
logic[XLEN:0] adder_in2_logic;
|
||||
|
||||
logic[XLEN-1:0] result;
|
||||
logic [31:0] rd_bank [MAX_INFLIGHT_COUNT-1:0];
|
||||
//implementation
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
|
@ -74,32 +76,25 @@ module alu_unit(
|
|||
//Result mux
|
||||
always_comb begin
|
||||
case (alu_inputs.op)
|
||||
ALU_ADD_SUB : alu_wb.rd = add_sub_result[XLEN-1:0];
|
||||
ALU_SLT : alu_wb.rd = {31'b0, add_sub_result[XLEN]};
|
||||
ALU_RSHIFT : alu_wb.rd = rshift_result;
|
||||
ALU_LSHIFT : alu_wb.rd = lshift_result;
|
||||
ALU_ADD_SUB : result = add_sub_result[XLEN-1:0];
|
||||
ALU_SLT : result = {31'b0, add_sub_result[XLEN]};
|
||||
ALU_RSHIFT : result = rshift_result;
|
||||
ALU_LSHIFT : result = lshift_result;
|
||||
endcase
|
||||
end
|
||||
|
||||
//Issue/write-back handshaking
|
||||
////////////////////////////////////////////////////
|
||||
assign alu_ex.ready = ~done | (done & alu_wb.accepted);
|
||||
//Output bank
|
||||
always_ff @ (posedge clk) begin
|
||||
if (alu_ex.possible_issue)
|
||||
rd_bank[alu_ex.instruction_id] <= result;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst)
|
||||
done <= 0;
|
||||
else if (alu_ex.new_request_dec)
|
||||
done <= 1;
|
||||
else if (alu_wb.accepted)
|
||||
done <= 0;
|
||||
end
|
||||
assign alu_ex.ready = 1;
|
||||
assign alu_wb.rd = rd_bank[alu_wb.writeback_instruction_id];
|
||||
assign alu_wb.done_next_cycle = alu_ex.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{alu_ex.new_request_dec}};
|
||||
|
||||
assign alu_wb.done_next_cycle = alu_ex.new_request_dec;
|
||||
assign alu_wb.instruction_id = alu_ex.instruction_id;
|
||||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
always_ff @ (posedge clk) begin
|
||||
assert (~alu_wb.accepted | (alu_wb.accepted & done)) else $error("Spurious ack for ALU");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -33,15 +33,19 @@ module barrel_shifter (
|
|||
);
|
||||
|
||||
logic[XLEN-1:0] shiftx8, shiftx2, shiftx1, shiftx1_l;
|
||||
|
||||
logic[XLEN-1:0] preshifted_input;
|
||||
//Bit flipping shared shifter
|
||||
//left shift occurs in decode logic
|
||||
always_comb begin
|
||||
foreach (shifter_input[i])
|
||||
preshifted_input[i] = lshift ? shifter_input[XLEN-i-1] : shifter_input[i];
|
||||
end
|
||||
|
||||
always_comb begin//8
|
||||
case (shift_amount[4:3])
|
||||
0: shiftx8 = shifter_input;
|
||||
1: shiftx8 = {{8{arith}}, shifter_input[31:8]};
|
||||
2: shiftx8 = {{16{arith}}, shifter_input[31:16]};
|
||||
3: shiftx8 = {{24{arith}}, shifter_input[31:24]};
|
||||
0: shiftx8 = preshifted_input;
|
||||
1: shiftx8 = {{8{arith}}, preshifted_input[31:8]};
|
||||
2: shiftx8 = {{16{arith}}, preshifted_input[31:16]};
|
||||
3: shiftx8 = {{24{arith}}, preshifted_input[31:24]};
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -54,14 +58,10 @@ module barrel_shifter (
|
|||
endcase
|
||||
end
|
||||
|
||||
//assign shiftx1_l = {arith,shiftx2[31:1]};
|
||||
always_comb begin
|
||||
//case ({lshift, shift_amount[0]})
|
||||
case (shift_amount[0])
|
||||
0: shiftx1 = shiftx2[31:0];
|
||||
1: shiftx1 = {arith,shiftx2[31:1]};
|
||||
//2: foreach (shiftx1[i]) shiftx1[i] = shiftx2[31-i];
|
||||
// 3: foreach (shiftx1[i]) shiftx1[i] = shiftx1_l[31-i];
|
||||
endcase
|
||||
end
|
||||
|
||||
|
@ -70,8 +70,6 @@ module barrel_shifter (
|
|||
foreach (shiftx1[i]) shifted_resultl[i] = shiftx1[31-i];
|
||||
end
|
||||
|
||||
//assign shifted_result = lshift ? signed'({arith,shifter_input} <<< shift_amount) : signed'({arith,shifter_input} >>> shift_amount);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ import taiga_types::*;
|
|||
|
||||
module branch_predictor_ram
|
||||
#(
|
||||
parameter C_DATA_WIDTH = 6,
|
||||
parameter C_DEPTH = 64
|
||||
parameter C_DATA_WIDTH = 20,
|
||||
parameter C_DEPTH = 512
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
|
|
|
@ -183,10 +183,7 @@ module branch_unit(
|
|||
|
||||
assign branch_ex.ready = 1;
|
||||
assign branch_wb.rd = rd_bank[branch_wb.writeback_instruction_id];
|
||||
|
||||
assign branch_wb.done_next_cycle = new_jal_jalr_dec_with_rd;
|
||||
assign branch_wb.instruction_id = branch_ex.instruction_id;
|
||||
|
||||
assign branch_wb.done_next_cycle = branch_ex.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{new_jal_jalr_dec_with_rd}};
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
////////////////////////////////////////////////////
|
||||
|
|
|
@ -204,12 +204,6 @@ module decode(
|
|||
//ALU unit inputs
|
||||
logic [XLEN-1:0] alu_rs1_data;
|
||||
logic [XLEN-1:0] alu_rs2_data;
|
||||
logic [XLEN-1:0] left_shift_in;
|
||||
|
||||
logic alu_sub;
|
||||
|
||||
logic [1:0] alu_op;
|
||||
logic [1:0] alu_logic_op;
|
||||
|
||||
always_comb begin
|
||||
if (opcode[2] & opcode[5]) //LUI
|
||||
|
@ -229,54 +223,14 @@ module decode(
|
|||
alu_rs2_data = rf_decode.rs2_data;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (fn3)
|
||||
SLT_fn3 : alu_logic_op = ALU_LOGIC_ADD;
|
||||
SLTU_fn3 : alu_logic_op = ALU_LOGIC_ADD;
|
||||
SLL_fn3 : alu_logic_op = ALU_LOGIC_ADD;
|
||||
XOR_fn3 : alu_logic_op = ALU_LOGIC_XOR;
|
||||
OR_fn3 : alu_logic_op = ALU_LOGIC_OR;
|
||||
AND_fn3 : alu_logic_op = ALU_LOGIC_AND;
|
||||
SRA_fn3 : alu_logic_op = ALU_LOGIC_ADD;
|
||||
ADD_SUB_fn3 : alu_logic_op = ALU_LOGIC_ADD;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (fn3)
|
||||
SLT_fn3 : alu_op = ALU_SLT;
|
||||
SLTU_fn3 : alu_op = ALU_SLT;
|
||||
SLL_fn3 : alu_op = ALU_LSHIFT;
|
||||
XOR_fn3 : alu_op = ALU_ADD_SUB;
|
||||
OR_fn3 : alu_op = ALU_ADD_SUB;
|
||||
AND_fn3 : alu_op = ALU_ADD_SUB;
|
||||
SRA_fn3 : alu_op = ALU_RSHIFT;
|
||||
ADD_SUB_fn3 : alu_op = ALU_ADD_SUB;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
foreach (left_shift_in[i])
|
||||
left_shift_in[i] = rf_decode.rs1_data[XLEN-i-1];
|
||||
end
|
||||
|
||||
//Add cases: LUI, AUIPC, ADD[I], all logic ops
|
||||
//sub cases: SUB, SLT[U][I]
|
||||
assign alu_sub = opcode[2] ? 0 : ((fn3 inside {SLTU_fn3, SLT_fn3}) || ((fn3 == ADD_SUB_fn3) && ib.data_out.instruction[30]) && opcode[5]);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (issue_ready[ALU_UNIT_WB_ID]) begin
|
||||
alu_inputs.in1 <= {(alu_rs1_data[XLEN-1] & ~fn3[0]), alu_rs1_data};//(fn3[0] is SLTU_fn3);
|
||||
alu_inputs.in2 <= {(alu_rs2_data[XLEN-1] & ~fn3[0]), alu_rs2_data};
|
||||
alu_inputs.shifter_in <= fn3[2] ? rf_decode.rs1_data : left_shift_in;
|
||||
alu_inputs.subtract <= alu_sub;
|
||||
alu_inputs.arith <= alu_rs1_data[XLEN-1] & ib.data_out.instruction[30];//shift in bit
|
||||
alu_inputs.lshift <= ~fn3[2];
|
||||
alu_inputs.logic_op <= opcode[2] ? ALU_LOGIC_ADD : alu_logic_op;//put LUI and AUIPC through adder path
|
||||
alu_inputs.op <= opcode[2] ? ALU_ADD_SUB : alu_op;//put LUI and AUIPC through adder path
|
||||
end
|
||||
end
|
||||
|
||||
assign alu_inputs.in1 = {(alu_rs1_data[XLEN-1] & ~fn3[0]), alu_rs1_data};//(fn3[0] is SLTU_fn3);
|
||||
assign alu_inputs.in2 = {(alu_rs2_data[XLEN-1] & ~fn3[0]), alu_rs2_data};
|
||||
assign alu_inputs.shifter_in = rf_decode.rs1_data;
|
||||
assign alu_inputs.subtract = ib.data_out.alu_sub;
|
||||
assign alu_inputs.arith = alu_rs1_data[XLEN-1] & ib.data_out.instruction[30];//shift in bit
|
||||
assign alu_inputs.lshift = ~fn3[2];
|
||||
assign alu_inputs.logic_op = ib.data_out.alu_logic_op;
|
||||
assign alu_inputs.op = ib.data_out.alu_op;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Load Store unit inputs
|
||||
|
@ -315,6 +269,7 @@ module decode(
|
|||
assign ls_inputs.load = ls_is_load;
|
||||
assign ls_inputs.store = (opcode_trim == STORE_T) || (amo_op && store_conditional);
|
||||
assign ls_inputs.load_store_forward = rf_decode.rs2_conflict;
|
||||
assign ls_inputs.instruction_id_one_hot = ti.issue_id_one_hot;
|
||||
assign ls_inputs.instruction_id = ti.issue_id;
|
||||
|
||||
//Last store RD tracking for Load-Store data forwarding
|
||||
|
@ -432,6 +387,7 @@ module decode(
|
|||
assign div_inputs.rs2 = rf_decode.rs2_data;
|
||||
assign div_inputs.op = fn3[1:0];
|
||||
assign div_inputs.reuse_result = prev_div_result_valid_r & current_op_resuses_rs1_rs2;
|
||||
assign div_inputs.instruction_id_one_hot = ti.issue_id_one_hot;
|
||||
assign div_inputs.instruction_id = ti.issue_id;
|
||||
end
|
||||
endgenerate
|
||||
|
@ -451,9 +407,12 @@ module decode(
|
|||
gc_ex.new_request <= issue[GC_UNIT_WB_ID];
|
||||
end
|
||||
|
||||
assign branch_ex.instruction_id_one_hot = ti.issue_id_one_hot;
|
||||
assign branch_ex.instruction_id = ti.issue_id;
|
||||
assign alu_ex.instruction_id_one_hot = ti.issue_id_one_hot;
|
||||
assign alu_ex.instruction_id = ti.issue_id;
|
||||
//Load Store unit stores ID in input FIFO
|
||||
assign gc_ex.instruction_id_one_hot = ti.issue_id_one_hot;
|
||||
assign gc_ex.instruction_id = ti.issue_id;
|
||||
|
||||
generate if (USE_MUL)
|
||||
|
@ -461,8 +420,9 @@ module decode(
|
|||
mul_ex.new_request <= issue[MUL_UNIT_WB_ID];
|
||||
end
|
||||
assign mul_ex.new_request_dec = issue[MUL_UNIT_WB_ID];
|
||||
assign mul_ex.instruction_id_one_hot = ti.issue_id_one_hot;
|
||||
assign mul_ex.instruction_id = ti.issue_id;
|
||||
assign mul_ex.possible_issue = new_request[MUL_UNIT_WB_ID];
|
||||
assign mul_ex.possible_issue = new_request[MUL_UNIT_WB_ID] & ti.id_available;
|
||||
endgenerate
|
||||
generate if (USE_DIV)
|
||||
always_ff @(posedge clk) begin
|
||||
|
@ -470,13 +430,13 @@ module decode(
|
|||
end
|
||||
//DIV unit stores ID in input FIFO
|
||||
assign div_ex.new_request_dec = issue[DIV_UNIT_WB_ID];
|
||||
assign div_ex.possible_issue = new_request[DIV_UNIT_WB_ID];
|
||||
assign div_ex.possible_issue = new_request[DIV_UNIT_WB_ID] & ti.id_available;
|
||||
endgenerate
|
||||
|
||||
assign branch_ex.possible_issue = new_request[BRANCH_UNIT_WB_ID];
|
||||
assign alu_ex.possible_issue = new_request[ALU_UNIT_WB_ID];
|
||||
assign ls_ex.possible_issue = new_request[LS_UNIT_WB_ID];
|
||||
assign gc_ex.possible_issue = new_request[GC_UNIT_WB_ID];
|
||||
assign branch_ex.possible_issue = new_request[BRANCH_UNIT_WB_ID] & ti.id_available;
|
||||
assign alu_ex.possible_issue = new_request[ALU_UNIT_WB_ID] & ti.id_available;
|
||||
assign ls_ex.possible_issue = new_request[LS_UNIT_WB_ID] & ti.id_available;
|
||||
assign gc_ex.possible_issue = new_request[GC_UNIT_WB_ID] & ti.id_available;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
|
|
@ -124,9 +124,9 @@ module div_unit
|
|||
rd_bank[stage1.instruction_id] <= wb_div_result;
|
||||
end
|
||||
|
||||
assign div_wb.done_next_cycle = stage1.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{div_done}};
|
||||
assign div_wb.rd = rd_bank[div_wb.writeback_instruction_id];
|
||||
assign div_wb.done_next_cycle = div_done;
|
||||
assign div_wb.instruction_id = stage1.instruction_id;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
|
|
|
@ -277,4 +277,38 @@ module fetch(
|
|||
assign ib.data_in.branch_prediction_used = prediction_used;
|
||||
assign ib.data_in.bp_update_way = update_way;
|
||||
|
||||
//Add cases: LUI, AUIPC, ADD[I], all logic ops
|
||||
//sub cases: SUB, SLT[U][I]
|
||||
assign ib.data_in.alu_sub = opcode[2] ? 0 : ((fn3 inside {SLTU_fn3, SLT_fn3}) || ((fn3 == ADD_SUB_fn3) && final_instruction[30]) && opcode[5]);
|
||||
|
||||
always_comb begin
|
||||
case (fn3)
|
||||
SLT_fn3 : ib.data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
SLTU_fn3 : ib.data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
SLL_fn3 : ib.data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
XOR_fn3 : ib.data_in.alu_logic_op = ALU_LOGIC_XOR;
|
||||
OR_fn3 : ib.data_in.alu_logic_op = ALU_LOGIC_OR;
|
||||
AND_fn3 : ib.data_in.alu_logic_op = ALU_LOGIC_AND;
|
||||
SRA_fn3 : ib.data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
ADD_SUB_fn3 : ib.data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
endcase
|
||||
//put LUI and AUIPC through adder path
|
||||
ib.data_in.alu_logic_op = opcode[2] ? ALU_LOGIC_ADD : ib.data_in.alu_logic_op;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (fn3)
|
||||
SLT_fn3 : ib.data_in.alu_op = ALU_SLT;
|
||||
SLTU_fn3 : ib.data_in.alu_op = ALU_SLT;
|
||||
SLL_fn3 : ib.data_in.alu_op = ALU_LSHIFT;
|
||||
XOR_fn3 : ib.data_in.alu_op = ALU_ADD_SUB;
|
||||
OR_fn3 : ib.data_in.alu_op = ALU_ADD_SUB;
|
||||
AND_fn3 : ib.data_in.alu_op = ALU_ADD_SUB;
|
||||
SRA_fn3 : ib.data_in.alu_op = ALU_RSHIFT;
|
||||
ADD_SUB_fn3 : ib.data_in.alu_op = ALU_ADD_SUB;
|
||||
endcase
|
||||
//put LUI and AUIPC through adder path
|
||||
ib.data_in.alu_op = opcode[2] ? ALU_ADD_SUB : ib.data_in.alu_op;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -160,7 +160,7 @@ module gc_unit(
|
|||
logic [4:0] rs1_addr;
|
||||
logic [4:0] rs2_addr;
|
||||
logic [4:0] future_rd_addr;
|
||||
|
||||
instruction_id_one_hot_t id;
|
||||
//implementation
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
|
@ -287,7 +287,18 @@ module gc_unit(
|
|||
processing <= 0;
|
||||
end
|
||||
|
||||
assign gc_ex.ready = (state == IDLE_STATE) & ~processing;
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst)
|
||||
gc_ex.ready <= 1;
|
||||
else
|
||||
gc_ex.ready <= (state == IDLE_STATE) & ~processing;
|
||||
end
|
||||
|
||||
//Write_back
|
||||
always_ff @(posedge clk) begin
|
||||
id <= gc_ex.instruction_id_one_hot;
|
||||
gc_wb.done_next_cycle <= id & {MAX_INFLIGHT_COUNT{(gc_ex.new_request & gc_inputs.is_csr)}};
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (gc_ex.new_request) begin
|
||||
|
@ -295,13 +306,6 @@ module gc_unit(
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
//Write_back
|
||||
assign gc_wb.done_next_cycle = gc_ex.new_request & gc_inputs.is_csr;
|
||||
always_ff @(posedge clk) begin
|
||||
gc_wb.instruction_id <= gc_ex.instruction_id;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
wb_done <= 0;
|
||||
|
|
|
@ -56,9 +56,10 @@ interface func_unit_ex_interface;
|
|||
logic new_request;
|
||||
logic ready;
|
||||
instruction_id_t instruction_id;
|
||||
instruction_id_one_hot_t instruction_id_one_hot;
|
||||
|
||||
modport decode (input ready, output possible_issue, new_request_dec, new_request, instruction_id);
|
||||
modport unit (output ready, input possible_issue, new_request_dec, new_request, instruction_id);
|
||||
modport decode (input ready, output possible_issue, new_request_dec, new_request, instruction_id, instruction_id_one_hot);
|
||||
modport unit (output ready, input possible_issue, new_request_dec, new_request, instruction_id, instruction_id_one_hot);
|
||||
endinterface
|
||||
|
||||
interface ras_interface;
|
||||
|
@ -75,14 +76,13 @@ endinterface
|
|||
|
||||
interface unit_writeback_interface;
|
||||
//unit output
|
||||
logic done_next_cycle;
|
||||
instruction_id_t instruction_id;
|
||||
instruction_id_one_hot_t done_next_cycle;
|
||||
logic [XLEN-1:0] rd;
|
||||
//writeback output
|
||||
logic accepted;
|
||||
instruction_id_t writeback_instruction_id;
|
||||
modport writeback (input done_next_cycle, instruction_id, rd, output accepted, writeback_instruction_id);
|
||||
modport unit (output done_next_cycle, instruction_id, rd, input accepted, writeback_instruction_id);
|
||||
modport writeback (input done_next_cycle, rd, output accepted, writeback_instruction_id);
|
||||
modport unit (output done_next_cycle, rd, input accepted, writeback_instruction_id);
|
||||
endinterface
|
||||
|
||||
//********************************
|
||||
|
@ -135,33 +135,30 @@ endinterface
|
|||
interface register_file_writeback_interface;
|
||||
logic[4:0] rd_addr;
|
||||
logic valid_write;
|
||||
logic rd_nzero;
|
||||
|
||||
logic[XLEN-1:0] rd_data;
|
||||
instruction_id_t id;
|
||||
|
||||
logic[XLEN-1:0] rs1_data_in;
|
||||
logic[XLEN-1:0] rs2_data_in;
|
||||
logic forward_rs1;
|
||||
logic forward_rs2;
|
||||
|
||||
logic[XLEN-1:0] rs1_data_out;
|
||||
logic[XLEN-1:0] rs2_data_out;
|
||||
|
||||
modport writeback (output rd_addr, valid_write, rd_data, id, rs1_data_out, rs2_data_out, input rs1_data_in, rs2_data_in, forward_rs1, forward_rs2);
|
||||
modport unit (input rd_addr, valid_write, rd_data, id, rs1_data_out, rs2_data_out, output rs1_data_in, rs2_data_in, forward_rs1, forward_rs2);
|
||||
modport writeback (output rd_addr, valid_write, rd_nzero, rd_data, id, input forward_rs1, forward_rs2);
|
||||
modport unit (input rd_addr, valid_write, rd_nzero, rd_data, id, output forward_rs1, forward_rs2);
|
||||
|
||||
endinterface
|
||||
|
||||
|
||||
interface tracking_interface;
|
||||
instruction_id_t issue_id;
|
||||
instruction_id_one_hot_t issue_id_one_hot;
|
||||
logic id_available;
|
||||
|
||||
inflight_instruction_packet inflight_packet;
|
||||
logic issued;
|
||||
|
||||
modport decode (input issue_id, id_available, output inflight_packet, issued);
|
||||
modport wb (output issue_id, id_available, input inflight_packet, issued);
|
||||
modport decode (input issue_id, id_available, issue_id_one_hot, output inflight_packet, issued);
|
||||
modport wb (output issue_id, id_available, issue_id_one_hot, input inflight_packet, issued);
|
||||
endinterface
|
||||
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ module load_store_unit (
|
|||
logic [2:0] fn3;
|
||||
logic [1:0] byte_addr;
|
||||
instruction_id_t instruction_id;
|
||||
instruction_id_one_hot_t instruction_id_one_hot;
|
||||
} load_attributes_t;
|
||||
load_attributes_t load_attributes_in, stage2_attr;
|
||||
load_store_inputs_t stage1;
|
||||
|
@ -221,17 +222,19 @@ module load_store_unit (
|
|||
assign shared_inputs.fn3 = stage1.fn3;
|
||||
|
||||
logic forward_data;
|
||||
assign forward_data = stage1.load_store_forward;
|
||||
assign forward_data = stage1.load_store_forward | dcache_forward_data;
|
||||
assign stage1_raw_data = forward_data ? previous_load : stage1.rs2;
|
||||
|
||||
//Input: ABCD
|
||||
//Assuming aligned requests,
|
||||
//Possible byte selections: (A/C/D, B/D, C/D, D)
|
||||
logic [1:0] data_in_mux;
|
||||
always_comb begin
|
||||
data_in_mux = dcache_forward_data ? dcache_stage2_fn3[1:0] : virtual_address[1:0];
|
||||
shared_inputs.data_in[7:0] = stage1_raw_data[7:0];
|
||||
shared_inputs.data_in[15:8] = (virtual_address[1:0] == 2'b01) ? stage1_raw_data[7:0] : stage1_raw_data[15:8];
|
||||
shared_inputs.data_in[23:16] = (virtual_address[1:0] == 2'b10) ? stage1_raw_data[7:0] : stage1_raw_data[23:16];
|
||||
case(virtual_address[1:0])
|
||||
shared_inputs.data_in[15:8] = (data_in_mux == 2'b01) ? stage1_raw_data[7:0] : stage1_raw_data[15:8];
|
||||
shared_inputs.data_in[23:16] = (data_in_mux == 2'b10) ? stage1_raw_data[7:0] : stage1_raw_data[23:16];
|
||||
case(data_in_mux)
|
||||
2'b10 : shared_inputs.data_in[31:24] = stage1_raw_data[15:8];
|
||||
2'b11 : shared_inputs.data_in[31:24] = stage1_raw_data[7:0];
|
||||
default : shared_inputs.data_in[31:24] = stage1_raw_data[31:24];
|
||||
|
@ -245,6 +248,7 @@ module load_store_unit (
|
|||
assign load_attributes_in.fn3 = stage1.fn3;
|
||||
assign load_attributes_in.byte_addr = virtual_address[1:0];
|
||||
assign load_attributes_in.instruction_id = stage1.instruction_id;
|
||||
assign load_attributes_in.instruction_id_one_hot = stage1.instruction_id_one_hot;
|
||||
|
||||
assign load_attributes.data_in = load_attributes_in;
|
||||
|
||||
|
@ -346,9 +350,7 @@ module load_store_unit (
|
|||
exception_complete <= (input_fifo.valid & ls_exception_valid & stage1.load);
|
||||
end
|
||||
|
||||
assign ls_wb.done_next_cycle = load_complete | exception_complete;
|
||||
assign ls_wb.instruction_id = stage2_attr.instruction_id;
|
||||
|
||||
assign ls_wb.done_next_cycle = stage2_attr.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{(load_complete | exception_complete)}};
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
////////////////////////////////////////////////////
|
||||
|
|
|
@ -33,7 +33,7 @@ module mul_unit(
|
|||
|
||||
logic signed [65:0] result;
|
||||
logic [1:0] mulh;
|
||||
logic [1:0] valid;
|
||||
instruction_id_one_hot_t id_one_hot_done [1:0];
|
||||
instruction_id_t id [1:0];
|
||||
|
||||
logic rs1_signed, rs2_signed;
|
||||
|
@ -58,30 +58,28 @@ module mul_unit(
|
|||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
valid[0] <= mul_ex.new_request_dec;
|
||||
valid[1] <= valid[0];
|
||||
|
||||
mulh[0] <= (mul_inputs.op[1:0] != MUL_fn3[1:0]);
|
||||
mulh[1] <= mulh[0];
|
||||
|
||||
id[0] <= mul_ex.instruction_id;
|
||||
id[1] <= id[0];
|
||||
|
||||
id_one_hot_done[0] <= mul_ex.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{mul_ex.new_request_dec}};
|
||||
id_one_hot_done[1] <= id_one_hot_done[0];
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Output bank
|
||||
always_ff @ (posedge clk) begin
|
||||
if (valid[1])
|
||||
if (|id_one_hot_done[1])
|
||||
rd_bank[id[1]] <= mulh[1] ? result[63:32] : result[31:0];
|
||||
end
|
||||
|
||||
//Issue/write-back handshaking
|
||||
////////////////////////////////////////////////////
|
||||
assign mul_ex.ready = 1;
|
||||
|
||||
assign mul_wb.rd = rd_bank[mul_wb.writeback_instruction_id];
|
||||
assign mul_wb.done_next_cycle = valid[1];
|
||||
assign mul_wb.instruction_id = id[1];
|
||||
assign mul_wb.done_next_cycle = id_one_hot_done[1];
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
|
|
|
@ -28,6 +28,7 @@ module register_file(
|
|||
input logic rst,
|
||||
input logic inorder,
|
||||
input logic inuse_clear,
|
||||
input logic gc_supress_writeback,
|
||||
register_file_writeback_interface.unit rf_wb,
|
||||
register_file_decode_interface.unit rf_decode
|
||||
);
|
||||
|
@ -55,7 +56,7 @@ module register_file(
|
|||
|
||||
//Writeback unit does not assert rf_wb.valid_write when the target register is r0
|
||||
always_ff @ (posedge clk) begin
|
||||
if (rf_wb.valid_write & (in_use_match | inorder)) //inorder needed for case when multiple outstanding writes to this register (common pattern: load, store, load) where the first load hasn't completed by the second causes an exception. Without inorder we wouldn't commit the first load
|
||||
if (~gc_supress_writeback & rf_wb.rd_nzero & rf_wb.valid_write & (in_use_match | inorder)) //inorder needed for case when multiple outstanding writes to this register (common pattern: load, store, load) where the first load hasn't completed by the second causes an exception. Without inorder we wouldn't commit the first load
|
||||
register[rf_wb.rd_addr] <= rf_wb.rd_data;
|
||||
end
|
||||
|
||||
|
@ -75,18 +76,13 @@ module register_file(
|
|||
end
|
||||
|
||||
assign in_use_by_id = in_use_by[rf_wb.rd_addr];
|
||||
assign in_use_match = ({1'b1, in_use_by_id} == {rf_wb.valid_write, rf_wb.id});
|
||||
assign in_use_match = ({3'b011, in_use_by_id} == {gc_supress_writeback, rf_wb.rd_nzero, rf_wb.valid_write, rf_wb.id});
|
||||
|
||||
assign rs1_feedforward = ({2'b11, in_use_by_id, rf_decode.rs1_addr} == {rf_decode.uses_rs1, rf_wb.valid_write, rf_wb.id, rf_wb.rd_addr});
|
||||
assign rs2_feedforward = ({2'b11, in_use_by_id, rf_decode.rs2_addr} == {rf_decode.uses_rs2, rf_wb.valid_write, rf_wb.id, rf_wb.rd_addr});
|
||||
assign rs1_feedforward = ({4'b0111, in_use_by_id, rf_decode.rs1_addr} == {gc_supress_writeback, rf_wb.rd_nzero, rf_decode.uses_rs1, rf_wb.valid_write, rf_wb.id, rf_wb.rd_addr});
|
||||
assign rs2_feedforward = ({4'b0111, in_use_by_id, rf_decode.rs2_addr} == {gc_supress_writeback, rf_wb.rd_nzero, rf_decode.uses_rs2, rf_wb.valid_write, rf_wb.id, rf_wb.rd_addr});
|
||||
|
||||
assign rf_wb.forward_rs1 = rs1_feedforward;
|
||||
assign rf_wb.forward_rs2 = rs2_feedforward;
|
||||
assign rf_wb.rs1_data_in = {32{~rs1_feedforward}} & register[rf_decode.rs1_addr];
|
||||
assign rf_wb.rs2_data_in = {32{~rs2_feedforward}} & register[rf_decode.rs2_addr];
|
||||
|
||||
assign rf_decode.rs1_data = rf_wb.rs1_data_out;//rs1_feedforward ? rf_wb.rd_data : register[rf_decode.rs1_addr];
|
||||
assign rf_decode.rs2_data = rf_wb.rs2_data_out;//rs2_feedforward ? rf_wb.rd_data : register[rf_decode.rs2_addr];
|
||||
assign rf_decode.rs1_data = rs1_feedforward ? rf_wb.rd_data : register[rf_decode.rs1_addr];
|
||||
assign rf_decode.rs2_data = rs2_feedforward ? rf_wb.rd_data : register[rf_decode.rs2_addr];
|
||||
|
||||
assign rf_decode.rs1_conflict = rs1_inuse & ~rs1_feedforward;
|
||||
assign rf_decode.rs2_conflict = rs2_inuse & ~rs2_feedforward;
|
||||
|
@ -97,10 +93,6 @@ module register_file(
|
|||
assert (!(rf_decode.instruction_issued && rf_decode.future_rd_addr == 0)) else $error("Write to inuse for register x0 occured!");
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
assert (!(rf_wb.valid_write && rf_wb.rd_addr == 0)) else $error("Register file write to zero register occured!");
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Simulation Only
|
||||
// synthesis translate_off
|
||||
|
|
|
@ -162,7 +162,7 @@ package taiga_config;
|
|||
////////////////////////////////////////////////////
|
||||
//FIFO/Buffer Depths
|
||||
//All parameters restricted to powers of two
|
||||
parameter MAX_INFLIGHT_COUNT = 8;
|
||||
parameter MAX_INFLIGHT_COUNT = 4;
|
||||
parameter FETCH_BUFFER_DEPTH = 4;
|
||||
|
||||
parameter LS_INPUT_BUFFER_DEPTH = 4;
|
||||
|
@ -188,7 +188,7 @@ package taiga_config;
|
|||
parameter WB_UNITS_WIDTH = $clog2(NUM_WB_UNITS);
|
||||
|
||||
|
||||
parameter ALU_UNIT_WB_ID = 0;//uses accepted
|
||||
parameter ALU_UNIT_WB_ID = 0;
|
||||
parameter GC_UNIT_WB_ID = 1;//uses accepted
|
||||
parameter BRANCH_UNIT_WB_ID = 2;
|
||||
parameter LS_UNIT_WB_ID = 3;
|
||||
|
|
|
@ -28,7 +28,7 @@ package taiga_types;
|
|||
parameter ECODE_W = 5;
|
||||
|
||||
typedef logic[$clog2(MAX_INFLIGHT_COUNT)-1:0] instruction_id_t;
|
||||
|
||||
typedef logic[MAX_INFLIGHT_COUNT-1:0] instruction_id_one_hot_t;
|
||||
typedef logic[1:0] branch_predictor_metadata_t;
|
||||
|
||||
typedef enum bit [6:0] {
|
||||
|
@ -273,6 +273,9 @@ package taiga_types;
|
|||
branch_predictor_metadata_t branch_metadata;
|
||||
logic branch_prediction_used;
|
||||
logic [BRANCH_PREDICTOR_WAYS-1:0] bp_update_way;
|
||||
logic alu_sub;
|
||||
logic [1:0] alu_logic_op;
|
||||
logic [1:0] alu_op;
|
||||
} instruction_buffer_packet;
|
||||
|
||||
|
||||
|
@ -352,6 +355,7 @@ package taiga_types;
|
|||
logic load;
|
||||
logic store;
|
||||
logic load_store_forward;
|
||||
instruction_id_one_hot_t instruction_id_one_hot;
|
||||
instruction_id_t instruction_id;
|
||||
//exception support
|
||||
logic [31:0] pc;
|
||||
|
@ -370,6 +374,7 @@ package taiga_types;
|
|||
logic [XLEN-1:0] rs2;
|
||||
logic [1:0] op;
|
||||
logic reuse_result;
|
||||
instruction_id_one_hot_t instruction_id_one_hot;
|
||||
instruction_id_t instruction_id;
|
||||
} div_inputs_t;
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ module write_back(
|
|||
input logic rst,
|
||||
|
||||
input logic inorder,
|
||||
input logic gc_supress_writeback,
|
||||
|
||||
input logic instruction_issued_with_rd,
|
||||
input logic store_committed,
|
||||
|
@ -50,9 +49,7 @@ module write_back(
|
|||
inflight_instruction_packet packet_table [MAX_INFLIGHT_COUNT-1:0];
|
||||
|
||||
//aliases for write-back-interface signals
|
||||
logic [NUM_WB_UNITS-1:0] unit_done_next_cycle;
|
||||
instruction_id_t unit_instruction_id [NUM_WB_UNITS-1:0];
|
||||
logic [MAX_INFLIGHT_COUNT-1:0] per_unit_one_hot_id_done [NUM_WB_UNITS-1:0];
|
||||
logic [MAX_INFLIGHT_COUNT-1:0] unit_done_next_cycle [NUM_WB_UNITS-1:0];
|
||||
logic [XLEN-1:0] unit_rd [NUM_WB_UNITS-1:0];
|
||||
logic [NUM_WB_UNITS-1:0] accepted;
|
||||
/////
|
||||
|
@ -79,7 +76,6 @@ module write_back(
|
|||
generate
|
||||
for (i=0; i< NUM_WB_UNITS; i++) begin : interface_to_array_g
|
||||
assign unit_done_next_cycle[i] = unit_wb[i].done_next_cycle;
|
||||
assign unit_instruction_id[i] = unit_wb[i].instruction_id;
|
||||
assign unit_rd[i] = unit_wb[i].rd;
|
||||
assign unit_wb[i].accepted = accepted[i];
|
||||
assign unit_wb[i].writeback_instruction_id = retired_id_r;
|
||||
|
@ -105,6 +101,10 @@ module write_back(
|
|||
);
|
||||
|
||||
assign ti.issue_id = issue_id;
|
||||
always_comb begin
|
||||
ti.issue_id_one_hot = 0;
|
||||
ti.issue_id_one_hot[issue_id] = 1;
|
||||
end
|
||||
|
||||
//Inflight Instruction ID table
|
||||
//Stores unit id (in one-hot encoding), rd_addr and whether rd_addr is zero
|
||||
|
@ -115,26 +115,16 @@ module write_back(
|
|||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (instruction_issued_with_rd)
|
||||
if (ti.id_available)//instruction_issued_with_rd
|
||||
packet_table[issue_id] <= ti.inflight_packet;
|
||||
end
|
||||
//////////////////////
|
||||
|
||||
|
||||
//One-hot id done for each unit
|
||||
always_comb begin
|
||||
for (int i=0; i< NUM_WB_UNITS; i++) begin
|
||||
per_unit_one_hot_id_done[i] = 0;
|
||||
per_unit_one_hot_id_done[i][unit_instruction_id[i]] = unit_done_next_cycle[i];
|
||||
end
|
||||
end
|
||||
//Or together all unit done signals for the same ID.
|
||||
always_comb begin
|
||||
id_done_next = 0;
|
||||
for (int i=0; i<MAX_INFLIGHT_COUNT; i++) begin
|
||||
for (int j=0; j<NUM_WB_UNITS; j++) begin
|
||||
id_done_next[i] |= per_unit_one_hot_id_done[j][i];
|
||||
end
|
||||
for (int i=0; i< NUM_WB_UNITS; i++) begin
|
||||
id_done_next |= unit_done_next_cycle[i];
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -191,7 +181,8 @@ module write_back(
|
|||
//Register file interaction
|
||||
assign rf_wb.rd_addr = retired_instruction_packet.rd_addr;
|
||||
assign rf_wb.id = retired_id_r;
|
||||
assign rf_wb.valid_write = retired_r & retired_instruction_packet.rd_addr_nzero & ~gc_supress_writeback;
|
||||
assign rf_wb.valid_write = retired_r;
|
||||
assign rf_wb.rd_nzero = retired_instruction_packet.rd_addr_nzero;
|
||||
|
||||
always_comb begin
|
||||
rf_wb.rd_data = 0;
|
||||
|
@ -200,9 +191,6 @@ module write_back(
|
|||
end
|
||||
end
|
||||
|
||||
assign rf_wb.rs1_data_out = ({32{rf_wb.forward_rs1}} & rf_wb.rd_data) | rf_wb.rs1_data_in;
|
||||
assign rf_wb.rs2_data_out = ({32{rf_wb.forward_rs2}} & rf_wb.rd_data) | rf_wb.rs2_data_in;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
////////////////////////////////////////////////////
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue