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