There is another register stage delay between the logical interrupt signal below and the "ic_irq" interrupt signal that goes to CPU pipeline and is responsible for saving the PC in the iret. If we align the GIE and IDLE instructions on a 64 bit boundary in the code as a workaround, then we know that they will enter the pipeline together on consecutive cycles guaranteeing that the interrupt cannot sneak between the GIE and IDLE instructions (really on the GIE instruction). I agree it would have been better to enable interrupts automatically with the IDLE instruction.. but sometimes you get lucky
Here's the key RTL code snippet..
assign ic_irq_select[IRQW-1:0]= ic_masked_ilat[IRQW-1:0] & //only if the ILAT bit is not masked by IMASK
~ic_ilat_priority_en_n[IRQW-1:0] & //only if there is no masked ilat bit <current
~ic_ipend_priority_en_n[IRQW-1:0] & //only if there is no ipend bit <=current
ic_global_en[IRQW-1:0]; //global vector for nested interrupts
always @ (posedge clk or posedge reset)
if(reset)
ic_irq_entry[IRQW-1:0] <= {(IRQW){1'b0}};
else if(clk_en)
if(~sq_ic_wait) // safety stall signal
ic_irq_entry[IRQW-1:0] <= ic_irq_select[IRQW-1:0];// & ~ic_irq_entry[IRQW-1:0] ;
assign ic_irq =|(ic_irq_entry[IRQW-1:0]); //interrupt pipeline
assign ic_flush =|(ic_irq_select[IRQW-1:0]); //flush pipelineStatistics: Posted by aolofsson — Thu Sep 26, 2013 3:05 am
]]>