OpenCores
URL https://opencores.org/ocsvn/interrupt_controller/interrupt_controller/trunk

Subversion Repositories interrupt_controller

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /interrupt_controller
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/rtl/int_contr.v
0,0 → 1,253
`timescale 1ns / 1ps
 
module interrupt_controller( clk,
reset,
cs,
adr,
oe,
we,
data_i,
data_o,
int1,
int2,
int3,
int4,
int5,
int6,
int7,
ack,
dtack,
ipl
);
 
input clk;
input reset;
input cs;
input [3:0] adr;
input oe;
input we;
input [7:0] data_i;
output [7:0] data_o;
input int1, int2, int3, int4, int5, int6, int7;
input ack;
output dtack;
output [2:0] ipl;
 
reg dtack = 1'b0;
reg ack_r = 1'b0;
reg [7:0] data_r;
reg [7:0] vectors [0:6];
reg [2:0] irq_nr [0:6];
reg [6:0] int_mask;
reg [6:0] int_pending;
reg [6:0] ie_reg;
reg [2:0] ipl_r, ipl_n;
 
wire [2:0] int_no = (6 - ipl_r);
wire assert_ack = (ack && ~ack_r);
wire deassert_ack = (ack_r && ~ack);
 
wire [2:0] ix = adr[2:0];
wire vectors_stb_we = (cs && we && adr[3] == 1'b0 && adr[2:0] != 3'b111 );
wire vectors_stb_oe = (cs && oe && adr[3] == 1'b0 && adr[2:0] != 3'b111 );
wire irq_stb_we = (cs && we && adr[3] == 1'b1 && adr[2:0] != 3'b111 );
wire irq_stb_oe = (cs && oe && adr[3] == 1'b1 && adr[2:0] != 3'b111 );
wire ier_stb_we = (cs && we && adr == 4'b0111);
wire ier_stb_oe = (cs && oe && adr == 4'b0111);
 
reg int1_r, int2_r, int3_r, int4_r, int5_r, int6_r, int7_r;
 
wire int1_on = (int1_r == 1'b0 && int1);
wire int2_on = (int2_r == 1'b0 && int2);
wire int3_on = (int3_r == 1'b0 && int3);
wire int4_on = (int4_r == 1'b0 && int4);
wire int5_on = (int5_r == 1'b0 && int5);
wire int6_on = (int6_r == 1'b0 && int6);
wire int7_on = (int7_r == 1'b0 && int7);
wire int1_of = (int1_r == 1'b1 && !int1);
wire int2_of = (int2_r == 1'b1 && !int2);
wire int3_of = (int3_r == 1'b1 && !int3);
wire int4_of = (int4_r == 1'b1 && !int4);
wire int5_of = (int5_r == 1'b1 && !int5);
wire int6_of = (int6_r == 1'b1 && !int6);
wire int7_of = (int7_r == 1'b1 && !int7);
 
wire pos_edge_trigger = (int1_on || int2_on || int3_on || int4_on || int5_on || int6_on || int7_on );
wire neg_edge_trigger = (int1_of || int2_of || int3_of || int4_of || int5_of || int6_of || int7_of );
 
integer i;
 
initial
begin
int_pending = 7'b0000000;
int_mask = 7'b1111111;
ie_reg = 7'b1111111;
ipl_r = 3'b111;
dtack = 1'b1;
int1_r = 1'b0;
int2_r = 1'b0;
int3_r = 1'b0;
int4_r = 1'b0;
int5_r = 1'b0;
int6_r = 1'b0;
int7_r = 1'b0;
for(i=0;i<7;i=i+1)
begin
vectors[i] = 25 + i;
irq_nr[i] = i;
end
end
 
always @(posedge clk)
begin
if( reset )
begin
int1_r <= 1'b0;
int2_r <= 1'b0;
int3_r <= 1'b0;
int4_r <= 1'b0;
int5_r <= 1'b0;
int6_r <= 1'b0;
int7_r <= 1'b0;
end else begin
int1_r <= int1;
int2_r <= int2;
int3_r <= int3;
int4_r <= int4;
int5_r <= int5;
int6_r <= int6;
int7_r <= int7;
end
end
 
always @(posedge clk)
if( reset )
ack_r <= 1'b0;
else
ack_r <= ack;
 
always @(posedge clk)
begin
if( vectors_stb_we )
vectors[ix] = data_i;
end
 
always @(posedge clk)
begin
if( irq_stb_we )
irq_nr[ix] = data_i;
end
 
always @(posedge clk)
begin
if( reset )
ie_reg = 7'b1111111;
else if( ier_stb_we )
ie_reg = data_i;
end
 
always @(posedge clk)
begin
dtack = 1'b1;
if( ack )
begin
if( assert_ack )
data_r = vectors[int_no];
dtack = (ipl_r == 3'b111);
end else if( cs ) begin
if( vectors_stb_oe )
data_r = vectors[ix];
else if( irq_stb_oe )
data_r = irq_nr[ix];
else if( ier_stb_oe )
data_r = ie_reg;
else
data_r = 8'bZ;
dtack = 1'b0;
end else
data_r = 8'bZ;
end
 
always @(posedge clk)
begin
if( reset )
begin
int_pending = 7'b0000000;
end else if( pos_edge_trigger ) begin
if(int7 && ie_reg[6])
int_pending[6] = 1;
else if(int6 && ie_reg[5])
int_pending[5] = 1;
else if(int5 && ie_reg[4])
int_pending[4] = 1;
else if(int4 && ie_reg[3])
int_pending[3] = 1;
else if(int3 && ie_reg[2])
int_pending[2] = 1;
else if(int2 && ie_reg[1])
int_pending[1] = 1;
else if(int1 && ie_reg[0])
int_pending[0] = 1;
end else if( neg_edge_trigger ) begin
if(!int7)
int_pending[6] = 0;
if(!int6)
int_pending[5] = 0;
if(!int5)
int_pending[4] = 0;
if(!int4)
int_pending[3] = 0;
if(!int3)
int_pending[2] = 0;
if(!int2)
int_pending[1] = 0;
if(!int1)
int_pending[0] = 0;
end
end
 
always @(posedge clk)
begin
if( deassert_ack || reset )
begin
ipl_r = 3'b111;
end else if( ipl_r == 3'b111 ) begin
if( int_pending[6] && int_mask[6] )
ipl_r = ~irq_nr[6];
else if( int_pending[5] && int_mask[5] )
ipl_r = ~irq_nr[5];
else if( int_pending[4] && int_mask[4] )
ipl_r = ~irq_nr[4];
else if( int_pending[3] && int_mask[3] )
ipl_r = ~irq_nr[3];
else if( int_pending[2] && int_mask[2] )
ipl_r = ~irq_nr[2];
else if( int_pending[1] && int_mask[1] )
ipl_r = ~irq_nr[1];
else if( int_pending[0] && int_mask[0] )
ipl_r = ~irq_nr[0];
end
end
 
always @(posedge clk)
begin
if( reset )
int_mask = 7'b1111111;
else if ( !pos_edge_trigger && !neg_edge_trigger )
casex(int_pending)
7'b1xxxxxx: int_mask = 7'b0000000;
7'b01xxxxx: int_mask = 7'b1000000;
7'b001xxxx: int_mask = 7'b1100000;
7'b0001xxx: int_mask = 7'b1110000;
7'b00001xx: int_mask = 7'b1111000;
7'b000001x: int_mask = 7'b1111100;
7'b0000001: int_mask = 7'b1111110;
7'b0000000: int_mask = 7'b1111111;
endcase
end
 
assign data_o = data_r;
 
assign ipl = ipl_r;
 
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.