Decode/Issue unit-interface signal refactoring

This commit is contained in:
Eric Matthews 2019-08-29 13:44:48 -07:00
parent bf5c12af25
commit 227bbc1385
9 changed files with 94 additions and 135 deletions

View file

@ -26,8 +26,8 @@ import taiga_types::*;
module alu_unit(
input logic clk,
input logic rst,
func_unit_ex_interface.unit alu_ex,
unit_writeback_interface.unit alu_wb,
unit_issue_interface.unit issue,
unit_writeback_interface.unit wb,
input alu_inputs_t alu_inputs
);
@ -86,13 +86,13 @@ module alu_unit(
////////////////////////////////////////////////////
//Output bank
always_ff @ (posedge clk) begin
if (alu_ex.possible_issue)
rd_bank[alu_ex.instruction_id] <= result;
if (issue.possible_issue)
rd_bank[issue.instruction_id] <= result;
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 issue.ready = 1;
assign wb.rd = rd_bank[wb.writeback_instruction_id];
assign wb.done_next_cycle = issue.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{issue.new_request}};
////////////////////////////////////////////////////
//Assertions

View file

@ -27,12 +27,14 @@ module branch_unit(
input logic clk,
input logic rst,
func_unit_ex_interface.unit branch_ex,
unit_issue_interface.unit issue,
input branch_inputs_t branch_inputs,
output branch_results_t br_results,
ras_interface.branch_unit ras,
output branch_flush,
input branch_issued,
//Trace signals
output logic tr_branch_misspredict,
output logic tr_return_misspredict
@ -82,7 +84,7 @@ module branch_unit(
instruction_id_t id;
//implementation
////////////////////////////////////////////////////
assign branch_ex.ready = 1;
assign issue.ready = 1;
branch_comparator bc (
.use_signed(branch_inputs.use_signed),
@ -92,7 +94,7 @@ module branch_unit(
.result(result)
);
assign branch_taken = branch_ex.new_request & ((~jump_ex & (result_ex ^ fn3_ex[0])) | jump_ex);
assign branch_taken = branch_issued & ((~jump_ex & (result_ex ^ fn3_ex[0])) | jump_ex);
assign jal_imm = {branch_inputs.instruction[31], branch_inputs.instruction[19:12], branch_inputs.instruction[20], branch_inputs.instruction[30:21]};
@ -118,7 +120,7 @@ module branch_unit(
assign jump_pc_dec = jump_base + pc_offset;
always_ff @(posedge clk) begin
if (branch_ex.new_request_dec) begin
if (issue.new_request) begin
fn3_ex <= branch_inputs.fn3;
result_ex <= result;
jump_ex <= (branch_inputs.jal | branch_inputs.jalr);
@ -128,7 +130,7 @@ module branch_unit(
//Predictor support
////////////////////////////////////////////////////
always_ff @(posedge clk) begin
if (branch_ex.new_request_dec) begin
if (issue.new_request) begin
pc_ex <= branch_inputs.dec_pc;
jump_pc <= {jump_pc_dec[31:1], 1'b0};
njump_pc <= branch_inputs.dec_pc + 4;
@ -144,7 +146,7 @@ module branch_unit(
assign br_results.branch_ex_metadata = branch_metadata;
assign br_results.branch_taken = branch_taken;
assign br_results.branch_ex = branch_ex.new_request & branch_inputs.dec_pc_valid;
assign br_results.branch_ex = branch_issued & branch_inputs.dec_pc_valid;
assign br_results.is_return_ex = is_return;
assign br_results.branch_prediction_used = branch_prediction_used;
assign br_results.bp_update_way = bp_update_way;
@ -152,16 +154,16 @@ module branch_unit(
assign branch_correctly_taken = {br_results.branch_taken, branch_inputs.dec_pc[31:1]} == {1'b1, br_results.jump_pc[31:1]};
assign branch_correclty_not_taken = {br_results.branch_taken, branch_inputs.dec_pc[31:1]} == {1'b0, br_results.njump_pc[31:1]};
assign miss_predict = branch_ex.new_request && branch_inputs.dec_pc_valid && ~(branch_correctly_taken || branch_correclty_not_taken);
assign miss_predict = branch_issued && branch_inputs.dec_pc_valid && ~(branch_correctly_taken || branch_correclty_not_taken);
assign branch_flush = USE_BRANCH_PREDICTOR ? miss_predict : branch_ex.new_request & branch_taken & branch_inputs.dec_pc_valid;
assign branch_flush = USE_BRANCH_PREDICTOR ? miss_predict : branch_issued & branch_taken & branch_inputs.dec_pc_valid;
//RAS support
////////////////////////////////////////////////////
generate if (USE_BRANCH_PREDICTOR) begin
always_ff @(posedge clk) begin
is_call <= branch_ex.new_request_dec & branch_inputs.is_call;
is_return <= branch_ex.new_request_dec & branch_inputs.is_return;
is_call <= issue.new_request & branch_inputs.is_call;
is_return <= issue.new_request & branch_inputs.is_return;
end
assign ras.push = is_call;

View file

@ -41,17 +41,13 @@ module decode(
output mul_inputs_t mul_inputs,
output div_inputs_t div_inputs,
func_unit_ex_interface.decode alu_ex,
func_unit_ex_interface.decode ls_ex,
func_unit_ex_interface.decode branch_ex,
func_unit_ex_interface.decode gc_ex,
func_unit_ex_interface.decode mul_ex,
func_unit_ex_interface.decode div_ex,
unit_issue_interface.decode unit_issue [NUM_UNITS-1:0],
input logic gc_issue_hold,
input logic gc_fetch_flush,
input logic gc_issue_flush,
output logic gc_flush_required,
output logic branch_issued,
output logic load_store_issue,
@ -94,7 +90,7 @@ module decode(
logic issue_valid;
logic load_store_operands_ready;
logic operands_ready;
logic [NUM_UNITS-1:0] unit_operands_ready;
logic mult_div_op;
logic [NUM_WB_UNITS-1:0] new_request_for_id_gen;
@ -108,7 +104,7 @@ module decode(
logic valid_opcode;
instruction_id_t last_id;
genvar i;
////////////////////////////////////////////////////
//Implementation
@ -176,17 +172,11 @@ module decode(
////////////////////////////////////////////////////
//Unit 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_ID] = new_request[GC_UNIT_ID] & gc_ex.ready;
generate if (USE_MUL)
assign issue_ready[MUL_UNIT_WB_ID] = new_request[MUL_UNIT_WB_ID] & mul_ex.ready;
generate
for (i=0; i<NUM_UNITS; i++) begin
assign issue_ready[i] = new_request[i] & unit_issue[i].ready;
end
endgenerate
generate if (USE_DIV)
assign issue_ready[DIV_UNIT_WB_ID] = new_request[DIV_UNIT_WB_ID] & div_ex.ready;
endgenerate
////////////////////////////////////////////////////
//Issue Determination
@ -195,16 +185,13 @@ module decode(
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_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_ID] = issue_valid & operands_ready & issue_ready[GC_UNIT_ID];
generate if (USE_MUL)
assign issue[MUL_UNIT_WB_ID] = issue_valid & operands_ready & issue_ready[MUL_UNIT_WB_ID];
endgenerate
generate if (USE_DIV)
assign issue[DIV_UNIT_WB_ID] = issue_valid & operands_ready & issue_ready[DIV_UNIT_WB_ID];
endgenerate
//All units share the same operand ready logic except load-store which has an internal forwarding path
always_comb begin
unit_operands_ready = {NUM_UNITS{operands_ready}};
unit_operands_ready[LS_UNIT_WB_ID] = load_store_operands_ready;
end
assign issue = {NUM_UNITS{issue_valid}} & unit_operands_ready & issue_ready;
assign instruction_issued =
((LS_INPUT_BUFFER_DEPTH >= MAX_INFLIGHT_COUNT) &&
@ -321,6 +308,7 @@ module decode(
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;
@ -409,59 +397,29 @@ 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_ID];
assign gc_ex.new_request_dec = issue[GC_UNIT_ID];
generate
for(i = 0; i < NUM_UNITS; i++) begin
assign unit_issue[i].possible_issue = new_request[i] & ti.id_available;
assign unit_issue[i].new_request = issue[i];
assign unit_issue[i].instruction_id = ti.issue_id;
assign unit_issue[i].instruction_id_one_hot = ti.issue_id_one_hot;
always_ff @(posedge clk) begin
unit_issue[i].new_request_r = issue[i];
end
end
endgenerate
always_ff @(posedge clk) begin
alu_ex.new_request <= issue[ALU_UNIT_WB_ID];
ls_ex.new_request <= issue[LS_UNIT_WB_ID];
gc_ex.new_request <= issue[GC_UNIT_ID];
end
//Branch new request is held if
//Special case for branch unit:
//Branch new request is held if the following instruction hasn't arrived at decode/issue yet
always_ff @(posedge clk) begin
if (rst)
branch_ex.new_request <= 0;
branch_issued <= 0;
else if (issue[BRANCH_UNIT_ID])
branch_ex.new_request <= 1;
branch_issued <= 1;
else if (fb_valid)
branch_ex.new_request <= 0;
branch_issued <= 0;
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)
always_ff @(posedge clk) begin
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] & ti.id_available;
endgenerate
generate if (USE_DIV)
always_ff @(posedge clk) begin
div_ex.new_request <= issue[DIV_UNIT_WB_ID];
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] & ti.id_available;
endgenerate
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_ID] & ti.id_available;
////////////////////////////////////////////////////
//Illegal Opcode check
always_comb begin

View file

@ -27,9 +27,10 @@ module div_unit
(
input logic clk,
input logic rst,
func_unit_ex_interface.unit div_ex,
input div_inputs_t div_inputs,
unit_writeback_interface.unit div_wb
unit_issue_interface.unit issue,
unit_writeback_interface.unit wb
);
logic computation_complete;
@ -72,8 +73,8 @@ module div_unit
) div_input_fifo (.fifo(input_fifo), .*);
assign input_fifo.data_in = div_inputs;
assign input_fifo.push = div_ex.new_request_dec;
assign div_ex.ready = (DIV_INPUT_BUFFER_DEPTH >= MAX_INFLIGHT_COUNT) ? 1 : ~input_fifo.full;
assign input_fifo.push = issue.new_request;
assign issue.ready = (DIV_INPUT_BUFFER_DEPTH >= MAX_INFLIGHT_COUNT) ? 1 : ~input_fifo.full;
assign input_fifo.pop = div_done;
assign stage1 = input_fifo.data_out;
@ -124,8 +125,8 @@ 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 wb.done_next_cycle = stage1.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{div_done}};
assign wb.rd = rd_bank[wb.writeback_instruction_id];
////////////////////////////////////////////////////

View file

@ -30,7 +30,7 @@ module gc_unit(
//Decode
func_unit_ex_interface.unit gc_ex,
unit_issue_interface.unit issue,
input gc_inputs_t gc_inputs,
input logic instruction_issued_no_rd,
input logic gc_flush_required,
@ -178,12 +178,12 @@ module gc_unit(
////////////////////////////////////////////////////
//GC Operation
assign is_csr = gc_ex.new_request & gc_inputs.is_csr;
assign is_csr = issue.new_request_r & gc_inputs.is_csr;
assign gc_fetch_flush = branch_flush | gc_fetch_pc_override;
always_ff @ (posedge clk) begin
gc_issue_hold <= gc_ex.new_request_dec || is_csr || processing_csr || (next_state inside {PRE_CLEAR_STATE, CLEAR_STATE, TLB_CLEAR_STATE, IQ_DRAIN, IQ_DISCARD});
gc_issue_hold <= issue.new_request || is_csr || processing_csr || (next_state inside {PRE_CLEAR_STATE, CLEAR_STATE, TLB_CLEAR_STATE, IQ_DRAIN, IQ_DISCARD});
inuse_clear <= (next_state == CLEAR_STATE);
inorder <= 0;//(next_state inside {LS_EXCEPTION_POSSIBLE, IQ_DRAIN});
end
@ -295,7 +295,7 @@ module gc_unit(
//CSR reads are passed through the Load-Store unit
//A CSR write is only committed once it is the oldest instruction in the pipeline
//while processing a csr operation, gc_issue_hold prevents further instructions from being issued
assign gc_ex.ready = 1;
assign issue.ready = 1;
always_ff @(posedge clk) begin
if (rst)
@ -311,9 +311,9 @@ module gc_unit(
csr_ready_to_complete_r <= csr_ready_to_complete;
csr_id_done <= id & {MAX_INFLIGHT_COUNT{csr_ready_to_complete}};
csr_id <= instruction_id;
if (gc_ex.new_request_dec) begin
id <= gc_ex.instruction_id_one_hot;
instruction_id <= gc_ex.instruction_id;
if (issue.new_request) begin
id <= issue.instruction_id_one_hot;
instruction_id <= issue.instruction_id;
end
end

View file

@ -50,16 +50,17 @@ interface branch_predictor_interface;
endinterface
interface func_unit_ex_interface;
logic new_request_dec;
interface unit_issue_interface;
logic possible_issue;
logic new_request;
logic ready;
logic new_request_r;
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, instruction_id_one_hot);
modport unit (output ready, input possible_issue, new_request_dec, new_request, instruction_id, instruction_id_one_hot);
logic ready;
modport decode (input ready, output possible_issue, new_request, new_request_r, instruction_id, instruction_id_one_hot);
modport unit (output ready, input possible_issue, new_request, new_request_r, instruction_id, instruction_id_one_hot);
endinterface
interface ras_interface;

View file

@ -27,7 +27,7 @@ module load_store_unit (
input logic clk,
input logic rst,
input load_store_inputs_t ls_inputs,
func_unit_ex_interface.unit ls_ex,
unit_issue_interface.unit issue,
input logic dcache_on,
input logic clear_reservation,
@ -58,7 +58,7 @@ module load_store_unit (
output exception_packet_t ls_exception,
output logic ls_exception_valid,
unit_writeback_interface.unit ls_wb
unit_writeback_interface.unit wb
);
localparam NUM_SUB_UNITS = USE_D_SCRATCH_MEM+USE_BUS+USE_DCACHE;
@ -126,10 +126,10 @@ module load_store_unit (
) ls_input_fifo (.fifo(input_fifo), .*);
assign input_fifo.data_in = ls_inputs;
assign input_fifo.push = ls_ex.new_request_dec;
assign ls_ex.ready = (LS_INPUT_BUFFER_DEPTH >= MAX_INFLIGHT_COUNT) ? 1 : ~input_fifo.full;
assign input_fifo.push = issue.new_request;
assign issue.ready = (LS_INPUT_BUFFER_DEPTH >= MAX_INFLIGHT_COUNT) ? 1 : ~input_fifo.full;
assign input_fifo.pop = issue_request | gc_issue_flush;
assign load_store_FIFO_emptying = input_fifo.almost_empty & issue_request & ~ls_ex.new_request_dec;
assign load_store_FIFO_emptying = input_fifo.almost_empty & issue_request & ~issue.new_request;
assign stage1 = input_fifo.data_out;
////////////////////////////////////////////////////
@ -342,7 +342,7 @@ module load_store_unit (
previous_load <= final_load_data;
end
assign ls_wb.rd = rd_bank[ls_wb.writeback_instruction_id];
assign wb.rd = rd_bank[wb.writeback_instruction_id];
logic exception_complete;
logic ls_done;
@ -351,7 +351,7 @@ module load_store_unit (
end
assign ls_done = load_complete | exception_complete;
assign ls_wb.done_next_cycle = csr_id_done | (stage2_attr.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{ls_done}});
assign wb.done_next_cycle = csr_id_done | (stage2_attr.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{ls_done}});
////////////////////////////////////////////////////
//End of Implementation
////////////////////////////////////////////////////

View file

@ -26,9 +26,10 @@ import taiga_types::*;
module mul_unit(
input logic clk,
input logic rst,
func_unit_ex_interface.unit mul_ex,
input mul_inputs_t mul_inputs,
unit_writeback_interface.unit mul_wb
unit_issue_interface.unit issue,
unit_writeback_interface.unit wb
);
logic signed [65:0] result;
@ -61,10 +62,10 @@ module mul_unit(
mulh[0] <= (mul_inputs.op[1:0] != MUL_fn3[1:0]);
mulh[1] <= mulh[0];
id[0] <= mul_ex.instruction_id;
id[0] <= issue.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[0] <= issue.instruction_id_one_hot & {MAX_INFLIGHT_COUNT{issue.new_request}};
id_one_hot_done[1] <= id_one_hot_done[0];
end
@ -77,9 +78,9 @@ module mul_unit(
//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 = id_one_hot_done[1];
assign issue.ready = 1;
assign wb.rd = rd_bank[wb.writeback_instruction_id];
assign wb.done_next_cycle = id_one_hot_done[1];
////////////////////////////////////////////////////
//End of Implementation

View file

@ -61,12 +61,7 @@ module taiga (
div_inputs_t div_inputs;
gc_inputs_t gc_inputs;
func_unit_ex_interface branch_ex();
func_unit_ex_interface alu_ex();
func_unit_ex_interface ls_ex();
func_unit_ex_interface gc_ex();
func_unit_ex_interface mul_ex();
func_unit_ex_interface div_ex();
unit_issue_interface unit_issue [NUM_UNITS-1:0]();
exception_packet_t ls_exception;
logic ls_exception_valid;
@ -134,6 +129,7 @@ module taiga (
logic instruction_complete;
logic instruction_issued;
logic gc_flush_required;
logic branch_issued;
//Trace Interface Signals
logic tr_operand_stall;
@ -182,9 +178,9 @@ module taiga (
////////////////////////////////////////////////////
//Execution Units
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]));
branch_unit branch_unit_block (.*, .issue(unit_issue[BRANCH_UNIT_ID]));
alu_unit alu_unit_block (.*, .issue(unit_issue[ALU_UNIT_WB_ID]), .wb(unit_wb[ALU_UNIT_WB_ID]));
load_store_unit load_store_unit_block (.*, .dcache_on(1'b1), .clear_reservation(1'b0), .tlb(dtlb), .issue(unit_issue[LS_UNIT_WB_ID]), .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
tlb_lut_ram #(DTLB_WAYS, DTLB_DEPTH) d_tlb (.*, .tlb(dtlb), .mmu(dmmu));
mmu d_mmu (.*, .mmu(dmmu), .l1_request(l1_request[L1_DMMU_ID]), .l1_response(l1_response[L1_DMMU_ID]), .mmu_exception());
@ -194,13 +190,13 @@ module taiga (
assign dtlb.physical_address = dtlb.virtual_address;
end
endgenerate
gc_unit gc_unit_block (.*);
gc_unit gc_unit_block (.*, .issue(unit_issue[GC_UNIT_ID]));
generate if (USE_MUL)
mul_unit mul_unit_block (.*, .mul_wb(unit_wb[MUL_UNIT_WB_ID]));
mul_unit mul_unit_block (.*, .issue(unit_issue[MUL_UNIT_WB_ID]), .wb(unit_wb[MUL_UNIT_WB_ID]));
endgenerate
generate if (USE_DIV)
div_unit div_unit_block (.*, .div_wb(unit_wb[DIV_UNIT_WB_ID]));
div_unit div_unit_block (.*, .issue(unit_issue[DIV_UNIT_WB_ID]), .wb(unit_wb[DIV_UNIT_WB_ID]));
endgenerate
////////////////////////////////////////////////////