Делает вид что работает...
Code: Select all
module interrupt_controller(IRQ,CLK,FC,ADDR,DIN,nAS,nUDS,nLDS,RW,nRESET,
RS_CTRL,RS_PCH,RS_PCL,RS_MH,RS_ML,
IPL, DOUT, DTEN, DTA);
input wire [19:0] IRQ;
input wire CLK;
input wire [2:0] FC;
input wire [23:1] ADDR;
input wire [15:0] DIN;
input wire nAS, nUDS, nLDS, RW, nRESET, RS_CTRL, RS_PCH, RS_PCL, RS_MH, RS_ML;
output wire [2:0] IPL;
output wire [15:0] DOUT;
output wire DTEN,DTA;
reg [19:0] MASK; //IRQ mask reg
reg [4:0] COUNTER; //IRQ scan counter
reg [31:0] IDC; //IRQ scan decoder output lines
reg IN_PROC,IPLF;
reg [2:0] IACK_SYNC; //synchronized and delayed IACK
wire XDS, WDS, WWSTB, RWSTB, MHWSTB, MLWSTB, MHRSTB, MLRSTB, PHRSTB, PLRSTB, CHWSTB;
wire CLWSTB, IACK, XFLAG;
wire [19:0] CLR;
wire [19:0] POLL;
wire [19:0] FLAG;
wire [7:0] VECTOR;
assign XDS = (~nUDS) | (~nLDS);
assign WDS = (~nUDS) & (~nLDS);
assign IACK = (ADDR[23:8] == 16'hFFFF) & (~nAS) & RW & (~nLDS) &
(ADDR[3] & ADDR[2] & (~ADDR[1])) & (FC[2] & FC[1] & FC[0]);
assign WWSTB = (~RW) & WDS; //write_word strobe
assign RWSTB = RW & WDS; //read_word strobe
assign MHWSTB = RS_MH & WWSTB; //mask reg H write strobe
assign MLWSTB = RS_ML & WWSTB; //mask reg L write strobe
assign MHRSTB = RS_MH & RWSTB; //mask reg H read strobe
assign MLRSTB = RS_ML & RWSTB; //mask reg L read strobe
assign PHRSTB = RS_PCH & RWSTB; //polling reg H read strobe
assign PLRSTB = RS_PCL & RWSTB; //polling reg L read strobe
assign CHWSTB = RS_PCH & WWSTB; //flag clr reg H write strobe
assign CLWSTB = RS_PCL & WWSTB; //flag clr reg L write strobe
assign CLR[15:0] = DIN[15:0] & {16{CLWSTB}}; // generate flag clear strobes
assign CLR[19:16] = DIN[3:0] & {4{CHWSTB}};
//load IRQ mask register
always@(negedge MHWSTB or negedge nRESET)
begin
if (~nRESET) MASK[19:16] <= 4'd0;
else MASK[19:16] <= DIN[3:0];
end
always@(negedge MLWSTB or negedge nRESET)
begin
if (~nRESET) MASK[15:0] <= 16'd0;
else MASK[15:0] <= DIN[15:0];
end
//generate output data
assign DOUT[15:8] = (POLL[15:8]&{8{PLRSTB}}) | (MASK[15:8]&{8{MLRSTB}});
assign DOUT[7:0] = (POLL[7:0] &{8{PLRSTB}}) | (POLL[19:16]&{4{PHRSTB}}) |
(MASK[7:0]&{8{MLRSTB}}) | (MASK[19:16]&{4{MHRSTB}}) |
(VECTOR[7:0]&{8{IACK}});
//sys data bus drive enable strobe (read cycle)
assign DTEN = (RW & XDS & (RS_CTRL | RS_PCH | RS_PCL | RS_MH | RS_ML)) | IACK;
//generate DTACK signal
assign DTA = (XDS & (RS_CTRL | RS_PCH | RS_PCL | RS_MH | RS_ML)) | IACK;
//generate IPL code for CPU
assign IPL[0] = 1;
assign IPL[1] = ~IPLF;
assign IPL[2] = ~IPLF;
//===========================================================
IRQ_channel IFLAG_19 (.IRQ(IRQ[19]),.CLR(CLR[19]),.RST(nRESET),.IACK(IACK),.IDC(IDC[19]),.MASK(MASK[19]),
.POLL(POLL[19]),.FLAG(FLAG[19]));
IRQ_channel IFLAG_18 (.IRQ(IRQ[18]),.CLR(CLR[18]),.RST(nRESET),.IACK(IACK),.IDC(IDC[18]),.MASK(MASK[18]),
.POLL(POLL[18]),.FLAG(FLAG[18]));
IRQ_channel IFLAG_17 (.IRQ(IRQ[17]),.CLR(CLR[17]),.RST(nRESET),.IACK(IACK),.IDC(IDC[17]),.MASK(MASK[17]),
.POLL(POLL[17]),.FLAG(FLAG[17]));
IRQ_channel IFLAG_16 (.IRQ(IRQ[16]),.CLR(CLR[16]),.RST(nRESET),.IACK(IACK),.IDC(IDC[16]),.MASK(MASK[16]),
.POLL(POLL[16]),.FLAG(FLAG[16]));
IRQ_channel IFLAG_15 (.IRQ(IRQ[15]),.CLR(CLR[15]),.RST(nRESET),.IACK(IACK),.IDC(IDC[15]),.MASK(MASK[15]),
.POLL(POLL[15]),.FLAG(FLAG[15]));
IRQ_channel IFLAG_14 (.IRQ(IRQ[14]),.CLR(CLR[14]),.RST(nRESET),.IACK(IACK),.IDC(IDC[14]),.MASK(MASK[14]),
.POLL(POLL[14]),.FLAG(FLAG[14]));
IRQ_channel IFLAG_13 (.IRQ(IRQ[13]),.CLR(CLR[13]),.RST(nRESET),.IACK(IACK),.IDC(IDC[13]),.MASK(MASK[13]),
.POLL(POLL[13]),.FLAG(FLAG[13]));
IRQ_channel IFLAG_12 (.IRQ(IRQ[12]),.CLR(CLR[12]),.RST(nRESET),.IACK(IACK),.IDC(IDC[12]),.MASK(MASK[12]),
.POLL(POLL[12]),.FLAG(FLAG[12]));
IRQ_channel IFLAG_11 (.IRQ(IRQ[11]),.CLR(CLR[11]),.RST(nRESET),.IACK(IACK),.IDC(IDC[11]),.MASK(MASK[11]),
.POLL(POLL[11]),.FLAG(FLAG[11]));
IRQ_channel IFLAG_10 (.IRQ(IRQ[10]),.CLR(CLR[10]),.RST(nRESET),.IACK(IACK),.IDC(IDC[10]),.MASK(MASK[10]),
.POLL(POLL[10]),.FLAG(FLAG[10]));
IRQ_channel IFLAG_9 (.IRQ(IRQ[9]),.CLR(CLR[9]),.RST(nRESET),.IACK(IACK),.IDC(IDC[9]),.MASK(MASK[9]),
.POLL(POLL[9]),.FLAG(FLAG[9]));
IRQ_channel IFLAG_8 (.IRQ(IRQ[8]),.CLR(CLR[8]),.RST(nRESET),.IACK(IACK),.IDC(IDC[8]),.MASK(MASK[8]),
.POLL(POLL[8]),.FLAG(FLAG[8]));
IRQ_channel IFLAG_7 (.IRQ(IRQ[7]),.CLR(CLR[7]),.RST(nRESET),.IACK(IACK),.IDC(IDC[7]),.MASK(MASK[7]),
.POLL(POLL[7]),.FLAG(FLAG[7]));
IRQ_channel IFLAG_6 (.IRQ(IRQ[6]),.CLR(CLR[6]),.RST(nRESET),.IACK(IACK),.IDC(IDC[6]),.MASK(MASK[6]),
.POLL(POLL[6]),.FLAG(FLAG[6]));
IRQ_channel IFLAG_5 (.IRQ(IRQ[5]),.CLR(CLR[5]),.RST(nRESET),.IACK(IACK),.IDC(IDC[5]),.MASK(MASK[5]),
.POLL(POLL[5]),.FLAG(FLAG[5]));
IRQ_channel IFLAG_4 (.IRQ(IRQ[4]),.CLR(CLR[4]),.RST(nRESET),.IACK(IACK),.IDC(IDC[4]),.MASK(MASK[4]),
.POLL(POLL[4]),.FLAG(FLAG[4]));
IRQ_channel IFLAG_3 (.IRQ(IRQ[3]),.CLR(CLR[3]),.RST(nRESET),.IACK(IACK),.IDC(IDC[3]),.MASK(MASK[3]),
.POLL(POLL[3]),.FLAG(FLAG[3]));
IRQ_channel IFLAG_2 (.IRQ(IRQ[2]),.CLR(CLR[2]),.RST(nRESET),.IACK(IACK),.IDC(IDC[2]),.MASK(MASK[2]),
.POLL(POLL[2]),.FLAG(FLAG[2]));
IRQ_channel IFLAG_1 (.IRQ(IRQ[1]),.CLR(CLR[1]),.RST(nRESET),.IACK(IACK),.IDC(IDC[1]),.MASK(MASK[1]),
.POLL(POLL[1]),.FLAG(FLAG[1]));
IRQ_channel IFLAG_0 (.IRQ(IRQ[0]),.CLR(CLR[0]),.RST(nRESET),.IACK(IACK),.IDC(IDC[0]),.MASK(MASK[0]),
.POLL(POLL[0]),.FLAG(FLAG[0]));
assign XFLAG = ~(FLAG == 20'h0);
always@(negedge CLK or posedge IACK or negedge nRESET)
begin
if (~nRESET) IPLF <= 0;
else
begin
if (IACK) IPLF <= 0;
else IPLF <= XFLAG;
end
end
always@(negedge CLK or posedge IPLF or negedge nRESET)
begin
if (~nRESET) IN_PROC <= 0;
else
begin
if (IPLF) IN_PROC <=1;
else IN_PROC <= IN_PROC & (IACK_SYNC[1] | (~IACK_SYNC[2])); //synchronous IN_PROC clear
end
end
always@(posedge CLK or negedge nRESET)
begin
if (~nRESET) COUNTER <= 5'd0;
else
begin
if (~IN_PROC)
begin
if (COUNTER == 5'd19) COUNTER <= 5'd0;
else COUNTER <= COUNTER + 1'd1;
end
end
end
assign VECTOR[7:5] = 3'b010; //vector = 0x40 + irq_num
assign VECTOR[4:0] = COUNTER;
always@(posedge CLK or negedge nRESET) //IACK synchronizer and delay
begin
if (~nRESET) IACK_SYNC <= 3'd0;
else
begin
IACK_SYNC[2:1] <= IACK_SYNC[1:0];
IACK_SYNC[0] <= IACK;
end
end
always@*
begin
case(COUNTER[4:0])
5'h0: IDC=32'b00000000000000000000000000000001;
5'h1: IDC=32'b00000000000000000000000000000010;
5'h2: IDC=32'b00000000000000000000000000000100;
5'h3: IDC=32'b00000000000000000000000000001000;
5'h4: IDC=32'b00000000000000000000000000010000;
5'h5: IDC=32'b00000000000000000000000000100000;
5'h6: IDC=32'b00000000000000000000000001000000;
5'h7: IDC=32'b00000000000000000000000010000000;
5'h8: IDC=32'b00000000000000000000000100000000;
5'h9: IDC=32'b00000000000000000000001000000000;
5'hA: IDC=32'b00000000000000000000010000000000;
5'hB: IDC=32'b00000000000000000000100000000000;
5'hC: IDC=32'b00000000000000000001000000000000;
5'hD: IDC=32'b00000000000000000010000000000000;
5'hE: IDC=32'b00000000000000000100000000000000;
5'hF: IDC=32'b00000000000000001000000000000000;
5'h10: IDC=32'b00000000000000010000000000000000;
5'h11: IDC=32'b00000000000000100000000000000000;
5'h12: IDC=32'b00000000000001000000000000000000;
5'h13: IDC=32'b00000000000010000000000000000000;
5'h14: IDC=32'b00000000000100000000000000000000;
5'h15: IDC=32'b00000000001000000000000000000000;
5'h16: IDC=32'b00000000010000000000000000000000;
5'h17: IDC=32'b00000000100000000000000000000000;
5'h18: IDC=32'b00000001000000000000000000000000;
5'h19: IDC=32'b00000010000000000000000000000000;
5'h1A: IDC=32'b00000100000000000000000000000000;
5'h1B: IDC=32'b00001000000000000000000000000000;
5'h1C: IDC=32'b00010000000000000000000000000000;
5'h1D: IDC=32'b00100000000000000000000000000000;
5'h1E: IDC=32'b01000000000000000000000000000000;
5'h1F: IDC=32'b10000000000000000000000000000000;
endcase
end
endmodule
//---------------------------------------------------------------------------------
module IRQ_channel(IRQ,CLR,RST,IACK,IDC,MASK, POLL,FLAG);
input wire IRQ;
input wire CLR;
input wire RST;
input wire IACK;
input wire IDC;
input wire MASK;
output wire POLL;
output wire FLAG;
reg IFLG;
wire FCLR;
assign FCLR = (~RST) | CLR | (IACK & IDC);
always@(posedge IRQ or posedge FCLR)
begin
if (FCLR) IFLG<= 0;
else IFLG <= 1;
end
assign POLL = IFLG;
assign FLAG = IFLG & IDC & MASK;
endmodule