Commit 3a366ea1 authored by Ille, Ondrej, Ing.'s avatar Ille, Ondrej, Ing.
Browse files

Merge branch '58-interrupt-register-restructuring' into 'master'

Resolve "Interrupt register restructuring"

Closes #58

See merge request illeondr/CAN_FD_IP_Core!44
parents 1b9cd172 5a57c43a
This diff is collapsed.
......@@ -46,46 +46,49 @@ enum can_fd_8bit_regs {
COMMAND = 0x5,
STATUS = 0x6,
SETTINGS = 0x7,
INT = 0x8,
INT_ENA = 0xa,
BTR = 0xc,
BTR_FD = 0xe,
ALC = 0x10,
SJW = 0x11,
BRP = 0x12,
BRP_FD = 0x13,
EWL = 0x14,
ERP = 0x15,
FAULT_STATE = 0x16,
RXC = 0x18,
TXC = 0x1a,
ERR_NORM = 0x1c,
ERR_FD = 0x1e,
CTR_PRES = 0x20,
FILTER_A_MASK = 0x24,
FILTER_A_VAL = 0x28,
FILTER_B_MASK = 0x2c,
FILTER_B_VAL = 0x30,
FILTER_C_MASK = 0x34,
FILTER_C_VAL = 0x38,
FILTER_RAN_LOW = 0x3c,
FILTER_RAN_HIGH = 0x40,
FILTER_CONTROL = 0x44,
FILTER_STATUS = 0x46,
RX_MEM_INFO = 0x48,
RX_POINTERS = 0x4c,
RX_STATUS = 0x50,
RX_SETTINGS = 0x52,
RX_DATA = 0x54,
TX_STATUS = 0x58,
TX_COMMAND = 0x5c,
TX_PRIORITY = 0x60,
ERR_CAPT = 0x64,
TRV_DELAY = 0x68,
RX_COUNTER = 0x6c,
TX_COUNTER = 0x70,
DEBUG_REGISTER = 0x74,
YOLO_REG = 0x78,
INT_STAT = 0x8,
INT_ENA_SET = 0xc,
INT_ENA_CLR = 0x10,
INT_MASK_SET = 0x14,
INT_MASK_CLR = 0x18,
BTR = 0x1c,
BTR_FD = 0x1e,
ALC = 0x20,
SJW = 0x21,
BRP = 0x22,
BRP_FD = 0x23,
EWL = 0x24,
ERP = 0x25,
FAULT_STATE = 0x26,
RXC = 0x28,
TXC = 0x2a,
ERR_NORM = 0x2c,
ERR_FD = 0x2e,
CTR_PRES = 0x30,
FILTER_A_MASK = 0x34,
FILTER_A_VAL = 0x38,
FILTER_B_MASK = 0x3c,
FILTER_B_VAL = 0x40,
FILTER_C_MASK = 0x44,
FILTER_C_VAL = 0x48,
FILTER_RAN_LOW = 0x4c,
FILTER_RAN_HIGH = 0x50,
FILTER_CONTROL = 0x54,
FILTER_STATUS = 0x56,
RX_MEM_INFO = 0x58,
RX_POINTERS = 0x5c,
RX_STATUS = 0x60,
RX_SETTINGS = 0x62,
RX_DATA = 0x64,
TX_STATUS = 0x68,
TX_COMMAND = 0x6c,
TX_PRIORITY = 0x70,
ERR_CAPT = 0x74,
TRV_DELAY = 0x78,
RX_COUNTER = 0x7c,
TX_COUNTER = 0x80,
DEBUG_REGISTER = 0x84,
YOLO_REG = 0x88,
TXTB1_DATA_1 = 0x100,
TXTB1_DATA_2 = 0x104,
TXTB1_DATA_20 = 0x14c,
......@@ -191,11 +194,11 @@ union mode_command_status_settings {
} s;
};
union int_int_ena {
union int_stat {
uint32_t u32;
struct int_int_ena_s {
struct int_stat_s {
#ifdef __BIG_ENDIAN_BITFIELD
/* INT */
/* INT_STAT */
uint32_t ri : 1;
uint32_t ti : 1;
uint32_t ei : 1;
......@@ -207,34 +210,9 @@ union int_int_ena {
uint32_t lfi : 1;
uint32_t rfi : 1;
uint32_t bsi : 1;
uint32_t reserved_15_11 : 5;
/* INT_ENA */
uint32_t rie : 1;
uint32_t tie : 1;
uint32_t eie : 1;
uint32_t doie : 1;
uint32_t reserved_20 : 1;
uint32_t epie : 1;
uint32_t alie : 1;
uint32_t beie : 1;
uint32_t lfie : 1;
uint32_t rfie : 1;
uint32_t bsie : 1;
uint32_t reserved_31_27 : 5;
uint32_t reserved_31_11 : 21;
#else
uint32_t reserved_31_27 : 5;
uint32_t bsie : 1;
uint32_t rfie : 1;
uint32_t lfie : 1;
uint32_t beie : 1;
uint32_t alie : 1;
uint32_t epie : 1;
uint32_t reserved_20 : 1;
uint32_t doie : 1;
uint32_t eie : 1;
uint32_t tie : 1;
uint32_t rie : 1;
uint32_t reserved_15_11 : 5;
uint32_t reserved_31_11 : 21;
uint32_t bsi : 1;
uint32_t rfi : 1;
uint32_t lfi : 1;
......@@ -250,6 +228,62 @@ union int_int_ena {
} s;
};
union int_ena_set {
uint32_t u32;
struct int_ena_set_s {
#ifdef __BIG_ENDIAN_BITFIELD
/* INT_ENA_SET */
uint32_t int_ena_set : 11;
uint32_t reserved_31_11 : 21;
#else
uint32_t reserved_31_11 : 21;
uint32_t int_ena_set : 11;
#endif
} s;
};
union int_ena_clr {
uint32_t u32;
struct int_ena_clr_s {
#ifdef __BIG_ENDIAN_BITFIELD
/* INT_ENA_CLR */
uint32_t int_ena_clr : 11;
uint32_t reserved_31_11 : 21;
#else
uint32_t reserved_31_11 : 21;
uint32_t int_ena_clr : 11;
#endif
} s;
};
union int_mask_set {
uint32_t u32;
struct int_mask_set_s {
#ifdef __BIG_ENDIAN_BITFIELD
/* INT_MASK_SET */
uint32_t int_mask_set : 11;
uint32_t reserved_31_11 : 21;
#else
uint32_t reserved_31_11 : 21;
uint32_t int_mask_set : 11;
#endif
} s;
};
union int_mask_clr {
uint32_t u32;
struct int_mask_clr_s {
#ifdef __BIG_ENDIAN_BITFIELD
/* INT_MASK_CLR */
uint32_t int_mask_clr : 11;
uint32_t reserved_31_11 : 21;
#else
uint32_t reserved_31_11 : 21;
uint32_t int_mask_clr : 11;
#endif
} s;
};
union btr_btr_fd {
uint32_t u32;
struct btr_btr_fd_s {
......
......@@ -162,8 +162,10 @@ entity CAN_top_level is
signal drv_bus : std_logic_vector(1023 downto 0);
signal stat_bus : std_logic_vector(511 downto 0);
--Interrupt vector (Interrupt register of SJA1000)
signal int_vector : std_logic_vector(10 downto 0);
--Interrupt signals
signal int_vector : std_logic_vector(INT_COUNT - 1 downto 0);
signal int_ena : std_logic_vector(INT_COUNT - 1 downto 0);
signal int_mask : std_logic_vector(INT_COUNT - 1 downto 0);
------------------------------------------------------------------------------
-- Registers <--> RX Buffer Interface
......@@ -511,8 +513,10 @@ begin
txtb_fsms => txtb_fsms,
txt_sw_cmd => txt_sw_cmd,
txt_buf_cmd_index => txt_buf_cmd_index,
txt_buf_prior_out => txt_buf_prior,
txt_buf_prior_out => txt_buf_prior,
int_vector => int_vector,
int_ena => int_ena,
int_mask => int_mask,
trv_delay_out => trv_delay_out,
loger_act_data => loger_act_data,
log_write_pointer => log_write_pointer,
......@@ -632,7 +636,7 @@ begin
int_man_comp : intManager
generic map(
int_length => 7
int_count => INT_COUNT
)
port map(
clk_sys => clk_sys,
......@@ -650,7 +654,9 @@ begin
loger_finished => loger_finished,
drv_bus => drv_bus,
int_out => int,
int_vector => int_vector
int_vector => int_vector,
int_ena => int_ena,
int_mask => int_mask
);
core_top_comp : core_top
......
......@@ -52,7 +52,10 @@
-- terrupt from the same source signal representing same event...
-- Fast CPU might get cycled in many interrupt handler calls.
-- 27.6.2016 Added bug fix of RX Buffer full interrupt
--
-- 07.3.2018 Reimplemented to support masking, separate set, and clear on
-- interrupt enable and interrupt mask. Interrupts changed to
-- be level based instead of edge based with fixed duration. This
-- is more fitting for SocketCAN implementation.
--------------------------------------------------------------------------------
Library ieee;
......@@ -63,7 +66,7 @@ USE WORK.CANconstants.ALL;
entity intManager is
GENERIC(
--Length in clock cycles how long will interrupt stay active
constant int_length:natural range 0 to 10:=5
constant int_count :natural range 0 to 32 := 11
);
PORT(
--------------------------
......@@ -116,242 +119,108 @@ entity intManager is
signal int_out :out std_logic; --Interrupt output
--Interrupt vector (Interrupt register of SJA1000)
signal int_vector :out std_logic_vector(10 downto 0)
signal int_vector :out std_logic_vector(int_count - 1 downto 0);
signal int_mask :out std_logic_vector(int_count - 1 downto 0);
signal int_ena :out std_logic_vector(int_count - 1 downto 0)
);
-----------------------
--Driving bus aliases--
-----------------------
--Bus Error interrupt enable
signal drv_bus_err_int_ena : std_logic;
--Arbitrarion lost interrupt enable
signal drv_arb_lst_int_ena : std_logic;
--Error state changed interrupt enable
signal drv_err_pas_int_ena : std_logic;
--Wake up interrupt enable
signal drv_wake_int_ena : std_logic;
--Data OverRun interrupt enable
signal drv_dov_int_ena : std_logic;
--Error warning limit reached
signal drv_err_war_int_ena : std_logic;
--Frame sucessfully transcieved
signal drv_tx_int_ena : std_logic;
--Frame sucessfully recieved
signal drv_rx_int_ena : std_logic;
--Event logging finished interrupt enable
signal drv_log_fin_int_ena : std_logic;
--Recieve buffer full interrupt enable
signal drv_rx_full_int_ena : std_logic;
--Bit Rate Shift interrupt enable
signal drv_brs_int_ena : std_logic;
--Logic 1 erases interrupt vector
signal drv_int_vect_erase : std_logic;
-- Erase previous vector value
signal drv_int_vect_erase_prev : std_logic;
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_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_clr : std_logic_vector(int_count - 1 downto 0);
----------------------------------
--Internal registers and signals--
----------------------------------
constant int_vector_length : natural:=11;
--Interrupt vector register
signal int_vector_reg : std_logic_vector(int_vector_length-1
downto 0);
signal int_ena_reg : std_logic_vector(int_count - 1 downto 0);
signal int_mask_reg : std_logic_vector(int_count - 1 downto 0);
signal int_vect_reg : std_logic_vector(int_count - 1 downto 0);
--Interrupt register Vector mask
signal int_mask : std_logic_vector(int_vector_length-1
downto 0);
signal int_input_active : std_logic_vector(int_count - 1 downto 0);
--Registered value of interrupt
signal int_out_reg : std_logic;
constant zero_mask : std_logic_vector(int_vector_length-1
downto 0):=(OTHERS=>'0');
signal interrupt_active : std_logic;
signal interrupt_counter : natural;
-------------------------------------------------
--Registers for edge detection on source signals
-------------------------------------------------
--Valid Error appeared for interrupt
signal error_valid_r : std_logic;
--Error pasive /Error acitve functionality changed
signal error_passive_changed_r : std_logic;
--Error warning limit reached
signal error_warning_limit_r : std_logic;
--Arbitration was lost input
signal arbitration_lost_r : std_logic;
--Wake up appeared
signal wake_up_valid_r : std_logic;
--Message stored in CAN Core was sucessfully transmitted
signal tx_finished_r : std_logic;
--Bit Rate Was Shifted
signal br_shifted_r : std_logic;
--Income message was discarded
signal rx_message_disc_r : std_logic;
--Message recieved!
signal rec_message_valid_r : std_logic;
signal rx_full_r : std_logic;
--Event logging finsihed
signal loger_finished_r : std_logic;
constant zero_mask : std_logic_vector(int_count - 1 downto 0)
:= (OTHERS => '0');
end entity;
architecture rtl of intManager is
begin
--Driving bus aliases
drv_bus_err_int_ena <= drv_bus(DRV_BUS_ERR_INT_ENA_INDEX);
drv_arb_lst_int_ena <= drv_bus(DRV_ARB_LST_INT_ENA_INDEX);
drv_err_pas_int_ena <= drv_bus(DRV_ERR_PAS_INT_ENA_INDEX);
drv_wake_int_ena <= drv_bus(DRV_WAKE_INT_ENA_INDEX);
drv_dov_int_ena <= drv_bus(DRV_DOV_INT_ENA_INDEX);
drv_err_war_int_ena <= drv_bus(DRV_ERR_WAR_INT_ENA_INDEX);
drv_tx_int_ena <= drv_bus(DRV_TX_INT_ENA_INDEX);
drv_rx_int_ena <= drv_bus(DRV_RX_INT_ENA_INDEX);
drv_log_fin_int_ena <= drv_bus(DRV_LOG_FIN_INT_ENA_INDEX);
drv_rx_full_int_ena <= drv_bus(DRV_RX_FULL_INT_ENA_INDEX);
drv_brs_int_ena <= drv_bus(DRV_BRS_INT_ENA_INDEX);
drv_int_vect_erase <= drv_bus(DRV_INT_VECT_ERASE_INDEX);
--Register to output propagation
int_vector <= int_vector_reg;
int_out <= int_out_reg;
--Interrupt register masking and enabling
int_mask(BUS_ERR_INT) <= drv_bus_err_int_ena and
error_valid and
(not error_valid_r);
int_mask(ARB_LST_INT) <= drv_arb_lst_int_ena and
arbitration_lost and
(not arbitration_lost_r);
int_mask(ERR_PAS_INT) <= drv_err_pas_int_ena and
error_passive_changed and
(not error_passive_changed_r);
int_mask(WAKE_INT) <= drv_wake_int_ena and
wake_up_valid and
(not wake_up_valid_r);
int_mask(DOV_INT) <= drv_dov_int_ena and
rx_message_disc and
(not rx_message_disc_r);
int_mask(ERR_WAR_INT) <= drv_err_war_int_ena and
error_warning_limit and
(not error_warning_limit_r);
int_mask(TX_INT) <= drv_tx_int_ena and
tx_finished and
(not tx_finished_r);
int_mask(RX_INT) <= drv_rx_int_ena and
rec_message_valid and
(not rec_message_valid_r);
int_mask(LOG_FIN_INT) <= drv_log_fin_int_ena and
loger_finished and
(not loger_finished_r);
int_mask(RX_FULL_INT) <= drv_rx_full_int_ena and
rx_full and (not rx_full_r);
--Note: also rec_message_valid has to be compared otherwise interrupt
--would start always when the buffer is full
int_mask(BRS_INT) <= drv_brs_int_ena and br_shifted;
int_out_reg <= '1' when interrupt_active = '1' else '0';
----------------------------------------------------
--Edge detection process
----------------------------------------------------
edge_det:process(res_n,clk_sys)
-- Driving bus aliases
drv_int_vect_clr <= drv_bus(DRV_INT_CLR_HIGH downto DRV_INT_CLR_LOW);
drv_int_ena_set <= drv_bus(DRV_INT_ENA_SET_HIGH downto DRV_INT_ENA_SET_LOW);
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_out <= '1' when (int_vect_reg and int_mask_reg) /= zero_mask else
'0';
-- Interrupt register masking and enabling
int_input_active(BUS_ERR_INT) <= error_valid;
int_input_active(ARB_LST_INT) <= arbitration_lost;
int_input_active(ERR_PAS_INT) <= error_passive_changed;
int_input_active(WAKE_INT) <= wake_up_valid;
int_input_active(DOV_INT) <= rx_message_disc;
int_input_active(ERR_WAR_INT) <= error_warning_limit;
int_input_active(TX_INT) <= tx_finished;
int_input_active(RX_INT) <= rec_message_valid;
int_input_active(LOG_FIN_INT) <= loger_finished;
int_input_active(RX_FULL_INT) <= rx_full;
int_input_active(BRS_INT) <= br_shifted;
int_proc:process(res_n, clk_sys)
begin
if(res_n=ACT_RESET)then
error_valid_r <= '0';
error_passive_changed_r <= '0';
error_warning_limit_r <= '0';
arbitration_lost_r <= '0';
wake_up_valid_r <= '0';
tx_finished_r <= '0';
br_shifted_r <= '0';
rx_message_disc_r <= '0';
rec_message_valid_r <= '0';
rx_full_r <= '0';
loger_finished_r <= '0';
elsif rising_edge(clk_sys)then
error_valid_r <= error_valid;
error_passive_changed_r <= error_passive_changed;
error_warning_limit_r <= error_warning_limit;
arbitration_lost_r <= arbitration_lost;
wake_up_valid_r <= wake_up_valid;
tx_finished_r <= tx_finished;
br_shifted_r <= br_shifted;
rx_message_disc_r <= rx_message_disc;
rec_message_valid_r <= rec_message_valid;
rx_full_r <= rx_full;
loger_finished_r <= loger_finished;
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) = '0') 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') 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;
----------------------------------------------------
--Main interrupt process
----------------------------------------------------
int_proc:process(res_n,clk_sys)
begin
if(res_n=ACT_RESET)then
int_vector_reg <= (OTHERS=>'0');
drv_int_vect_erase_prev <= '0';
interrupt_active <= '0';
interrupt_counter <= 0;
elsif rising_edge(clk_sys)then
drv_int_vect_erase_prev <= drv_int_vect_erase;
interrupt_active <= interrupt_active;
interrupt_counter <= interrupt_counter;
--Interrupt vector handling (falling edge of reading detection)
if(drv_int_vect_erase='0' and drv_int_vect_erase_prev='1' )then
int_vector_reg <= (OTHERS=>'0');
else
--Storing actual interrupt mask
int_vector_reg <= int_vector_reg or int_mask;
end if;
--Interrupt output
if(int_mask /= zero_mask and interrupt_active='0')then
interrupt_active <= '1';
end if;
--Keep the interrupt active for int_length clock cycles
if(interrupt_active='1')then
if(interrupt_counter=int_length)then
interrupt_active<='0';
interrupt_counter<=0;
else
interrupt_counter<=interrupt_counter+1;
end if;
end if;
end if;
end process;
end architecture;
......@@ -57,46 +57,49 @@ package CAN_FD_register_map is
constant COMMAND_ADR : std_logic_vector(11 downto 0) := x"005";
constant STATUS_ADR : std_logic_vector(11 downto 0) := x"006";
constant SETTINGS_ADR : std_logic_vector(11 downto 0) := x"007";
constant INT_ADR : std_logic_vector(11 downto 0) := x"008";
constant INT_ENA_ADR : std_logic_vector(11 downto 0) := x"00A";
constant BTR_ADR : std_logic_vector(11 downto 0) := x"00C";
constant BTR_FD_ADR : std_logic_vector(11 downto