Commit 0b9d3454 authored by egousiou's avatar egousiou

vic on svec tdc

git-svn-id: http://svn.ohwr.org/fmc-tdc@136 85dfdc96-de2c-444c-878d-45b388be74a9
parent 3fcb563b
......@@ -16,11 +16,11 @@
<files>
<file xil_pn:name="blk_mem_circ_buff_v6_4.ngc" xil_pn:type="FILE_NGC">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="Implementation" xil_pn:seqID="1"/>
</file>
<file xil_pn:name="blk_mem_circ_buff_v6_4.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="Implementation" xil_pn:seqID="2"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="2"/>
......
files = ["vic_prio_enc.vhd",
"wb_slave_vic.vhd",
"wb_vic.vhd",
"xwb_vic.vhd"]
library ieee;
use ieee.std_logic_1164.all;
entity vic_prio_enc is
port (
in_i : in std_logic_vector(31 downto 0);
out_o : out std_logic_vector(4 downto 0)
);
end vic_prio_enc;
architecture syn of vic_prio_enc is
begin -- syn
prencode : process (in_i)
begin -- process prencode
if in_i(0) = '1' then
out_o <= "00000";
elsif in_i(1) = '1' then
out_o <= "00001";
elsif in_i(2) = '1' then
out_o <= "00010";
elsif in_i(3) = '1' then
out_o <= "00011";
elsif in_i(4) = '1' then
out_o <= "00100";
elsif in_i(5) = '1' then
out_o <= "00101";
elsif in_i(6) = '1' then
out_o <= "00110";
elsif in_i(7) = '1' then
out_o <= "00111";
elsif in_i(8+0) = '1' then
out_o <= "01000";
elsif in_i(8+1) = '1' then
out_o <= "01001";
elsif in_i(8+2) = '1' then
out_o <= "01010";
elsif in_i(8+3) = '1' then
out_o <= "01011";
elsif in_i(8+4) = '1' then
out_o <= "01100";
elsif in_i(8+5) = '1' then
out_o <= "01101";
elsif in_i(8+6) = '1' then
out_o <= "01110";
elsif in_i(8+7) = '1' then
out_o <= "01111";
elsif in_i(16+0) = '1' then
out_o <= "10000";
elsif in_i(16+1) = '1' then
out_o <= "10001";
elsif in_i(16+2) = '1' then
out_o <= "10010";
elsif in_i(16+3) = '1' then
out_o <= "10011";
elsif in_i(16+4) = '1' then
out_o <= "10100";
elsif in_i(16+5) = '1' then
out_o <= "10101";
elsif in_i(16+6) = '1' then
out_o <= "10110";
elsif in_i(16+7) = '1' then
out_o <= "10111";
elsif in_i(24+0) = '1' then
out_o <= "11000";
elsif in_i(24+1) = '1' then
out_o <= "11001";
elsif in_i(24+2) = '1' then
out_o <= "11010";
elsif in_i(24+3) = '1' then
out_o <= "11011";
elsif in_i(24+4) = '1' then
out_o <= "11100";
elsif in_i(24+5) = '1' then
out_o <= "11101";
elsif in_i(24+6) = '1' then
out_o <= "11110";
elsif in_i(24+7) = '1' then
out_o <= "11111";
else
out_o <= "XXXXX";
end if;
end process prencode;
end syn;
This diff is collapsed.
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name = "Vectored Interrupt Controller (VIC)";
description = "Module implementing a 2 to 32-input prioritized interrupt controller with internal interrupt vector storage support.";
prefix = "VIC";
hdl_entity = "wb_slave_vic";
reg {
name = "VIC Control Register";
prefix = "CTL";
field {
name = "VIC Enable";
description = "- 1: enables VIC operation\n- 0: disables VIC operation";
prefix = "ENABLE";
type = BIT;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
field {
name = "VIC output polarity";
description = "- 1: IRQ output is active high\n- 0: IRQ output is active low";
prefix = "POL";
type = BIT;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
field {
name = "Emulate Edge sensitive output";
description = "- 1: Forces a low pulse of <code>EMU_LEN</code> clock cycles at each write to <code>EOIR</code>. Useful for edge-only IRQ controllers such as Gennum.\n- 0: Normal IRQ master line behavior";
prefix = "EMU_EDGE";
type = BIT;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
field {
name = "Emulated Edge pulse timer";
description = "Length of the delay (in <code>clk_sys_i</code> cycles) between write to <code>EOIR</code> and re-assertion of <code>irq_master_o</code>.";
prefix = "EMU_LEN";
type = SLV;
size = 16;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
};
reg {
name = "Raw Interrupt Status Register";
prefix = "RISR";
field {
name = "Raw interrupt status";
description = "Each bit reflects the current state of corresponding IRQ input line.\n- read 1: interrupt line is currently active\n- read 0: interrupt line is inactive";
type = SLV;
size = 32;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "Interrupt Enable Register";
prefix = "IER";
field {
name = "Enable IRQ";
description = "- write 1: enables interrupt associated with written bit\n- write 0: no effect";
type = PASS_THROUGH;
size = 32;
};
};
reg {
name = "Interrupt Disable Register";
prefix = "IDR";
field {
name = "Disable IRQ";
description = "- write 1: enables interrupt associated with written bit\n- write 0: no effect";
type = PASS_THROUGH;
size = 32;
};
};
reg {
name = "Interrupt Mask Register";
prefix = "IMR";
field {
name = "IRQ disabled/enabled";
description = "- read 1: interrupt associated with read bit is enabled\n- read 0: interrupt is disabled";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Vector Address Register";
prefix = "VAR";
field {
name = "Vector Address";
description = "Address of pending interrupt vector, read from Interrupt Vector Table";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Software Interrupt Register";
description = "Writing 1 to one of bits of this register causes a software emulation of the respective interrupt.";
prefix = "SWIR";
field {
name = "SWI interrupt mask";
type = PASS_THROUGH;
size = 32;
};
};
reg {
name = "End Of Interrupt Acknowledge Register";
prefix = "EOIR";
field {
name = "End of Interrupt";
description = "Any write operation acknowledges the pending interrupt. Then, VIC advances to another pending interrupt(s) or releases the master interrupt output.";
type = PASS_THROUGH;
size = 32;
};
};
ram {
name = "Interrupt Vector Table";
description = "Vector Address Table. Word at offset N stores the vector address of IRQ N. When interrupt is requested, VIC reads it's vector address from this memory and stores it in VAR register. The contents of this table can be pre-initialized during synthesis through <code>g_init_vectors</code> generic parameter. This is used to auto-enumerate interrupts in SDB-based designs.";
prefix = "IVT_RAM";
size = 32;
width = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
\ No newline at end of file
This diff is collapsed.
------------------------------------------------------------------------------
-- Title : Wishbone Vectored Interrupt Controller
-- Project : White Rabbit Switch
------------------------------------------------------------------------------
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-05-18
-- Last update: 2013-04-16
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Simple interrupt controller/multiplexer:
-- - designed to cooperate with wbgen2 peripherals Embedded Interrupt
-- Controllers (EICs)
-- - accepts 2 to 32 inputs (configurable using g_num_interrupts)
-- - inputs are high-level sensitive
-- - inputs have fixed priorities. Input 0 has the highest priority, Input
-- g_num_interrupts-1 has the lowest priority.
-- - output interrupt line (to the CPU) is active low or high depending on
-- a configuration bit.
-- - interrupt is acknowledged by writing to EIC_EOIR register.
-- - register layout: see wb_vic.wb for details.
-------------------------------------------------------------------------------
-- Copyright (c) 2010 Tomasz Wlostowski
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-05-18 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
entity xwb_vic is
generic (
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD;
g_num_interrupts : natural := 32; -- number of IRQ inputs.
g_init_vectors : t_wishbone_address_array := cc_dummy_address_array
);
port (
clk_sys_i : in std_logic; -- wishbone clock
rst_n_i : in std_logic; -- reset
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
irqs_i : in std_logic_vector(g_num_interrupts-1 downto 0); -- IRQ inputs
irq_master_o : out std_logic -- master IRQ output (multiplexed line, to the CPU)
);
end xwb_vic;
architecture wrapper of xwb_vic is
begin -- wrapper
U_Wrapped_VIC : wb_vic
generic map (
g_interface_mode => g_interface_mode,
g_address_granularity => g_address_granularity,
g_num_interrupts => g_num_interrupts,
g_init_vectors => g_init_vectors)
port map (
clk_sys_i => clk_sys_i,
rst_n_i => rst_n_i,
wb_adr_i => slave_i.adr,
wb_dat_i => slave_i.dat,
wb_dat_o => slave_o.dat,
wb_cyc_i => slave_i.Cyc,
wb_sel_i => slave_i.sel,
wb_stb_i => slave_i.stb,
wb_we_i => slave_i.we,
wb_ack_o => slave_o.ack,
wb_stall_o => slave_o.stall,
irqs_i => irqs_i,
irq_master_o => irq_master_o);
slave_o.err <= '0';
slave_o.rty <= '0';
slave_o.int <= '0';
end wrapper;
This diff is collapsed.
......@@ -144,6 +144,7 @@ entity fmc_tdc_mezzanine is
wb_tdc_mezz_we_i : in std_logic;
wb_tdc_mezz_ack_o : out std_logic;
wb_tdc_mezz_stall_o : out std_logic;
wb_irq_o : out std_logic;
-- I2C EEPROM interface
sys_scl_b : inout std_logic;
sys_sda_b : inout std_logic;
......@@ -166,7 +167,7 @@ architecture rtl of fmc_tdc_mezzanine is
constant c_NUM_WB_MASTERS : integer := 5;
constant c_WB_SLAVE_TDC_CORE_CONFIG : integer := 0; -- TDC core configuration registers
constant c_WB_SLAVE_TDC_ONEWIRE : integer := 1; -- TDC mezzanine board UnidueID&Thermometer 1-wire
constant c_WB_SLAVE_DUMMY : integer := 2; -- Dummy for debugging
constant c_WB_SLAVE_IRQ : integer := 2; -- TDC interrupts
constant c_WB_SLAVE_TDC_SYS_I2C : integer := 3; -- TDC mezzanine board system EEPROM I2C
constant c_WB_SLAVE_TSTAMP_MEM : integer := 4; -- Access to TDC core timestamps memory
......@@ -180,7 +181,7 @@ architecture rtl of fmc_tdc_mezzanine is
constant c_INTERCONNECT_LAYOUT : t_sdb_record_array(4 downto 0) :=
(0 => f_sdb_embed_device(c_TDC_CONFIG_SDB_DEVICE, x"00010000"),
1 => f_sdb_embed_device(c_ONEWIRE_SDB_DEVICE, x"00011000"),
2 => f_sdb_embed_device(c_TDC_CONFIG_SDB_DEVICE, x"00012000"),
2 => f_sdb_embed_device(c_INT_SDB_DEVICE, x"00012000"),
3 => f_sdb_embed_device(c_I2C_SDB_DEVICE, x"00013000"),
4 => f_sdb_embed_device(c_TDC_MEM_SDB_DEVICE, x"00014000"));
......@@ -206,8 +207,9 @@ architecture rtl of fmc_tdc_mezzanine is
signal sys_scl_in, sys_scl_out : std_logic;
signal sys_scl_oe_n, sys_sda_in : std_logic;
signal sys_sda_out, sys_sda_oe_n : std_logic;
-- dummy
signal dummy_reg_1 : std_logic_vector(31 downto 0) := x"F000000D";
-- IRQ
signal irq_tstamp_p, irq_time_p : std_logic;
signal irq_acam_err_p : std_logic;
--=================================================================================================
......@@ -308,9 +310,9 @@ begin
tdc_led_trig4_o => tdc_led_trig4_o,
tdc_led_trig5_o => tdc_led_trig5_o,
-- Interrupts
irq_tstamp_p_o => irq_tstamp_p_o,
irq_time_p_o => irq_time_p_o,
irq_acam_err_p_o => irq_acam_err_p_o,
irq_tstamp_p_o => irq_tstamp_p,
irq_time_p_o => irq_time_p,
irq_acam_err_p_o => irq_acam_err_p,
-- WISHBONE CSR for core configuration
tdc_config_wb_adr_i => tdc_core_wb_adr,
tdc_config_wb_dat_i => cnx_master_out(c_WB_SLAVE_TDC_CORE_CONFIG).dat,
......@@ -395,58 +397,30 @@ begin
---------------------------------------------------------------------------------------------------
-- Dummy for debugging only! --
-- INTERRUPTS CONTROLLER --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- WISHBONE ack generation
dummy_ack_generator: process (clk_125m_i)
begin
if rising_edge (clk_125m_i) then
if general_rst_n = '0' then
cnx_master_in(c_WB_SLAVE_DUMMY).ack <= '0';
else
cnx_master_in(c_WB_SLAVE_DUMMY).ack <= cnx_master_out(c_WB_SLAVE_DUMMY).stb and
cnx_master_out(c_WB_SLAVE_DUMMY).cyc;
end if;
end if;
end process;
-- IRQ sources
-- 0 -> number of accumulated timestamps reached threshold
-- 1 -> number of seconds passed reached threshold and number of accumulated tstamps > 0
-- 1 -> ACAM error
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Registers read/write
dummy_regs_exchange: process (clk_125m_i)
begin
if rising_edge (clk_125m_i) then
if general_rst_n = '0' then
dummy_reg_1 <= x"F000000D";
elsif cnx_master_out(c_WB_SLAVE_DUMMY).cyc = '1' and cnx_master_out(c_WB_SLAVE_DUMMY).stb = '1'
and cnx_master_out(c_WB_SLAVE_DUMMY).we = '1' then
if dummy_core_wb_adr(7 downto 0) = x"00" then
dummy_reg_1 <= cnx_master_out(c_WB_SLAVE_DUMMY).dat;
end if;
elsif cnx_master_out(c_WB_SLAVE_DUMMY).cyc = '1' and cnx_master_out(c_WB_SLAVE_DUMMY).stb = '1'
and cnx_master_out(c_WB_SLAVE_DUMMY).we = '0' then
if dummy_core_wb_adr(7 downto 0) = x"00" then
cnx_master_in(c_WB_SLAVE_DUMMY).dat <= dummy_reg_1;
elsif dummy_core_wb_adr(7 downto 0) = x"01" then
cnx_master_in(c_WB_SLAVE_DUMMY).dat <= wb_tdc_mezz_adr_i;
else
cnx_master_in(c_WB_SLAVE_DUMMY).dat <= dummy_core_wb_adr;
end if;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
dummy_core_wb_adr <= cnx_master_out(c_WB_SLAVE_DUMMY).adr;
cnx_master_in(c_WB_SLAVE_DUMMY).err <= '0';
cnx_master_in(c_WB_SLAVE_DUMMY).rty <= '0';
cnx_master_in(c_WB_SLAVE_DUMMY).stall <= '0';
cnx_master_in(c_WB_SLAVE_DUMMY).int <= '0';
cmp_irq_controller : irq_controller
port map
(clk_sys_i => clk_125m_i,
rst_n_i => general_rst_n,
wb_adr_i => cnx_master_out(c_WB_SLAVE_IRQ).adr(3 downto 2),
wb_dat_i => cnx_master_out(c_WB_SLAVE_IRQ).dat,
wb_dat_o => cnx_master_in(c_WB_SLAVE_IRQ).dat,
wb_cyc_i => cnx_master_out(c_WB_SLAVE_IRQ).cyc,
wb_sel_i => cnx_master_out(c_WB_SLAVE_IRQ).sel,
wb_stb_i => cnx_master_out(c_WB_SLAVE_IRQ).stb,
wb_we_i => cnx_master_out(c_WB_SLAVE_IRQ).we,
wb_ack_o => cnx_master_in(c_WB_SLAVE_IRQ).ack,
wb_stall_o => cnx_master_in(c_WB_SLAVE_IRQ).stall,
wb_int_o => wb_irq_o,
irq_tdc_tstamps_i => irq_tstamp_p,
irq_tdc_time_i => irq_time_p,
irq_tdc_acam_err_i => irq_acam_err_p);
end rtl;
......
This diff is collapsed.
This diff is collapsed.
No preview for this file type
This diff is collapsed.
This diff is collapsed.
......@@ -349,9 +349,6 @@ package tdc_core_pkg is
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
irq_tstamp_p_o : out std_logic;
irq_time_p_o : out std_logic;
irq_acam_err_p_o : out std_logic;
wb_tdc_mezz_adr_i : in std_logic_vector(31 downto 0);
wb_tdc_mezz_dat_i : in std_logic_vector(31 downto 0);
wb_tdc_mezz_dat_o : out std_logic_vector(31 downto 0);
......@@ -361,6 +358,7 @@ package tdc_core_pkg is
wb_tdc_mezz_we_i : in std_logic;
wb_tdc_mezz_ack_o : out std_logic;
wb_tdc_mezz_stall_o : out std_logic;
wb_irq_o : out std_logic;
sys_scl_b : inout std_logic;
sys_sda_b : inout std_logic;
mezz_one_wire_b : inout std_logic);
......@@ -717,22 +715,21 @@ package tdc_core_pkg is
---------------------------------------------------------------------------------------------------
component irq_controller
port
(rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_tdc1_tstamps_i : in std_logic;
irq_tdc1_acam_err_i : in std_logic;
irq_tdc2_tstamps_i : in std_logic;
irq_tdc2_acam_err_i : in std_logic);
(rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_tdc_tstamps_i : in std_logic;
irq_tdc_time_i : in std_logic;
irq_tdc_acam_err_i : in std_logic);
end component irq_controller;
......
This diff is collapsed.
peripheral {
name = "Interrupt controller";
description = "FMC TDC interrrupt controller.";
hdl_entity = "irq_controller";
prefix = "irq_ctrl";
irq {
name = "FMC TDC timestamps interrupt";
description = "FMC TDC timestamp interrupt (rising edge sensitive).";
prefix = "tdc_tstamps";
trigger = EDGE_RISING;
};
irq {
name = "FMC TDC time interrupt";
description = "FMC TDC time interrupt (rising edge sensitive).";
prefix = "tdc_time";
trigger = EDGE_RISING;
};
irq {
name = "FMC TDC acam error interrupt";
description = "FMC slot 1 acam error interrupt (rising edge sensitive).";
prefix = "tdc_acam_err";
trigger = EDGE_RISING;
};
};
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for IRQ controller registers
---------------------------------------------------------------------------------------
-- File : ../rtl/svec_irq_controller_regs.vhd
-- Author : auto-generated by wbgen2 from svec_irq_controller_regs.wb
-- Created : Fri Jul 5 10:18:32 2013
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE svec_irq_controller_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity irq_controller_regs is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
-- Port for std_logic_vector field: 'Multiple interrupt' in reg: 'Multiple interrupt register'
irq_ctrl_multi_irq_o : out std_logic_vector(31 downto 0);
irq_ctrl_multi_irq_i : in std_logic_vector(31 downto 0);
irq_ctrl_multi_irq_load_o : out std_logic;
-- Port for std_logic_vector field: 'Interrupt sources' in reg: 'Interrupt sources register '
irq_ctrl_src_o : out std_logic_vector(31 downto 0);
irq_ctrl_src_i : in std_logic_vector(31 downto 0);
irq_ctrl_src_load_o : out std_logic;
-- Port for std_logic_vector field: 'Interrupt enable mask' in reg: 'Interrupt enable mask register'
irq_ctrl_en_mask_o : out std_logic_vector(31 downto 0)
);
end irq_controller_regs;
architecture syn of irq_controller_regs is
signal irq_ctrl_en_mask_int : std_logic_vector(31 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_load_o <= '0';
irq_ctrl_en_mask_int <= "00000000000000000000000000000000";
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_load_o <= '0';
ack_in_progress <= '0';
else
irq_ctrl_multi_irq_load_o <= '0';
irq_ctrl_src_load_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
irq_ctrl_multi_irq_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= irq_ctrl_multi_irq_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
irq_ctrl_src_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= irq_ctrl_src_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
irq_ctrl_en_mask_int <= wrdata_reg(31 downto 0);
end if;
rddata_reg(31 downto 0) <= irq_ctrl_en_mask_int;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- Multiple interrupt
irq_ctrl_multi_irq_o <= wrdata_reg(31 downto 0);
-- Interrupt sources
irq_ctrl_src_o <= wrdata_reg(31 downto 0);
-- Interrupt enable mask
irq_ctrl_en_mask_o <= irq_ctrl_en_mask_int;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
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