Commit 48b1a8b7 authored by Ille, Ondrej, Ing.'s avatar Ille, Ondrej, Ing.

Separated Interrupt module to stand-alone component.

parent 4f84d370
......@@ -67,6 +67,9 @@
-- Thus TXT Buffer can properly filter commands, to avoid
-- overflow of interrupts! Replaced "txt_hw_cmd" with
-- "txt_hw_cmd_int" signal.
-- 11.12.2018 Separated interrupt logic to dedicated sub-module. Added
-- option to have configurable set/clear of interrupt by
-- generic option...
--------------------------------------------------------------------------------
Library ieee;
......@@ -75,6 +78,7 @@ USE IEEE.numeric_std.ALL;
USE WORK.CANconstants.ALL;
use work.CAN_FD_register_map.all;
use work.reduce_lib.all;
use work.CANcomponents.all;
entity intManager is
generic(
......@@ -152,40 +156,29 @@ entity intManager is
----------------------------------------------------------------------------
-- Driving bus aliases
----------------------------------------------------------------------------
signal drv_int_vect_clr : std_logic_vector(
int_count - 1 downto 0);
signal drv_int_vect_clr : std_logic_vector(int_count - 1 downto 0);
signal drv_int_ena_set : std_logic_vector(
int_count - 1 downto 0);
signal drv_int_ena_set : std_logic_vector(int_count - 1 downto 0);
signal drv_int_ena_clr : std_logic_vector(
int_count - 1 downto 0);
signal drv_int_ena_clr : std_logic_vector(int_count - 1 downto 0);
signal drv_int_mask_set : std_logic_vector(
int_count - 1 downto 0);
signal drv_int_mask_set : std_logic_vector(int_count - 1 downto 0);
signal drv_int_mask_clr : std_logic_vector(
int_count - 1 downto 0);
signal drv_int_mask_clr : std_logic_vector(int_count - 1 downto 0);
----------------------------------------------------------------------------
-- Internal registers and signals
----------------------------------------------------------------------------
signal int_ena_reg : std_logic_vector(
int_count - 1 downto 0);
signal int_ena_i : std_logic_vector(int_count - 1 downto 0);
signal int_mask_reg : std_logic_vector(
int_count - 1 downto 0);
signal int_mask_i : std_logic_vector(int_count - 1 downto 0);
signal int_vect_reg : std_logic_vector(
int_count - 1 downto 0);
signal int_vect_i : std_logic_vector(int_count - 1 downto 0);
signal int_input_active : std_logic_vector(
int_count - 1 downto 0);
signal int_input_active : std_logic_vector(int_count - 1 downto 0);
-- Registered value of interrupt
constant zero_mask : std_logic_vector(
int_count - 1 downto 0)
constant zero_mask : std_logic_vector(int_count - 1 downto 0)
:= (OTHERS => '0');
end entity;
......@@ -199,16 +192,26 @@ begin
drv_int_ena_clr <= drv_bus(DRV_INT_ENA_CLR_HIGH downto DRV_INT_ENA_CLR_LOW);
drv_int_mask_set <= drv_bus(DRV_INT_MASK_SET_HIGH downto DRV_INT_MASK_SET_LOW);
drv_int_mask_clr <= drv_bus(DRV_INT_MASK_CLR_HIGH downto DRV_INT_MASK_CLR_LOW);
---------------------------------------------------------------------------
-- Register to output propagation
int_vector <= int_vect_reg;
int_mask <= int_mask_reg;
int_ena <= int_ena_reg;
---------------------------------------------------------------------------
int_vector <= int_vect_i;
int_mask <= int_mask_i;
int_ena <= int_ena_i;
int_out <= '0' when (int_vect_reg and int_ena_reg) = zero_mask else
---------------------------------------------------------------------------
-- Driving Interrupt output when there is at least one active interrupt
-- enabled.
---------------------------------------------------------------------------
int_out <= '0' when (int_vect_i and int_ena_i) = zero_mask else
'1';
---------------------------------------------------------------------------
-- Interrupt register masking and enabling
---------------------------------------------------------------------------
int_input_active(BEI_IND) <= error_valid;
int_input_active(ALI_IND) <= arbitration_lost;
int_input_active(EPI_IND) <= error_passive_changed;
......@@ -222,46 +225,34 @@ begin
int_input_active(RBNEI_IND) <= not rx_empty;
int_input_active(TXBHCI_IND) <= or_reduce(txt_hw_cmd_int);
int_proc : process(res_n, clk_sys)
begin
if (res_n = ACT_RESET) then
int_ena_reg <= (OTHERS => '0');
int_mask_reg <= (OTHERS => '0');
int_vect_reg <= (OTHERS => '0');
elsif rising_edge(clk_sys) then
for i in 0 to int_count - 1 loop
-- Interrupt enable
if (drv_int_ena_set(i) = '1') then
int_ena_reg(i) <= '1';
elsif (drv_int_ena_clr(i) = '1') then
int_ena_reg(i) <= '0';
else
int_ena_reg(i) <= int_ena_reg(i);
end if;
-- Interrupt mask
if (drv_int_mask_set(i) = '1') then
int_mask_reg(i) <= '1';
elsif (drv_int_mask_clr(i) = '1') then
int_mask_reg(i) <= '0';
else
int_mask_reg(i) <= int_mask_reg(i);
end if;
-- Interrupt status (vector)
if (int_input_active(i) = '1' and int_mask_reg(i) = '0') then
int_vect_reg(i) <= '1';
elsif (drv_int_vect_clr(i) = '1') then
int_vect_reg(i) <= '0';
else
int_vect_reg(i) <= int_vect_reg(i);
end if;
end loop;
end if;
end process;
---------------------------------------------------------------------------
-- Interrupt module instances
---------------------------------------------------------------------------
int_module_gen : for i in 0 to int_count - 1 generate
int_module_comp : int_module
generic map(
reset_polarity => ACT_RESET,
clear_priority => false
)
port map(
clk_sys => clk_sys,
res_n => res_n,
int_status_set => int_input_active(i),
int_status_clear => drv_int_vect_clr(i),
int_mask_set => drv_int_mask_set(i),
int_mask_clear => drv_int_mask_clr(i),
int_ena_set => drv_int_ena_set(i),
int_ena_clear => drv_int_ena_clr(i),
int_status => int_vect_i(i),
int_mask => int_mask_i(i),
int_ena => int_ena_i(i)
);
end generate int_module_gen;
end architecture;
--------------------------------------------------------------------------------
--
-- CTU CAN FD IP Core
-- Copyright (C) 2015-2018
--
-- Authors:
-- Ondrej Ille <ondrej.ille@gmail.com>
-- Martin Jerabek <martin.jerabek01@gmail.com>
--
-- Project advisors:
-- Jiri Novak <jnovak@fel.cvut.cz>
-- Pavel Pisa <pisa@cmp.felk.cvut.cz>
--
-- Department of Measurement (http://meas.fel.cvut.cz/)
-- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
-- Czech Technical University (http://www.cvut.cz/)
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this VHDL component and associated documentation files (the "Component"),
-- to deal in the Component without restriction, including without limitation
-- the rights to use, copy, modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Component, and to permit persons to whom the
-- Component is furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Component.
--
-- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS
-- IN THE COMPONENT.
--
-- The CAN protocol is developed by Robert Bosch GmbH and protected by patents.
-- Anybody who wants to implement this IP core on silicon has to obtain a CAN
-- protocol license from Bosch.
--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Purpose:
-- Single Interrupt unit. Contains Interrupt enable, Interrupt mask and
-- Interrupt status.
--
-- Interrupt status can be set by "int_set" and cleared by "int_clear".
-- Preference is selected by "clear_priority". If "clear_priority = true",
-- clear has priority over set, otherwise set has priority over clear.
--
-- Interrupt mask is set by "int_mask_set" and cleared by "int_mask_clear".
-- Simulteneous set/clear of interrupt mask is not allowed!
--
-- Interrupt enable is set by "int_ena_set" and cleared by "int_ena_clear".
-- Simulteneous set/clear of interrupt mask is not allowed!
--
--------------------------------------------------------------------------------
-- Revision History:
-- 11.12.2018 Created file
--------------------------------------------------------------------------------
Library ieee;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.ALL;
USE WORK.CANconstants.ALL;
use work.CAN_FD_register_map.all;
use work.reduce_lib.all;
entity int_module is
generic(
-- Reset polarity
constant reset_polarity : std_logic := '0';
-- If true, Interrupt status clear has priority over write.
constant clear_priority : boolean := true
);
port(
------------------------------------------------------------------------
-- System Clock and reset
------------------------------------------------------------------------
signal clk_sys :in std_logic; --System Clock
signal res_n :in std_logic; --Async Reset
------------------------------------------------------------------------
-- Interrupt module control signals
------------------------------------------------------------------------
signal int_status_set :in std_logic;
signal int_status_clear :in std_logic;
signal int_mask_set :in std_logic;
signal int_mask_clear :in std_logic;
signal int_ena_set :in std_logic;
signal int_ena_clear :in std_logic;
------------------------------------------------------------------------
-- Interrupt status signals
------------------------------------------------------------------------
signal int_status :out std_logic;
signal int_mask :out std_logic;
signal int_ena :out std_logic
);
end entity;
architecture rtl of int_module is
signal int_mask_i : std_logic;
signal int_ena_i : std_logic;
begin
------------------------------------------------------------------------
-- Interrupt status - Set priority
------------------------------------------------------------------------
set_priority_gen : if (clear_priority = false) generate
int_stat_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
int_status <= '0';
elsif rising_edge(clk_sys) then
-- Setting Interrupt
if (int_status_set = '1' and int_mask_i = '0') then
int_status <= '1';
-- Clearing Interrupt
elsif (int_status_clear = '1') then
int_status <= '0';
end if;
end if;
end process;
end generate set_priority_gen;
------------------------------------------------------------------------
-- Interrupt status - Clear priority
------------------------------------------------------------------------
clear_priority_gen : if (clear_priority = true) generate
int_stat_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
int_status <= '0';
elsif rising_edge(clk_sys) then
-- Clearing Interrupt
if (int_status_clear = '1') then
int_status <= '0';
-- Setting Interrupt
elsif (int_status_set = '1' and int_mask_i = '0') then
int_status <= '1';
end if;
end if;
end process;
end generate clear_priority_gen;
------------------------------------------------------------------------
-- Interrupt mask
------------------------------------------------------------------------
int_mask_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
int_mask_i <= '0';
elsif rising_edge(clk_sys) then
-- Setting Interrupt Mask
if (int_mask_set = '1') then
int_mask_i <= '1';
-- Clearing Interrupt Mask
elsif (int_mask_clear = '1') then
int_mask_i <= '0';
end if;
end if;
end process;
------------------------------------------------------------------------
-- Interrupt Enable
------------------------------------------------------------------------
int_ena_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
int_ena_i <= '0';
elsif rising_edge(clk_sys) then
-- Setting Interrupt Mask
if (int_ena_set = '1') then
int_ena_i <= '1';
-- Clearing Interrupt Mask
elsif (int_ena_clear = '1') then
int_ena_i <= '0';
end if;
end if;
end process;
-- Propagation to outputs
int_mask <= int_mask_i;
int_ena <= int_ena_i;
end architecture;
......@@ -531,6 +531,34 @@ package CANcomponents is
end component;
----------------------------------------------------------------------------
-- Single Interrupt module
----------------------------------------------------------------------------
component int_module is
generic(
constant reset_polarity : std_logic := '0';
constant clear_priority : boolean := true
);
port(
signal clk_sys :in std_logic; --System Clock
signal res_n :in std_logic; --Async Reset
signal int_status_set :in std_logic;
signal int_status_clear :in std_logic;
signal int_mask_set :in std_logic;
signal int_mask_clear :in std_logic;
signal int_ena_set :in std_logic;
signal int_ena_clear :in std_logic;
signal int_status :out std_logic;
signal int_mask :out std_logic;
signal int_ena :out std_logic
);
end component;
----------------------------------------------------------------------------
-- CAN Core module
----------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment