Implement new IRQ behaviour, and change mip.meip to be masked by individual enables in meip0
This commit is contained in:
		
							parent
							
								
									4053458485
								
							
						
					
					
						commit
						5f8d217395
					
				|  | @ -1 +0,0 @@ | |||
| *.pdf | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -72,9 +72,9 @@ External IRQ pending register 0. Contains a read-only bit for each external inte | |||
| 
 | ||||
| Addresses `0xfe1` through `0xfe3` are reserved for further `meip` registers, supporting up to 128 external interrupts. | ||||
| 
 | ||||
| When any bit is set in `meip0`, the standard external interrupt pending bit `mip.meip` is also set. An external interrupt is taken when all of the following are true: | ||||
| When any bit is set in both `meip0` and `meie0`, the standard external interrupt pending bit `mip.meip` is also set. In other words, `meip0` is filtered by `meie0` to generate the standard `mip.meip` flag. So, an external interrupt is taken when _all_ of the following are true: | ||||
| 
 | ||||
| * The interrupt is currently asserted in `meip0` | ||||
| * An interrupt is currently asserted in `meip0` | ||||
| * The matching interrupt enable bit is set in `meie0` | ||||
| * The standard M-mode interrupt enable `mstatus.mie` is set | ||||
| * The standard M-mode global external interrupt enable `mie.meie` is set | ||||
|  | @ -84,7 +84,7 @@ In this case, the processor jumps to either: | |||
| * `mtvec` directly, if vectoring is disabled (`mtvec[0]` is 0) | ||||
| * `mtvec + 0x2c`, if vectoring is enabled (`mtvec[0]` is 1) and modified external IRQ vectoring is disabled (`midcr.eivect` is 0) | ||||
| * `mtvect + (mlei + 16) * 4`, if vectoring is enabled (`mtvec[0]` is 1) and modified external IRQ vectoring is enabled (`midcr.eivect` is 1). ` | ||||
| ** `mlei` is a read-only CSR containing the lowest-numbered | ||||
| ** `mlei` is a read-only CSR containing the lowest-numbered pending-and-enabled external interrupt. | ||||
| 
 | ||||
| ==== mlei | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,6 +4,10 @@ | |||
| // your top-level instantiation, it's up to you. These parameters are all | ||||
| // plumbed through Hazard3's internal hierarchy to the appropriate places. | ||||
| 
 | ||||
| // If you add a parameter here, you should add a matching line to | ||||
| // hazard3_config_inst.vh to propagate the parameter through module | ||||
| // instantiations. | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Reset state configuration | ||||
| 
 | ||||
|  | @ -41,7 +45,11 @@ parameter CSR_M_MANDATORY = 1, | |||
| parameter CSR_M_TRAP      = 1, | ||||
| 
 | ||||
| // CSR_COUNTER: Include performance counters and relevant M-mode CSRs | ||||
| parameter CSR_COUNTER     = 0, | ||||
| parameter CSR_COUNTER     = 1, | ||||
| 
 | ||||
| // NUM_IRQ: Number of external IRQs implemented in meie0 and meip0. | ||||
| // Minimum 1 (if CSR_M_TRAP = 1), maximum 32. | ||||
| parameter NUM_IRQ         = 32, | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // ID registers | ||||
|  |  | |||
|  | @ -9,6 +9,10 @@ | |||
| .CSR_M_MANDATORY (CSR_M_MANDATORY), | ||||
| .CSR_M_TRAP      (CSR_M_TRAP), | ||||
| .CSR_COUNTER     (CSR_COUNTER), | ||||
| .NUM_IRQ         (NUM_IRQ), | ||||
| .MVENDORID_VAL   (MVENDORID_VAL), | ||||
| .MARCHID_VAL     (MARCHID_VAL), | ||||
| .MIMPID_VAL      (MIMPID_VAL), | ||||
| .REDUCED_BYPASS  (REDUCED_BYPASS), | ||||
| .MULDIV_UNROLL   (MULDIV_UNROLL), | ||||
| .MUL_FAST        (MUL_FAST), | ||||
|  |  | |||
|  | @ -53,8 +53,10 @@ module hazard3_core #( | |||
| 	output reg  [W_DATA-1:0] bus_wdata_d, | ||||
| 	input  wire [W_DATA-1:0] bus_rdata_d, | ||||
| 
 | ||||
| 	// External level-sensitive interrupt sources (tie 0 if unused) | ||||
| 	input wire [15:0]        irq | ||||
| 	// Level-sensitive interrupt sources | ||||
| 	input wire [NUM_IRQ-1:0] irq,       // -> mip.meip | ||||
| 	input wire               soft_irq,  // -> mip.msip | ||||
| 	input wire               timer_irq  // -> mip.mtip | ||||
| ); | ||||
| 
 | ||||
| `include "hazard3_ops.vh" | ||||
|  | @ -493,6 +495,8 @@ hazard3_csr #( | |||
| 	// IRQ and exception requests | ||||
| 	.delay_irq_entry         (xm_delay_irq_entry), | ||||
| 	.irq                     (irq), | ||||
| 	.irq_software            (soft_irq), | ||||
| 	.irq_timer               (timer_irq), | ||||
| 	.except                  (xm_except), | ||||
| 
 | ||||
