import Vivado project, rearrange Verilog sources
This commit is contained in:
parent
18b95b6bb6
commit
a441e7e042
29 changed files with 789 additions and 742 deletions
|
|
@ -1,73 +0,0 @@
|
|||
`timescale 1ns / 1ps
|
||||
|
||||
module irqctrl #(IRQ_LINES = 2, IRQ_DELAY_WIDTH = 4) (
|
||||
input wire clk,
|
||||
input wire [IRQ_LINES-1:0] irq_in,
|
||||
input wire cs,
|
||||
input wire wr_en,
|
||||
input wire irq_wr_seten,
|
||||
output wire [IRQ_LINES-1:0] rd_data,
|
||||
output wire irq_out
|
||||
);
|
||||
|
||||
reg [IRQ_LINES-1:0] irq_status; // a 1 bit here means we have seen an interrupt on that line
|
||||
reg [IRQ_LINES-1:0] irq_mask; // a bit in irq_status is only set if the corresponding bit in irq_mask is not set
|
||||
// irq_mask is set from irq_status when an interrupt occurs (ie irq_out is set)
|
||||
|
||||
reg irq_enabled; // globally enable/disable irq_out
|
||||
reg [IRQ_DELAY_WIDTH-1:0] irq_delay; // counter to delay irq_out for a few cycles
|
||||
reg irq_delaying; // delay is active
|
||||
|
||||
wire irq_pending = (irq_status != 0);
|
||||
|
||||
assign rd_data = irq_mask;
|
||||
assign irq_out = irq_enabled && irq_pending && !irq_delaying;
|
||||
|
||||
// irq_status and irq_pending flags
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(irq_out) // when an interrupt is being signaled to the cpu,
|
||||
irq_status <= 0; // clear irq status, status will be copied to irq_mask (see below)
|
||||
else
|
||||
if(irq_in != 0)
|
||||
irq_status <= irq_status | (irq_in & ~irq_mask); // add active irq to irq_status
|
||||
end
|
||||
|
||||
// irq mask
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (cs && wr_en && irq_wr_seten) // when enabling interrupts, clear mask
|
||||
irq_mask <= 0;
|
||||
else
|
||||
if(irq_out) // when signalling an interrupt, set mask from status
|
||||
irq_mask <= irq_status;
|
||||
end
|
||||
|
||||
// manage irq_enabled and irq_delay/irq_delaying
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(cs && wr_en) // when writing to control register
|
||||
begin
|
||||
if(irq_wr_seten) // if wr_seten flag is set, enable interrupts and start delay
|
||||
begin
|
||||
irq_enabled <= 1;
|
||||
irq_delaying <= 1;
|
||||
irq_delay <= 1;
|
||||
end
|
||||
else
|
||||
irq_enabled <= 0; // else disable interrupts
|
||||
end
|
||||
else if(irq_out) irq_enabled <= 0; // after sending interrupt to cpu, disable further interrupts
|
||||
|
||||
if(irq_delaying) // the delay gives the CPU a chance to return from an interrupt handler
|
||||
begin // if an interrupt is triggered again right after re-enabling interrupts
|
||||
if(irq_delay==0)
|
||||
begin
|
||||
irq_delay <= 1;
|
||||
irq_delaying <= 0;
|
||||
end
|
||||
else
|
||||
irq_delay <= irq_delay + 1;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Loading…
Add table
Add a link
Reference in a new issue