mirror of https://github.com/YosysHQ/picorv32.git
Being more aggressive with parallel cases
This commit is contained in:
parent
c10125eb5c
commit
ab503d5756
326
picorv32.v
326
picorv32.v
|
@ -639,26 +639,29 @@ module picorv32 #(
|
||||||
|
|
||||||
current_pc = reg_next_pc;
|
current_pc = reg_next_pc;
|
||||||
|
|
||||||
if (latched_branch) begin
|
(* parallel_case *)
|
||||||
current_pc = latched_store ? (latched_stalu ? reg_alu_out : reg_out) : reg_next_pc;
|
case (1'b1)
|
||||||
`debug($display("ST_RD: %2d 0x%08x, BRANCH 0x%08x", latched_rd, reg_pc + 4, current_pc);)
|
latched_branch: begin
|
||||||
cpuregs[latched_rd] <= reg_pc + 4;
|
current_pc = latched_store ? (latched_stalu ? reg_alu_out : reg_out) : reg_next_pc;
|
||||||
end else
|
`debug($display("ST_RD: %2d 0x%08x, BRANCH 0x%08x", latched_rd, reg_pc + 4, current_pc);)
|
||||||
if (latched_store) begin
|
cpuregs[latched_rd] <= reg_pc + 4;
|
||||||
`debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? reg_alu_out : reg_out);)
|
end
|
||||||
cpuregs[latched_rd] <= latched_stalu ? reg_alu_out : reg_out;
|
latched_store && !latched_branch: begin
|
||||||
end else
|
`debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? reg_alu_out : reg_out);)
|
||||||
if (ENABLE_IRQ && irq_state[0]) begin
|
cpuregs[latched_rd] <= latched_stalu ? reg_alu_out : reg_out;
|
||||||
cpuregs[latched_rd] <= current_pc;
|
end
|
||||||
current_pc = PROGADDR_IRQ;
|
ENABLE_IRQ && irq_state[0]: begin
|
||||||
irq_active <= 1;
|
cpuregs[latched_rd] <= current_pc;
|
||||||
mem_do_rinst <= 1;
|
current_pc = PROGADDR_IRQ;
|
||||||
end else
|
irq_active <= 1;
|
||||||
if (ENABLE_IRQ && irq_state[1]) begin
|
mem_do_rinst <= 1;
|
||||||
eoi <= irq_pending & ~irq_mask;
|
end
|
||||||
cpuregs[latched_rd] <= irq_pending & ~irq_mask;
|
ENABLE_IRQ && irq_state[1]: begin
|
||||||
next_irq_pending = next_irq_pending & irq_mask;
|
eoi <= irq_pending & ~irq_mask;
|
||||||
end
|
cpuregs[latched_rd] <= irq_pending & ~irq_mask;
|
||||||
|
next_irq_pending = next_irq_pending & irq_mask;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
reg_pc <= current_pc;
|
reg_pc <= current_pc;
|
||||||
reg_next_pc <= current_pc;
|
reg_next_pc <= current_pc;
|
||||||
|
@ -711,153 +714,178 @@ module picorv32 #(
|
||||||
reg_op1 <= 'bx;
|
reg_op1 <= 'bx;
|
||||||
reg_op2 <= 'bx;
|
reg_op2 <= 'bx;
|
||||||
`debug($display("DECODE: 0x%08x %-0s", reg_pc, instruction ? instruction : "UNKNOWN");)
|
`debug($display("DECODE: 0x%08x %-0s", reg_pc, instruction ? instruction : "UNKNOWN");)
|
||||||
if ((CATCH_ILLINSN || WITH_PCPI) && instr_trap) begin
|
|
||||||
if (WITH_PCPI) begin
|
(* parallel_case *)
|
||||||
reg_op1 <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
case (1'b1)
|
||||||
if (ENABLE_REGS_DUALPORT) begin
|
(CATCH_ILLINSN || WITH_PCPI) && instr_trap: begin
|
||||||
pcpi_valid <= 1;
|
if (WITH_PCPI) begin
|
||||||
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
reg_op1 <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
||||||
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
if (ENABLE_REGS_DUALPORT) begin
|
||||||
if (pcpi_int_ready) begin
|
pcpi_valid <= 1;
|
||||||
mem_do_rinst <= 1;
|
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
pcpi_valid <= 0;
|
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
reg_out <= pcpi_int_rd;
|
if (pcpi_int_ready) begin
|
||||||
latched_store <= pcpi_int_wr;
|
mem_do_rinst <= 1;
|
||||||
cpu_state <= cpu_state_fetch;
|
pcpi_valid <= 0;
|
||||||
end else
|
reg_out <= pcpi_int_rd;
|
||||||
if (CATCH_ILLINSN && pcpi_timeout) begin
|
latched_store <= pcpi_int_wr;
|
||||||
`debug($display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
|
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_sbreak] && !irq_active) begin
|
|
||||||
next_irq_pending[irq_sbreak] = 1;
|
|
||||||
cpu_state <= cpu_state_fetch;
|
cpu_state <= cpu_state_fetch;
|
||||||
end else
|
end else
|
||||||
cpu_state <= cpu_state_trap;
|
if (CATCH_ILLINSN && pcpi_timeout) begin
|
||||||
|
`debug($display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
|
||||||
|
if (ENABLE_IRQ && !irq_mask[irq_sbreak] && !irq_active) begin
|
||||||
|
next_irq_pending[irq_sbreak] = 1;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end else
|
||||||
|
cpu_state <= cpu_state_trap;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
cpu_state <= cpu_state_ld_rs2;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
cpu_state <= cpu_state_ld_rs2;
|
`debug($display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
|
||||||
|
if (ENABLE_IRQ && !irq_mask[irq_sbreak] && !irq_active) begin
|
||||||
|
next_irq_pending[irq_sbreak] = 1;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end else
|
||||||
|
cpu_state <= cpu_state_trap;
|
||||||
end
|
end
|
||||||
end else begin
|
|
||||||
`debug($display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
|
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_sbreak] && !irq_active) begin
|
|
||||||
next_irq_pending[irq_sbreak] = 1;
|
|
||||||
cpu_state <= cpu_state_fetch;
|
|
||||||
end else
|
|
||||||
cpu_state <= cpu_state_trap;
|
|
||||||
end
|
end
|
||||||
end else
|
ENABLE_COUNTERS && is_rdcycle_rdcycleh_rdinstr_rdinstrh: begin
|
||||||
if (is_rdcycle_rdcycleh_rdinstr_rdinstrh) begin
|
(* parallel_case, full_case *)
|
||||||
(* parallel_case, full_case *)
|
case (1'b1)
|
||||||
case (1'b1)
|
instr_rdcycle:
|
||||||
instr_rdcycle:
|
reg_out <= count_cycle[31:0];
|
||||||
reg_out <= count_cycle[31:0];
|
instr_rdcycleh:
|
||||||
instr_rdcycleh:
|
reg_out <= count_cycle[63:32];
|
||||||
reg_out <= count_cycle[63:32];
|
instr_rdinstr:
|
||||||
instr_rdinstr:
|
reg_out <= count_instr[31:0];
|
||||||
reg_out <= count_instr[31:0];
|
instr_rdinstrh:
|
||||||
instr_rdinstrh:
|
reg_out <= count_instr[63:32];
|
||||||
reg_out <= count_instr[63:32];
|
endcase
|
||||||
endcase
|
latched_store <= 1;
|
||||||
latched_store <= 1;
|
cpu_state <= cpu_state_fetch;
|
||||||
cpu_state <= cpu_state_fetch;
|
end
|
||||||
end else
|
is_lui_auipc_jal: begin
|
||||||
if (is_lui_auipc_jal) begin
|
reg_op1 <= instr_lui ? 0 : reg_pc;
|
||||||
reg_op1 <= instr_lui ? 0 : reg_pc;
|
|
||||||
reg_op2 <= decoded_imm;
|
|
||||||
mem_do_rinst <= mem_do_prefetch;
|
|
||||||
cpu_state <= cpu_state_exec;
|
|
||||||
end else
|
|
||||||
if (ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_getq) begin
|
|
||||||
reg_out <= cpuregs[decoded_rs1];
|
|
||||||
latched_store <= 1;
|
|
||||||
cpu_state <= cpu_state_fetch;
|
|
||||||
end else
|
|
||||||
if (ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_setq) begin
|
|
||||||
reg_out <= cpuregs[decoded_rs1];
|
|
||||||
latched_rd <= latched_rd | irqregs_offset;
|
|
||||||
latched_store <= 1;
|
|
||||||
cpu_state <= cpu_state_fetch;
|
|
||||||
end else
|
|
||||||
if (ENABLE_IRQ && instr_retirq) begin
|
|
||||||
eoi <= 0;
|
|
||||||
irq_active <= 0;
|
|
||||||
latched_branch <= 1;
|
|
||||||
latched_store <= 1;
|
|
||||||
reg_out <= cpuregs[decoded_rs1];
|
|
||||||
cpu_state <= cpu_state_fetch;
|
|
||||||
end else
|
|
||||||
if (ENABLE_IRQ && instr_maskirq) begin
|
|
||||||
latched_store <= 1;
|
|
||||||
reg_out <= irq_mask;
|
|
||||||
irq_mask <= (decoded_rs1 ? cpuregs[decoded_rs1] : 0) | MASKED_IRQ;
|
|
||||||
cpu_state <= cpu_state_fetch;
|
|
||||||
end else
|
|
||||||
if (ENABLE_IRQ && ENABLE_IRQ_TIMER && instr_timer) begin
|
|
||||||
latched_store <= 1;
|
|
||||||
reg_out <= timer;
|
|
||||||
timer <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
|
||||||
cpu_state <= cpu_state_fetch;
|
|
||||||
end else begin
|
|
||||||
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, decoded_rs1 ? cpuregs[decoded_rs1] : 0);)
|
|
||||||
reg_op1 <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
|
||||||
if (is_lb_lh_lw_lbu_lhu) begin
|
|
||||||
cpu_state <= cpu_state_ldmem;
|
|
||||||
mem_do_rinst <= 1;
|
|
||||||
end else if (is_slli_srli_srai) begin
|
|
||||||
reg_sh <= decoded_rs2;
|
|
||||||
cpu_state <= cpu_state_shift;
|
|
||||||
end else if (is_jalr_addi_slti_sltiu_xori_ori_andi) begin
|
|
||||||
reg_op2 <= decoded_imm;
|
reg_op2 <= decoded_imm;
|
||||||
mem_do_rinst <= mem_do_prefetch;
|
mem_do_rinst <= mem_do_prefetch;
|
||||||
cpu_state <= cpu_state_exec;
|
cpu_state <= cpu_state_exec;
|
||||||
end else if (ENABLE_REGS_DUALPORT) begin
|
end
|
||||||
`debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, decoded_rs2 ? cpuregs[decoded_rs2] : 0);)
|
ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_getq: begin
|
||||||
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
reg_out <= cpuregs[decoded_rs1];
|
||||||
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
latched_store <= 1;
|
||||||
if (is_sb_sh_sw) begin
|
cpu_state <= cpu_state_fetch;
|
||||||
cpu_state <= cpu_state_stmem;
|
end
|
||||||
mem_do_rinst <= 1;
|
ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_setq: begin
|
||||||
end else if (is_sll_srl_sra) begin
|
reg_out <= cpuregs[decoded_rs1];
|
||||||
cpu_state <= cpu_state_shift;
|
latched_rd <= latched_rd | irqregs_offset;
|
||||||
end else begin
|
latched_store <= 1;
|
||||||
mem_do_rinst <= mem_do_prefetch;
|
cpu_state <= cpu_state_fetch;
|
||||||
cpu_state <= cpu_state_exec;
|
end
|
||||||
end
|
ENABLE_IRQ && instr_retirq: begin
|
||||||
end else
|
eoi <= 0;
|
||||||
cpu_state <= cpu_state_ld_rs2;
|
irq_active <= 0;
|
||||||
end
|
latched_branch <= 1;
|
||||||
|
latched_store <= 1;
|
||||||
|
reg_out <= cpuregs[decoded_rs1];
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end
|
||||||
|
ENABLE_IRQ && instr_maskirq: begin
|
||||||
|
latched_store <= 1;
|
||||||
|
reg_out <= irq_mask;
|
||||||
|
irq_mask <= (decoded_rs1 ? cpuregs[decoded_rs1] : 0) | MASKED_IRQ;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end
|
||||||
|
ENABLE_IRQ && ENABLE_IRQ_TIMER && instr_timer: begin
|
||||||
|
latched_store <= 1;
|
||||||
|
reg_out <= timer;
|
||||||
|
timer <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end
|
||||||
|
is_lb_lh_lw_lbu_lhu: begin
|
||||||
|
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, decoded_rs1 ? cpuregs[decoded_rs1] : 0);)
|
||||||
|
reg_op1 <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
||||||
|
cpu_state <= cpu_state_ldmem;
|
||||||
|
mem_do_rinst <= 1;
|
||||||
|
end
|
||||||
|
is_slli_srli_srai: begin
|
||||||
|
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, decoded_rs1 ? cpuregs[decoded_rs1] : 0);)
|
||||||
|
reg_op1 <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
||||||
|
reg_sh <= decoded_rs2;
|
||||||
|
cpu_state <= cpu_state_shift;
|
||||||
|
end
|
||||||
|
is_jalr_addi_slti_sltiu_xori_ori_andi: begin
|
||||||
|
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, decoded_rs1 ? cpuregs[decoded_rs1] : 0);)
|
||||||
|
reg_op1 <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
||||||
|
reg_op2 <= decoded_imm;
|
||||||
|
mem_do_rinst <= mem_do_prefetch;
|
||||||
|
cpu_state <= cpu_state_exec;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, decoded_rs1 ? cpuregs[decoded_rs1] : 0);)
|
||||||
|
reg_op1 <= decoded_rs1 ? cpuregs[decoded_rs1] : 0;
|
||||||
|
if (ENABLE_REGS_DUALPORT) begin
|
||||||
|
`debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, decoded_rs2 ? cpuregs[decoded_rs2] : 0);)
|
||||||
|
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
|
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
|
(* parallel_case *)
|
||||||
|
case (1'b1)
|
||||||
|
is_sb_sh_sw: begin
|
||||||
|
cpu_state <= cpu_state_stmem;
|
||||||
|
mem_do_rinst <= 1;
|
||||||
|
end
|
||||||
|
is_sll_srl_sra: begin
|
||||||
|
cpu_state <= cpu_state_shift;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
mem_do_rinst <= mem_do_prefetch;
|
||||||
|
cpu_state <= cpu_state_exec;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end else
|
||||||
|
cpu_state <= cpu_state_ld_rs2;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
cpu_state_ld_rs2: begin
|
cpu_state_ld_rs2: begin
|
||||||
`debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, decoded_rs2 ? cpuregs[decoded_rs2] : 0);)
|
`debug($display("LD_RS2: %2d 0x%08x", decoded_rs2, decoded_rs2 ? cpuregs[decoded_rs2] : 0);)
|
||||||
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
reg_sh <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
reg_op2 <= decoded_rs2 ? cpuregs[decoded_rs2] : 0;
|
||||||
if (WITH_PCPI && instr_trap) begin
|
|
||||||
pcpi_valid <= 1;
|
(* parallel_case *)
|
||||||
if (pcpi_int_ready) begin
|
case (1'b1)
|
||||||
mem_do_rinst <= 1;
|
WITH_PCPI && instr_trap: begin
|
||||||
pcpi_valid <= 0;
|
pcpi_valid <= 1;
|
||||||
reg_out <= pcpi_int_rd;
|
if (pcpi_int_ready) begin
|
||||||
latched_store <= pcpi_int_wr;
|
mem_do_rinst <= 1;
|
||||||
cpu_state <= cpu_state_fetch;
|
pcpi_valid <= 0;
|
||||||
end else
|
reg_out <= pcpi_int_rd;
|
||||||
if (CATCH_ILLINSN && pcpi_timeout) begin
|
latched_store <= pcpi_int_wr;
|
||||||
`debug($display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
|
|
||||||
if (ENABLE_IRQ && !irq_mask[irq_sbreak] && !irq_active) begin
|
|
||||||
next_irq_pending[irq_sbreak] = 1;
|
|
||||||
cpu_state <= cpu_state_fetch;
|
cpu_state <= cpu_state_fetch;
|
||||||
end else
|
end else
|
||||||
cpu_state <= cpu_state_trap;
|
if (CATCH_ILLINSN && pcpi_timeout) begin
|
||||||
|
`debug($display("SBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
|
||||||
|
if (ENABLE_IRQ && !irq_mask[irq_sbreak] && !irq_active) begin
|
||||||
|
next_irq_pending[irq_sbreak] = 1;
|
||||||
|
cpu_state <= cpu_state_fetch;
|
||||||
|
end else
|
||||||
|
cpu_state <= cpu_state_trap;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end else
|
is_sb_sh_sw: begin
|
||||||
if (is_sb_sh_sw) begin
|
cpu_state <= cpu_state_stmem;
|
||||||
cpu_state <= cpu_state_stmem;
|
mem_do_rinst <= 1;
|
||||||
mem_do_rinst <= 1;
|
end
|
||||||
end else if (is_sll_srl_sra) begin
|
is_sll_srl_sra: begin
|
||||||
cpu_state <= cpu_state_shift;
|
cpu_state <= cpu_state_shift;
|
||||||
end else begin
|
end
|
||||||
mem_do_rinst <= mem_do_prefetch;
|
default: begin
|
||||||
cpu_state <= cpu_state_exec;
|
mem_do_rinst <= mem_do_prefetch;
|
||||||
end
|
cpu_state <= cpu_state_exec;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
cpu_state_exec: begin
|
cpu_state_exec: begin
|
||||||
|
|
Loading…
Reference in New Issue