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

Subversion Repositories light52

[/] [light52/] [trunk/] [vhdl/] [light52_cpu.vhdl] - Diff between revs 14 and 17

Show entire file | Details | Blame | View Log

Rev 14 Rev 17
Line 134... Line 134...
use work.light52_pkg.all;
use work.light52_pkg.all;
use work.light52_ucode_pkg.all;
use work.light52_ucode_pkg.all;
 
 
entity light52_cpu is
entity light52_cpu is
    generic (
    generic (
 
        -- Do not map unused BRAM onto XRAM space.
        USE_BRAM_FOR_XRAM : boolean := false;
        USE_BRAM_FOR_XRAM : boolean := false;
 
        -- Implement DA and XCHD instructions by default.
        IMPLEMENT_BCD_INSTRUCTIONS : boolean := false;
        IMPLEMENT_BCD_INSTRUCTIONS : boolean := false;
 
        -- Use a combinational (dedicated) multiplier by default. 
        SEQUENTIAL_MULTIPLIER : boolean := false
        SEQUENTIAL_MULTIPLIER : boolean := false
    );
    );
    port(
    port(
        clk             : in std_logic;
        clk             : in std_logic;
        reset           : in std_logic;
        reset           : in std_logic;
Line 226... Line 229...
-- Present state register and Next state
-- Present state register and Next state
signal ps, ns :             t_cpu_state;
signal ps, ns :             t_cpu_state;
 
 
---- Interrupt handling --------------------------------------------------------
---- Interrupt handling --------------------------------------------------------
 
 
-- IRQ inputs ANDed to IE mask bits
-- IRQ inputs ANDed to IE mask bits.
signal irq_masked_inputs :  std_logic_vector(4 downto 0);
signal irq_masked_inputs :  std_logic_vector(4 downto 0);
 
-- IRQ inputs ANDed to IE mask bits ANDed to IP mask bits.
 
signal irq_masked_inputs_hp :  std_logic_vector(4 downto 0);
-- Level of highest-level active IRQ input. 0 is highest, 4 lowest, 7 is none.
-- Level of highest-level active IRQ input. 0 is highest, 4 lowest, 7 is none.
signal irq_level_inputs :   unsigned(2 downto 0);
signal irq_level_inputs :   unsigned(2 downto 0);
-- Level of IRQ being serviced. 7 if none. Set by IRQ, reset to 7 by RETI.
 
signal irq_level_current :  unsigned(2 downto 0);
 
-- Low 6 bits of IRQ service address.
-- Low 6 bits of IRQ service address.
signal irq_vector :         unsigned(5 downto 0);
signal irq_vector :         unsigned(5 downto 0);
signal irq_active :         std_logic;  -- IRQ pending service
signal irq_active :         std_logic;  -- IRQ pending service
signal load_ie :            std_logic;  -- IE register load enable
signal load_ie :            std_logic;  -- IE register load enable
signal irq_restore_level :  std_logic;  -- Restore irq_level_current to 7 (RETI)
signal load_ip :            std_logic;  -- IP register load enable
 
-- Restore irq priority level (as per RETI execution).
 
signal irq_restore_level :  std_logic;
 
-- High wwhen the active IRQ is allowed by the priority rules.
 
signal irq_active_allowed : std_logic;
 
-- High when serving a LOw Priority interrupt.
 
signal irq_serving_lop :    std_logic;
 
-- High when serving a HIgh Priority interrupt.
 
signal irq_serving_hip :    std_logic;
 
-- High when the active interrupt line is a HIgh Priority interrupt.
 
signal irq_active_hip :     std_logic;
 
 
---- CPU programmer's model registers ------------------------------------------
---- CPU programmer's model registers ------------------------------------------
 
 
signal PC_reg :             t_address;      -- PC
signal PC_reg :             t_address;      -- PC
signal pc_incremented :     t_address;      -- PC + 1 | PC, controlled by...
signal pc_incremented :     t_address;      -- PC + 1 | PC, controlled by...
Line 250... Line 263...
signal PSW_reg :            unsigned(7 downto 1); -- PSW excluding P flag
signal PSW_reg :            unsigned(7 downto 1); -- PSW excluding P flag
signal PSW :                t_byte;         -- PSW, full (P is combinational)
signal PSW :                t_byte;         -- PSW, full (P is combinational)
signal SP_reg :             t_byte;         -- SP
signal SP_reg :             t_byte;         -- SP
signal SP_next :            t_byte;         -- Next value for SP
signal SP_next :            t_byte;         -- Next value for SP
signal IE_reg :             t_byte;         -- IE
signal IE_reg :             t_byte;         -- IE
 
signal IP_reg :             t_byte;         -- IP
 
 
 
 
signal alu_p :              std_logic;      -- P flag (from ALU)
signal alu_p :              std_logic;      -- P flag (from ALU)
signal DPTR_reg :           t_address;      -- DPTR
signal DPTR_reg :           t_address;      -- DPTR
 
 
signal next_pc :            t_address;      -- Next value for PC
signal next_pc :            t_address;      -- Next value for PC
Line 895... Line 910...
end process cpu_state_machine_transitions;
end process cpu_state_machine_transitions;
 
 
 
 
--## 2.- Interrupt handling ####################################################
--## 2.- Interrupt handling ####################################################
 
 
 
 
 
-- IP SFR is implemented as a regular SFR as per the MC51 architecture.
 
load_ip <= '1' when sfr_addr_internal=SFR_ADDR_IP and sfr_we_internal='1'
 
           else '0';
 
 
 
IP_register:
 
process(clk)
 
begin
 
    if clk'event and clk='1' then
 
        if reset='1' then
 
            IP_reg <= (others => '0');
 
        else
 
            if load_ip='1' then
 
                IP_reg <= alu_result;
 
            end if;
 
        end if;
 
    end if;
 
end process IP_register;
 
 
 
 
 
-- IE SFR is implemented as a regular SFR as per the MC51 architecture.
load_ie <= '1' when sfr_addr_internal=SFR_ADDR_IE and sfr_we_internal='1'
load_ie <= '1' when sfr_addr_internal=SFR_ADDR_IE and sfr_we_internal='1'
           else '0';
           else '0';
 
 
IE_register:
IE_register:
process(clk)
process(clk)
Line 918... Line 954...
-- if its level is below this. Remember 0 is top, 4 is bottom and 7 is idle. 
-- if its level is below this. Remember 0 is top, 4 is bottom and 7 is idle. 
irq_restore_level <= '1' when ps=ret_0 and alu_fn_reg(0)='1' else '0';
irq_restore_level <= '1' when ps=ret_0 and alu_fn_reg(0)='1' else '0';
 
 
-- Mask the irq inputs with IE register bits...
-- Mask the irq inputs with IE register bits...
irq_masked_inputs <= irq_source and std_logic_vector(IE_reg(4 downto 0));
irq_masked_inputs <= irq_source and std_logic_vector(IE_reg(4 downto 0));
 
-- ...separate the highpriority interrupt inputs by masking with IP register...
 
irq_masked_inputs_hp <= irq_masked_inputs and std_logic_vector(IP_reg(4 downto 0));
-- ...and encode the highest priority active input
-- ...and encode the highest priority active input
irq_level_inputs <=
irq_level_inputs <=
 
    "000" when irq_masked_inputs_hp(0)='1' else
 
    "001" when irq_masked_inputs_hp(1)='1' else
 
    "010" when irq_masked_inputs_hp(2)='1' else
 
    "011" when irq_masked_inputs_hp(3)='1' else
 
    "100" when irq_masked_inputs_hp(4)='1' else
    "000" when irq_masked_inputs(0)='1' else
    "000" when irq_masked_inputs(0)='1' else
    "001" when irq_masked_inputs(1)='1' else
    "001" when irq_masked_inputs(1)='1' else
    "010" when irq_masked_inputs(2)='1' else
    "010" when irq_masked_inputs(2)='1' else
    "011" when irq_masked_inputs(3)='1' else
    "011" when irq_masked_inputs(3)='1' else
    "100" when irq_masked_inputs(4)='1' else
    "100" when irq_masked_inputs(4)='1' else
    "111";
    "111";
 
 
 
irq_active_hip <= '1' when irq_masked_inputs_hp/="00000" else '0';
 
 
 
-- An active, enabled interrupt will be serviced only if...
 
irq_active_allowed <= '1' when
 
                    -- ...other high-priority interrupt is NOT being serviced...
 
                    irq_serving_hip='0' and
 
                    -- ...and either the incoming interrupt is high-priority...
 
                    (irq_active_hip='1' or
 
                    -- -- ...or no interrupt is being serviced at all;
 
                    (irq_active_hip='0' and irq_serving_lop='0'))
 
                    -- otherwise the interrupt is not allowed to proceed.
 
                    else '0';
 
 
-- We have a pending irq if interrupts are enabled...    
-- We have a pending irq if interrupts are enabled...    
irq_active <= '1' when IE_reg(7)='1' and
irq_active <= '1' when IE_reg(7)='1' and
                       -- ...and the active irq has higher priority than any 
                    -- ...and some interrupt source is active...
                       -- ongoing irq routine.
                    irq_level_inputs/="111" and
                       (irq_level_inputs < irq_level_current)
                    -- ...and the active interrupt is allowed by the priority 
 
                    -- rules...
 
                    irq_active_allowed='1'
 
                    -- ...otherwise the interrupt is ignored.
              else '0';
              else '0';
 
 
irq_registered_priority_encoder:
irq_registered_priority_encoder:
process(clk)
process(clk)
begin
begin
    if clk'event and clk='1' then
    if clk'event and clk='1' then
        if reset='1' or irq_restore_level='1' then
        if reset='1' then
            -- After reset, irq level is 7, which means all irqs are accepted.
            -- After reset, no interrupt of either priority level is being
            -- Note that valid levels are 0 to 4 and the lower the number,
            -- serviced.
            -- the higher the priority.
            irq_serving_hip <= '0';
            -- The level is restored to 7 by the RETI instruction too.
            irq_serving_lop <= '0';
            irq_level_current <= "111";
        elsif irq_restore_level='1' then
 
            -- RETI executed: if high-priority level was active...
 
            if irq_serving_hip='1' then
 
                -- ...disable it, reverting to the previous priority level...
 
                irq_serving_hip <= '0';
 
            else
 
                -- otherwise disable the low priority level.
 
                irq_serving_lop <= '0';
 
            end if;
        else
        else
            -- Evaluate and register the interrupt priority in the same state 
            -- Evaluate and register the interrupt priority in the same state 
            -- the irq is to be acknowledged.
            -- the irq is to be acknowledged.
            if ps=fetch_1 and irq_active='1' then
            if ps=fetch_1 and irq_active='1' then
                irq_level_current <= irq_level_inputs;
                irq_serving_hip <= irq_active_hip;
 
                irq_serving_lop <= irq_serving_lop or (not irq_active_hip);
 
                -- This irq vector is going to be used in state irq_2.
 
                irq_vector <= irq_level_inputs & "011";
            end if;
            end if;
        end if;
        end if;
    end if;
    end if;
end process irq_registered_priority_encoder;
end process irq_registered_priority_encoder;
 
 
-- This irq vector is going to be used in state irq_2.
 
irq_vector <= irq_level_current & "011";
 
 
 
 
 
--## 3.- Combined register bank & decoding table ###############################
--## 3.- Combined register bank & decoding table ###############################
 
 
-- No support yet for XRAM on this RAM block
-- No support yet for XRAM on this RAM block
Line 1615... Line 1683...
    A_reg                   when SFR_ADDR_ACC,
    A_reg                   when SFR_ADDR_ACC,
    B_reg                   when SFR_ADDR_B,
    B_reg                   when SFR_ADDR_B,
    DPTR_reg(15 downto 8)   when SFR_ADDR_DPH,
    DPTR_reg(15 downto 8)   when SFR_ADDR_DPH,
    DPTR_reg( 7 downto 0)   when SFR_ADDR_DPL,
    DPTR_reg( 7 downto 0)   when SFR_ADDR_DPL,
    IE_reg                  when SFR_ADDR_IE,
    IE_reg                  when SFR_ADDR_IE,
 
    IP_reg                  when SFR_ADDR_IP,
    unsigned(sfr_rd)  when others;
    unsigned(sfr_rd)  when others;
 
 
-- Registering the SFR read mux gives the SFR block the same timing behavior as
-- Registering the SFR read mux gives the SFR block the same timing behavior as
-- the IRAM block, and improves clock rate a lot.
-- the IRAM block, and improves clock rate a lot.
SFR_mux_register:
SFR_mux_register:

powered by: WebSVN 2.1.0

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