alu writeback changes and writeback frequency improvements

This commit is contained in:
Eric Matthews 2019-08-19 14:51:54 -07:00
parent e41fb648be
commit 1ac97a8872
15 changed files with 148 additions and 178 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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