| 	// Other CSR-specific signalling | ||||
|  |  | |||
|  | @ -43,8 +43,10 @@ module hazard3_cpu_1port #( | |||
| 	output wire [W_DATA-1:0] ahblm_hwdata, | ||||
| 	input  wire [W_DATA-1:0] ahblm_hrdata, | ||||
| 
 | ||||
| 	// External level-sensitive interrupt sources (tie 0 if unused) | ||||
| 	input wire [15:0]        irq | ||||
| 	// Level-sensitive interrupt sources | ||||
| 	input wire [NUM_IRQ-1:0] irq,          // -> mip.meip | ||||
| 	input wire               irq_software, // -> mip.msip | ||||
| 	input wire               irq_timer     // -> mip.mtip | ||||
| ); | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
|  | @ -104,7 +106,9 @@ hazard3_core #( | |||
| 	.bus_wdata_d     (core_wdata_d), | ||||
| 	.bus_rdata_d     (core_rdata_d), | ||||
| 
 | ||||
| 	.irq             (irq) | ||||
| 	.irq             (irq), | ||||
| 	.soft_irq        (soft_irq), | ||||
| 	.timer_irq       (timer_irq) | ||||
| ); | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -56,8 +56,10 @@ module hazard3_cpu_2port #( | |||
| 	output wire [W_DATA-1:0] d_hwdata, | ||||
| 	input  wire [W_DATA-1:0] d_hrdata, | ||||
| 
 | ||||
| 	// External level-sensitive interrupt sources (tie 0 if unused) | ||||
| 	input wire [15:0]        irq | ||||
| 	// Level-sensitive interrupt sources | ||||
| 	input wire [NUM_IRQ-1:0] irq,       // -> mip.meip | ||||
| 	input wire               soft_irq,  // -> mip.msip | ||||
| 	input wire               timer_irq  // -> mip.mtip | ||||
| ); | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
|  | @ -117,7 +119,9 @@ hazard3_core #( | |||
| 	.bus_wdata_d     (core_wdata_d), | ||||
| 	.bus_rdata_d     (core_rdata_d), | ||||
| 
 | ||||
| 	.irq             (irq) | ||||
| 	.irq             (irq), | ||||
| 	.soft_irq        (soft_irq), | ||||
| 	.timer_irq       (timer_irq) | ||||
| ); | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
|  |  | |||
|  | @ -70,10 +70,14 @@ module hazard3_csr #( | |||
| 	input  wire [XLEN-1:0]     mepc_in, | ||||
| 
 | ||||
| 	// Exceptions must *not* be a function of bus stall. | ||||
| 	input  wire                delay_irq_entry, | ||||
| 	input  wire [15:0]         irq, | ||||
| 	input  wire [W_EXCEPT-1:0] except, | ||||
| 
 | ||||
