critical path improvements

This commit is contained in:
Eric Matthews 2019-08-19 22:18:59 -07:00
parent 1a5751adb2
commit ba64f8dcae
6 changed files with 38 additions and 35 deletions

View file

@ -48,6 +48,7 @@ module decode(
input logic gc_issue_hold,
input logic gc_fetch_flush,
input logic gc_issue_flush,
output logic gc_flush_required,
output logic load_store_issue,
@ -334,12 +335,12 @@ module decode(
gc_inputs.is_fence <= (opcode_trim == FENCE_T) && ~fn3[0];
gc_inputs.is_csr <= (opcode_trim == SYSTEM_T) && (fn3 != 0);
end
gc_inputs.flush_required <= issue[GC_UNIT_WB_ID] && (environment_op | ifence);
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_i_fence <= issue[GC_UNIT_WB_ID] && ifence;
end
assign gc_flush_required = issue[GC_UNIT_WB_ID] && (environment_op | ifence);
////////////////////////////////////////////////////

View file

@ -33,7 +33,7 @@ module gc_unit(
func_unit_ex_interface.unit gc_ex,
input gc_inputs_t gc_inputs,
input logic instruction_issued_no_rd,
input logic gc_flush_required,
//Branch miss predict
input logic branch_flush,
@ -136,6 +136,7 @@ module gc_unit(
logic i_fence_flush;
exception_code_t ecall_code;
logic second_cycle_flush;
//CSR
logic mret;
@ -220,7 +221,7 @@ module gc_unit(
assign gc_exception.valid = gc_inputs.is_ecall | gc_inputs.is_ebreak | ls_exception_second_cycle;
assign gc_fetch_flush = branch_flush | gc_inputs.flush_required | gc_fetch_pc_override | ls_exception_first_cycle;
assign gc_fetch_flush = branch_flush | gc_fetch_pc_override;
always_ff @ (posedge clk) begin
gc_issue_hold <= gc_ex.new_request_dec || processing || (next_state inside {PRE_CLEAR_STATE, CLEAR_STATE, TLB_CLEAR_STATE, IQ_DRAIN, IQ_DISCARD});
@ -238,7 +239,8 @@ module gc_unit(
always_ff @ (posedge clk) begin
gc_fetch_pc_override <= gc_inputs.flush_required | ls_exception_first_cycle;
second_cycle_flush <= gc_flush_required;
gc_fetch_pc_override <= gc_flush_required | second_cycle_flush | ls_exception_first_cycle;
gc_fetch_pc <=
gc_inputs.is_i_fence ? gc_inputs.pc + 4 :
gc_inputs.is_ret ? csr_mepc :

View file

@ -47,6 +47,8 @@ module id_stack # (
logic [STACK_DEPTH_W-1:0] store_shiffted_stack [STACK_DEPTH-1:0];
logic [STACK_DEPTH_W-1:0] retired_store_shiffted_stack [STACK_DEPTH-1:0];
logic [STACK_DEPTH-1:0] store_done_ordered;
logic [STACK_DEPTH-1:0] store_shift_bits;
logic [STACK_DEPTH-1:0] retired_shift_bits;
@ -61,13 +63,21 @@ module id_stack # (
end
end
//TODO inorder support
generate begin
genvar i;
assign store_shift_bits[0] = 1;
assign retired_shift_bits[0] = retired;
for (i=1; i<STACK_DEPTH; i++) begin
assign store_shift_bits[i] = |store_done_ordered[STACK_DEPTH-1:i];
assign retired_shift_bits[i] = |id_done_ordered[STACK_DEPTH-1:i];
end
end endgenerate
always_comb begin
//Lowest entry always shifted, each older entry shifts all below
store_shift_bits = 0;
store_shift_bits[0] = 1;
for (int i=1; i<STACK_DEPTH; i++) begin
if (stack[i] == store_id)
store_shift_bits |= (2**(i+1)-1);
for (int i=0; i<STACK_DEPTH; i++) begin
store_done_ordered[i] = (stack[i] == store_id);
end
//Stack shift due to stores being popped
@ -79,18 +89,11 @@ module id_stack # (
end
always_comb begin
retired_shift_bits = 0;
retired_shift_bits[0] = 1;
for (int i=1; i<STACK_DEPTH; i++) begin
if (id_done_ordered[i])
retired_shift_bits |= (2**(i+1)-1);
end
//Stack shift due to writes to register file being popped
retired_store_shiffted_stack[STACK_DEPTH-1:1] = store_shiffted_stack[STACK_DEPTH-2:0];
retired_store_shiffted_stack[0] = retired_id;
foreach (new_stack[i]) begin
new_stack[i] = (retired & retired_shift_bits[i]) ? retired_store_shiffted_stack[i] : store_shiffted_stack[i];
new_stack[i] = (retired_shift_bits[i]) ? retired_store_shiffted_stack[i] : store_shiffted_stack[i];
end
end

View file

@ -120,6 +120,7 @@ module taiga (
logic instruction_issued_with_rd;
logic instruction_complete;
logic instruction_issued;
logic gc_flush_required;
//Trace Interface Signals
logic tr_operand_stall;

View file

@ -166,7 +166,7 @@ package taiga_config;
parameter FETCH_BUFFER_DEPTH = 4;
parameter LS_INPUT_BUFFER_DEPTH = 4;
parameter DIV_INPUT_BUFFER_DEPTH = 2;
parameter DIV_INPUT_BUFFER_DEPTH = 4;
////////////////////////////////////////////////////
//Trace Options

View file

@ -61,7 +61,6 @@ module write_back(
instruction_id_t id_ordering_post_store [MAX_INFLIGHT_COUNT-1:0];
logic [MAX_INFLIGHT_COUNT-1:0] id_done;
logic [MAX_INFLIGHT_COUNT-1:0] id_done_next;
logic [MAX_INFLIGHT_COUNT-1:0] id_done_r;
logic [MAX_INFLIGHT_COUNT-1:0] id_done_ordered;
@ -120,14 +119,6 @@ module write_back(
end
//////////////////////
//Or together all unit done signals for the same ID.
always_comb begin
id_done_next = 0;
for (int i=0; i< NUM_WB_UNITS; i++) begin
id_done_next |= unit_done_next_cycle[i];
end
end
//One-hot ID retired last cycle
logic [MAX_INFLIGHT_COUNT-1:0] id_retired_last_cycle;
always_comb begin
@ -135,8 +126,13 @@ module write_back(
id_retired_last_cycle[retired_id_r] = retired_r;
end
//ID done is a combination of newly completed and already completed instructions
assign id_done = id_done_next | (id_done_r & ~id_retired_last_cycle);
//Or together all unit done signals for the same ID.
always_comb begin
id_done = (id_done_r & ~id_retired_last_cycle); //Still pending instructions
for (int i=0; i< NUM_WB_UNITS; i++) begin
id_done |= unit_done_next_cycle[i];
end
end
always_ff @ (posedge clk) begin
if (rst)
@ -160,11 +156,11 @@ module write_back(
id_done_ordered[i] = id_done[id_ordering_post_store[i]];
end
retired_id = id_ordering_post_store[0];
for (int i=1; i<MAX_INFLIGHT_COUNT; i++) begin
if (id_done_ordered[i]) begin
retired_id = id_ordering_post_store[i];
end
retired_id = id_ordering_post_store[MAX_INFLIGHT_COUNT-1];
for (int i=MAX_INFLIGHT_COUNT-1; i>0; i--) begin
if (id_done_ordered[i])
break;
retired_id = id_ordering_post_store[i-1];
end
if (inorder)
@ -174,7 +170,7 @@ module write_back(
//Read table for unit ID (acks, and rd_addr for register file)
assign retired_instruction_packet = packet_table[retired_id_r];
assign accepted = retired_instruction_packet.unit_id & {NUM_WB_UNITS{retired_r}};
//assign accepted = retired_instruction_packet.unit_id & {NUM_WB_UNITS{retired_r}};
assign instruction_complete = retired_r;