|
@@ -219,6 +219,7 @@ module picorv32 #(
|
|
|
reg [31:0] irq_mask;
|
|
|
reg [31:0] irq_pending;
|
|
|
reg [31:0] timer;
|
|
|
+ reg [31:0] buserr_address;
|
|
|
|
|
|
`ifndef PICORV32_REGS
|
|
|
reg [31:0] cpuregs [0:regfile_size-1];
|
|
@@ -671,7 +672,7 @@ module picorv32 #(
|
|
|
reg instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw;
|
|
|
reg instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai;
|
|
|
reg instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and;
|
|
|
- reg instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh, instr_ecall_ebreak;
|
|
|
+ reg instr_csrr, instr_ecall_ebreak;
|
|
|
reg instr_addqxi, instr_addxqi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer;
|
|
|
|
|
|
wire instr_trap;
|
|
@@ -705,11 +706,7 @@ module picorv32 #(
|
|
|
instr_lb, instr_lh, instr_lw, instr_lbu, instr_lhu, instr_sb, instr_sh, instr_sw,
|
|
|
instr_addi, instr_slti, instr_sltiu, instr_xori, instr_ori, instr_andi, instr_slli, instr_srli, instr_srai,
|
|
|
instr_add, instr_sub, instr_sll, instr_slt, instr_sltu, instr_xor, instr_srl, instr_sra, instr_or, instr_and,
|
|
|
- instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh,
|
|
|
- instr_addqxi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer};
|
|
|
-
|
|
|
- wire is_rdcycle_rdcycleh_rdinstr_rdinstrh;
|
|
|
- assign is_rdcycle_rdcycleh_rdinstr_rdinstrh = |{instr_rdcycle, instr_rdcycleh, instr_rdinstr, instr_rdinstrh};
|
|
|
+ instr_csrr, instr_addqxi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer};
|
|
|
|
|
|
reg [63:0] new_ascii_instr;
|
|
|
`FORMAL_KEEP reg [63:0] dbg_ascii_instr;
|
|
@@ -767,10 +764,7 @@ module picorv32 #(
|
|
|
if (instr_or) new_ascii_instr = "or";
|
|
|
if (instr_and) new_ascii_instr = "and";
|
|
|
|
|
|
- if (instr_rdcycle) new_ascii_instr = "rdcycle";
|
|
|
- if (instr_rdcycleh) new_ascii_instr = "rdcycleh";
|
|
|
- if (instr_rdinstr) new_ascii_instr = "rdinstr";
|
|
|
- if (instr_rdinstrh) new_ascii_instr = "rdinstrh";
|
|
|
+ if (instr_csrr) new_ascii_instr = "csrr";
|
|
|
|
|
|
if (instr_addqxi) new_ascii_instr = "addqxi";
|
|
|
if (instr_addxqi) new_ascii_instr = "addxqi";
|
|
@@ -1118,12 +1112,8 @@ module picorv32 #(
|
|
|
instr_or <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b110 && mem_rdata_q[31:25] == 7'b0000000;
|
|
|
instr_and <= is_alu_reg_reg && mem_rdata_q[14:12] == 3'b111 && mem_rdata_q[31:25] == 7'b0000000;
|
|
|
|
|
|
- instr_rdcycle <= ((mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000000000000010) ||
|
|
|
- (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000000100000010)) && ENABLE_COUNTERS;
|
|
|
- instr_rdcycleh <= ((mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000000000000010) ||
|
|
|
- (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000000100000010)) && ENABLE_COUNTERS && ENABLE_COUNTERS64;
|
|
|
- instr_rdinstr <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11000000001000000010) && ENABLE_COUNTERS;
|
|
|
- instr_rdinstrh <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[31:12] == 'b11001000001000000010) && ENABLE_COUNTERS && ENABLE_COUNTERS64;
|
|
|
+ // The only CSR reference supported is CSRR
|
|
|
+ instr_csrr <= (mem_rdata_q[6:0] == 7'b1110011 && mem_rdata_q[19:12] == 'b00000010);
|
|
|
|
|
|
instr_ecall_ebreak <= ((mem_rdata_q[6:0] == 7'b1110011 && !mem_rdata_q[31:21] && !mem_rdata_q[19:7]) ||
|
|
|
(COMPRESSED_ISA && mem_rdata_q[15:0] == 16'h9002));
|
|
@@ -1131,6 +1121,7 @@ module picorv32 #(
|
|
|
instr_maskirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0000011 && ENABLE_IRQ;
|
|
|
instr_waitirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0000100 && ENABLE_IRQ;
|
|
|
instr_timer <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0000101 && ENABLE_IRQ && ENABLE_IRQ_TIMER;
|
|
|
+
|
|
|
// instr_addqxi includes addxqi; instr_addxqi is only used for debug
|
|
|
instr_addqxi <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[14:13] == 2'b01 && ENABLE_IRQ && ENABLE_IRQ_QREGS;
|
|
|
instr_addxqi <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[14:12] == 3'b011 && ENABLE_IRQ && ENABLE_IRQ_QREGS;
|
|
@@ -1165,14 +1156,12 @@ module picorv32 #(
|
|
|
decoded_imm <= decoded_imm_j;
|
|
|
|{instr_lui, instr_auipc}:
|
|
|
decoded_imm <= mem_rdata_q[31:12] << 12;
|
|
|
- |{instr_jalr, is_lb_lh_lw_lbu_lhu, is_alu_reg_imm, is_addqxi}:
|
|
|
- decoded_imm <= $signed(mem_rdata_q[31:20]);
|
|
|
is_beq_bne_blt_bge_bltu_bgeu:
|
|
|
decoded_imm <= $signed({mem_rdata_q[31], mem_rdata_q[7], mem_rdata_q[30:25], mem_rdata_q[11:8], 1'b0});
|
|
|
is_sb_sh_sw:
|
|
|
decoded_imm <= $signed({mem_rdata_q[31:25], mem_rdata_q[11:7]});
|
|
|
default:
|
|
|
- decoded_imm <= 1'bx;
|
|
|
+ decoded_imm <= $signed(mem_rdata_q[31:20]);
|
|
|
endcase
|
|
|
end
|
|
|
|
|
@@ -1679,18 +1668,22 @@ module picorv32 #(
|
|
|
cpu_state <= cpu_state_trap;
|
|
|
end
|
|
|
end
|
|
|
- ENABLE_COUNTERS && is_rdcycle_rdcycleh_rdinstr_rdinstrh: begin
|
|
|
- (* parallel_case, full_case *)
|
|
|
- case (1'b1)
|
|
|
- instr_rdcycle:
|
|
|
- reg_out <= count_cycle[31:0];
|
|
|
- instr_rdcycleh && ENABLE_COUNTERS64:
|
|
|
- reg_out <= count_cycle[63:32];
|
|
|
- instr_rdinstr:
|
|
|
- reg_out <= count_instr[31:0];
|
|
|
- instr_rdinstrh && ENABLE_COUNTERS64:
|
|
|
- reg_out <= count_instr[63:32];
|
|
|
- endcase
|
|
|
+ instr_csrr: begin
|
|
|
+ reg_out <= 32'bx;
|
|
|
+ case (decoded_imm[11:0])
|
|
|
+ 12'hc00, 12'hc01: // cycle, time
|
|
|
+ if (ENABLE_COUNTERS) reg_out <= count_cycle[31:0];
|
|
|
+ 12'hc80, 12'hc81: // cycleh, timeh
|
|
|
+ if (ENABLE_COUNTERS64) reg_out <= count_cycle[63:32];
|
|
|
+ 12'hc02: // instret (rdinstr)
|
|
|
+ if (ENABLE_COUNTERS) reg_out <= count_instr[31:0];
|
|
|
+ 12'hc82: // instret (rdinstr)
|
|
|
+ if (ENABLE_COUNTERS64) reg_out <= count_instr[63:32];
|
|
|
+ 12'h343: // mtval
|
|
|
+ if (CATCH_MISALIGN) reg_out <= buserr_address;
|
|
|
+ default:
|
|
|
+ reg_out <= 32'bx;
|
|
|
+ endcase // case (decoded_imm[11:0])
|
|
|
latched_store <= 1;
|
|
|
cpu_state <= cpu_state_fetch;
|
|
|
end
|
|
@@ -1978,6 +1971,7 @@ module picorv32 #(
|
|
|
if (mem_wordsize == 0 && reg_op1[1:0] != 0) begin
|
|
|
`debug($display("MISALIGNED WORD: 0x%08x", reg_op1);)
|
|
|
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
|
|
+ buserr_address <= reg_op1;
|
|
|
next_irq_pending[irq_buserror] = 1;
|
|
|
end else
|
|
|
cpu_state <= cpu_state_trap;
|
|
@@ -1985,6 +1979,7 @@ module picorv32 #(
|
|
|
if (mem_wordsize == 1 && reg_op1[0] != 0) begin
|
|
|
`debug($display("MISALIGNED HALFWORD: 0x%08x", reg_op1);)
|
|
|
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
|
|
+ buserr_address <= reg_op1;
|
|
|
next_irq_pending[irq_buserror] = 1;
|
|
|
end else
|
|
|
cpu_state <= cpu_state_trap;
|
|
@@ -1993,6 +1988,7 @@ module picorv32 #(
|
|
|
if (CATCH_MISALIGN && resetn && mem_do_rinst && (COMPRESSED_ISA ? reg_pc[0] : |reg_pc[1:0])) begin
|
|
|
`debug($display("MISALIGNED INSTRUCTION: 0x%08x", reg_pc);)
|
|
|
if (ENABLE_IRQ && !irq_mask[irq_buserror] && !irq_active) begin
|
|
|
+ buserr_address <= reg_pc;
|
|
|
next_irq_pending[irq_buserror] = 1;
|
|
|
end else
|
|
|
cpu_state <= cpu_state_trap;
|