Remove Config of IRQ, Use reg module from latch.

This commit is contained in:
colin.liang 2023-01-12 17:02:34 +08:00
parent 9c0d7d7593
commit 9adf1c0029
2 changed files with 41 additions and 95 deletions

View File

@ -38,9 +38,6 @@
`define assert(assert_expr) empty_statement `define assert(assert_expr) empty_statement
`define FORMAL_KEEP `define FORMAL_KEEP
// uncomment this for register file in extra module
// `define PICORV32_REGS picorv32_regs
// this macro can be used to check if the verilog files in your // this macro can be used to check if the verilog files in your
// design are read in the correct order. // design are read in the correct order.
`define PICORV32_V `define PICORV32_V
@ -55,9 +52,6 @@ module picorv32 #(
parameter [ 0:0] BARREL_SHIFTER = 0, parameter [ 0:0] BARREL_SHIFTER = 0,
parameter [ 0:0] TWO_CYCLE_COMPARE = 0, parameter [ 0:0] TWO_CYCLE_COMPARE = 0,
parameter [ 0:0] TWO_CYCLE_ALU = 0, parameter [ 0:0] TWO_CYCLE_ALU = 0,
parameter [ 0:0] ENABLE_IRQ = 0,
parameter [ 0:0] ENABLE_IRQ_QREGS = 1,
parameter [ 0:0] ENABLE_IRQ_TIMER = 1,
parameter [ 0:0] ENABLE_TRACE = 0, parameter [ 0:0] ENABLE_TRACE = 0,
parameter [31:0] MASKED_IRQ = 32'h 0000_0000, parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff, parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff,
@ -107,8 +101,8 @@ module picorv32 #(
localparam integer irq_buserror = 2; localparam integer irq_buserror = 2;
localparam integer irqregs_offset = 32; localparam integer irqregs_offset = 32;
localparam integer regfile_size = 32 + 4*ENABLE_IRQ*ENABLE_IRQ_QREGS; localparam integer regfile_size = 32 + 4;
localparam integer regindex_bits = 5 + ENABLE_IRQ*ENABLE_IRQ_QREGS; localparam integer regindex_bits = 5 + 1;
localparam WITH_PCPI = 1; // AAAA localparam WITH_PCPI = 1; // AAAA
@ -143,10 +137,6 @@ module picorv32 #(
reg [31:0] irq_pending; reg [31:0] irq_pending;
reg [31:0] timer; reg [31:0] timer;
`ifndef PICORV32_REGS
reg [31:0] cpuregs [0:regfile_size-1];
`endif
task empty_statement; task empty_statement;
// This task is used by the `assert directive in non-formal mode to // This task is used by the `assert directive in non-formal mode to
// avoid empty statement (which are unsupported by plain Verilog syntax). // avoid empty statement (which are unsupported by plain Verilog syntax).
@ -602,8 +592,8 @@ module picorv32 #(
instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111; instr_auipc <= mem_rdata_latched[6:0] == 7'b0010111;
instr_jal <= mem_rdata_latched[6:0] == 7'b1101111; instr_jal <= mem_rdata_latched[6:0] == 7'b1101111;
instr_jalr <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000; instr_jalr <= mem_rdata_latched[6:0] == 7'b1100111 && mem_rdata_latched[14:12] == 3'b000;
instr_retirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ; instr_retirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010;
instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100 && ENABLE_IRQ; instr_waitirq <= mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000100;
is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011; is_beq_bne_blt_bge_bltu_bgeu <= mem_rdata_latched[6:0] == 7'b1100011;
is_lb_lh_lw_lbu_lhu <= mem_rdata_latched[6:0] == 7'b0000011; is_lb_lh_lw_lbu_lhu <= mem_rdata_latched[6:0] == 7'b0000011;
@ -617,11 +607,11 @@ module picorv32 #(
decoded_rs1 <= mem_rdata_latched[19:15]; decoded_rs1 <= mem_rdata_latched[19:15];
decoded_rs2 <= mem_rdata_latched[24:20]; decoded_rs2 <= mem_rdata_latched[24:20];
if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS) if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000000)
decoded_rs1[regindex_bits-1] <= 1; // instr_getq decoded_rs1[regindex_bits-1] <= 1; // instr_getq
if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010 && ENABLE_IRQ) if (mem_rdata_latched[6:0] == 7'b0001011 && mem_rdata_latched[31:25] == 7'b0000010)
decoded_rs1 <= ENABLE_IRQ_QREGS ? irqregs_offset : 3; // instr_retirq decoded_rs1 <= irqregs_offset; // instr_retirq
compressed_instr <= 0; compressed_instr <= 0;
end end
@ -677,10 +667,10 @@ module picorv32 #(
instr_ecall_ebreak <= (mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]); instr_ecall_ebreak <= (mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]);
instr_getq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000000 && ENABLE_IRQ && ENABLE_IRQ_QREGS; instr_getq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000000;
instr_setq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000001 && ENABLE_IRQ && ENABLE_IRQ_QREGS; instr_setq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000001;
instr_maskirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000011 && ENABLE_IRQ; instr_maskirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000011;
instr_timer <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000101 && ENABLE_IRQ && ENABLE_IRQ_TIMER; instr_timer <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[31:25] == 7'b0000101;
is_slli_srli_srai <= is_alu_reg_imm && |{ is_slli_srli_srai <= is_alu_reg_imm && |{
mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000, mem_rdata_q[14:12] == 3'b001 && mem_rdata_q[31:25] == 7'b0000000,
@ -868,11 +858,6 @@ module picorv32 #(
BARREL_SHIFTER && (instr_srl || instr_srli || instr_sra || instr_srai): BARREL_SHIFTER && (instr_srl || instr_srli || instr_sra || instr_srai):
alu_out = alu_shr; alu_out = alu_shr;
endcase endcase
`ifdef RISCV_FORMAL_BLACKBOX_ALU
alu_out_0 = $anyseq;
alu_out = $anyseq;
`endif
end end
reg cpuregs_write; reg cpuregs_write;
@ -896,11 +881,11 @@ module picorv32 #(
cpuregs_wrdata = latched_stalu ? alu_out_q : reg_out; cpuregs_wrdata = latched_stalu ? alu_out_q : reg_out;
cpuregs_write = 1; cpuregs_write = 1;
end end
ENABLE_IRQ && irq_state[0]: begin irq_state[0]: begin
cpuregs_wrdata = reg_next_pc | latched_compr; cpuregs_wrdata = reg_next_pc | latched_compr;
cpuregs_write = 1; cpuregs_write = 1;
end end
ENABLE_IRQ && irq_state[1]: begin irq_state[1]: begin
cpuregs_wrdata = irq_pending & ~irq_mask; cpuregs_wrdata = irq_pending & ~irq_mask;
cpuregs_write = 1; cpuregs_write = 1;
end end
@ -908,30 +893,6 @@ module picorv32 #(
end end
end end
`ifndef PICORV32_REGS
always @(posedge clk) begin
if (resetn && cpuregs_write && latched_rd)
`ifdef PICORV32_TESTBUG_001
cpuregs[latched_rd ^ 1] <= cpuregs_wrdata;
`elsif PICORV32_TESTBUG_002
cpuregs[latched_rd] <= cpuregs_wrdata ^ 1;
`else
cpuregs[latched_rd] <= cpuregs_wrdata;
`endif
end
always @* begin
decoded_rs = 'bx;
`ifndef RISCV_FORMAL_BLACKBOX_REGS
cpuregs_rs1 = decoded_rs1 ? cpuregs[decoded_rs1] : 0;
cpuregs_rs2 = decoded_rs2 ? cpuregs[decoded_rs2] : 0;
`else
cpuregs_rs1 = decoded_rs1 ? $anyseq : 0;
cpuregs_rs2 = decoded_rs2 ? $anyseq : 0;
`endif
end
`else
wire[31:0] cpuregs_rdata1; wire[31:0] cpuregs_rdata1;
wire[31:0] cpuregs_rdata2; wire[31:0] cpuregs_rdata2;
@ -939,7 +900,7 @@ module picorv32 #(
wire [5:0] cpuregs_raddr1 = decoded_rs1; wire [5:0] cpuregs_raddr1 = decoded_rs1;
wire [5:0] cpuregs_raddr2 = decoded_rs2; wire [5:0] cpuregs_raddr2 = decoded_rs2;
`PICORV32_REGS cpuregs ( picorv32_regs cpuregs (
.clk(clk), .clk(clk),
.wen(resetn && cpuregs_write && latched_rd), .wen(resetn && cpuregs_write && latched_rd),
.waddr(cpuregs_waddr), .waddr(cpuregs_waddr),
@ -955,9 +916,8 @@ module picorv32 #(
cpuregs_rs1 = decoded_rs1 ? cpuregs_rdata1 : 0; cpuregs_rs1 = decoded_rs1 ? cpuregs_rdata1 : 0;
cpuregs_rs2 = decoded_rs2 ? cpuregs_rdata2 : 0; cpuregs_rs2 = decoded_rs2 ? cpuregs_rdata2 : 0;
end end
`endif
assign launch_next_insn = cpu_state == cpu_state_fetch && decoder_trigger && (!ENABLE_IRQ || irq_delay || irq_active || !(irq_pending & ~irq_mask)); assign launch_next_insn = cpu_state == cpu_state_fetch && decoder_trigger && (irq_delay || irq_active || !(irq_pending & ~irq_mask));
always @(posedge clk) begin always @(posedge clk) begin
trap <= 0; trap <= 0;
@ -989,9 +949,9 @@ module picorv32 #(
pcpi_timeout <= !pcpi_timeout_counter; pcpi_timeout <= !pcpi_timeout_counter;
end end
count_cycle <= resetn ? count_cycle + 1 : 0; count_cycle <= resetn ? count_cycle + 1 : 0;
next_irq_pending = ENABLE_IRQ ? irq_pending & LATCHED_IRQ : 'bx; next_irq_pending = irq_pending & LATCHED_IRQ;
if (ENABLE_IRQ && ENABLE_IRQ_TIMER && timer) begin if (timer) begin
timer <= timer - 1; timer <= timer - 1;
end end
@ -1054,12 +1014,12 @@ module picorv32 #(
latched_store && !latched_branch: begin latched_store && !latched_branch: begin
`debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out);) `debug($display("ST_RD: %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out);)
end end
ENABLE_IRQ && irq_state[0]: begin irq_state[0]: begin
current_pc = PROGADDR_IRQ; current_pc = PROGADDR_IRQ;
irq_active <= 1; irq_active <= 1;
mem_do_rinst <= 1; mem_do_rinst <= 1;
end end
ENABLE_IRQ && irq_state[1]: begin irq_state[1]: begin
eoi <= irq_pending & ~irq_mask; eoi <= irq_pending & ~irq_mask;
next_irq_pending = next_irq_pending & irq_mask; next_irq_pending = next_irq_pending & irq_mask;
end end
@ -1086,17 +1046,14 @@ module picorv32 #(
latched_rd <= decoded_rd; latched_rd <= decoded_rd;
latched_compr <= compressed_instr; latched_compr <= compressed_instr;
if (ENABLE_IRQ && ((decoder_trigger && !irq_active && !irq_delay && |(irq_pending & ~irq_mask)) || irq_state)) begin if (((decoder_trigger && !irq_active && !irq_delay && |(irq_pending & ~irq_mask)) || irq_state)) begin
irq_state <= irq_state <=
irq_state == 2'b00 ? 2'b01 : irq_state == 2'b00 ? 2'b01 :
irq_state == 2'b01 ? 2'b10 : 2'b00; irq_state == 2'b01 ? 2'b10 : 2'b00;
latched_compr <= latched_compr; latched_compr <= latched_compr;
if (ENABLE_IRQ_QREGS) latched_rd <= irqregs_offset | irq_state[0];
latched_rd <= irqregs_offset | irq_state[0];
else
latched_rd <= irq_state[0] ? 4 : 3;
end else end else
if (ENABLE_IRQ && (decoder_trigger || do_waitirq) && instr_waitirq) begin if ((decoder_trigger || do_waitirq) && instr_waitirq) begin
if (irq_pending) begin if (irq_pending) begin
latched_store <= 1; latched_store <= 1;
reg_out <= irq_pending; reg_out <= irq_pending;
@ -1152,7 +1109,7 @@ module picorv32 #(
if (pcpi_timeout || instr_ecall_ebreak) begin if (pcpi_timeout || instr_ecall_ebreak) begin
pcpi_valid <= 0; pcpi_valid <= 0;
`debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin if (!irq_mask[irq_ebreak] && !irq_active) begin
next_irq_pending[irq_ebreak] = 1; next_irq_pending[irq_ebreak] = 1;
cpu_state <= cpu_state_fetch; cpu_state <= cpu_state_fetch;
end else end else
@ -1160,7 +1117,7 @@ module picorv32 #(
end end
end else begin end else begin
`debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin if (!irq_mask[irq_ebreak] && !irq_active) begin
next_irq_pending[irq_ebreak] = 1; next_irq_pending[irq_ebreak] = 1;
cpu_state <= cpu_state_fetch; cpu_state <= cpu_state_fetch;
end else end else
@ -1191,7 +1148,7 @@ module picorv32 #(
mem_do_rinst <= mem_do_prefetch; mem_do_rinst <= mem_do_prefetch;
cpu_state <= cpu_state_exec; cpu_state <= cpu_state_exec;
end end
ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_getq: begin instr_getq: begin
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
reg_out <= cpuregs_rs1; reg_out <= cpuregs_rs1;
dbg_rs1val <= cpuregs_rs1; dbg_rs1val <= cpuregs_rs1;
@ -1199,7 +1156,7 @@ module picorv32 #(
latched_store <= 1; latched_store <= 1;
cpu_state <= cpu_state_fetch; cpu_state <= cpu_state_fetch;
end end
ENABLE_IRQ && ENABLE_IRQ_QREGS && instr_setq: begin instr_setq: begin
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
reg_out <= cpuregs_rs1; reg_out <= cpuregs_rs1;
dbg_rs1val <= cpuregs_rs1; dbg_rs1val <= cpuregs_rs1;
@ -1208,7 +1165,7 @@ module picorv32 #(
latched_store <= 1; latched_store <= 1;
cpu_state <= cpu_state_fetch; cpu_state <= cpu_state_fetch;
end end
ENABLE_IRQ && instr_retirq: begin instr_retirq: begin
eoi <= 0; eoi <= 0;
irq_active <= 0; irq_active <= 0;
latched_branch <= 1; latched_branch <= 1;
@ -1219,7 +1176,7 @@ module picorv32 #(
dbg_rs1val_valid <= 1; dbg_rs1val_valid <= 1;
cpu_state <= cpu_state_fetch; cpu_state <= cpu_state_fetch;
end end
ENABLE_IRQ && instr_maskirq: begin instr_maskirq: begin
latched_store <= 1; latched_store <= 1;
reg_out <= irq_mask; reg_out <= irq_mask;
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
@ -1228,7 +1185,7 @@ module picorv32 #(
dbg_rs1val_valid <= 1; dbg_rs1val_valid <= 1;
cpu_state <= cpu_state_fetch; cpu_state <= cpu_state_fetch;
end end
ENABLE_IRQ && ENABLE_IRQ_TIMER && instr_timer: begin instr_timer: begin
latched_store <= 1; latched_store <= 1;
reg_out <= timer; reg_out <= timer;
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
@ -1318,7 +1275,7 @@ module picorv32 #(
if (pcpi_timeout || instr_ecall_ebreak) begin if (pcpi_timeout || instr_ecall_ebreak) begin
pcpi_valid <= 0; pcpi_valid <= 0;
`debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);) `debug($display("EBREAK OR UNSUPPORTED INSN AT 0x%08x", reg_pc);)
if (ENABLE_IRQ && !irq_mask[irq_ebreak] && !irq_active) begin if (!irq_mask[irq_ebreak] && !irq_active) begin
next_irq_pending[irq_ebreak] = 1; next_irq_pending[irq_ebreak] = 1;
cpu_state <= cpu_state_fetch; cpu_state <= cpu_state_fetch;
end else end else
@ -1453,24 +1410,22 @@ module picorv32 #(
end end
endcase endcase
if (ENABLE_IRQ) begin next_irq_pending = next_irq_pending | irq;
next_irq_pending = next_irq_pending | irq; if(timer)
if(ENABLE_IRQ_TIMER && timer) if (timer - 1 == 0)
if (timer - 1 == 0) next_irq_pending[irq_timer] = 1;
next_irq_pending[irq_timer] = 1;
end
if (resetn && (mem_do_rdata || mem_do_wdata)) begin if (resetn && (mem_do_rdata || mem_do_wdata)) begin
if (mem_wordsize == 0 && reg_op1[1:0] != 0) begin if (mem_wordsize == 0 && reg_op1[1:0] != 0) begin
`debug($display("MISALIGNED WORD: 0x%08x", reg_op1);) `debug($display("MISALIGNED WORD: 0x%08x", reg_op1);)
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin if (!irq_mask[irq_buserror] && !irq_active) begin
next_irq_pending[irq_buserror] = 1; next_irq_pending[irq_buserror] = 1;
end else end else
cpu_state <= cpu_state_trap; cpu_state <= cpu_state_trap;
end end
if (mem_wordsize == 1 && reg_op1[0] != 0) begin if (mem_wordsize == 1 && reg_op1[0] != 0) begin
`debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);) `debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);)
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin if (!irq_mask[irq_buserror] && !irq_active) begin
next_irq_pending[irq_buserror] = 1; next_irq_pending[irq_buserror] = 1;
end else end else
cpu_state <= cpu_state_trap; cpu_state <= cpu_state_trap;
@ -1478,7 +1433,7 @@ module picorv32 #(
end end
if (resetn && mem_do_rinst && (|reg_pc[1:0])) begin if (resetn && mem_do_rinst && (|reg_pc[1:0])) begin
`debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);) `debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin if (!irq_mask[irq_buserror] && !irq_active) begin
next_irq_pending[irq_buserror] = 1; next_irq_pending[irq_buserror] = 1;
end else end else
cpu_state <= cpu_state_trap; cpu_state <= cpu_state_trap;
@ -1503,11 +1458,6 @@ module picorv32 #(
end end
endmodule endmodule
// This is a simple example implementation of PICORV32_REGS.
// Use the PICORV32_REGS mechanism if you want to use custom
// memory resources to implement the processor register file.
// Note that your implementation must match the requirements of
// the PicoRV32 configuration. (e.g. QREGS, etc)
module picorv32_regs ( module picorv32_regs (
input clk, wen, input clk, wen,
input [5:0] waddr, input [5:0] waddr,
@ -1517,16 +1467,13 @@ module picorv32_regs (
output [31:0] rdata1, output [31:0] rdata1,
output [31:0] rdata2 output [31:0] rdata2
); );
reg [31:0] regs [0:30]; reg [31:0] regs [0:35];
always @(posedge clk) always @(posedge clk)
if (wen) regs[~waddr[4:0]] <= wdata; if (wen) regs[waddr[5:0]] <= wdata;
assign rdata1 = regs[raddr1];
assign rdata1 = regs[~raddr1[4:0]]; assign rdata2 = regs[raddr2];
assign rdata2 = regs[~raddr2[4:0]];
endmodule endmodule
/*************************************************************** /***************************************************************
* picorv32_pcpi_mul * picorv32_pcpi_mul
***************************************************************/ ***************************************************************/

View File

@ -191,7 +191,6 @@ module picorv32_wb #(
assign resetn = ~wb_rst_i; assign resetn = ~wb_rst_i;
picorv32 #( picorv32 #(
.ENABLE_IRQ(1),
.ENABLE_TRACE(1), .ENABLE_TRACE(1),
.MASKED_IRQ(32'h0000_0000), .MASKED_IRQ(32'h0000_0000),
.LATCHED_IRQ(32'hffff_ffff), .LATCHED_IRQ(32'hffff_ffff),