mirror of
https://github.com/openhwgroup/cva5.git
synced 2025-04-24 14:08:57 -04:00
moved gc input registers to gc unit
This commit is contained in:
parent
986f718da8
commit
db8bf69966
3 changed files with 42 additions and 48 deletions
|
@ -107,15 +107,6 @@ module decode(
|
|||
|
||||
logic valid_opcode;
|
||||
|
||||
//LS-inputs
|
||||
logic [11:0] ls_offset;
|
||||
logic is_load;
|
||||
logic is_store;
|
||||
logic amo_op;
|
||||
logic store_conditional;
|
||||
logic load_reserve;
|
||||
logic [4:0] amo_type;
|
||||
|
||||
genvar i;
|
||||
////////////////////////////////////////////////////
|
||||
//Implementation
|
||||
|
@ -248,6 +239,14 @@ module decode(
|
|||
|
||||
////////////////////////////////////////////////////
|
||||
//Load Store unit inputs
|
||||
logic [11:0] ls_offset;
|
||||
logic is_load;
|
||||
logic is_store;
|
||||
logic amo_op;
|
||||
logic store_conditional;
|
||||
logic load_reserve;
|
||||
logic [4:0] amo_type;
|
||||
|
||||
assign amo_op = USE_AMO ? (opcode_trim == AMO_T) : 1'b0;
|
||||
assign amo_type = fb.instruction[31:27];
|
||||
assign store_conditional = (amo_type == AMO_SC);
|
||||
|
@ -309,23 +308,19 @@ module decode(
|
|||
assign environment_op = (opcode_trim == SYSTEM_T) && (fn3 == 0);
|
||||
assign is_csr = (opcode_trim == SYSTEM_T) && (fn3 != 0);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (issue[GC_UNIT_ID]) begin
|
||||
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 <= is_csr;
|
||||
end
|
||||
gc_inputs.is_ecall <= issue[GC_UNIT_ID] && environment_op && (fb.instruction[21:20] == 0);
|
||||
gc_inputs.is_ebreak <= issue[GC_UNIT_ID] && environment_op && (fb.instruction[21:20] == 2'b01);
|
||||
gc_inputs.is_ret <= issue[GC_UNIT_ID] && environment_op && (fb.instruction[21:20] == 2'b10);
|
||||
gc_inputs.is_i_fence <= issue[GC_UNIT_ID] && ifence;
|
||||
end
|
||||
assign gc_flush_required = issue[GC_UNIT_ID] && (environment_op | ifence);
|
||||
assign gc_inputs.pc = fb.pc;
|
||||
assign gc_inputs.instruction = fb.instruction;
|
||||
assign gc_inputs.rs1 = rf_decode.rs1_data;
|
||||
assign gc_inputs.rs2 = rf_decode.rs2_data;
|
||||
assign gc_inputs.is_fence = (opcode_trim == FENCE_T) && ~fn3[0];
|
||||
assign gc_inputs.is_i_fence = issue[GC_UNIT_ID] && ifence;
|
||||
assign gc_inputs.is_csr = is_csr;
|
||||
|
||||
assign gc_inputs.is_ecall = environment_op && (fb.instruction[21:20] == 0);
|
||||
assign gc_inputs.is_ebreak = environment_op && (fb.instruction[21:20] == 2'b01);
|
||||
assign gc_inputs.is_ret = environment_op && (fb.instruction[21:20] == 2'b10);
|
||||
|
||||
assign gc_flush_required = issue[GC_UNIT_ID] && (environment_op | ifence);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Mul unit inputs
|
||||
|
@ -336,7 +331,6 @@ module decode(
|
|||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Div unit inputs
|
||||
generate if (USE_DIV) begin
|
||||
|
@ -383,7 +377,6 @@ module decode(
|
|||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Unit EX signals
|
||||
generate
|
||||
|
|
|
@ -155,31 +155,34 @@ module gc_unit(
|
|||
|
||||
logic [4:0] rs1_addr;
|
||||
logic [4:0] rs2_addr;
|
||||
logic [4:0] future_rd_addr;
|
||||
logic [4:0] rd_addr;
|
||||
|
||||
logic is_csr;
|
||||
gc_inputs_t stage1;
|
||||
logic processing_csr;
|
||||
logic csr_ready_to_complete;
|
||||
logic csr_ready_to_complete_r;
|
||||
instruction_id_t instruction_id;
|
||||
//implementation
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (issue.new_request) begin
|
||||
stage1 <= gc_inputs;
|
||||
end
|
||||
end
|
||||
|
||||
//Instruction decode
|
||||
assign opcode = gc_inputs.instruction[6:0];
|
||||
assign opcode = stage1.instruction[6:0];
|
||||
assign opcode_trim = opcode[6:2];
|
||||
assign fn3 = gc_inputs.instruction[14:12];
|
||||
assign rs1_addr = gc_inputs.instruction[19:15];
|
||||
assign fn3 = stage1.instruction[14:12];
|
||||
assign rs1_addr = stage1.instruction[19:15];
|
||||
assign rd_addr = stage1.instruction[11:7];
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//GC Operation
|
||||
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 <= issue.new_request || is_csr || processing_csr || (next_state inside {TLB_CLEAR_STATE, IQ_DRAIN, IQ_DISCARD});
|
||||
gc_issue_hold <= issue.new_request || processing_csr || (next_state inside {TLB_CLEAR_STATE, IQ_DRAIN, IQ_DISCARD});
|
||||
end
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
|
@ -238,26 +241,25 @@ module gc_unit(
|
|||
gc_inputs.is_ecall ? ecall_code : BREAK;
|
||||
assign gc_exception.pc = ls_exception_second_cycle ? ls_exception.pc : gc_inputs.pc;
|
||||
assign gc_exception.tval = ls_exception_second_cycle ? ls_exception.tval : '0;
|
||||
assign gc_exception.valid = gc_inputs.is_ecall | gc_inputs.is_ebreak | ls_exception_second_cycle;
|
||||
assign gc_exception.valid = issue.new_request & (gc_inputs.is_ecall | gc_inputs.is_ebreak) | ls_exception_second_cycle;
|
||||
|
||||
always_ff @ (posedge clk) begin
|
||||
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 :
|
||||
trap_pc;
|
||||
gc_fetch_pc <= ls_exception_second_cycle ? trap_pc :
|
||||
stage1.is_i_fence ? stage1.pc + 4 : //Could stall on dec_pc valid and use instead of another adder
|
||||
csr_mepc;// gc_inputs.is_ret
|
||||
end
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//CSR registers
|
||||
assign csr_inputs.rs1 = fn3[2] ? {27'b0, rs1_addr} : gc_inputs.rs1;
|
||||
assign csr_inputs.csr_addr = gc_inputs.instruction[31:20];
|
||||
assign csr_inputs.rs1 = fn3[2] ? {27'b0, rs1_addr} : stage1.rs1;
|
||||
assign csr_inputs.csr_addr = stage1.instruction[31:20];
|
||||
assign csr_inputs.csr_op = fn3[1:0];
|
||||
assign csr_inputs.rs1_is_zero = (rs1_addr == 0);
|
||||
assign csr_inputs.rd_is_zero = gc_inputs.rd_is_zero;
|
||||
assign csr_inputs.rd_is_zero = (rd_addr == 0);
|
||||
|
||||
csr_regs csr_registers (.*, .new_request(is_csr), .read_regs(csr_ready_to_complete), .commit(csr_ready_to_complete_r));
|
||||
csr_regs csr_registers (.*, .new_request(stage1.is_csr), .read_regs(csr_ready_to_complete), .commit(csr_ready_to_complete_r));
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//Decode / Write-back Handshaking
|
||||
|
@ -271,11 +273,11 @@ module gc_unit(
|
|||
processing_csr <= 0;
|
||||
else if (csr_ready_to_complete)
|
||||
processing_csr <= 0;
|
||||
else if (is_csr)
|
||||
else if (issue.new_request & gc_inputs.is_csr)
|
||||
processing_csr <= 1;
|
||||
end
|
||||
|
||||
assign csr_ready_to_complete = (is_csr | processing_csr) && (oldest_id == csr_id);
|
||||
assign csr_ready_to_complete = processing_csr && (oldest_id == csr_id);
|
||||
always_ff @(posedge clk) begin
|
||||
csr_ready_to_complete_r <= csr_ready_to_complete;
|
||||
csr_id <= instruction_id;
|
||||
|
|
|
@ -406,7 +406,6 @@ package taiga_types;
|
|||
logic [31:0] instruction;
|
||||
logic [XLEN-1:0] rs1;
|
||||
logic [XLEN-1:0] rs2;
|
||||
logic rd_is_zero;
|
||||
logic is_csr;
|
||||
logic is_fence;
|
||||
logic is_i_fence;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue