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

Subversion Repositories light8080

[/] [light8080/] [trunk/] [verilog/] [rtl/] [intr_ctrl.v] - Diff between revs 66 and 88

Only display areas with differences | Details | Blame | View Log

Rev 66 Rev 88
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//      Project:                        light8080 SOC           WiCores Solutions 
//      Project:                        light8080 SOC           WiCores Solutions 
//
//
//      File name:                      intr_ctrl.v             (March 02, 2012)
//      File name:                      intr_ctrl.v             (March 02, 2012)
//
//
//      Writer:                         Moti Litochevski 
//      Writer:                         Moti Litochevski 
//
//
//      Description:
//      Description:
//              This file contains the light8080 SOC interrupt controller. The controller 
//              This file contains the light8080 SOC interrupt controller. The controller 
//              supports 4 external interrupt requests with fixed interrupt vector addresses. 
//              supports 4 external interrupt requests with fixed interrupt vector addresses. 
//              The interrupt vectors code is implemented in the "intr_vec.h" file included in 
//              The interrupt vectors code is implemented in the "intr_vec.h" file included in 
//              the projects C directory. 
//              the projects C directory. 
//              Note that the controller clears the interrupt request after the CPU read the 
//              Note that the controller clears the interrupt request after the CPU read the 
//              interrupt vector. 
//              interrupt vector. 
//
//
//      Revision History:
//      Revision History:
//
//
//      Rev <revnumber>                 <Date>                  <owner> 
//      Rev <revnumber>                 <Date>                  <owner> 
//              <comment>
//              <comment>
// 
// 
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// 
// 
//      Copyright (C) 2012 Moti Litochevski 
//      Copyright (C) 2012 Moti Litochevski 
// 
// 
//      This source file may be used and distributed without restriction provided that this 
//      This source file may be used and distributed without restriction provided that this 
//      copyright statement is not removed from the file and that any derivative work 
//      copyright statement is not removed from the file and that any derivative work 
//      contains the original copyright notice and the associated disclaimer.
//      contains the original copyright notice and the associated disclaimer.
//
//
//      THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 
//      THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 
//      INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND 
//      INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND 
//      FITNESS FOR A PARTICULAR PURPOSE. 
//      FITNESS FOR A PARTICULAR PURPOSE. 
// 
// 
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
 
 
module intr_ctrl
module intr_ctrl
(
(
        clock, reset,
        clock, reset,
        ext_intr, cpu_intr,
        ext_intr, cpu_intr,
        cpu_inte, cpu_inta,
        cpu_inte, cpu_inta,
        cpu_rd, cpu_inst,
        cpu_rd, cpu_inst,
        intr_ena
        intr_ena
);
);
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// module interfaces 
// module interfaces 
// global signals 
// global signals 
input                   clock;          // global clock input 
input                   clock;          // global clock input 
input                   reset;          // global reset input 
input                   reset;          // global reset input 
// external interrupt sources 
// external interrupt sources 
// least significant bit has the highest priority, most significant bit has the lowest 
// least significant bit has the highest priority, most significant bit has the lowest 
// priority. 
// priority. 
input   [3:0]    ext_intr;       // active high 
input   [3:0]    ext_intr;       // active high 
// CPU interface 
// CPU interface 
output                  cpu_intr;       // CPU interrupt request 
output                  cpu_intr;       // CPU interrupt request 
input                   cpu_inte;       // CPU interrupt enable - just to mask 
input                   cpu_inte;       // CPU interrupt enable - just to mask 
input                   cpu_inta;       // CPU interrupt acknowledge 
input                   cpu_inta;       // CPU interrupt acknowledge 
input                   cpu_rd;         // CPU read signal 
input                   cpu_rd;         // CPU read signal 
output  [7:0]    cpu_inst;       // interrupt calling instruction 
output  [7:0]    cpu_inst;       // interrupt calling instruction 
 
 
// interrupt enable register 
// interrupt enable register 
input   [3:0]    intr_ena;       // set high to enable respective interrupt 
input   [3:0]    intr_ena;       // set high to enable respective interrupt 
 
 
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// 8080 assembly code constants 
// 8080 assembly code constants 
// call instruction opcode used to call interrupt routine 
// RST instruction opcode used to call interrupt routines at addresses 
`define CALL_INST                       8'hcd
// int0: 0x08 / int1: 0x18 / int2: 0x28 / int3: 0x38 
// interrupt vectors fixed addresses - high address byte is 0 
`define RST_1_INST                      8'hcf
`define INT0_VEC                        8'h08
`define RST_3_INST                      8'hdf
`define INT1_VEC                        8'h18
`define RST_5_INST                      8'hef
`define INT2_VEC                        8'h28
`define RST_7_INST                      8'hff
`define INT3_VEC                        8'h38
 
 
 
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// internal declarations 
// internal declarations 
// registered output 
// registered output 
reg [7:0] cpu_inst;
reg [7:0] cpu_inst;
 
 
// internals 
// internals 
reg [1:0] intSq, intSel;
reg [1:0] intSq, intSel;
reg [3:0] act_int, int_clr;
reg [3:0] act_int, int_clr;
reg [7:0] int_vec;
reg [7:0] int_vec;
 
 
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
// module implementation 
// module implementation 
// main interrupt controller control process 
// main interrupt controller control process 
always @ (posedge reset or posedge clock)
always @ (posedge reset or posedge clock)
begin
begin
        if (reset)
        if (reset)
        begin
        begin
                intSq <= 2'b0;
                intSq <= 2'b0;
                intSel <= 2'b0;
                intSel <= 2'b0;
                cpu_inst <= 8'b0;
                cpu_inst <= 8'b0;
        end
        end
        else
        else
        begin
        begin
                // interrupt controller state machine 
                // interrupt controller state machine 
                case (intSq)
                case (intSq)
                        2'd0:           // idle state - wait for active interrupt 
                        2'd0:           // idle state - wait for active interrupt 
                                if ((act_int != 4'b0) && cpu_inte)
                                if ((act_int != 4'b0) && cpu_inte)
                                begin
                                begin
                                        // latch the index of the active interrupt according to priority 
                                        // latch the index of the active interrupt according to priority 
                                        if (act_int[0])          intSel <= 2'd0;
                                        if (act_int[0])          intSel <= 2'd0;
                                        else if (act_int[2])    intSel <= 2'd1;
                                        else if (act_int[2])    intSel <= 2'd1;
                                        else if (act_int[3])    intSel <= 2'd2;
                                        else if (act_int[3])    intSel <= 2'd2;
                                        else                                    intSel <= 2'd3;
                                        else                                    intSel <= 2'd3;
                                        // switch to next state 
                                        // switch to next state 
                                        intSq <= 2'd1;
                                        intSq <= 2'd1;
                                end
                                end
                        default:        // all other states increment the state register on inta read 
                        2'd1:           // wait for inta read cycle 
                                if (cpu_inta && cpu_rd)
                                if (cpu_inta && cpu_rd)
                                begin
                                begin
                                        // update state 
                                        // update instruction opcode 
                                        intSq <= intSq + 1;
                                        cpu_inst <= int_vec;
 
                                        // switch to end for inta release 
                                        // update instruction opcode for each byte read during inta 
                                        intSq <= 2'd2;
                                        case (intSq)
 
                                                2'd1:           cpu_inst <= `CALL_INST;
 
                                                2'd2:           cpu_inst <= int_vec;
 
                                                default:        cpu_inst <= 8'd0;
 
                                        endcase
 
                                end
                                end
                                else if (!cpu_inta)
                        default:        // wait for inta end 
 
                                if (!cpu_inta)
                                begin
                                begin
                                        intSq <= 2'd0;
                                        // reset state machine 
                                        cpu_inst <= 8'd0;
                                        intSq <= 2'b0;
 
                                        cpu_inst <= 8'b0;
                                end
                                end
                endcase
                endcase
        end
        end
end
end
 
 
// assign interrupt vector address according to selected interrupt 
// assign interrupt vector address according to selected interrupt 
always @ (intSel)
always @ (intSel)
begin
begin
        case (intSel)
        case (intSel)
                2'd0:   int_vec <= `INT0_VEC;
                2'd0:   int_vec <= `RST_1_INST;
                2'd1:   int_vec <= `INT1_VEC;
                2'd1:   int_vec <= `RST_3_INST;
                2'd2:   int_vec <= `INT2_VEC;
                2'd2:   int_vec <= `RST_5_INST;
                2'd3:   int_vec <= `INT3_VEC;
                2'd3:   int_vec <= `RST_7_INST;
        endcase
        endcase
end
end
 
 
// latch active interrupt on rising edge 
// latch active interrupt on rising edge 
always @ (posedge reset or posedge clock)
always @ (posedge reset or posedge clock)
begin
begin
        if (reset)
        if (reset)
                act_int <= 4'b0;
                act_int <= 4'b0;
        else
        else
                act_int <= (act_int & ~int_clr) | (ext_intr & intr_ena);
                act_int <= (act_int & ~int_clr) | (ext_intr & intr_ena);
end
end
// CPU interrupt is asserted when at least one interrupt is active 
// CPU interrupt is asserted when at least one interrupt is active 
assign cpu_intr = |act_int;
assign cpu_intr = |act_int;
 
 
// clear serviced interrupt 
// clear serviced interrupt 
always @ (cpu_inta or cpu_rd or intSq or intSel)
always @ (cpu_inta or cpu_rd or intSq or intSel)
begin
begin
        if (cpu_inta && cpu_rd && (intSq == 2'd3))
        if (cpu_inta && cpu_rd && (intSq == 2'd1))
        begin
        begin
                case (intSel)
                case (intSel)
                        2'd0:   int_clr <= 4'b0001;
                        2'd0:   int_clr <= 4'b0001;
                        2'd1:   int_clr <= 4'b0010;
                        2'd1:   int_clr <= 4'b0010;
                        2'd2:   int_clr <= 4'b0100;
                        2'd2:   int_clr <= 4'b0100;
                        2'd3:   int_clr <= 4'b1000;
                        2'd3:   int_clr <= 4'b1000;
                endcase
                endcase
        end
        end
        else
        else
                int_clr <= 4'b0;
                int_clr <= 4'b0;
end
end
 
 
endmodule
endmodule
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//                                              Th.. Th.. Th.. Thats all folks !!!
//                                              Th.. Th.. Th.. Thats all folks !!!
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
 
 

powered by: WebSVN 2.1.0

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