|  | @@ -15,14 +15,15 @@
 | 
	
		
			
				|  |  |   *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
	
		
			
				|  |  |   *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  | - *  Changes by hpa 2021-2022:
 | 
	
		
			
				|  |  | + *  Changes by hpa 2021-2023:
 | 
	
		
			
				|  |  |   *  - maskirq instruction takes a mask in rs2.
 | 
	
		
			
				|  |  | - *  - retirq opcode changed to mret; no functional change.
 | 
	
		
			
				|  |  | + *  - retirq opcode changed to mret.
 | 
	
		
			
				|  |  |   *  - qregs replaced with a full register bank switch. In general,
 | 
	
		
			
				|  |  |   *    non-power-of-two register files don't save anything, especially in
 | 
	
		
			
				|  |  |   *    FPGAs.
 | 
	
		
			
				|  |  |   *  - getq and setq replaced with new instructions addqxi and addxqi
 | 
	
		
			
				|  |  |   *    for cross-bank register accesses if needed,
 | 
	
		
			
				|  |  | + *    taking immediate as additive argument.
 | 
	
		
			
				|  |  |   *    e.g. for stack setup (addqxi sp,sp,frame_size).
 | 
	
		
			
				|  |  |   *  - PROGADDR_RESET and PROGADDR_IRQ changed to ports (allows external
 | 
	
		
			
				|  |  |   *    implementation of vectorized interrupts or fallback reset.)
 | 
	
	
		
			
				|  | @@ -30,8 +31,23 @@
 | 
	
		
			
				|  |  |   *  - add two masks to waitirq: an AND mask and an OR mask.
 | 
	
		
			
				|  |  |   *    waitirq exists if either all interrupts in the AND
 | 
	
		
			
				|  |  |   *    mask are pending or any interrupt in the OR mask is pending.
 | 
	
		
			
				|  |  | + *    Note that waitirq with an AND mask of zero will exit immediately;
 | 
	
		
			
				|  |  | + *    this can be used to poll the status of interrupts (masked and unmasked.)
 | 
	
		
			
				|  |  |   *  - multiple user (non-interrupt) register banks (tasks) now supported;
 | 
	
		
			
				|  |  | - *
 | 
	
		
			
				|  |  | + *    these are set via a custom user_context CSR (0x7f0). They are numbered
 | 
	
		
			
				|  |  | + *    starting with 1; 0 is reserved for the IRQ context. After reset,
 | 
	
		
			
				|  |  | + *    this register is set to the maximum supported user context number.
 | 
	
		
			
				|  |  | + *    Writing this register also causes a transition to the IRQ context,
 | 
	
		
			
				|  |  | + *    so the context switch can be processed atomically.
 | 
	
		
			
				|  |  | + *  - the interrupt return address moved the mepc CSR, to make it
 | 
	
		
			
				|  |  | + *    globally available at interrupt time. This simplifies context switching.
 | 
	
		
			
				|  |  | + *  - implement the ctz instruction from the Zbb extension to improve
 | 
	
		
			
				|  |  | + *    interrupt latency by speeding up the dispatch substantially.
 | 
	
		
			
				|  |  | + *  - new pollirq instruction: returns a mask of pending unmasked
 | 
	
		
			
				|  |  | + *    interrupts AND ~rs1 OR rs2. EOIs pending unmasked interrupts AND ~rs1.
 | 
	
		
			
				|  |  | + *    This is intended to avoid priority inversion in the IRQ dispatch.
 | 
	
		
			
				|  |  | + *  - separately parameterize the width of the cycle and instruction counters;
 | 
	
		
			
				|  |  | + *    they can be independently set to any value from 0 to 64 bits.
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* verilator lint_off WIDTH */
 | 
	
	
		
			
				|  | @@ -88,8 +104,8 @@ endfunction // do_ctz
 | 
	
		
			
				|  |  |   ***************************************************************/
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  module picorv32 #(
 | 
	
		
			
				|  |  | -	parameter [ 0:0] ENABLE_COUNTERS = 1,
 | 
	
		
			
				|  |  | -	parameter [ 0:0] ENABLE_COUNTERS64 = 1,
 | 
	
		
			
				|  |  | +	parameter integer COUNTER_CYCLE_WIDTH = 64,
 | 
	
		
			
				|  |  | +	parameter integer COUNTER_INSTR_WIDTH = 64,
 | 
	
		
			
				|  |  |  	parameter [ 0:0] ENABLE_REGS_16_31 = 1,
 | 
	
		
			
				|  |  |  	parameter [ 0:0] ENABLE_REGS_DUALPORT = 1,
 | 
	
		
			
				|  |  |  	parameter [ 0:0] LATCHED_MEM_RDATA = 0,
 | 
	
	
		
			
				|  | @@ -111,9 +127,8 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  	parameter [31:0] MASKED_IRQ = 32'h 0000_0000,
 | 
	
		
			
				|  |  |  	parameter [31:0] LATCHED_IRQ = 32'h ffff_ffff,
 | 
	
		
			
				|  |  |  	parameter [31:0] STACKADDR = 32'h ffff_ffff,
 | 
	
		
			
				|  |  | -	parameter [ 4:0] RA_IRQ_REG    = ENABLE_IRQ_QREGS ? 26 : 3,
 | 
	
		
			
				|  |  | -	parameter [ 4:0] MASK_IRQ_REG  = ENABLE_IRQ_QREGS ? 27 : 4,
 | 
	
		
			
				|  |  | -        parameter        USER_CONTEXTS = 1,
 | 
	
		
			
				|  |  | +	parameter [ 4:0] MASK_IRQ_REG = ENABLE_IRQ_QREGS ? 27 : 4,
 | 
	
		
			
				|  |  | +	parameter	 USER_CONTEXTS = 1,
 | 
	
		
			
				|  |  |  	parameter [ 0:0] ENABLE_IRQ_QREGS = USER_CONTEXTS > 0
 | 
	
		
			
				|  |  |  ) (
 | 
	
		
			
				|  |  |  	input		  clk, resetn,
 | 
	
	
		
			
				|  | @@ -121,7 +136,7 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  	output reg	  trap,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	input [31:0]	  progaddr_reset,
 | 
	
		
			
				|  |  | -        input [31:0]	  progaddr_irq,
 | 
	
		
			
				|  |  | +	input [31:0]	  progaddr_irq,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	output reg	  mem_valid,
 | 
	
		
			
				|  |  |  	output reg	  mem_instr,
 | 
	
	
		
			
				|  | @@ -215,8 +230,12 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  	localparam [35:0] TRACE_ADDR   = {4'b 0010, 32'b 0};
 | 
	
		
			
				|  |  |  	localparam [35:0] TRACE_IRQ    = {4'b 1000, 32'b 0};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	reg [63:0] count_cycle, count_instr;
 | 
	
		
			
				|  |  | -	reg [31:0] reg_pc, reg_next_pc, reg_op1, reg_op2, reg_out;
 | 
	
		
			
				|  |  | +        reg [63:0]  count_cycle;
 | 
	
		
			
				|  |  | +        localparam [63:0] count_cycle_mask = (1'b1 << COUNTER_CYCLE_WIDTH) - 1'b1;
 | 
	
		
			
				|  |  | +        reg  [63:0] count_instr;
 | 
	
		
			
				|  |  | +        localparam [63:0] count_instr_mask = (1'b1 << COUNTER_INSTR_WIDTH) - 1'b1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	reg [31:0] reg_pc, reg_next_pc, reg_mepc, reg_op1, reg_op2, reg_out;
 | 
	
		
			
				|  |  |  	reg [4:0] reg_sh;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	reg [31:0] next_insn_opcode;
 | 
	
	
		
			
				|  | @@ -695,7 +714,7 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  	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_csrr, instr_ecall_ebreak;
 | 
	
		
			
				|  |  | -	reg instr_addqxi, instr_addxqi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer;
 | 
	
		
			
				|  |  | +	reg instr_addqxi, instr_addxqi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer, instr_pollirq;
 | 
	
		
			
				|  |  |  	reg instr_ctz;
 | 
	
		
			
				|  |  |          reg [2:0] instr_funct2;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -730,7 +749,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_csrr, instr_addqxi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer, instr_ctz};
 | 
	
		
			
				|  |  | +			instr_csrr, instr_addqxi, instr_retirq, instr_maskirq, instr_waitirq, instr_timer, instr_pollirq, instr_ctz};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	reg [63:0] new_ascii_instr;
 | 
	
		
			
				|  |  |  	`FORMAL_KEEP reg [63:0] dbg_ascii_instr;
 | 
	
	
		
			
				|  | @@ -793,10 +812,11 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	        if (instr_addqxi)   new_ascii_instr = "addqxi";
 | 
	
		
			
				|  |  |  	        if (instr_addxqi)   new_ascii_instr = "addxqi";
 | 
	
		
			
				|  |  | -		if (instr_retirq)   new_ascii_instr = "retirq";
 | 
	
		
			
				|  |  | +	        if (instr_retirq)   new_ascii_instr = "mret";
 | 
	
		
			
				|  |  |  		if (instr_maskirq)  new_ascii_instr = "maskirq";
 | 
	
		
			
				|  |  |  		if (instr_waitirq)  new_ascii_instr = "waitirq";
 | 
	
		
			
				|  |  |  		if (instr_timer)    new_ascii_instr = "timer";
 | 
	
		
			
				|  |  | +	        if (instr_pollirq)  new_ascii_instr = "pollirq";
 | 
	
		
			
				|  |  |  	end
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	reg [63:0] q_ascii_instr;
 | 
	
	
		
			
				|  | @@ -929,9 +949,6 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  			decoded_rs1   <= mem_rdata_latched[19:15];
 | 
	
		
			
				|  |  |  			decoded_rs2   <= mem_rdata_latched[24:20];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		        if (instr_la_retirq)
 | 
	
		
			
				|  |  | -				decoded_rs1 <= RA_IRQ_REG;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  			compressed_instr <= 0;
 | 
	
		
			
				|  |  |  			if (COMPRESSED_ISA && mem_rdata_latched[1:0] != 2'b11) begin
 | 
	
		
			
				|  |  |  				compressed_instr <= 1;
 | 
	
	
		
			
				|  | @@ -1148,6 +1165,8 @@ 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_pollirq <= mem_rdata_q[6:0] == 7'b0001011 && mem_rdata_q[14:12] == 3'b000 && mem_rdata_q[31:25] == 7'b0000110 && ENABLE_IRQ;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			// 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;
 | 
	
	
		
			
				|  | @@ -1230,6 +1249,7 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  		        instr_addxqi <= 0;
 | 
	
		
			
				|  |  |  		        instr_maskirq <= 0;
 | 
	
		
			
				|  |  |  		        instr_waitirq <= 0;
 | 
	
		
			
				|  |  | +		        instr_pollirq <= 0;
 | 
	
		
			
				|  |  |  		        instr_timer   <= 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		        instr_ecall_ebreak <= 0;
 | 
	
	
		
			
				|  | @@ -1394,10 +1414,6 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  					cpuregs_wrdata = latched_stalu ? alu_out_q : reg_out;
 | 
	
		
			
				|  |  |  					cpuregs_write = 1;
 | 
	
		
			
				|  |  |  				end
 | 
	
		
			
				|  |  | -				ENABLE_IRQ && irq_state[0]: begin
 | 
	
		
			
				|  |  | -					cpuregs_wrdata = reg_next_pc | latched_compr;
 | 
	
		
			
				|  |  | -					cpuregs_write = 1;
 | 
	
		
			
				|  |  | -				end
 | 
	
		
			
				|  |  |  				ENABLE_IRQ && irq_state[1]: begin
 | 
	
		
			
				|  |  |  					cpuregs_wrdata = irq_pending & ~irq_mask;
 | 
	
		
			
				|  |  |  					cpuregs_write = 1;
 | 
	
	
		
			
				|  | @@ -1516,14 +1532,6 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  			pcpi_timeout <= !pcpi_timeout_counter;
 | 
	
		
			
				|  |  |  		end
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		if (ENABLE_COUNTERS) begin
 | 
	
		
			
				|  |  | -			count_cycle <= resetn ? count_cycle + 1 : 0;
 | 
	
		
			
				|  |  | -			if (!ENABLE_COUNTERS64) count_cycle[63:32] <= 0;
 | 
	
		
			
				|  |  | -		end else begin
 | 
	
		
			
				|  |  | -			count_cycle <= 'bx;
 | 
	
		
			
				|  |  | -			count_instr <= 'bx;
 | 
	
		
			
				|  |  | -		end
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  		next_irq_pending = ENABLE_IRQ ? (irq_pending & LATCHED_IRQ & ~MASKED_IRQ) : 'bx;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		if (ENABLE_IRQ && ENABLE_IRQ_TIMER && timer) begin
 | 
	
	
		
			
				|  | @@ -1541,11 +1549,16 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  		if (!ENABLE_TRACE)
 | 
	
		
			
				|  |  |  			trace_data <= 'bx;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	        if (!resetn)
 | 
	
		
			
				|  |  | +			count_cycle <= 0;
 | 
	
		
			
				|  |  | +	        else
 | 
	
		
			
				|  |  | +			count_cycle <= (count_cycle + 1'b1) & count_cycle_mask;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  		if (!resetn) begin
 | 
	
		
			
				|  |  |  			reg_pc <= progaddr_reset;
 | 
	
		
			
				|  |  |  			reg_next_pc <= progaddr_reset;
 | 
	
		
			
				|  |  | -			if (ENABLE_COUNTERS)
 | 
	
		
			
				|  |  | -				count_instr <= 0;
 | 
	
		
			
				|  |  | +		        reg_mepc <= 0;
 | 
	
		
			
				|  |  | +		        count_instr <= 0;
 | 
	
		
			
				|  |  |  			latched_store <= 0;
 | 
	
		
			
				|  |  |  			latched_stalu <= 0;
 | 
	
		
			
				|  |  |  			latched_branch <= 0;
 | 
	
	
		
			
				|  | @@ -1569,7 +1582,7 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  				reg_out <= STACKADDR;
 | 
	
		
			
				|  |  |  			end
 | 
	
		
			
				|  |  |  			cpu_state <= cpu_state_fetch;
 | 
	
		
			
				|  |  | -		end else
 | 
	
		
			
				|  |  | +		end else // if (!resetn)
 | 
	
		
			
				|  |  |  		(* parallel_case, full_case *)
 | 
	
		
			
				|  |  |  		case (cpu_state)
 | 
	
		
			
				|  |  |  			cpu_state_trap: begin
 | 
	
	
		
			
				|  | @@ -1592,7 +1605,7 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  						`debug($display("ST_RD:  %2d 0x%08x", latched_rd, latched_stalu ? alu_out_q : reg_out);)
 | 
	
		
			
				|  |  |  					end
 | 
	
		
			
				|  |  |  					ENABLE_IRQ && irq_state[0]: begin
 | 
	
		
			
				|  |  | -						current_pc = progaddr_irq;
 | 
	
		
			
				|  |  | +						current_pc = progaddr_irq & ~1;
 | 
	
		
			
				|  |  |  						irq_active <= 1;
 | 
	
		
			
				|  |  |  						mem_do_rinst <= 1;
 | 
	
		
			
				|  |  |  					end
 | 
	
	
		
			
				|  | @@ -1631,7 +1644,8 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  						irq_state == 2'b00 ? 2'b01 :
 | 
	
		
			
				|  |  |  						irq_state == 2'b01 ? 2'b10 : 2'b00;
 | 
	
		
			
				|  |  |  					latched_compr <= latched_compr;
 | 
	
		
			
				|  |  | -				        latched_rd <= irq_state[0] ? MASK_IRQ_REG : RA_IRQ_REG;
 | 
	
		
			
				|  |  | +				        latched_rd <= MASK_IRQ_REG;
 | 
	
		
			
				|  |  | +				        reg_mepc  <= reg_next_pc | latched_compr;
 | 
	
		
			
				|  |  |  				end else
 | 
	
		
			
				|  |  |  				if (ENABLE_IRQ && do_waitirq) begin
 | 
	
		
			
				|  |  |  					if (&(irq_pending | ~reg_op1) || |(irq_pending & reg_op2)) begin
 | 
	
	
		
			
				|  | @@ -1654,10 +1668,7 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  					reg_next_pc <= current_pc + (compressed_instr ? 2 : 4);
 | 
	
		
			
				|  |  |  					if (ENABLE_TRACE)
 | 
	
		
			
				|  |  |  						latched_trace <= 1;
 | 
	
		
			
				|  |  | -					if (ENABLE_COUNTERS) begin
 | 
	
		
			
				|  |  | -						count_instr <= count_instr + 1;
 | 
	
		
			
				|  |  | -						if (!ENABLE_COUNTERS64) count_instr[63:32] <= 0;
 | 
	
		
			
				|  |  | -					end
 | 
	
		
			
				|  |  | +				        count_instr <= (count_instr + 1'b1) & count_instr_mask;
 | 
	
		
			
				|  |  |  					if (instr_jal) begin
 | 
	
		
			
				|  |  |  						mem_do_rinst <= 1;
 | 
	
		
			
				|  |  |  						reg_next_pc <= current_pc + decoded_imm_j;
 | 
	
	
		
			
				|  | @@ -1722,13 +1733,15 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  						reg_out <= 32'bx;
 | 
	
		
			
				|  |  |  						case (decoded_imm[11:0])
 | 
	
		
			
				|  |  |  							12'hc00, 12'hc01:	 // cycle, time
 | 
	
		
			
				|  |  | -							  if (ENABLE_COUNTERS)   reg_out <= count_cycle[31:0];
 | 
	
		
			
				|  |  | +							  reg_out <= count_cycle[31:0];
 | 
	
		
			
				|  |  |  							12'hc80, 12'hc81:	 // cycleh, timeh
 | 
	
		
			
				|  |  | -							  if (ENABLE_COUNTERS64) reg_out <= count_cycle[63:32];
 | 
	
		
			
				|  |  | +							  reg_out <= count_cycle[63:32];
 | 
	
		
			
				|  |  |  							12'hc02:		 // instret (rdinstr)
 | 
	
		
			
				|  |  | -							  if (ENABLE_COUNTERS)   reg_out <= count_instr[31:0];
 | 
	
		
			
				|  |  | +							  reg_out <= count_instr[31:0];
 | 
	
		
			
				|  |  |  							12'hc82:		 // instret (rdinstr)
 | 
	
		
			
				|  |  | -							  if (ENABLE_COUNTERS64) reg_out <= count_instr[63:32];
 | 
	
		
			
				|  |  | +							  reg_out <= count_instr[63:32];
 | 
	
		
			
				|  |  | +						        12'h341:		 // mepc
 | 
	
		
			
				|  |  | +							  if (ENABLE_IRQ) reg_out <= reg_mepc;
 | 
	
		
			
				|  |  |  							12'h343:		 // mtval
 | 
	
		
			
				|  |  |  							  if (CATCH_MISALIGN)    reg_out <= buserr_address;
 | 
	
		
			
				|  |  |  						        12'h7f0:                 // user_context
 | 
	
	
		
			
				|  | @@ -1740,6 +1753,9 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  					        // Bitops not supported ATM, treat as readonly
 | 
	
		
			
				|  |  |  					        if (~instr_funct2[1])
 | 
	
		
			
				|  |  |  						  case (decoded_imm[11:0])
 | 
	
		
			
				|  |  | +						    12'h341: begin		        // mepc
 | 
	
		
			
				|  |  | +						       reg_mepc <= csrr_src;
 | 
	
		
			
				|  |  | +						    end
 | 
	
		
			
				|  |  |  						    12'h7f0: begin			// user_context
 | 
	
		
			
				|  |  |  						       user_context <= csrr_src;
 | 
	
		
			
				|  |  |  						       irq_active   <= 1'b1;
 | 
	
	
		
			
				|  | @@ -1766,9 +1782,9 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  						irq_active <= 0;
 | 
	
		
			
				|  |  |  						latched_branch <= 1;
 | 
	
		
			
				|  |  |  						latched_store <= 1;
 | 
	
		
			
				|  |  | -						`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
 | 
	
		
			
				|  |  | -						reg_out <= CATCH_MISALIGN ? (cpuregs_rs1 & 32'h fffffffe) : cpuregs_rs1;
 | 
	
		
			
				|  |  | -						dbg_rs1val <= cpuregs_rs1;
 | 
	
		
			
				|  |  | +					        `debug($display("MRET: 0x%08x", reg_mepc);)
 | 
	
		
			
				|  |  | +					        reg_out <= reg_mepc & ~1;
 | 
	
		
			
				|  |  | +					        dbg_rs1val <= reg_mepc;
 | 
	
		
			
				|  |  |  						dbg_rs1val_valid <= 1;
 | 
	
		
			
				|  |  |  						cpu_state <= cpu_state_fetch;
 | 
	
		
			
				|  |  |  					end
 | 
	
	
		
			
				|  | @@ -1806,6 +1822,12 @@ module picorv32 #(
 | 
	
		
			
				|  |  |  						dbg_rs1val_valid <= 1;
 | 
	
		
			
				|  |  |  						cpu_state <= cpu_state_fetch;
 | 
	
		
			
				|  |  |  					end
 | 
	
		
			
				|  |  | +				        ENABLE_IRQ && instr_pollirq: begin
 | 
	
		
			
				|  |  | +						latched_store <= 1;
 | 
	
		
			
				|  |  | +					        reg_out <= (irq_pending & ~irq_mask & ~cpuregs_rs1) | cpuregs_rs2;
 | 
	
		
			
				|  |  | +					        eoi <= irq_pending & ~irq_mask & ~cpuregs_rs1;
 | 
	
		
			
				|  |  | +					        next_irq_pending = next_irq_pending & (irq_mask | cpuregs_rs1);
 | 
	
		
			
				|  |  | +					end
 | 
	
		
			
				|  |  |  					is_lb_lh_lw_lbu_lhu && !instr_trap: begin
 | 
	
		
			
				|  |  |  						`debug($display("LD_RS1: %2d 0x%08x", decoded_rs1, cpuregs_rs1);)
 | 
	
		
			
				|  |  |  						reg_op1 <= cpuregs_rs1;
 |