| Code: 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 | |