Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

pic: fix OPTION_PIC_TRIGGER="EDGE"

As pointed out in github issue #29, clearing an edge triggered
interrupt while the interrupt source is still high would
re-trigger the interrupt even though no new edge has
occurred.

This cures this by adding an additional registering
of the irq_unmasked signals and only set the picsr
spr register when an edge occurs.

Also, the priority between setting and clearing the
bits in picsr have been reversed.
  • Loading branch information...
commit 6caa7dba90cbe7c51421b542bd7b5ed487c83195 1 parent 28674ca
@skristiansson skristiansson authored
Showing with 25 additions and 17 deletions.
  1. +25 −17 rtl/verilog/mor1kx_pic.v
View
42 rtl/verilog/mor1kx_pic.v
@@ -72,23 +72,31 @@ module mor1kx_pic
genvar irqline;
if (OPTION_PIC_TRIGGER=="EDGE") begin : edge_triggered
- for(irqline=0;irqline<32;irqline=irqline+1)
- begin: picgenerate
- // PIC status register
- always @(posedge clk `OR_ASYNC_RST)
- if (rst)
- spr_picsr[irqline] <= 0;
- // Clear
- else if (spr_we_i & spr_picsr_access)
- spr_picsr[irqline] <= spr_dat_i[irqline] ? 0 :
- spr_picsr[irqline];
- // Set
- else if (!spr_picsr[irqline] & irq_unmasked[irqline])
- spr_picsr[irqline] <= 1;
- end // block: picgenerate
- end // if (OPTION_PIC_TRIGGER=="EDGE")
-
- else if (OPTION_PIC_TRIGGER=="LEVEL") begin : level_triggered
+ reg [31:0] irq_unmasked_r;
+ wire [31:0] irq_unmasked_edge;
+
+ always @(posedge clk `OR_ASYNC_RST)
+ if (rst)
+ irq_unmasked_r <= 0;
+ else
+ irq_unmasked_r <= irq_unmasked;
+
+ for(irqline=0;irqline<32;irqline=irqline+1) begin: picgenerate
+ assign irq_unmasked_edge[irqline] = irq_unmasked[irqline] &
+ !irq_unmasked_r[irqline];
+
+ // PIC status register
+ always @(posedge clk `OR_ASYNC_RST)
+ if (rst)
+ spr_picsr[irqline] <= 0;
+ // Set
+ else if (irq_unmasked_edge[irqline])
+ spr_picsr[irqline] <= 1;
+ // Clear
+ else if (spr_we_i & spr_picsr_access & spr_dat_i[irqline])
+ spr_picsr[irqline] <= 0;
+ end
+ end else if (OPTION_PIC_TRIGGER=="LEVEL") begin : level_triggered
for(irqline=0;irqline<32;irqline=irqline+1)
begin: picsrlevelgenerate
// PIC status register
Please sign in to comment.
Something went wrong with that request. Please try again.