Refine picorv code.
This commit is contained in:
parent
b03844d9ac
commit
7f42e7f7a4
89
picorv32.v
89
picorv32.v
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue