Refine picorv code.

This commit is contained in:
colin.liang 2023-01-17 14:37:11 +08:00
parent b03844d9ac
commit 7f42e7f7a4
1 changed files with 37 additions and 52 deletions

View File

@ -89,14 +89,6 @@ module picorv32 #(
reg [31:0] next_insn_opcode; reg [31:0] next_insn_opcode;
wire dbg_mem_valid = mem_valid;
wire dbg_mem_instr = mem_instr;
wire dbg_mem_ready = mem_ready;
wire [31:0] dbg_mem_addr = mem_addr;
wire [31:0] dbg_mem_wdata = mem_wdata;
wire [3:0] dbg_mem_wstrb = mem_wstrb;
wire [31:0] dbg_mem_rdata = mem_rdata;
assign pcpi_rs1 = reg_op1; assign pcpi_rs1 = reg_op1;
assign pcpi_rs2 = reg_op2; assign pcpi_rs2 = reg_op2;
@ -161,10 +153,6 @@ module picorv32 #(
(* parallel_case *) (* parallel_case *)
case (1'b1) case (1'b1)
0: begin
pcpi_int_wr = 0;
pcpi_int_rd = 0;
end
pcpi_mul_ready: begin pcpi_mul_ready: begin
pcpi_int_wr = pcpi_mul_wr; pcpi_int_wr = pcpi_mul_wr;
pcpi_int_rd = pcpi_mul_rd; pcpi_int_rd = pcpi_mul_rd;
@ -184,7 +172,7 @@ module picorv32 #(
reg [31:0] mem_rdata_word; reg [31:0] mem_rdata_word;
reg [31:0] mem_rdata_q; reg [31:0] mem_rdata_q;
reg mem_do_prefetch; reg mem_do_prefetch;
reg mem_do_rinst; reg mem_do_r_inst;
reg mem_do_rdata; reg mem_do_rdata;
reg mem_do_wdata; reg mem_do_wdata;
@ -198,12 +186,12 @@ module picorv32 #(
assign mem_xfer = mem_valid && mem_ready; assign mem_xfer = mem_valid && mem_ready;
wire mem_busy = |{mem_do_prefetch, mem_do_rinst, mem_do_rdata, mem_do_wdata}; wire mem_busy = |{mem_do_prefetch, mem_do_r_inst, mem_do_rdata, mem_do_wdata};
wire mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_rinst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_rinst)); wire mem_done = resetn && ((mem_xfer && |mem_state && (mem_do_r_inst || mem_do_rdata || mem_do_wdata)) || (&mem_state && mem_do_r_inst));
assign mem_la_write = resetn && !mem_state && mem_do_wdata; assign mem_la_write = resetn && !mem_state && mem_do_wdata;
assign mem_la_read = resetn && ((!mem_state && (mem_do_rinst || mem_do_prefetch || mem_do_rdata))); assign mem_la_read = resetn && ((!mem_state && (mem_do_r_inst || mem_do_prefetch || mem_do_rdata)));
assign mem_la_addr = (mem_do_prefetch || mem_do_rinst) ? {next_pc[31:2], 2'b00} : {reg_op1[31:2], 2'b00}; assign mem_la_addr = (mem_do_prefetch || mem_do_r_inst) ? {next_pc[31:2], 2'b00} : {reg_op1[31:2], 2'b00};
assign mem_rdata_latched_noshuffle = mem_xfer ? mem_rdata : mem_rdata_q; assign mem_rdata_latched_noshuffle = mem_xfer ? mem_rdata : mem_rdata_q;
@ -255,17 +243,17 @@ module picorv32 #(
always @(posedge clk) begin always @(posedge clk) begin
if (resetn && !trap) begin if (resetn && !trap) begin
if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) if (mem_do_prefetch || mem_do_r_inst || mem_do_rdata)
`assert(!mem_do_wdata); `assert(!mem_do_wdata);
if (mem_do_prefetch || mem_do_rinst) if (mem_do_prefetch || mem_do_r_inst)
`assert(!mem_do_rdata); `assert(!mem_do_rdata);
if (mem_do_rdata) if (mem_do_rdata)
`assert(!mem_do_prefetch && !mem_do_rinst); `assert(!mem_do_prefetch && !mem_do_r_inst);
if (mem_do_wdata) if (mem_do_wdata)
`assert(!(mem_do_prefetch || mem_do_rinst || mem_do_rdata)); `assert(!(mem_do_prefetch || mem_do_r_inst || mem_do_rdata));
if (mem_state == 2 || mem_state == 3) if (mem_state == 2 || mem_state == 3)
`assert(mem_valid || mem_do_prefetch); `assert(mem_valid || mem_do_prefetch);
@ -286,9 +274,9 @@ module picorv32 #(
end end
case (mem_state) case (mem_state)
0: begin 0: begin
if (mem_do_prefetch || mem_do_rinst || mem_do_rdata) begin if (mem_do_prefetch || mem_do_r_inst || mem_do_rdata) begin
mem_valid <= 1; mem_valid <= 1;
mem_instr <= mem_do_prefetch || mem_do_rinst; mem_instr <= mem_do_prefetch || mem_do_r_inst;
mem_wstrb <= 0; mem_wstrb <= 0;
mem_state <= 1; mem_state <= 1;
end end
@ -300,12 +288,12 @@ module picorv32 #(
end end
1: begin 1: begin
`assert(mem_wstrb == 0); `assert(mem_wstrb == 0);
`assert(mem_do_prefetch || mem_do_rinst || mem_do_rdata); `assert(mem_do_prefetch || mem_do_r_inst || mem_do_rdata);
`assert(mem_valid == 1); `assert(mem_valid == 1);
`assert(mem_instr == (mem_do_prefetch || mem_do_rinst)); `assert(mem_instr == (mem_do_prefetch || mem_do_r_inst));
if (mem_xfer) begin if (mem_xfer) begin
mem_valid <= 0; mem_valid <= 0;
mem_state <= mem_do_rinst || mem_do_rdata ? 0 : 3; mem_state <= mem_do_r_inst || mem_do_rdata ? 0 : 3;
end end
end end
2: begin 2: begin
@ -319,7 +307,7 @@ module picorv32 #(
3: begin 3: begin
`assert(mem_wstrb == 0); `assert(mem_wstrb == 0);
`assert(mem_do_prefetch); `assert(mem_do_prefetch);
if (mem_do_rinst) begin if (mem_do_r_inst) begin
mem_state <= 0; mem_state <= 0;
end end
end end
@ -327,6 +315,8 @@ module picorv32 #(
end end
end end
// Memory Interface End
// Instruction Decoder // Instruction Decoder
@ -517,7 +507,7 @@ module picorv32 #(
is_lbu_lhu_lw <= |{instr_lbu, instr_lhu, instr_lw}; is_lbu_lhu_lw <= |{instr_lbu, instr_lhu, instr_lw};
is_compare <= |{is_beq_bne_blt_bge_bltu_bgeu, instr_slti, instr_slt, instr_sltiu, instr_sltu}; is_compare <= |{is_beq_bne_blt_bge_bltu_bgeu, instr_slti, instr_slt, instr_sltiu, instr_sltu};
if (mem_do_rinst && mem_done) begin if (mem_do_r_inst && mem_done) begin
instr_lui <= mem_rdata_latched[6:0] == 7'b0110111; instr_lui <= mem_rdata_latched[6:0] == 7'b0110111;
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;
@ -704,7 +694,7 @@ module picorv32 #(
reg pcpi_timeout; reg pcpi_timeout;
reg [31:0] alu_out, alu_out_q; reg [31:0] alu_out, alu_out_q;
reg alu_out_0, alu_out_0_q; reg alu_out_0;
reg [31:0] alu_add_sub; reg [31:0] alu_add_sub;
reg [31:0] alu_shl, alu_shr; reg [31:0] alu_shl, alu_shr;
@ -739,8 +729,6 @@ module picorv32 #(
instr_xori || instr_xor: alu_out = reg_op1 ^ reg_op2; instr_xori || instr_xor: alu_out = reg_op1 ^ reg_op2;
instr_ori || instr_or: alu_out = reg_op1 | reg_op2; instr_ori || instr_or: alu_out = reg_op1 | reg_op2;
instr_andi || instr_and: alu_out = reg_op1 & reg_op2; instr_andi || instr_and: alu_out = reg_op1 & reg_op2;
0: alu_out = alu_shl;
0: alu_out = alu_shr;
endcase endcase
end end
@ -748,7 +736,6 @@ module picorv32 #(
reg [31:0] cpuregs_wrdata; reg [31:0] cpuregs_wrdata;
reg [31:0] cpuregs_rs1; reg [31:0] cpuregs_rs1;
reg [31:0] cpuregs_rs2; reg [31:0] cpuregs_rs2;
reg [regindex_bits-1:0] decoded_rs;
always @* begin always @* begin
cpuregs_write = 0; cpuregs_write = 0;
@ -788,7 +775,6 @@ module picorv32 #(
); );
always @* begin always @* begin
decoded_rs = 'bx;
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
@ -803,7 +789,6 @@ module picorv32 #(
set_mem_do_rdata = 0; set_mem_do_rdata = 0;
set_mem_do_wdata = 0; set_mem_do_wdata = 0;
alu_out_0_q <= alu_out_0;
alu_out_q <= alu_out; alu_out_q <= alu_out;
if (launch_next_insn) begin if (launch_next_insn) begin
@ -819,7 +804,7 @@ module picorv32 #(
pcpi_timeout <= !pcpi_timeout_counter; pcpi_timeout <= !pcpi_timeout_counter;
count_cycle <= resetn ? count_cycle + 1 : 0; count_cycle <= resetn ? count_cycle + 1 : 0;
decoder_trigger <= mem_do_rinst && mem_done; decoder_trigger <= mem_do_r_inst && mem_done;
decoder_trigger_q <= decoder_trigger; decoder_trigger_q <= decoder_trigger;
decoder_pseudo_trigger <= 0; decoder_pseudo_trigger <= 0;
decoder_pseudo_trigger_q <= decoder_pseudo_trigger; decoder_pseudo_trigger_q <= decoder_pseudo_trigger;
@ -849,8 +834,8 @@ module picorv32 #(
end end
cpu_state_fetch: begin cpu_state_fetch: begin
mem_do_rinst <= !decoder_trigger; mem_do_r_inst <= !decoder_trigger;
mem_wordsize <= 0; mem_wordsize <= 0;
current_pc = reg_next_pc; current_pc = reg_next_pc;
@ -883,11 +868,11 @@ module picorv32 #(
reg_next_pc <= current_pc + 4; reg_next_pc <= current_pc + 4;
count_instr <= count_instr + 1; count_instr <= count_instr + 1;
if (instr_jal) begin if (instr_jal) begin
mem_do_rinst <= 1; mem_do_r_inst <= 1;
reg_next_pc <= current_pc + decoded_imm_j; reg_next_pc <= current_pc + decoded_imm_j;
latched_branch <= 1; latched_branch <= 1;
end else begin end else begin
mem_do_rinst <= 0; mem_do_r_inst <= 0;
mem_do_prefetch <= !instr_jalr; mem_do_prefetch <= !instr_jalr;
cpu_state <= cpu_state_ld_rs1; cpu_state <= cpu_state_ld_rs1;
end end
@ -912,7 +897,7 @@ module picorv32 #(
dbg_rs2val <= cpuregs_rs2; dbg_rs2val <= cpuregs_rs2;
dbg_rs2val_valid <= 1; dbg_rs2val_valid <= 1;
if (pcpi_int_ready) begin if (pcpi_int_ready) begin
mem_do_rinst <= 1; mem_do_r_inst <= 1;
pcpi_valid <= 0; pcpi_valid <= 0;
reg_out <= pcpi_int_rd; reg_out <= pcpi_int_rd;
latched_store <= pcpi_int_wr; latched_store <= pcpi_int_wr;
@ -937,7 +922,7 @@ module picorv32 #(
is_lui_auipc_jal: begin is_lui_auipc_jal: begin
reg_op1 <= instr_lui ? 0 : reg_pc; reg_op1 <= instr_lui ? 0 : reg_pc;
reg_op2 <= decoded_imm; reg_op2 <= decoded_imm;
mem_do_rinst <= mem_do_prefetch; mem_do_r_inst <= mem_do_prefetch;
cpu_state <= cpu_state_exec; cpu_state <= cpu_state_exec;
end end
is_lb_lh_lw_lbu_lhu && !instr_trap: begin is_lb_lh_lw_lbu_lhu && !instr_trap: begin
@ -946,7 +931,7 @@ module picorv32 #(
dbg_rs1val <= cpuregs_rs1; dbg_rs1val <= cpuregs_rs1;
dbg_rs1val_valid <= 1; dbg_rs1val_valid <= 1;
cpu_state <= cpu_state_ldmem; cpu_state <= cpu_state_ldmem;
mem_do_rinst <= 1; mem_do_r_inst <= 1;
end end
is_slli_srli_srai: begin is_slli_srli_srai: begin
`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);) `debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
@ -962,7 +947,7 @@ module picorv32 #(
dbg_rs1val <= cpuregs_rs1; dbg_rs1val <= cpuregs_rs1;
dbg_rs1val_valid <= 1; dbg_rs1val_valid <= 1;
reg_op2 <= decoded_imm; reg_op2 <= decoded_imm;
mem_do_rinst <= mem_do_prefetch; mem_do_r_inst <= mem_do_prefetch;
cpu_state <= cpu_state_exec; cpu_state <= cpu_state_exec;
end end
default: begin default: begin
@ -979,13 +964,13 @@ module picorv32 #(
case (1'b1) case (1'b1)
is_sb_sh_sw: begin is_sb_sh_sw: begin
cpu_state <= cpu_state_stmem; cpu_state <= cpu_state_stmem;
mem_do_rinst <= 1; mem_do_r_inst <= 1;
end end
is_sll_srl_sra: begin is_sll_srl_sra: begin
cpu_state <= cpu_state_shift; cpu_state <= cpu_state_shift;
end end
default: begin default: begin
mem_do_rinst <= mem_do_prefetch; mem_do_r_inst <= mem_do_prefetch;
cpu_state <= cpu_state_exec; cpu_state <= cpu_state_exec;
end end
endcase endcase
@ -1005,7 +990,7 @@ module picorv32 #(
instr_trap: begin instr_trap: begin
pcpi_valid <= 1; pcpi_valid <= 1;
if (pcpi_int_ready) begin if (pcpi_int_ready) begin
mem_do_rinst <= 1; mem_do_r_inst <= 1;
pcpi_valid <= 0; pcpi_valid <= 0;
reg_out <= pcpi_int_rd; reg_out <= pcpi_int_rd;
latched_store <= pcpi_int_wr; latched_store <= pcpi_int_wr;
@ -1018,13 +1003,13 @@ module picorv32 #(
end end
is_sb_sh_sw: begin is_sb_sh_sw: begin
cpu_state <= cpu_state_stmem; cpu_state <= cpu_state_stmem;
mem_do_rinst <= 1; mem_do_r_inst <= 1;
end end
is_sll_srl_sra: begin is_sll_srl_sra: begin
cpu_state <= cpu_state_shift; cpu_state <= cpu_state_shift;
end end
default: begin default: begin
mem_do_rinst <= mem_do_prefetch; mem_do_r_inst <= mem_do_prefetch;
cpu_state <= cpu_state_exec; cpu_state <= cpu_state_exec;
end end
endcase endcase
@ -1052,7 +1037,7 @@ module picorv32 #(
latched_store <= 1; latched_store <= 1;
if (reg_sh == 0) begin if (reg_sh == 0) begin
reg_out <= reg_op1; reg_out <= reg_op1;
mem_do_rinst <= mem_do_prefetch; mem_do_r_inst <= mem_do_prefetch;
cpu_state <= cpu_state_fetch; cpu_state <= cpu_state_fetch;
end else if (reg_sh >= 4) begin end else if (reg_sh >= 4) begin
(* parallel_case, full_case *) (* parallel_case, full_case *)
@ -1134,19 +1119,19 @@ module picorv32 #(
cpu_state <= cpu_state_trap; cpu_state <= cpu_state_trap;
end end
end end
if (resetn && mem_do_rinst && (|reg_pc[1:0])) begin if (resetn && mem_do_r_inst && (|reg_pc[1:0])) begin
`debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);) `debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
cpu_state <= cpu_state_trap; cpu_state <= cpu_state_trap;
end end
if (!resetn || mem_done) begin if (!resetn || mem_done) begin
mem_do_prefetch <= 0; mem_do_prefetch <= 0;
mem_do_rinst <= 0; mem_do_r_inst <= 0;
mem_do_rdata <= 0; mem_do_rdata <= 0;
mem_do_wdata <= 0; mem_do_wdata <= 0;
end end
if (set_mem_do_rinst) mem_do_rinst <= 1; if (set_mem_do_rinst) mem_do_r_inst <= 1;
if (set_mem_do_rdata) mem_do_rdata <= 1; if (set_mem_do_rdata) mem_do_rdata <= 1;
if (set_mem_do_wdata) mem_do_wdata <= 1; if (set_mem_do_wdata) mem_do_wdata <= 1;