| 	// Level-sensitive interrupt sources | ||||
| 	input  wire                delay_irq_entry, | ||||
| 	input  wire [NUM_IRQ-1:0]  irq, | ||||
| 	input  wire                irq_software, | ||||
| 	input  wire                irq_timer, | ||||
| 
 | ||||
| 	// Other CSR-specific signalling | ||||
| 	input  wire                instr_ret | ||||
| ); | ||||
|  | @ -215,6 +219,12 @@ localparam MHPMEVENT29    = 12'h33d; // WARL (we tie to 0) | |||
| localparam MHPMEVENT30    = 12'h33e; // WARL (we tie to 0) | ||||
| localparam MHPMEVENT31    = 12'h33f; // WARL (we tie to 0) | ||||
| 
 | ||||
| // Custom M-mode CSRs: | ||||
| localparam MIDCR          = 12'hbc0; // Implementation-defined control register (bag of bits) | ||||
| localparam MEIE0          = 12'hbe0; // External interrupt enable register 0 | ||||
| localparam MEIP0          = 12'hfe0; // External interrupt pending register 0 | ||||
| localparam MLEI           = 12'hfe4; // Lowest external interrupt number | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // CSR state + update logic | ||||
| // ---------------------------------------------------------------------------- | ||||
|  | @ -231,8 +241,38 @@ begin | |||
| end | ||||
| endfunction | ||||
| 
 | ||||
| function [XLEN-1:0] update_nonconst; | ||||
| 	input [XLEN-1:0] prev; | ||||
| 	input [XLEN-1:0] nonconst; | ||||
| begin | ||||
| 	update_nonconst = (( | ||||
| 		wtype == CSR_WTYPE_C ? prev & ~wdata : | ||||
| 		wtype == CSR_WTYPE_S ? prev | wdata : | ||||
| 		wdata) & nonconst) | (prev & ~nonconst) ; | ||||
| end | ||||
| endfunction | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Trap-handling | ||||
| // Implementation-defined control register | ||||
| 
 | ||||
| localparam MIDCR_INIT = X0; | ||||
| localparam MIDCR_WMASK = 32'h00000001; | ||||
| 
 | ||||
| reg [XLEN-1:0] midcr; | ||||
| 
 | ||||
| always @ (posedge clk or negedge rst_n) begin | ||||
| 	if (!rst_n) begin | ||||
| 		midcr <= MIDCR_INIT; | ||||
| 	end else if (wen && addr == MIDCR) begin | ||||
| 		midcr <= update_nonconst(midcr, MIDCR_WMASK); | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| // Modified external interrupt vectoring | ||||
| wire midcr_eivect = midcr[0]; | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Trap-handling CSRs | ||||
| 
 | ||||
| // Two-level interrupt enable stack, shuffled on entry/exit: | ||||
| reg mstatus_mpie; | ||||
|  | @ -273,7 +313,7 @@ end | |||
| 
 | ||||
