mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-20 12:07:53 -04:00
Removed branch unit as a write-back unit. Refactored pre-decode logic into its own file
This commit is contained in:
parent
ce1dea3d1d
commit
d79aba9d23
10 changed files with 277 additions and 240 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017, 2018 Eric Matthews, Lesley Shannon
|
||||
* Copyright © 2017-2019 Eric Matthews, Lesley Shannon
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -33,8 +33,6 @@ module branch_unit(
|
|||
ras_interface.branch_unit ras,
|
||||
output branch_flush,
|
||||
|
||||
unit_writeback_interface.unit branch_wb,
|
||||
|
||||
//Trace signals
|
||||
output logic tr_branch_misspredict,
|
||||
output logic tr_return_misspredict
|
||||
|
@ -48,8 +46,6 @@ module branch_unit(
|
|||
logic [31:0] jump_base;
|
||||
logic [31:0] jump_pc_dec;
|
||||
|
||||
logic [31:0] pc_plus_4;
|
||||
|
||||
logic signed [32:0] rs1_sext;
|
||||
logic signed [32:0] rs2_sext;
|
||||
logic signed [30:0] sub_toss;
|
||||
|
@ -86,6 +82,7 @@ module branch_unit(
|
|||
instruction_id_t id;
|
||||
//implementation
|
||||
////////////////////////////////////////////////////
|
||||
assign branch_ex.ready = 1;
|
||||
|
||||
branch_comparator bc (
|
||||
.use_signed(branch_inputs.use_signed),
|
||||
|
@ -119,8 +116,6 @@ module branch_unit(
|
|||
end
|
||||
|
||||
assign jump_pc_dec = jump_base + pc_offset;
|
||||
assign pc_plus_4 = branch_inputs.dec_pc + 4;
|
||||
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
fn3_ex <= branch_inputs.fn3;
|
||||
|
@ -128,13 +123,12 @@ module branch_unit(
|
|||
jump_ex <= (branch_inputs.jal | branch_inputs.jalr);
|
||||
end
|
||||
|
||||
|
||||
//Predictor support
|
||||
////////////////////////////////////////////////////
|
||||
always_ff @(posedge clk) begin
|
||||
pc_ex <= branch_inputs.dec_pc;
|
||||
jump_pc <= {jump_pc_dec[31:1], 1'b0};
|
||||
njump_pc <= pc_plus_4;
|
||||
njump_pc <= branch_inputs.dec_pc + 4;
|
||||
branch_metadata <= branch_inputs.branch_metadata;
|
||||
branch_prediction_used <= branch_inputs.branch_prediction_used;
|
||||
bp_update_way <= branch_inputs.bp_update_way;
|
||||
|
@ -171,19 +165,6 @@ module branch_unit(
|
|||
assign ras.new_addr = njump_pc;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Output bank
|
||||
assign new_jal_jalr_dec_with_rd = branch_ex.new_request_dec & branch_inputs.uses_rd;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
if (new_jal_jalr_dec_with_rd)
|
||||
rd_bank[branch_ex.instruction_id] <= pc_plus_4;
|
||||
end
|
||||
|
||||
assign branch_ex.ready = 1;
|
||||
assign branch_wb.rd = rd_bank[branch_wb.writeback_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
|
||||
////////////////////////////////////////////////////
|
||||
|
|
133
core/decode.sv
133
core/decode.sv
|
@ -27,7 +27,10 @@ module decode(
|
|||
input logic clk,
|
||||
input logic rst,
|
||||
|
||||
instruction_buffer_interface.decode ib,
|
||||
output logic pre_decode_pop,
|
||||
input logic fb_valid,
|
||||
input fetch_buffer_packet_t fb,
|
||||
|
||||
tracking_interface.decode ti,
|
||||
register_file_decode_interface.decode rf_decode,
|
||||
|
||||
|
@ -94,10 +97,10 @@ module decode(
|
|||
|
||||
logic mult_div_op;
|
||||
|
||||
logic [NUM_WB_UNITS-1:0] new_request;
|
||||
logic [NUM_UNITS-1:0] new_request;
|
||||
logic [WB_UNITS_WIDTH-1:0] new_request_int;
|
||||
logic [NUM_WB_UNITS-1:0] issue_ready;
|
||||
logic [NUM_WB_UNITS-1:0] issue;
|
||||
logic [NUM_UNITS-1:0] issue_ready;
|
||||
logic [NUM_UNITS-1:0] issue;
|
||||
|
||||
logic instruction_issued;
|
||||
|
||||
|
@ -111,20 +114,20 @@ module decode(
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Instruction Buffer / Instruction aliases
|
||||
assign ib.pop = instruction_issued;
|
||||
assign pre_decode_pop = instruction_issued;
|
||||
|
||||
assign opcode = ib.data_out.instruction[6:0];
|
||||
assign opcode = fb.instruction[6:0];
|
||||
assign opcode_trim = opcode[6:2];
|
||||
assign fn3 = ib.data_out.instruction[14:12];
|
||||
assign fn3 = fb.instruction[14:12];
|
||||
|
||||
assign uses_rs1 = ib.data_out.uses_rs1;
|
||||
assign uses_rs2 = ib.data_out.uses_rs2;
|
||||
assign uses_rd = ib.data_out.uses_rd;
|
||||
assign rd_zero = ib.data_out.rd_zero;
|
||||
assign uses_rs1 = fb.uses_rs1;
|
||||
assign uses_rs2 = fb.uses_rs2;
|
||||
assign uses_rd = fb.uses_rd;
|
||||
assign rd_zero = fb.rd_zero;
|
||||
|
||||
assign rs1_addr = ib.data_out.instruction[19:15];
|
||||
assign rs2_addr = ib.data_out.instruction[24:20];
|
||||
assign future_rd_addr = ib.data_out.instruction[11:7];
|
||||
assign rs1_addr = fb.instruction[19:15];
|
||||
assign rs2_addr = fb.instruction[24:20];
|
||||
assign future_rd_addr = fb.instruction[11:7];
|
||||
assign nop = (opcode_trim inside {LUI_T, AUIPC_T, ARITH_T, ARITH_IMM_T} && rd_zero);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -144,13 +147,13 @@ module decode(
|
|||
assign ti.inflight_packet.rd_addr = future_rd_addr;
|
||||
assign ti.inflight_packet.rd_addr_nzero = ~rd_zero;
|
||||
assign ti.issued = instruction_issued & (uses_rd | new_request[LS_UNIT_WB_ID]);
|
||||
one_hot_to_integer #(NUM_WB_UNITS) new_request_to_int (.*, .one_hot(new_request), .int_out(ti.inflight_packet.unit_id));
|
||||
one_hot_to_integer #(NUM_WB_UNITS) new_request_to_int (.*, .one_hot(new_request[NUM_WB_UNITS-1:0]), .int_out(ti.inflight_packet.unit_id));
|
||||
////////////////////////////////////////////////////
|
||||
//Unit Determination
|
||||
assign mult_div_op = ib.data_out.instruction[25];
|
||||
assign mult_div_op = fb.instruction[25];
|
||||
|
||||
assign new_request[BRANCH_UNIT_WB_ID] = opcode_trim inside {BRANCH_T, JAL_T, JALR_T};
|
||||
assign new_request[ALU_UNIT_WB_ID] = ((opcode_trim == ARITH_T) && ~mult_div_op) || opcode_trim inside {ARITH_IMM_T, AUIPC_T, LUI_T};
|
||||
assign new_request[BRANCH_UNIT_ID] = opcode_trim inside {BRANCH_T, JAL_T, JALR_T};
|
||||
assign new_request[ALU_UNIT_WB_ID] = fb.alu_request;
|
||||
assign new_request[LS_UNIT_WB_ID] = opcode_trim inside {LOAD_T, STORE_T, AMO_T};
|
||||
assign new_request[GC_UNIT_WB_ID] = opcode_trim inside {SYSTEM_T, FENCE_T};
|
||||
|
||||
|
@ -166,7 +169,7 @@ module decode(
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Unit ready
|
||||
assign issue_ready[BRANCH_UNIT_WB_ID] = new_request[BRANCH_UNIT_WB_ID] & branch_ex.ready;
|
||||
assign issue_ready[BRANCH_UNIT_ID] = new_request[BRANCH_UNIT_ID] & branch_ex.ready;
|
||||
assign issue_ready[ALU_UNIT_WB_ID] = new_request[ALU_UNIT_WB_ID] & alu_ex.ready;
|
||||
assign issue_ready[LS_UNIT_WB_ID] = new_request[LS_UNIT_WB_ID] & ls_ex.ready;
|
||||
assign issue_ready[GC_UNIT_WB_ID] = new_request[GC_UNIT_WB_ID] & gc_ex.ready;
|
||||
|
@ -180,12 +183,12 @@ module decode(
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Issue Determination
|
||||
assign issue_valid = ib.valid & ti.id_available & ~gc_issue_hold & ~gc_fetch_flush;
|
||||
assign issue_valid = fb_valid & ti.id_available & ~gc_issue_hold & ~gc_fetch_flush;
|
||||
|
||||
assign operands_ready = ~rf_decode.rs1_conflict & ~rf_decode.rs2_conflict;
|
||||
assign load_store_operands_ready = ~rf_decode.rs1_conflict & (~rf_decode.rs2_conflict | (rf_decode.rs2_conflict & load_store_forward_possible));
|
||||
|
||||
assign issue[BRANCH_UNIT_WB_ID] = issue_valid & operands_ready & issue_ready[BRANCH_UNIT_WB_ID];
|
||||
assign issue[BRANCH_UNIT_ID] = issue_valid & operands_ready & issue_ready[BRANCH_UNIT_ID];
|
||||
assign issue[ALU_UNIT_WB_ID] = issue_valid & operands_ready & issue_ready[ALU_UNIT_WB_ID];
|
||||
assign issue[LS_UNIT_WB_ID] = issue_valid & load_store_operands_ready & issue_ready[LS_UNIT_WB_ID];
|
||||
assign issue[GC_UNIT_WB_ID] = issue_valid & operands_ready & issue_ready[GC_UNIT_WB_ID];
|
||||
|
@ -214,31 +217,28 @@ module decode(
|
|||
logic [XLEN-1:0] alu_rs2_data;
|
||||
|
||||
always_comb begin
|
||||
if (opcode[2] & opcode[5]) //LUI
|
||||
alu_rs1_data = '0;
|
||||
else if (opcode[2] & ~opcode[5])//AUIPC
|
||||
alu_rs1_data = ib.data_out.pc;
|
||||
else
|
||||
alu_rs1_data = rf_decode.rs1_data;
|
||||
end
|
||||
case(fb.alu_rs1_sel)
|
||||
ALU_RS1_ZERO : alu_rs1_data = '0;
|
||||
ALU_RS1_PC : alu_rs1_data = fb.pc;
|
||||
default : alu_rs1_data = rf_decode.rs1_data; //ALU_RS1_RF
|
||||
endcase
|
||||
|
||||
always_comb begin
|
||||
if (opcode[2])//LUI or AUIPC
|
||||
alu_rs2_data = {ib.data_out.instruction[31:12], 12'b0};
|
||||
else if (~opcode[5]) //ARITH_IMM
|
||||
alu_rs2_data = 32'(signed'(ib.data_out.instruction[31:20]));
|
||||
else// ARITH instructions
|
||||
alu_rs2_data = rf_decode.rs2_data;
|
||||
case(fb.alu_rs2_sel)
|
||||
ALU_RS2_LUI_AUIPC : alu_rs2_data = {fb.instruction[31:12], 12'b0};
|
||||
ALU_RS2_ARITH_IMM : alu_rs2_data = 32'(signed'(fb.instruction[31:20]));
|
||||
ALU_RS2_JAL_JALR : alu_rs2_data = 4;
|
||||
ALU_RS2_RF : alu_rs2_data = rf_decode.rs2_data;
|
||||
endcase
|
||||
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.subtract = fb.alu_sub;
|
||||
assign alu_inputs.arith = alu_rs1_data[XLEN-1] & fb.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;
|
||||
assign alu_inputs.logic_op = fb.alu_logic_op;
|
||||
assign alu_inputs.op = fb.alu_op;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Load Store unit inputs
|
||||
|
@ -251,7 +251,7 @@ module decode(
|
|||
logic [4:0] amo_type;
|
||||
|
||||
assign amo_op = USE_AMO ? (opcode_trim == AMO_T) : 1'b0;
|
||||
assign amo_type = ib.data_out.instruction[31:27];
|
||||
assign amo_type = fb.instruction[31:27];
|
||||
assign store_conditional = (amo_type == AMO_SC);
|
||||
assign load_reserve = (amo_type == AMO_LR);
|
||||
|
||||
|
@ -267,12 +267,12 @@ module decode(
|
|||
endgenerate
|
||||
|
||||
assign ls_is_load = (opcode_trim inside {LOAD_T, AMO_T}) && !(amo_op & store_conditional); //LR and AMO_ops perform a read operation as well
|
||||
assign ls_offset = opcode[5] ? {ib.data_out.instruction[31:25], ib.data_out.instruction[11:7]} : ib.data_out.instruction[31:20];
|
||||
assign ls_offset = opcode[5] ? {fb.instruction[31:25], fb.instruction[11:7]} : fb.instruction[31:20];
|
||||
|
||||
assign ls_inputs.offset = ls_offset;
|
||||
assign ls_inputs.virtual_address = rf_decode.rs1_data + 32'(signed'(ls_offset));
|
||||
assign ls_inputs.rs2 = rf_decode.rs2_data;
|
||||
assign ls_inputs.pc = ib.data_out.pc;
|
||||
assign ls_inputs.pc = fb.pc;
|
||||
assign ls_inputs.fn3 = amo_op ? LS_W_fn3 : fn3;
|
||||
assign ls_inputs.load = ls_is_load;
|
||||
assign ls_inputs.store = (opcode_trim == STORE_T) || (amo_op && store_conditional);
|
||||
|
@ -303,40 +303,39 @@ module decode(
|
|||
assign branch_inputs.rs1 = rf_decode.rs1_data;
|
||||
assign branch_inputs.rs2 = rf_decode.rs2_data;
|
||||
assign branch_inputs.fn3 = fn3;
|
||||
assign branch_inputs.dec_pc = ib.data_out.pc;
|
||||
assign branch_inputs.dec_pc_valid = ib.valid;
|
||||
assign branch_inputs.dec_pc = fb.pc;
|
||||
assign branch_inputs.dec_pc_valid = fb_valid;
|
||||
assign branch_inputs.use_signed = !(fn3 inside {BLTU_fn3, BGEU_fn3});
|
||||
assign branch_inputs.jal = opcode[3];//(opcode == JAL);
|
||||
assign branch_inputs.jalr = ~opcode[3] & opcode[2];//(opcode == JALR);
|
||||
assign branch_inputs.uses_rd = uses_rd;//not (future_rd_addr == 0); jal jalr x0
|
||||
assign branch_inputs.is_call = ib.data_out.is_call;
|
||||
assign branch_inputs.is_return = ib.data_out.is_return;
|
||||
assign branch_inputs.instruction = ib.data_out.instruction;
|
||||
assign branch_inputs.branch_metadata = ib.data_out.branch_metadata;
|
||||
assign branch_inputs.branch_prediction_used = ib.data_out.branch_prediction_used;
|
||||
assign branch_inputs.bp_update_way = ib.data_out.bp_update_way;
|
||||
assign branch_inputs.is_call = fb.is_call;
|
||||
assign branch_inputs.is_return = fb.is_return;
|
||||
assign branch_inputs.instruction = fb.instruction;
|
||||
assign branch_inputs.branch_metadata = fb.branch_metadata;
|
||||
assign branch_inputs.branch_prediction_used = fb.branch_prediction_used;
|
||||
assign branch_inputs.bp_update_way = fb.bp_update_way;
|
||||
////////////////////////////////////////////////////
|
||||
//Global Control unit inputs
|
||||
logic sfence;
|
||||
logic ifence;
|
||||
logic environment_op;
|
||||
assign sfence = ib.data_out.instruction[25];
|
||||
assign sfence = fb.instruction[25];
|
||||
assign ifence = (opcode_trim == FENCE_T) && fn3[0];
|
||||
assign environment_op = (opcode_trim == SYSTEM_T) && (fn3 == 0);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (issue_ready[GC_UNIT_WB_ID]) begin
|
||||
gc_inputs.pc <= ib.data_out.pc;
|
||||
gc_inputs.instruction <= ib.data_out.instruction;
|
||||
gc_inputs.pc <= fb.pc;
|
||||
gc_inputs.instruction <= fb.instruction;
|
||||
gc_inputs.rs1 <= rf_decode.rs1_data;
|
||||
gc_inputs.rs2 <= rf_decode.rs2_data;
|
||||
gc_inputs.rd_is_zero <= rd_zero;
|
||||
gc_inputs.is_fence <= (opcode_trim == FENCE_T) && ~fn3[0];
|
||||
gc_inputs.is_csr <= (opcode_trim == SYSTEM_T) && (fn3 != 0);
|
||||
end
|
||||
gc_inputs.is_ecall <= issue[GC_UNIT_WB_ID] && environment_op && (ib.data_out.instruction[21:20] == 0);
|
||||
gc_inputs.is_ebreak <= issue[GC_UNIT_WB_ID] && environment_op && (ib.data_out.instruction[21:20] == 2'b01);
|
||||
gc_inputs.is_ret <= issue[GC_UNIT_WB_ID] && environment_op && (ib.data_out.instruction[21:20] == 2'b10);
|
||||
gc_inputs.is_ecall <= issue[GC_UNIT_WB_ID] && environment_op && (fb.instruction[21:20] == 0);
|
||||
gc_inputs.is_ebreak <= issue[GC_UNIT_WB_ID] && environment_op && (fb.instruction[21:20] == 2'b01);
|
||||
gc_inputs.is_ret <= issue[GC_UNIT_WB_ID] && environment_op && (fb.instruction[21:20] == 2'b10);
|
||||
gc_inputs.is_i_fence <= issue[GC_UNIT_WB_ID] && ifence;
|
||||
end
|
||||
assign gc_flush_required = issue[GC_UNIT_WB_ID] && (environment_op | ifence);
|
||||
|
@ -405,13 +404,13 @@ module decode(
|
|||
//Unit EX signals
|
||||
assign alu_ex.new_request_dec = issue[ALU_UNIT_WB_ID];
|
||||
assign ls_ex.new_request_dec = issue[LS_UNIT_WB_ID];
|
||||
assign branch_ex.new_request_dec = issue[BRANCH_UNIT_WB_ID];
|
||||
assign branch_ex.new_request_dec = issue[BRANCH_UNIT_ID];
|
||||
assign gc_ex.new_request_dec = issue[GC_UNIT_WB_ID];
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
alu_ex.new_request <= issue[ALU_UNIT_WB_ID];
|
||||
ls_ex.new_request <= issue[LS_UNIT_WB_ID];
|
||||
branch_ex.new_request <= issue[BRANCH_UNIT_WB_ID];
|
||||
branch_ex.new_request <= issue[BRANCH_UNIT_ID];
|
||||
gc_ex.new_request <= issue[GC_UNIT_WB_ID];
|
||||
end
|
||||
|
||||
|
@ -441,7 +440,7 @@ module decode(
|
|||
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] & ti.id_available;
|
||||
assign branch_ex.possible_issue = new_request[BRANCH_UNIT_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;
|
||||
|
@ -453,11 +452,11 @@ module decode(
|
|||
illegal_instruction = !(opcode inside {LUI, AUIPC, JAL, JALR, BRANCH, LOAD, STORE, ARITH, ARITH_IMM, FENCE, AMO, SYSTEM});
|
||||
if (opcode == ARITH) begin
|
||||
if (!USE_MUL && !USE_DIV)
|
||||
illegal_instruction = ib.data_out.instruction[25];
|
||||
illegal_instruction = fb.instruction[25];
|
||||
else if (!USE_MUL && USE_DIV)
|
||||
illegal_instruction = ib.data_out.instruction[25] & ~fn3[2];
|
||||
illegal_instruction = fb.instruction[25] & ~fn3[2];
|
||||
else if (!USE_MUL && !USE_DIV)
|
||||
illegal_instruction = ib.data_out.instruction[25] & fn3[2];
|
||||
illegal_instruction = fb.instruction[25] & fn3[2];
|
||||
else
|
||||
illegal_instruction = 0;
|
||||
end
|
||||
|
@ -474,13 +473,13 @@ module decode(
|
|||
//Trace Interface
|
||||
assign tr_operand_stall = (|issue_ready) & issue_valid & ~load_store_operands_ready;
|
||||
assign tr_unit_stall = ~(|issue_ready) & issue_valid & load_store_operands_ready;
|
||||
assign tr_no_id_stall = (|issue_ready) & (ib.valid & ~ti.id_available & ~gc_issue_hold & ~gc_fetch_flush) & load_store_operands_ready;
|
||||
assign tr_no_instruction_stall = ~ib.valid;
|
||||
assign tr_no_id_stall = (|issue_ready) & (fb_valid & ~ti.id_available & ~gc_issue_hold & ~gc_fetch_flush) & load_store_operands_ready;
|
||||
assign tr_no_instruction_stall = ~fb_valid;
|
||||
assign tr_other_stall = ~instruction_issued & ~(tr_operand_stall | tr_unit_stall | tr_no_id_stall | tr_no_instruction_stall);
|
||||
|
||||
assign tr_instruction_issued_dec = instruction_issued;
|
||||
assign tr_instruction_pc_dec = ib.data_out.pc;
|
||||
assign tr_instruction_data_dec = ib.data_out.instruction;
|
||||
assign tr_instruction_pc_dec = fb.pc;
|
||||
assign tr_instruction_data_dec = fb.instruction;
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
117
core/fetch.sv
117
core/fetch.sv
|
@ -42,7 +42,14 @@ module fetch(
|
|||
l1_arbiter_request_interface.master l1_request,
|
||||
l1_arbiter_return_interface.master l1_response,
|
||||
|
||||
instruction_buffer_interface.fetch ib
|
||||
input logic pre_decode_pop,
|
||||
|
||||
output logic [31:0] pre_decode_instruction,
|
||||
output logic [31:0] pre_decode_pc,
|
||||
output branch_predictor_metadata_t branch_metadata,
|
||||
output logic branch_prediction_used,
|
||||
output logic [BRANCH_PREDICTOR_WAYS-1:0] bp_update_way,
|
||||
output logic pre_decode_push
|
||||
);
|
||||
|
||||
localparam NUM_SUB_UNITS = USE_I_SCRATCH_MEM + USE_ICACHE;
|
||||
|
@ -66,6 +73,7 @@ module fetch(
|
|||
logic [31:0] next_pc;
|
||||
logic [31:0] if_pc;
|
||||
|
||||
logic[$clog2(FETCH_BUFFER_DEPTH+1)-1:0] inflight_count;
|
||||
logic space_in_inst_buffer;
|
||||
logic mem_ready;
|
||||
logic new_mem_request;
|
||||
|
@ -81,19 +89,8 @@ module fetch(
|
|||
logic update_pc;
|
||||
|
||||
logic [31:0] final_instruction;
|
||||
logic [6:0] opcode;
|
||||
logic [4:0] opcode_trimmed;
|
||||
logic [4:0] rs1_addr;
|
||||
logic [4:0] rs2_addr;
|
||||
logic [4:0] rd_addr;
|
||||
logic [2:0] fn3;
|
||||
|
||||
logic csr_imm_op;
|
||||
logic sys_op;
|
||||
logic jal_jalr_x0;
|
||||
|
||||
logic rs1_link, rd_link, rs1_eq_rd, use_ras;
|
||||
logic[$clog2(FETCH_BUFFER_DEPTH+1)-1:0] inflight_count;
|
||||
/////////////////////////////////////////
|
||||
|
||||
genvar i;
|
||||
|
@ -147,18 +144,18 @@ module fetch(
|
|||
always_ff @(posedge clk) begin
|
||||
if (rst | gc_fetch_flush)
|
||||
inflight_count <= 0;
|
||||
else if (mem_ready & ~ib.pop)
|
||||
else if (mem_ready & ~pre_decode_pop)
|
||||
inflight_count <= inflight_count + 1;
|
||||
else if (~mem_ready & ib.pop)
|
||||
else if (~mem_ready & pre_decode_pop)
|
||||
inflight_count <= inflight_count - 1;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst | gc_fetch_flush)
|
||||
space_in_inst_buffer <= 1;
|
||||
else if (mem_ready & ~ib.pop)
|
||||
else if (mem_ready & ~pre_decode_pop)
|
||||
space_in_inst_buffer <= inflight_count < (FETCH_BUFFER_DEPTH-1);
|
||||
else if (~mem_ready & ib.pop)
|
||||
else if (~mem_ready & pre_decode_pop)
|
||||
space_in_inst_buffer <= 1;
|
||||
end
|
||||
|
||||
|
@ -215,9 +212,6 @@ module fetch(
|
|||
|
||||
assign mem_valid = ~(gc_fetch_flush | delayed_flush);
|
||||
assign new_issue = mem_valid & (|unit_data_valid);
|
||||
assign ib.push = new_issue;
|
||||
assign ib.flush = gc_fetch_flush;
|
||||
|
||||
|
||||
//bitwise AND all subunit outputs with valid signal then or all outputs together
|
||||
always_comb begin
|
||||
|
@ -228,87 +222,18 @@ module fetch(
|
|||
end
|
||||
end
|
||||
|
||||
assign ib.data_in.instruction = final_instruction;
|
||||
assign ib.data_in.pc = stage2_phys_address;
|
||||
////////////////////////////////////////////////////
|
||||
//Pre-Decode Output
|
||||
assign pre_decode_instruction = final_instruction;
|
||||
assign pre_decode_pc = stage2_phys_address;
|
||||
assign pre_decode_push = new_issue;
|
||||
|
||||
///////////////////////////////////
|
||||
//Early decode
|
||||
///////////////////////////////////
|
||||
assign fn3 = final_instruction[14:12];
|
||||
assign opcode = final_instruction[6:0];
|
||||
assign opcode_trimmed = opcode[6:2];
|
||||
|
||||
assign rs1_addr = final_instruction[19:15];
|
||||
assign rs2_addr = final_instruction[24:20];
|
||||
assign rd_addr = final_instruction[11:7];
|
||||
|
||||
assign csr_imm_op = (opcode_trimmed == SYSTEM_T) && fn3[2];
|
||||
assign sys_op = (opcode_trimmed == SYSTEM_T) && (fn3 == 0);
|
||||
|
||||
assign jal_jalr_x0 = (opcode_trimmed inside {JAL_T, JALR_T}) && (rd_addr == 0);
|
||||
|
||||
//RAS support ///////////////////
|
||||
assign rs1_link = (rs1_addr inside {1,5});
|
||||
assign rd_link = (rd_addr inside {1,5});
|
||||
assign rs1_eq_rd = (rs1_addr == rd_addr);
|
||||
assign use_ras = (opcode_trimmed == JALR_T) && ((rs1_link & ~rd_link) | (rs1_link & rd_link & ~rs1_eq_rd));
|
||||
///////////////////////////////////
|
||||
|
||||
//Output FIFO
|
||||
assign ib.data_in.uses_rs1 = !(opcode_trimmed inside {LUI_T, AUIPC_T, JAL_T, FENCE_T} || csr_imm_op || sys_op);
|
||||
assign ib.data_in.uses_rs2 = opcode_trimmed inside {BRANCH_T, STORE_T, ARITH_T, AMO_T};
|
||||
assign ib.data_in.uses_rd = !(opcode_trimmed inside {BRANCH_T, STORE_T, FENCE_T} || sys_op || jal_jalr_x0);
|
||||
assign ib.data_in.rd_zero = (rd_addr == 0);
|
||||
|
||||
assign ib.data_in.is_return = use_ras;
|
||||
assign ib.data_in.is_call = (opcode_trimmed inside {JAL_T, JALR_T}) && rd_link;
|
||||
|
||||
logic [1:0] branch_metadata_r;
|
||||
logic prediction_used;
|
||||
logic [BRANCH_PREDICTOR_WAYS-1:0] update_way;
|
||||
always_ff @(posedge clk) begin
|
||||
if (new_mem_request) begin
|
||||
branch_metadata_r <= bp.metadata;
|
||||
prediction_used <= bp.use_prediction;
|
||||
update_way <= bp.update_way;
|
||||
branch_metadata <= bp.metadata;
|
||||
branch_prediction_used <= bp.use_prediction;
|
||||
bp_update_way <= bp.update_way;
|
||||
end
|
||||
end
|
||||
assign ib.data_in.branch_metadata = branch_metadata_r;
|
||||
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
|
||||
|
|
|
@ -161,23 +161,6 @@ interface tracking_interface;
|
|||
modport wb (output issue_id, id_available, issue_id_one_hot, input inflight_packet, issued);
|
||||
endinterface
|
||||
|
||||
|
||||
interface instruction_buffer_interface;
|
||||
logic push;
|
||||
logic pop;
|
||||
logic flush;
|
||||
instruction_buffer_packet data_in;
|
||||
instruction_buffer_packet data_out;
|
||||
logic valid;
|
||||
logic full;
|
||||
|
||||
modport buffer (input push, pop, flush, data_in, output data_out, valid, full);
|
||||
modport fetch (input full, pop, output push, data_in, flush);
|
||||
modport decode (input valid, data_out, output pop);
|
||||
//modport exception_control (output flush);
|
||||
endinterface
|
||||
|
||||
|
||||
interface fifo_interface #(parameter DATA_WIDTH = 42);//#(parameter type data_type = logic[31:0]);
|
||||
logic push;
|
||||
logic pop;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2017 Eric Matthews, Lesley Shannon
|
||||
* Copyright © 2017-2019 Eric Matthews, Lesley Shannon
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -23,43 +23,172 @@
|
|||
import taiga_config::*;
|
||||
import taiga_types::*;
|
||||
|
||||
//Circular buffer for instruction buffer. Isolates push and pop signals so that critical paths can be separated
|
||||
module instruction_buffer
|
||||
module pre_decode
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
instruction_buffer_interface.buffer ib
|
||||
|
||||
//Fetch
|
||||
input logic [31:0] pre_decode_instruction,
|
||||
input logic [31:0] pre_decode_pc,
|
||||
input branch_predictor_metadata_t branch_metadata,
|
||||
input logic branch_prediction_used,
|
||||
input logic [BRANCH_PREDICTOR_WAYS-1:0] bp_update_way,
|
||||
input logic pre_decode_push,
|
||||
|
||||
//Global Control
|
||||
input logic gc_fetch_flush,
|
||||
|
||||
//Decode
|
||||
input logic pre_decode_pop,
|
||||
output logic fb_valid,
|
||||
output fetch_buffer_packet_t fb
|
||||
);
|
||||
|
||||
logic buffer_reset;
|
||||
fifo_interface #(.DATA_WIDTH($bits(instruction_buffer_packet))) ib_fifo();
|
||||
|
||||
logic [6:0] opcode;
|
||||
logic [4:0] opcode_trimmed;
|
||||
logic [4:0] rs1_addr;
|
||||
logic [4:0] rs2_addr;
|
||||
logic [4:0] rd_addr;
|
||||
logic [2:0] fn3;
|
||||
|
||||
logic csr_imm_op;
|
||||
logic sys_op;
|
||||
logic jal_jalr_x0;
|
||||
|
||||
logic rs1_link, rd_link, rs1_eq_rd, use_ras;
|
||||
|
||||
fetch_buffer_packet_t data_in;
|
||||
fifo_interface #(.DATA_WIDTH($bits(fetch_buffer_packet_t))) fb_fifo();
|
||||
|
||||
//implementation
|
||||
////////////////////////////////////////////////////
|
||||
//Control signals
|
||||
//implementation
|
||||
//FIFO
|
||||
assign buffer_reset = rst | gc_fetch_flush;
|
||||
|
||||
assign buffer_reset = rst | ib.flush;
|
||||
|
||||
assign ib_fifo.push = ib.push;
|
||||
assign ib_fifo.pop = ib.pop;
|
||||
assign ib_fifo.data_in = ib.data_in;
|
||||
|
||||
assign ib.data_out = ib_fifo.data_out;
|
||||
|
||||
assign ib.valid = ib_fifo.valid;
|
||||
assign ib.full = ib_fifo.full;
|
||||
assign fb_fifo.push = pre_decode_push;
|
||||
assign fb_fifo.pop = pre_decode_pop;
|
||||
assign fb_fifo.data_in = data_in;
|
||||
assign fb = fb_fifo.data_out;
|
||||
assign fb_valid = fb_fifo.valid;
|
||||
|
||||
taiga_fifo #(
|
||||
.DATA_WIDTH($bits(instruction_buffer_packet)),
|
||||
.DATA_WIDTH($bits(fetch_buffer_packet_t)),
|
||||
.FIFO_DEPTH(FETCH_BUFFER_DEPTH),
|
||||
.FIFO_TYPE(LUTRAM_FIFO)
|
||||
) ib_fifo_block (.fifo(ib_fifo), .rst(buffer_reset), .*);
|
||||
) fb_fifo_block (.fifo(fb_fifo), .rst(buffer_reset), .*);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Pre-Decode
|
||||
assign data_in.instruction = pre_decode_instruction;
|
||||
assign data_in.pc = pre_decode_pc;
|
||||
|
||||
//Instruction components
|
||||
assign fn3 = pre_decode_instruction[14:12];
|
||||
assign opcode = pre_decode_instruction[6:0];
|
||||
assign opcode_trimmed = opcode[6:2];
|
||||
|
||||
assign rs1_addr = pre_decode_instruction[19:15];
|
||||
assign rs2_addr = pre_decode_instruction[24:20];
|
||||
assign rd_addr = pre_decode_instruction[11:7];
|
||||
|
||||
assign csr_imm_op = (opcode_trimmed == SYSTEM_T) && fn3[2];
|
||||
assign sys_op = (opcode_trimmed == SYSTEM_T) && (fn3 == 0);
|
||||
|
||||
assign jal_jalr_x0 = (opcode_trimmed inside {JAL_T, JALR_T}) && (rd_addr == 0);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//RAS Support
|
||||
assign rs1_link = (rs1_addr inside {1,5});
|
||||
assign rd_link = (rd_addr inside {1,5});
|
||||
assign rs1_eq_rd = (rs1_addr == rd_addr);
|
||||
assign use_ras = (opcode_trimmed == JALR_T) && ((rs1_link & ~rd_link) | (rs1_link & rd_link & ~rs1_eq_rd));
|
||||
assign data_in.is_return = use_ras;
|
||||
assign data_in.is_call = (opcode_trimmed inside {JAL_T, JALR_T}) && rd_link;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Register File Support
|
||||
assign data_in.uses_rs1 = !(opcode_trimmed inside {LUI_T, AUIPC_T, JAL_T, FENCE_T} || csr_imm_op || sys_op);
|
||||
assign data_in.uses_rs2 = opcode_trimmed inside {BRANCH_T, STORE_T, ARITH_T, AMO_T};
|
||||
assign data_in.uses_rd = !(opcode_trimmed inside {BRANCH_T, STORE_T, FENCE_T} || sys_op || jal_jalr_x0);
|
||||
assign data_in.rd_zero = (rd_addr == 0);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Branch Predictor support
|
||||
assign data_in.branch_metadata = branch_metadata;
|
||||
assign data_in.branch_prediction_used = branch_prediction_used;
|
||||
assign data_in.bp_update_way = bp_update_way;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//ALU Control Signals
|
||||
//Add cases: JAL, JALR, LUI, AUIPC, ADD[I], all logic ops
|
||||
//sub cases: SUB, SLT[U][I]
|
||||
logic sub_instruction;
|
||||
assign sub_instruction = (fn3 == ADD_SUB_fn3) && pre_decode_instruction[30] && opcode[5];//If ARITH instruction
|
||||
assign data_in.alu_sub = ~opcode[2] & (fn3 inside {SLTU_fn3, SLT_fn3} || sub_instruction);//opcode[2] covers LUI,AUIPC,JAL,JALR
|
||||
|
||||
always_comb begin
|
||||
case (fn3)
|
||||
SLT_fn3 : data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
SLTU_fn3 : data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
SLL_fn3 : data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
XOR_fn3 : data_in.alu_logic_op = ALU_LOGIC_XOR;
|
||||
OR_fn3 : data_in.alu_logic_op = ALU_LOGIC_OR;
|
||||
AND_fn3 : data_in.alu_logic_op = ALU_LOGIC_AND;
|
||||
SRA_fn3 : data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
ADD_SUB_fn3 : data_in.alu_logic_op = ALU_LOGIC_ADD;
|
||||
endcase
|
||||
//put LUI, AUIPC, JAL and JALR through adder path
|
||||
data_in.alu_logic_op = opcode[2] ? ALU_LOGIC_ADD : data_in.alu_logic_op;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (fn3)
|
||||
SLT_fn3 : data_in.alu_op = ALU_SLT;
|
||||
SLTU_fn3 : data_in.alu_op = ALU_SLT;
|
||||
SLL_fn3 : data_in.alu_op = ALU_LSHIFT;
|
||||
XOR_fn3 : data_in.alu_op = ALU_ADD_SUB;
|
||||
OR_fn3 : data_in.alu_op = ALU_ADD_SUB;
|
||||
AND_fn3 : data_in.alu_op = ALU_ADD_SUB;
|
||||
SRA_fn3 : data_in.alu_op = ALU_RSHIFT;
|
||||
ADD_SUB_fn3 : data_in.alu_op = ALU_ADD_SUB;
|
||||
endcase
|
||||
//put LUI, AUIPC, JAL and JALR through adder path
|
||||
data_in.alu_op = opcode[2] ? ALU_ADD_SUB : data_in.alu_op;
|
||||
end
|
||||
|
||||
logic non_zero_jal_jalr;
|
||||
logic non_mul_div_arith_op;
|
||||
assign non_zero_jal_jalr = (opcode_trimmed inside {JAL_T, JALR_T} && (rd_addr != 0));
|
||||
assign non_mul_div_arith_op = ((opcode_trimmed == ARITH_T) && ~pre_decode_instruction[25]);//pre_decode_instruction[25] denotes multiply/divide instructions
|
||||
assign data_in.alu_request = non_mul_div_arith_op || (opcode_trimmed inside {ARITH_IMM_T, AUIPC_T, LUI_T} || non_zero_jal_jalr);
|
||||
|
||||
always_comb begin
|
||||
if (opcode_trimmed inside {ARITH_T, ARITH_IMM_T})
|
||||
data_in.alu_rs1_sel = ALU_RS1_RF;
|
||||
else if (opcode_trimmed inside {JAL_T, JALR_T, AUIPC_T})//AUIPC JAL JALR
|
||||
data_in.alu_rs1_sel = ALU_RS1_PC;
|
||||
else
|
||||
data_in.alu_rs1_sel = ALU_RS1_ZERO;//LUI
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
if (opcode_trimmed inside {LUI_T, AUIPC_T}) //LUI or AUIPC
|
||||
data_in.alu_rs2_sel = ALU_RS2_LUI_AUIPC;
|
||||
else if (opcode_trimmed == ARITH_IMM_T) //ARITH_IMM
|
||||
data_in.alu_rs2_sel = ALU_RS2_ARITH_IMM;
|
||||
else if (non_zero_jal_jalr) //JAL JALR
|
||||
data_in.alu_rs2_sel = ALU_RS2_JAL_JALR;
|
||||
else
|
||||
data_in.alu_rs2_sel = ALU_RS2_RF;
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Assertions
|
||||
always_ff @ (posedge clk) begin
|
||||
assert (!(~rst & ib.flush & (ib.push | ib.pop))) else $error("ib push/pop during flush");
|
||||
assert (!(~rst & gc_fetch_flush & (pre_decode_push | pre_decode_pop))) else $error("fb push/pop during flush");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -68,8 +68,6 @@ module taiga (
|
|||
func_unit_ex_interface mul_ex();
|
||||
func_unit_ex_interface div_ex();
|
||||
|
||||
instruction_buffer_interface ib();
|
||||
|
||||
exception_packet_t ls_exception;
|
||||
logic ls_exception_valid;
|
||||
|
||||
|
@ -86,6 +84,17 @@ module taiga (
|
|||
logic [ASIDLEN-1:0] asid;
|
||||
logic return_from_exception;
|
||||
|
||||
//Pre-Decode
|
||||
logic pre_decode_push;
|
||||
logic pre_decode_pop;
|
||||
logic [31:0] pre_decode_instruction;
|
||||
logic [31:0] pre_decode_pc;
|
||||
branch_predictor_metadata_t branch_metadata;
|
||||
logic branch_prediction_used;
|
||||
logic [BRANCH_PREDICTOR_WAYS-1:0] bp_update_way;
|
||||
logic fb_valid;
|
||||
fetch_buffer_packet_t fb;
|
||||
|
||||
//Global Control
|
||||
logic load_store_FIFO_emptying;
|
||||
logic gc_issue_hold;
|
||||
|
@ -111,7 +120,6 @@ module taiga (
|
|||
logic jalr;
|
||||
|
||||
//Decode Unit and Fetch Unit
|
||||
logic dec_instruction_issued;
|
||||
logic illegal_instruction;
|
||||
|
||||
logic instruction_queue_empty;
|
||||
|
@ -160,7 +168,7 @@ module taiga (
|
|||
assign itlb.physical_address = itlb.virtual_address;
|
||||
end
|
||||
endgenerate
|
||||
instruction_buffer inst_buffer(.*);
|
||||
pre_decode pre_decode_block(.*);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Decode/Issue
|
||||
|
@ -169,7 +177,7 @@ module taiga (
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Execution Units
|
||||
branch_unit branch_unit_block (.*, .branch_wb(unit_wb[BRANCH_UNIT_WB_ID]));
|
||||
branch_unit branch_unit_block (.*);
|
||||
alu_unit alu_unit_block (.*, .alu_wb(unit_wb[ALU_UNIT_WB_ID]));
|
||||
load_store_unit load_store_unit_block (.*, .dcache_on(1'b1), .clear_reservation(1'b0), .tlb(dtlb), .ls_wb(unit_wb[LS_UNIT_WB_ID]), .l1_request(l1_request[L1_DCACHE_ID]), .l1_response(l1_response[L1_DCACHE_ID]));
|
||||
generate if (ENABLE_S_MODE) begin
|
||||
|
|
|
@ -184,16 +184,18 @@ package taiga_config;
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Write-Back Unit IDs
|
||||
parameter NUM_WB_UNITS = 4 + USE_MUL + USE_DIV;
|
||||
parameter NUM_WB_UNITS = 3 + USE_MUL + USE_DIV;
|
||||
parameter WB_UNITS_WIDTH = $clog2(NUM_WB_UNITS);
|
||||
|
||||
parameter NUM_UNITS = NUM_WB_UNITS + 1;
|
||||
|
||||
parameter ALU_UNIT_WB_ID = 0;
|
||||
parameter GC_UNIT_WB_ID = 1;
|
||||
parameter BRANCH_UNIT_WB_ID = 2;
|
||||
parameter LS_UNIT_WB_ID = 3;
|
||||
parameter LS_UNIT_WB_ID = 2;
|
||||
parameter DIV_UNIT_WB_ID = LS_UNIT_WB_ID + USE_DIV;
|
||||
parameter MUL_UNIT_WB_ID = DIV_UNIT_WB_ID + USE_MUL;
|
||||
//Non-writeback units
|
||||
parameter BRANCH_UNIT_ID = MUL_UNIT_WB_ID + 1;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -90,6 +90,19 @@ package taiga_types;
|
|||
ALU_LSHIFT =2'b11
|
||||
} alu_op_t;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
ALU_RS1_ZERO = 2'b00,
|
||||
ALU_RS1_PC = 2'b01,
|
||||
ALU_RS1_RF =2'b10
|
||||
} alu_rs1_op_t;
|
||||
|
||||
typedef enum bit [1:0] {
|
||||
ALU_RS2_LUI_AUIPC = 2'b00,
|
||||
ALU_RS2_ARITH_IMM = 2'b01,
|
||||
ALU_RS2_JAL_JALR = 2'b10,
|
||||
ALU_RS2_RF =2'b11
|
||||
} alu_rs2_op_t;
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
LS_B_fn3 = 3'b000,
|
||||
LS_H_fn3 = 3'b001,
|
||||
|
@ -276,7 +289,10 @@ package taiga_types;
|
|||
logic alu_sub;
|
||||
logic [1:0] alu_logic_op;
|
||||
logic [1:0] alu_op;
|
||||
} instruction_buffer_packet;
|
||||
logic alu_request;
|
||||
alu_rs1_op_t alu_rs1_sel;
|
||||
alu_rs2_op_t alu_rs2_sel;
|
||||
} fetch_buffer_packet_t;
|
||||
|
||||
|
||||
typedef struct packed{
|
||||
|
@ -299,7 +315,6 @@ package taiga_types;
|
|||
logic use_signed;
|
||||
logic jal;
|
||||
logic jalr;
|
||||
logic uses_rd;
|
||||
logic is_call;
|
||||
logic is_return;
|
||||
logic [31:0] instruction;
|
||||
|
@ -398,7 +413,6 @@ package taiga_types;
|
|||
logic is_ecall;
|
||||
logic is_ebreak;
|
||||
logic is_ret;
|
||||
logic flush_required;
|
||||
} gc_inputs_t;
|
||||
|
||||
typedef struct packed{
|
||||
|
|
|
@ -50,7 +50,7 @@ module write_back(
|
|||
|
||||
//aliases for write-back-interface signals
|
||||
logic [MAX_INFLIGHT_COUNT-1:0] unit_done_next_cycle [NUM_WB_UNITS-1:0];
|
||||
logic [XLEN-1:0] unit_rd [2**($clog2(NUM_WB_UNITS))-1:0];
|
||||
logic [XLEN-1:0] unit_rd [NUM_WB_UNITS-1:0];
|
||||
/////
|
||||
|
||||
instruction_id_t issue_id, retired_id, retired_id_r;
|
||||
|
@ -77,8 +77,6 @@ module write_back(
|
|||
assign unit_rd[i] = unit_wb[i].rd;
|
||||
assign unit_wb[i].writeback_instruction_id = retired_id_r;
|
||||
end
|
||||
assign unit_rd[6] = unit_rd[GC_UNIT_WB_ID];
|
||||
assign unit_rd[7] = unit_rd[ALU_UNIT_WB_ID];
|
||||
endgenerate
|
||||
|
||||
//ID stack. id_ordering[0] is the next ID to be issued. Entries filled from
|
||||
|
@ -177,10 +175,8 @@ module write_back(
|
|||
assign rf_wb.id = retired_id_r;
|
||||
assign rf_wb.valid_write = retired_r;
|
||||
assign rf_wb.rd_nzero = retired_instruction_packet.rd_addr_nzero;
|
||||
|
||||
assign rf_wb.rd_data = unit_rd[retired_instruction_packet.unit_id];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//End of Implementation
|
||||
////////////////////////////////////////////////////
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
../core/branch_predictor_ram.sv
|
||||
../core/branch_predictor.sv
|
||||
../core/fetch.sv
|
||||
../core/instruction_buffer.sv
|
||||
../core/pre_decode.sv
|
||||
../core/decode.sv
|
||||
|
||||
../core/inuse.sv
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue