Being more aggressive with parallel cases

This commit is contained in:
Clifford Wolf 2015-07-02 12:55:05 +02:00
parent c10125eb5c
commit ab503d5756
1 changed files with 177 additions and 149 deletions

View File

@ -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