| // Trap vector base | ||||
| reg  [XLEN-1:0] mtvec_reg; | ||||
| wire [XLEN-1:0] mtvec = ((mtvec_reg & MTVEC_WMASK) | (MTVEC_INIT & ~MTVEC_WMASK)) & ({XLEN{1'b1}} << 2); | ||||
| wire [XLEN-1:0] mtvec = mtvec_reg & ({XLEN{1'b1}} << 2); | ||||
| wire            irq_vector_enable = mtvec_reg[0]; | ||||
| 
 | ||||
| always @ (posedge clk or negedge rst_n) begin | ||||
|  | @ -281,7 +321,7 @@ always @ (posedge clk or negedge rst_n) begin | |||
| 		mtvec_reg <= MTVEC_INIT; | ||||
| 	end else if (CSR_M_TRAP) begin | ||||
| 		if (wen && addr == MTVEC) | ||||
| 			mtvec_reg <= update(mtvec_reg); | ||||
| 			mtvec_reg <= update_nonconst(mtvec_reg, MTVEC_WMASK); | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
|  | @ -304,21 +344,18 @@ end | |||
| 
 | ||||
| // Interrupt enable (reserved bits are tied to 0) | ||||
| reg [XLEN-1:0] mie; | ||||
| localparam MIE_CONST_MASK = 32'h0000f777; | ||||
| localparam MIE_WMASK = 32'h00000888; // meie, mtip, msip | ||||
| 
 | ||||
| always @ (posedge clk or negedge rst_n) begin | ||||
| 	if (!rst_n) begin | ||||
| 		mie <= X0; | ||||
| 	end else if (CSR_M_TRAP) begin | ||||
| 		if (wen && addr == MIE) | ||||
| 			mie <= update(mie) & ~MIE_CONST_MASK; | ||||
| 			mie <= update_nonconst(mie, MIE_WMASK); | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| wire [15:0] mie_irq  = mie[31:16]; // Per-IRQ mask. Nonstandard, but legal. | ||||
| wire        mie_meie = mie[11];   // Global external IRQ enable. This is ANDed over our per-IRQ mask | ||||
| wire        mie_mtie = mie[7];    // Timer interrupt enable | ||||
| wire        mie_msie = mie[3];    // Software interrupt enable | ||||
| wire mie_meie = mie[11]; | ||||
| 
 | ||||
| // Interrupt status ("pending") register, handled later | ||||
| wire [XLEN-1:0] mip; | ||||
|  | @ -329,27 +366,47 @@ wire [XLEN-1:0] mip; | |||
| // Trap cause registers. The non-constant bits can be written by software, | ||||
| // and update automatically on trap entry. (bits 30:0 are WLRL, so we tie most off) | ||||
| reg        mcause_irq; | ||||
| reg  [4:0] mcause_code; | ||||
| reg  [5:0] mcause_code; | ||||
| wire       mcause_irq_next; | ||||
| wire [4:0] mcause_code_next; | ||||
| wire [5:0] mcause_code_next; | ||||
| 
 | ||||
| always @ (posedge clk or negedge rst_n) begin | ||||
| 	if (!rst_n) begin | ||||
| 		mcause_irq <= 1'b0; | ||||
| 		mcause_code <= 5'h0; | ||||
| 		mcause_code <= 6'h0; | ||||
| 	end else if (CSR_M_TRAP) begin | ||||
| 		if (trap_enter_vld && trap_enter_rdy && except != EXCEPT_MRET) begin | ||||
| 			mcause_irq <= mcause_irq_next; | ||||
| 			mcause_code <= mcause_code_next; | ||||
| 		end else if (wen && addr == MCAUSE) begin | ||||
| 			{mcause_irq, mcause_code} <= | ||||
| 				wtype == CSR_WTYPE_C ? {mcause_irq, mcause_code} & ~{wdata[31], wdata[4:0]} : | ||||
| 				wtype == CSR_WTYPE_S ? {mcause_irq, mcause_code} |  {wdata[31], wdata[4:0]} : | ||||
| 				                                                    {wdata[31], wdata[4:0]} ; | ||||
| 				wtype == CSR_WTYPE_C ? {mcause_irq, mcause_code} & ~{wdata[31], wdata[5:0]} : | ||||
| 				wtype == CSR_WTYPE_S ? {mcause_irq, mcause_code} |  {wdata[31], wdata[5:0]} : | ||||
| 				                                                    {wdata[31], wdata[5:0]} ; | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| // Custom external interrupt enable register (would be at top of mie, but that | ||||
| // only leaves room for 16 external interrupts) | ||||
| 
 | ||||
| localparam MEIE0_WMASK = ~({XLEN{1'b1}} << NUM_IRQ); | ||||
| 
 | ||||
| reg [XLEN-1:0] meie0; | ||||
| 
 | ||||
| always @ (posedge clk or negedge rst_n) begin | ||||
| 	if (!rst_n) begin | ||||
| 		// All-ones for implemented IRQs | ||||
| 		meie0 <= MEIE0_WMASK; | ||||
| 	end else if (wen && addr == MEIE0) begin | ||||
| 		meie0 <= update_nonconst(meie0, MEIE0_WMASK); | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| // Assigned later: | ||||
| wire [XLEN-1:0] meip0; | ||||
| wire [4:0] mlei; | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Counters | ||||
| 
 | ||||
|  | @ -517,6 +574,7 @@ always @ (*) begin | |||
| 	end | ||||
| 
 | ||||
| 	MIP: if (CSR_M_TRAP) begin | ||||
| 		// Writes are permitted, but ignored. | ||||
| 		decode_match = 1'b1; | ||||
| 		rdata = mip; | ||||
| 	end | ||||
|  | @ -652,6 +710,29 @@ always @ (*) begin | |||
| 		rdata = minstreth; | ||||
| 	end | ||||
| 
 | ||||
|     // ------------------------------------------------------------------------ | ||||
| 	// Custom CSRs | ||||
| 
 | ||||
| 	MIDCR: if (CSR_M_TRAP) begin | ||||
| 		decode_match = 1'b1; | ||||
| 		rdata = midcr; | ||||
| 	end | ||||
| 
 | ||||
| 	MEIE0: if (CSR_M_TRAP) begin | ||||
| 		decode_match = 1'b1; | ||||
| 		rdata = meie0; | ||||
| 	end | ||||
| 
 | ||||
| 	MEIP0: if (CSR_M_TRAP) begin | ||||
| 		decode_match = !wen_soon; | ||||
| 		rdata = meip0; | ||||
| 	end | ||||
| 
 | ||||
| 	MLEI: if (CSR_M_TRAP) begin | ||||
| 		decode_match = !wen_soon; | ||||
| 		rdata = {{XLEN-5{1'b0}}, mlei}; | ||||
| 	end | ||||
| 
 | ||||
| 	default: begin end | ||||
| 	endcase | ||||
| end | ||||
|  | @ -660,53 +741,74 @@ assign illegal = (wen_soon || ren_soon) && !decode_match; | |||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| // Trap request generation | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
| reg [NUM_IRQ-1:0] irq_r; | ||||
| reg irq_software_r; | ||||
| reg irq_timer_r; | ||||
| 
 | ||||
| always @ (posedge clk or negedge rst_n) begin | ||||
| 	if (!rst_n) begin | ||||
| 		irq_r <= {NUM_IRQ{1'b0}}; | ||||
| 		irq_software_r <= 1'b0; | ||||
| 		irq_timer_r <= 1'b0; | ||||
| 	end else begin | ||||
| 		irq_r <= irq; | ||||
| 		irq_software_r <= irq_software; | ||||
| 		irq_timer_r <= irq_timer; | ||||
| 	end | ||||
| end | ||||
| 
 | ||||
| assign meip0 = {{XLEN-NUM_IRQ{1'b0}}, irq_r}; | ||||
| wire external_irq_pending = |(meie0 & meip0); | ||||
| 
 | ||||
| assign mip = { | ||||
| 	20'h0,                // Reserved | ||||
| 	external_irq_pending, // meip, Global pending bit for external IRQs | ||||
| 	3'h0,                 // Reserved | ||||
| 	irq_timer_r,          // mtip, interrupt from memory-mapped timer peripheral | ||||
| 	3'h0,                 // Reserved | ||||
| 	irq_software_r,       // msip, software interrupt from memory-mapped register | ||||
| 	3'h0                  // Reserved | ||||
| }; | ||||
| 
 | ||||
| // When eivect = 1, mip.meip is masked from the standard IRQs, so that the | ||||
| // platform-specific causes and vectors are used instead. | ||||
| wire [31:0] mip_no_global = mip & ~(32'h800 & ~{XLEN{midcr_eivect}}); | ||||
| wire standard_irq_active = |(mip_no_global & mie) && mstatus_mie; | ||||
| wire external_irq_active = external_irq_pending && mstatus_mie && mie_meie; | ||||
| 
 | ||||
| wire [4:0] external_irq_num; | ||||
| wire [3:0] standard_irq_num; | ||||
| assign mlei = external_irq_num; | ||||
| 
 | ||||
| hazard3_priority_encode #( | ||||
| 	.W_REQ (32) | ||||
| ) mlei_priority_encode ( | ||||
| 	.req (meie0 & meip0), | ||||
| 	.gnt (external_irq_num) | ||||
| ); | ||||
| 
 | ||||
| hazard3_priority_encode #( | ||||
| 	.W_REQ (16) | ||||
| ) irq_priority ( | ||||
| 	.req (mip_no_global[15:0] & mie[15:0]), | ||||
| 	.gnt (standard_irq_num) | ||||
| ); | ||||
| 
 | ||||
| wire exception_req_any = except != EXCEPT_NONE; | ||||
| 
 | ||||
| // Interrupt masking and selection | ||||
| wire [5:0] vector_sel =  | ||||
| 	exception_req_any || !irq_vector_enable ? 6'd0                     : | ||||
| 	standard_irq_active                     ? standard_irq_num         : | ||||
| 	external_irq_active                     ? 6'd16 + external_irq_num : 6'd0; | ||||
| 
 | ||||
| reg [15:0] irq_r; | ||||
| 
 | ||||
| always @ (posedge clk or negedge rst_n) | ||||
| 	if (!rst_n) | ||||
| 		irq_r <= 16'h0; | ||||
| 	else | ||||
| 		irq_r <= irq; | ||||
| 
 | ||||
| assign mip = { | ||||
| 	irq_r,  // Our nonstandard bits for per-IRQ status | ||||
| 	4'h0,   // Reserved | ||||
| 	|irq_r, // Global pending bit for external IRQs | ||||
| 	3'h0,   // Reserved | ||||
| 	1'b0,   // Timer (FIXME) | ||||
| 	3'h0,   // Reserved | ||||
| 	1'b0,   // Software interrupt (FIXME) | ||||
| 	3'h0    // Reserved | ||||
| }; | ||||
| 
 | ||||
| // We don't actually trap the aggregate IRQ, just provide it for software info | ||||
| wire [31:0] mip_no_global = mip & 32'hffff_f7ff; | ||||
| wire        irq_any = |(mip_no_global & {{16{mie_meie}}, {16{1'b1}}}) && mstatus_mie && !delay_irq_entry; | ||||
| wire [4:0]  irq_num; | ||||
| 
 | ||||
| hazard3_priority_encode #( | ||||
| 	.W_REQ(32) | ||||
| ) irq_priority ( | ||||
| 	.req (mip_no_global), | ||||
| 	.gnt (irq_num) | ||||
| ); | ||||
| 
 | ||||
| wire [11:0] mtvec_offs = ( | ||||
| 	exception_req_any || !irq_vector_enable ? 12'h0 : {7'h0, irq_num} | ||||
| ) << 2; | ||||
| 
 | ||||
| assign trap_addr = except == EXCEPT_MRET ? mepc : mtvec | {20'h0, mtvec_offs}; | ||||
| assign trap_addr = except == EXCEPT_MRET ? mepc : mtvec | {24'h0, vector_sel, 2'h0}; | ||||
| assign trap_is_irq = !exception_req_any; | ||||
| assign trap_enter_vld = CSR_M_TRAP && (exception_req_any || irq_any); | ||||
| assign trap_enter_vld = CSR_M_TRAP && (exception_req_any || | ||||
| 	!delay_irq_entry && (standard_irq_active || external_irq_active)); | ||||
| 
 | ||||
| assign mcause_irq_next = !exception_req_any; | ||||
| assign mcause_code_next = exception_req_any ? except : {1'b0, irq_num}; | ||||
| assign mcause_code_next = exception_req_any ? {2'h0, except} : vector_sel; | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------- | ||||
| 
 | ||||
|  | @ -736,6 +838,9 @@ always @ (posedge clk) begin | |||
| 	if (!trap_enter_rdy) | ||||
| 		assume(~|(irq_r & ~irq)); | ||||
| 
 | ||||
| 	// Make sure CSR accesses are flushed | ||||
| 	if (trap_enter_vld && trap_enter_rdy) | ||||
| 		assert(!(wen || ren)); | ||||
| 	// Something is screwed up if this happens | ||||
| 	if ($past(trap_enter_vld && trap_enter_rdy)) | ||||
| 		assert(!wen); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue