1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-02-08 17:11:24 +00:00
Files
Gehstock.Mist_FPGA/Computer_MiST/Robotron - KC87_MiST/rtl/periph/simpleIntcontroller.vhd
Gehstock b4920d3288 1
2018-10-27 14:54:23 +02:00

120 lines
4.4 KiB
VHDL

-- Copyright (c) 2015, $ME
-- All rights reserved.
--
-- Redistribution and use in source and synthezised forms, with or without modification, are permitted
-- provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this list of conditions
-- and the following disclaimer.
--
-- 2. Redistributions in synthezised form must reproduce the above copyright notice, this list of conditions
-- and the following disclaimer in the documentation and/or other materials provided with the distribution.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
-- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-- TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
--
-- simple interrupt controller
-- - no retriggering of ints after int acknowledge
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity intController is
generic (
numInts : integer := 8
);
port (
clk : in std_logic;
res_n : in std_logic;
int_n : out std_logic;
intPeriph : in std_logic_vector(numInts-1 downto 0);
intAck : out std_logic_vector(numInts-1 downto 0);
cpuDIn : in std_logic_vector(7 downto 0);
m1_n : in std_logic;
iorq_n : in std_logic;
rd_n : in std_logic;
RETI_n : in std_logic
);
end intController;
architecture rtl of intController is
constant zeroVect : std_logic_vector(numInts-1 downto 0) := (others => '0');
signal intInternal : std_logic_vector(numInts-1 downto 0);
signal intMask : std_logic_vector(numInts-1 downto 0);
signal currentInt : std_logic_vector(numInts-1 downto 0);
type controllerStates is (idle, intAccepted, waitForRetiEnd, waitForM1, finishInt);
signal state : controllerStates := idle;
begin
intAck <= currentInt when m1_n='0' and iorq_n='0' else (others => '0');
-- determine int with highest priority
int_mask : process(intInternal)
begin
intMask <= (others => '0');
for i in 0 to numInts-1 -- 0 is highest prio
loop
if intInternal(i)='1' then
intMask(i) <= '1';
exit;
end if;
end loop;
end process;
-- handle ints
process
variable intResetMask : std_logic_vector(numInts-1 downto 0);
begin
wait until rising_edge(clk);
if (res_n='0') then
state <= idle;
int_n <= '1';
currentInt <= (others => '0');
intInternal <= (others => '0');
else
intResetMask := (others => '1');
if (m1_n='1') then
if intMask /= zeroVect and state=idle then -- new int + update to higher prio until int ack
int_n <= '0';
currentInt <= intMask;
end if;
if RETI_n='0' and state=intAccepted then
state <= waitForRetiEnd;
elsif RETI_n='1' and state=waitForRetiEnd then
state <= waitForM1;
elsif state=finishInt then
currentInt <= (others => '0'); -- restart int cycle
state <= idle;
end if;
else
if state=waitForM1 then -- allow int after 1 additional m1-cycle
state <= finishInt;
end if;
if iorq_n='0' then -- int ack
state <= intAccepted;
int_n <= '1';
intResetMask := not currentInt; -- reset current int
end if;
end if;
intInternal <= (intInternal and intResetMask) or intPeriph;
end if;
end process;
end;