Skip to content
Snippets Groups Projects
Commit 32bb699e authored by David Gabriel Monk's avatar David Gabriel Monk
Browse files

Increase number of FE modules to six for a full station

parent 72ea223a
No related branches found
No related tags found
1 merge request!18Increase number of FE modules to six for a full station
Showing
with 1146 additions and 589 deletions
# MProcessor Firmware
# MProcessor Firmware - 2x10gbe
## Instructions to Run
```bash
# Pull the package onto the Serenity card
......
......@@ -49,5 +49,5 @@ sources:
url: https://github.com/KristianHahn/verilog-ethernet.git
10gb-ethernet:
tag: v1.0.0
tag: v2.0.0
url: https://gitlab.cern.ch/cms-tracker-phase2-data-processing/BE_firmware/10gb-ethernet.git
......@@ -3,7 +3,7 @@
<node id="ctrl" module="file://emp_ctrl.xml" address="0x200"/>
<node id="ttc" module="file://emp_ttc.xml" address="0x400"/>
<node id="datapath" module="file://emp_datapath.xml" address="0x2000"/>
<node id="eth10g" module="file://emp_eth10g.xml" address="0x4000"/>
<node id="eth10g" module="file://emp_eth10g_interface.xml" address="0x4000"/>
<node id="freq" module="file://ipbus_freq_ctr.xml" address="0x40000000"/>
<node id="payload" module="file://emp_payload.xml" address="0x80000000" fwinfo="endpoint;width=31"/>
</node>
......@@ -57,10 +57,10 @@ entity top is
tcds_tx_p : out std_logic;
tcds_tx_n : out std_logic;
-- 10g eth signals
gbe_rx_p : in std_logic;
gbe_rx_n : in std_logic;
gbe_tx_p : out std_logic;
gbe_tx_n : out std_logic;
gbe_rx_p : in std_logic_vector(1 downto 0);
gbe_rx_n : in std_logic_vector(1 downto 0);
gbe_tx_p : out std_logic_vector(1 downto 0);
gbe_tx_n : out std_logic_vector(1 downto 0);
gbe_mgt_refclk_p : in std_logic;
gbe_mgt_refclk_n : in std_logic;
-- Transceiver ref-clocks
......@@ -115,18 +115,10 @@ architecture rtl of top is
signal clk125_s : std_logic;
signal gbe_ldata : lword;
signal dbg_pause_count : std_logic_vector(31 downto 0);
signal dbg_pkt_count : std_logic_vector(15 downto 0);
signal dbg_pkt_ctrl : std_logic_vector(2 downto 0);
signal dbg_pkt_rdy : std_logic;
signal dbg_pkt_go : std_logic;
-- aug28
signal lff,lff_rcvd : std_logic;
signal payload_rst : std_logic; -- sep2
-- 10g
signal gbe_ldata : ldata(1 downto 0);
signal gbe_lff : std_logic_vector(1 downto 0);
-- KH tmp
signal clk_40_div, clk_p_div : std_logic;
......@@ -298,34 +290,40 @@ begin
q => payload_q,
gpio => open,
gpio_en => open,
--
ldata_out => gbe_ldata,
lff => lff
-- 10g
gbe_q => gbe_ldata,
gbe_backpressure => gbe_lff
);
eth : entity work.emp_eth10g
generic map( ILA_DEBUG => true)
--ILA_DEBUG_MORE => false)
port map (
--
-- 10g
--
eth10g : entity work.emp_eth10g_interface
generic map ( ETH10G_CHANNELS => 2 )
port map (
clk_ipb => ipb_clk,
rst_ipb => ipb_rst,
ipb_in => ipb_w_array(N_SLV_ETH10G),
ipb_out => ipb_r_array(N_SLV_ETH10G),
--
clk_p => clk_p,
rst_p => rst_p,
clk125 => clk125,
gbe_rx_p => gbe_rx_p,
gbe_rx_n => gbe_rx_n,
gbe_tx_p => gbe_tx_p,
gbe_tx_n => gbe_tx_n,
gbe_mgt_refclk_p => gbe_mgt_refclk_p,
gbe_mgt_refclk_n => gbe_mgt_refclk_n,
ldata_in => gbe_ldata,
--
lff => lff
clk_p => clk_p,
rst_p => rst_p,
clk125 => clk125,
-- Input from payload
ldata_in => gbe_ldata,
-- backpressure to payload
lff => gbe_lff,
--10g
gbe_rx_p => gbe_rx_p,
gbe_rx_n => gbe_rx_n,
gbe_tx_p => gbe_tx_p,
gbe_tx_n => gbe_tx_n,
gbe_mgt_refclk_p => gbe_mgt_refclk_p,
gbe_mgt_refclk_n => gbe_mgt_refclk_n
);
-- KH tmp to check clk_p
......
......@@ -14,43 +14,11 @@
</node>
<node id="fe_chan" address="0x040" description="FE channel control and status" module="file://link_interface.xml" fwinfo="endpoint;width=6"/>
<node id="mprocessor" address="0x080" description="Link Aggregator control and status" fwinfo="endpoint;width=3">
<node id="link_aggregator_control" address="0x0">
<node id="reset" mask="0x0001"/>
</node>
<node id="link_combiner_control" address="0x1">
<node id="reset" mask="0x0001"/>
<node id="enable" mask="0x0002"/>
</node>
<node id="input_link_mask" address="0x2">
<node id="link_aggregator" mask="0xf"/>
<node id="link_combiner" mask="0xff0"/>
<node id="head_start_select" mask="0x3000"/>
</node>
<node id="header_user_bits" address="0x3"/>
<node id="super_id" address="0x4"/>
<node id="lff" address="0x5" mask="0x0001"/>
<node id="link_combiner_fifo" address="0x6">
<node id="data_count" mask="0xff"/>
<node id="full" mask="0x100"/>
<node id="rd_en" mask="0x200"/>
<node id="overflow" mask="0x400"/>
</node>
<node id="status" address="0x7">
<node id="link_aggregator_output_0_overflow" mask="0x1"/>
<node id="link_aggregator_output_1_overflow" mask="0x2"/>
<node id="link_aggregator_output_2_overflow" mask="0x4"/>
<node id="link_aggregator_output_3_overflow" mask="0x8"/>
<node id="link_aggregator_output_4_overflow" mask="0x10"/>
<node id="link_aggregator_output_5_overflow" mask="0x20"/>
<node id="link_aggregator_output_6_overflow" mask="0x40"/>
<node id="link_aggregator_output_7_overflow" mask="0x80"/>
<node id="link_aggregator_cache_0_0_overflow" mask="0x100"/>
<node id="link_aggregator_route_0_0_overflow" mask="0x200"/>
</node>
<node id="mproc_ctrl" address="0x1ff" description="MProcessor channel control" fwinfo="endpoint;width=0">
<node id="chan_sel" mask="0x7f"/>
</node>
<node id="mprocessor" address="0x200" description="MProcessor control and status" module="file://mprocessor.xml" fwinfo="endpoint;width=7"/>
<node id="mem1" address="0x1000" size="0x200" mode="incremental" fwinfo="endpoint;width=9"/>
<node id="mem2" address="0x2000" size="0x200" mode="incremental" fwinfo="endpoint;width=9"/>
......
<node description="Link Aggregator control and status" fwinfo="endpoint">
<node id="chan_sel" address="0x000" description="Bx channel select" fwinfo="endpoint;width=0"/>
<node id="control" address="0x001" fwinfo="endpoint;width=0">
<node id="input_link_mask" mask="0x03f"/>
<node id="reset" mask="0x40"/>
</node>
<node id="monitoring" address="0x008" fwinfo="endpoint;width=3">
<node id="non_empty_count_0" address="0x0"/>
<node id="non_empty_count_1" address="0x1"/>
<node id="non_empty_count_2" address="0x2"/>
<node id="non_empty_count_3" address="0x3"/>
<node id="non_empty_count_4" address="0x4"/>
<node id="non_empty_count_5" address="0x5"/>
</node>
</node>
<node description="MProcessor Control and Status" fwinfo="endpoint">
<node id="link_aggregator" address="0x0" description="Link Aggregator control and status" module="file://link_aggregator.xml" fwinfo="endpoint;width=5"/>
<node id="link_combiner" address="0x20" description="Link Combiner control and status" fwinfo="endpoint;width=1">
<node id="control" address="0x000">
<node id="input_link_mask" mask="0x0ff"/>
<node id="reset" mask="0x100"/>
<node id="enable" mask="0x200"/>
</node>
<node id="header_user_bits" address="0x1"/>
</node>
<node id="csr" address="0x22" description="MProcessor control and status" fwinfo="endpoint;width=1">
<node id="header_start_select" address="0x0" mask="0x7"/>
<node id="lff" address="0x1" mask="0x0001"/>
</node>
</node>
......@@ -22,10 +22,16 @@ src emp_project_decl.vhd
src emp_payload.vhd
src link_maps.vhd
src ipbus_decode_emp_payload.vhd
src LinkAggregator.vhd
src mprocessor_constants.vhd
src MProcessor.vhd
src ipbus_decode_mprocessor.vhd
src LinkAggregatorCore.vhd
src LinkAggregatorIPBus.vhd
src ipbus_decode_link_aggregator.vhd
src fixed_pkg_2008.vhd
src --vhdl2008 TrackReconstructor.vhd
src LinkCombiner.vhd
src LinkCombinerCore.vhd
src LinkCombinerIPBus.vhd
src --cd ../cgn link_agg_single_link_fifo.xci
setup -f --cd ../cgn link_agg_single_link_fifo.tcl
......@@ -40,4 +46,6 @@ src --cd ../cgn link_combin_buffer.xci
setup -f --cd ../cgn link_combin_buffer.tcl
addrtab link_aggregator.xml
addrtab emp_payload.xml
addrtab mprocessor.xml
......@@ -3,31 +3,38 @@ use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.emp_data_types.all;
entity LinkAggregator is
generic (
N_LINKS : integer
);
port (
--- Input Ports ---
clk_p : in std_logic;
reset : in std_logic;
packet_start : in std_logic;
links_in : in ldata(N_LINKS - 1 downto 0);
--- Output Ports ---
links_out : out ldata(7 downto 0) := (others => LWORD_NULL);
uncompressed_stubs : out ldata(N_LINKS * 8 - 1 downto 0) := (others => LWORD_NULL);
readout_reset : out std_logic := '0';
--- Debug Ports ---
status_bits : out std_logic_vector(15 downto 0)
);
end LinkAggregator;
architecture compressed of LinkAggregator is
use work.ipbus.all;
use work.ipbus_reg_types.all;
entity LinkAggregatorCore is
generic (
N_LINKS : integer
);
port (
--- Input Ports ---
clk_p : in std_logic;
reset : in std_logic;
packet_start : in std_logic;
links_in : in ldata(N_LINKS - 1 downto 0);
--- Output Ports ---
links_out : out ldata(7 downto 0) := (others => LWORD_NULL);
uncompressed_stubs : out ldata(N_LINKS * 8 - 1 downto 0) := (others => LWORD_NULL);
readout_reset : out std_logic := '0';
--- Debug Ports ---
status_bits : out std_logic_vector(15 downto 0);
--- IPBus Ports ---
non_empty_counts : out ipb_reg_v(8*N_LINKS - 1 downto 0)
);
end LinkAggregatorCore;
architecture compressed of LinkAggregatorCore is
constant cFIFOWidth : integer := 64;
-- FIFO IP Cores
-- FIFO IP Coress
COMPONENT link_agg_single_link_fifo
PORT (
......@@ -117,8 +124,11 @@ architecture compressed of LinkAggregator is
end function;
signal output_overflow_array : std_logic_vector(cBoxcarBx - 1 downto 0) := (others => '0');
signal route_overflow_array : tEnableArray := cNullEnableArray;
signal cache_overflow_array : tEnableArray := cNullEnableArray;
signal route_overflow_array : tEnableArray := cNullEnableArray;
signal cache_overflow_array : tEnableArray := cNullEnableArray;
signal non_empty_fifo_count : ipb_reg_v(8*N_LINKS - 1 downto 0) := (others => (others => '0'));
begin
......@@ -178,6 +188,12 @@ begin
rd_en_cache <= '0';
end if;
end if;
-- Check for non-empty FIFOs at reset
if route_reset = '1' then
if empty_route = '0' then
non_empty_fifo_count(N_LINKS*j + i) <= std_logic_vector(unsigned(non_empty_fifo_count(N_LINKS*j + i)) + 1);
end if;
end if;
end if;
end process pTransferToRoutingFIFO;
......@@ -381,269 +397,6 @@ begin
status_bits(7) <= output_overflow_array(7); -- link_aggregator_output_7_overflow;
status_bits(8) <= cache_overflow_array(0)(0); -- link_aggregator_cache_0_0_overflow;
status_bits(9) <= route_overflow_array(0)(0); -- link_aggregator_route_0_0_overflow;
non_empty_counts <= non_empty_fifo_count;
end compressed;
--======================================================================================================================================================--
architecture uncompressed of LinkAggregator is
constant cFIFOWidth : integer := 64;
-- FIFO IP Cores
COMPONENT link_agg_single_link_fifo
PORT (
--- Input Ports ---
clk : IN STD_LOGIC;
srst : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
--- Output Ports ---
dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
almost_empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC;
data_count : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
wr_rst_busy : OUT STD_LOGIC;
rd_rst_busy : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT link_agg_single_link_fifo_fwft
PORT (
--- Input Ports ---
clk : IN STD_LOGIC;
srst : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
--- Output Ports ---
dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
almost_empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC;
data_count : OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
wr_rst_busy : OUT STD_LOGIC;
rd_rst_busy : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT link_agg_all_links_fifo
PORT (
--- Input Ports ---
clk : IN STD_LOGIC;
srst : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
--- Output Ports ---
dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
almost_empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC;
data_count : OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
wr_rst_busy : OUT STD_LOGIC;
rd_rst_busy : OUT STD_LOGIC
);
END COMPONENT;
constant cBoxcarBx : integer := 8;
type tLinkDataArray is array(N_LINKS - 1 downto 0) of std_logic_vector(cFIFOWidth - 1 downto 0);
type t2DDataArray is array(cBoxcarBx - 1 downto 0) of tLinkDataArray;
type tEnableArray is array(cBoxcarBx - 1 downto 0) of std_logic_vector(N_LINKS - 1 downto 0);
signal data : t2DDataArray := (others => (others => (others => '0')));
signal rd_en_route_array : tEnableArray := (others => (others => '0'));
signal valid_route_array : tEnableArray := (others => (others => '0'));
signal counter : integer := 0;
begin
--==============================--
genLinkCache : for i in N_LINKS - 1 downto 0 generate
--==============================--
signal wr_en_array_cache : std_logic_vector(cBoxcarBx - 1 downto 0) := (others => '0');
signal data_in : std_logic_vector(cFIFOWidth - 1 downto 0);
begin
-- Send the data to the correct FIFO, using the Bx field of the stub
pRouteInputData : process(clk_p)
begin
if rising_edge(clk_p) then
wr_en_array_cache <= (others => '0');
wr_en_array_cache(to_integer(unsigned(links_in(i).data(17 downto 15)))) <= links_in(i).valid;
data_in <= std_logic_vector(to_unsigned(i, 4)) & links_in(i).data(cFIFOWidth - 1 - 4 downto 0);
end if;
end process;
--==============================--
genLinkBxCache : for j in cBoxcarBx - 1 downto 0 generate
--==============================--
signal dout_cache : std_logic_vector(cFIFOWidth - 1 downto 0);
signal rd_en_cache, full_cache, empty_cache, valid_cache, almost_empty_cache : std_logic := '0';
signal count_cache : std_logic_vector(3 downto 0);
signal wr_en_route, rd_en_route, empty_route, full_route, valid_route, almost_empty_route : std_logic := '0';
signal din_route, dout_route : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0');
signal count_route : std_logic_vector(4 downto 0);
signal route_reset : std_logic := '0';
begin
pTransferToRoutingFIFO : process(clk_p)
begin
if rising_edge(clk_p) then
-- If FIFO is not empty at start of packet, enable readout to routing FIFO
if packet_start = '1' then
if empty_cache = '0' then
rd_en_cache <= '1';
end if;
end if;
if rd_en_cache = '1' then
-- Use almost empty flag to avoid underflow
if almost_empty_cache = '1' then
rd_en_cache <= '0';
end if;
end if;
end if;
end process;
-- Enable writing of routing FIFO using the validflag of the cache FIFO
wr_en_route <= valid_cache;
din_route <= dout_cache;
SingleLinkCacheInstance : link_agg_single_link_fifo
PORT MAP (
--- Input Ports ---
clk => clk_p,
srst => reset,
din => data_in,
wr_en => wr_en_array_cache(j),
rd_en => rd_en_cache,
--- Output Ports ---
dout => dout_cache,
full => full_cache,
empty => empty_cache,
valid => valid_cache,
almost_empty => almost_empty_cache,
data_count => count_cache
);
SingleLinkRoutingFIFOInstance : link_agg_single_link_fifo_fwft
PORT MAP (
--- Input Ports ---
clk => clk_p,
srst => route_reset, -- Reset FIFO for every packet
din => din_route,
wr_en => wr_en_route,
rd_en => rd_en_route_array(j)(i),
--- Output Ports ---
dout => data(j)(i),
full => full_route,
empty => empty_route,
valid => valid_route_array(j)(i),
data_count => count_route
);
route_reset <= reset or packet_start;
end generate;
end generate;
genAggregatedFIFOs : for i in 7 downto 0 generate
signal pointer : integer := 0;
signal din : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0');
signal wr_en, rd_en, full, empty, almost_empty, valid : std_logic := '0';
signal dout : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0');
signal data_count : std_logic_vector(5 downto 0);
signal all_links_reset : std_logic := '0';
begin
pIteratePointer : process(clk_p)
begin
if rising_edge(clk_p) then
-- Loop pointer over all the links
if pointer = N_LINKS - 1 then
pointer <= 0;
else
pointer <= pointer + 1;
end if;
-- Readout value of FIFO which is currently pointed to
rd_en_route_array(i) <= (others => '0');
rd_en_route_array(i)(pointer) <= valid_route_array(i)(pointer);
din <= data(i)(pointer);
-- If counter is at the end of a packet, then start to readout the contents of the aggregated FIFOs
if counter = 48 then
rd_en <= '1';
end if;
if rd_en = '1' then
if almost_empty = '1' then
rd_en <= '0';
end if;
end if;
if valid = '1' then
links_out(i).valid <= '1';
links_out(i).data <= dout;
links_out(i).strobe <= '1';
else
links_out(i).valid <= '0';
links_out(i).data <= (others => '0');
links_out(i).strobe <= '1';
end if;
wr_en <= valid_route_array(i)(pointer);
end if;
end process;
AllLinksFIFOInstance : link_agg_all_links_fifo
PORT MAP (
--- Input Ports ---
clk => clk_p,
srst => all_links_reset, -- Reset FIFO on every packet
din => din,
wr_en => wr_en,
rd_en => rd_en,
--- Output Ports ---
dout => dout,
full => full,
empty => empty,
almost_empty => almost_empty,
valid => valid,
data_count => data_count
);
all_links_reset <= packet_start or reset;
end generate;
pReadoutReset : process(clk_p)
begin
if rising_edge(clk_p) then
if packet_start = '1' then
counter <= 0;
else
counter <= counter + 1;
end if;
-- If counter is at the end of a packet, then start to readout the contents of the aggregated FIFOs
readout_reset <= '0';
if counter = 64 then
counter <= counter;
elsif counter = 48 then
readout_reset <= '1';
end if;
end if;
end process pReadoutReset;
end uncompressed;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.emp_data_types.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.ipbus_decode_link_aggregator.all;
entity LinkAggregatorIPBus is
generic (
N_LINKS : integer
);
port (
--- Input Ports ---
clk_p : in std_logic;
packet_start : in std_logic;
links_in : in ldata(N_LINKS - 1 downto 0);
--- Output Ports ---
links_out : out ldata(7 downto 0) := (others => LWORD_NULL);
uncompressed_stubs : out ldata(N_LINKS * 8 - 1 downto 0) := (others => LWORD_NULL);
readout_reset : out std_logic := '0';
--- IPBus Ports ---
ipb_clk : in std_logic;
ipb_rst : in std_logic;
ipb_in : in ipb_wbus;
ipb_out : out ipb_rbus
);
end LinkAggregatorIPBus;
architecture Behavorial of LinkAggregatorIPBus is
signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0);
signal channel_sel : ipb_reg_v(0 downto 0);
signal ipb_chain : ipbdc_bus_array(8 downto 0);
-- signal link_aggregator_status_registers : ipb_reg_v(4 - 1 downto 0) := (others => (others => '0'));
signal control_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0'));
signal mprocessor_monitoring_registers : ipb_reg_v(8*N_LINKS - 1 downto 0) := (others => (others => '0'));
signal masked_links : ldata(N_LINKS - 1 downto 0) := (others => LWORD_NULL);
begin
--==============================--
-- IPBus
--==============================--
--==============================--
fabric: entity work.ipbus_fabric_sel
--==============================--
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_link_aggregator(ipb_in.ipb_addr),
ipb_to_slaves => ipb_to_slaves,
ipb_from_slaves => ipb_from_slaves
);
--==============================--
channel_ctrl: entity work.ipbus_reg_v
--==============================--
generic map(
N_REG => 1
)
port map(
clk => ipb_clk,
reset => ipb_rst,
ipbus_in => ipb_to_slaves(N_SLV_CHAN_SEL),
ipbus_out => ipb_from_slaves(N_SLV_CHAN_SEL),
q => channel_sel,
qmask => (0 => X"0000007f")
);
--==============================--
ControlInstance: entity work.ipbus_ctrlreg_v
--==============================--
generic map(
N_CTRL => 1,
N_STAT => 0
)
port map(
clk => ipb_clk,
reset => ipb_rst,
ipbus_in => ipb_to_slaves(N_SLV_CONTROL),
ipbus_out => ipb_from_slaves(N_SLV_CONTROL),
-- d => link_aggregator_status_registers,
q => control_registers
);
--==============================--
channel_select: entity work.ipbus_dc_fabric_sel
--==============================--
generic map(
SEL_WIDTH => 7
)
port map(
clk => ipb_clk,
rst => ipb_rst,
sel => channel_sel(0)(6 downto 0),
ipb_in => ipb_to_slaves(N_SLV_MONITORING),
ipb_out => ipb_from_slaves(N_SLV_MONITORING),
ipbdc_out => ipb_chain(0),
ipbdc_in => ipb_chain(8)
);
--==============================--
pInputLinkMask: process(clk_p)
--==============================--
begin
if rising_edge(clk_p) then
for i in 0 to N_LINKS - 1 loop
if control_registers(0)(i) = '1' then
masked_links(i) <= links_in(i);
else
masked_links(i) <= LWORD_NULL;
end if;
end loop;
end if;
end process;
--==============================--
gMonitoringRegisters : for i in 0 to 7 generate
--==============================--
signal ipb_to_channel : ipb_wbus;
signal ipb_from_channel : ipb_rbus;
signal din : ipb_reg_v(6 - 1 downto 0) := (others => (others => '0'));
begin
--==============================--
channel_node: entity work.ipbus_dc_node
--==============================--
generic map(
I_SLV => i,
SEL_WIDTH => 7,
PIPELINE => false
)
port map(
clk => ipb_clk,
rst => ipb_rst,
ipb_out => ipb_to_channel,
ipb_in => ipb_from_channel,
ipbdc_in => ipb_chain(i),
ipbdc_out => ipb_chain(i + 1)
);
--==============================--
MProcessorMonitoringInstance: entity work.ipbus_ctrlreg_v
--==============================--
generic map(
N_CTRL => 0,
N_STAT => 6
)
port map(
clk => ipb_clk,
reset => ipb_rst,
ipbus_in => ipb_to_channel,
ipbus_out => ipb_from_channel,
d => din
);
din(N_LINKS - 1 downto 0) <= mprocessor_monitoring_registers((i+1)*N_LINKS - 1 downto i*N_LINKS);
end generate gMonitoringRegisters;
--==============================--
LinkAggregatorInstance: entity work.LinkAggregatorCore
--==============================--
generic map (
N_LINKS => N_LINKS
)
port map (
--- Input Ports ---
clk_p => clk_p,
reset => control_registers(0)(N_LINKS + 1 - 1),
packet_start => packet_start,
links_in => masked_links,
--- Output Ports ---
links_out => links_out,
readout_reset => readout_reset,
--- Debug Ports ---
-- status_bits => link_aggregator_status_registers(3)(15 downto 0),
non_empty_counts => mprocessor_monitoring_registers
);
end Behavorial;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.emp_data_types.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
entity LinkAggregator is
generic (
N_LINKS : integer
);
port (
--- Input Ports ---
clk_p : in std_logic;
reset : in std_logic;
packet_start : in std_logic;
links_in : in ldata(N_LINKS - 1 downto 0);
--- Output Ports ---
links_out : out ldata(7 downto 0) := (others => LWORD_NULL);
uncompressed_stubs : out ldata(N_LINKS * 8 - 1 downto 0) := (others => LWORD_NULL);
readout_reset : out std_logic := '0';
--- Debug Ports ---
status_bits : out std_logic_vector(15 downto 0);
--- IPBus Ports ---
clk : in std_logic;
rst : in std_logic;
ipb_in : in ipb_wbus;
ipb_out : out ipb_rbus;
non_empty_counts : out ipb_reg_v(8*N_LINKS - 1 downto 0)
);
end LinkAggregator;
architecture uncompressed of LinkAggregator is
constant cFIFOWidth : integer := 64;
-- FIFO IP Cores
COMPONENT link_agg_single_link_fifo
PORT (
--- Input Ports ---
clk : IN STD_LOGIC;
srst : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
--- Output Ports ---
dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
almost_empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC;
data_count : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
wr_rst_busy : OUT STD_LOGIC;
rd_rst_busy : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT link_agg_single_link_fifo_fwft
PORT (
--- Input Ports ---
clk : IN STD_LOGIC;
srst : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
--- Output Ports ---
dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
almost_empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC;
data_count : OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
wr_rst_busy : OUT STD_LOGIC;
rd_rst_busy : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT link_agg_all_links_fifo
PORT (
--- Input Ports ---
clk : IN STD_LOGIC;
srst : IN STD_LOGIC;
din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
wr_en : IN STD_LOGIC;
rd_en : IN STD_LOGIC;
--- Output Ports ---
dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0);
full : OUT STD_LOGIC;
empty : OUT STD_LOGIC;
almost_empty : OUT STD_LOGIC;
valid : OUT STD_LOGIC;
data_count : OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
wr_rst_busy : OUT STD_LOGIC;
rd_rst_busy : OUT STD_LOGIC
);
END COMPONENT;
constant cBoxcarBx : integer := 8;
type tLinkDataArray is array(N_LINKS - 1 downto 0) of std_logic_vector(cFIFOWidth - 1 downto 0);
type t2DDataArray is array(cBoxcarBx - 1 downto 0) of tLinkDataArray;
type tEnableArray is array(cBoxcarBx - 1 downto 0) of std_logic_vector(N_LINKS - 1 downto 0);
signal data : t2DDataArray := (others => (others => (others => '0')));
signal rd_en_route_array : tEnableArray := (others => (others => '0'));
signal valid_route_array : tEnableArray := (others => (others => '0'));
signal counter : integer := 0;
begin
--==============================--
genLinkCache : for i in N_LINKS - 1 downto 0 generate
--==============================--
signal wr_en_array_cache : std_logic_vector(cBoxcarBx - 1 downto 0) := (others => '0');
signal data_in : std_logic_vector(cFIFOWidth - 1 downto 0);
begin
-- Send the data to the correct FIFO, using the Bx field of the stub
pRouteInputData : process(clk_p)
begin
if rising_edge(clk_p) then
wr_en_array_cache <= (others => '0');
wr_en_array_cache(to_integer(unsigned(links_in(i).data(17 downto 15)))) <= links_in(i).valid;
data_in <= std_logic_vector(to_unsigned(i, 4)) & links_in(i).data(cFIFOWidth - 1 - 4 downto 0);
end if;
end process;
--==============================--
genLinkBxCache : for j in cBoxcarBx - 1 downto 0 generate
--==============================--
signal dout_cache : std_logic_vector(cFIFOWidth - 1 downto 0);
signal rd_en_cache, full_cache, empty_cache, valid_cache, almost_empty_cache : std_logic := '0';
signal count_cache : std_logic_vector(3 downto 0);
signal wr_en_route, rd_en_route, empty_route, full_route, valid_route, almost_empty_route : std_logic := '0';
signal din_route, dout_route : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0');
signal count_route : std_logic_vector(4 downto 0);
signal route_reset : std_logic := '0';
begin
pTransferToRoutingFIFO : process(clk_p)
begin
if rising_edge(clk_p) then
-- If FIFO is not empty at start of packet, enable readout to routing FIFO
if packet_start = '1' then
if empty_cache = '0' then
rd_en_cache <= '1';
end if;
end if;
if rd_en_cache = '1' then
-- Use almost empty flag to avoid underflow
if almost_empty_cache = '1' then
rd_en_cache <= '0';
end if;
end if;
end if;
end process;
-- Enable writing of routing FIFO using the validflag of the cache FIFO
wr_en_route <= valid_cache;
din_route <= dout_cache;
SingleLinkCacheInstance : link_agg_single_link_fifo
PORT MAP (
--- Input Ports ---
clk => clk_p,
srst => reset,
din => data_in,
wr_en => wr_en_array_cache(j),
rd_en => rd_en_cache,
--- Output Ports ---
dout => dout_cache,
full => full_cache,
empty => empty_cache,
valid => valid_cache,
almost_empty => almost_empty_cache,
data_count => count_cache
);
SingleLinkRoutingFIFOInstance : link_agg_single_link_fifo_fwft
PORT MAP (
--- Input Ports ---
clk => clk_p,
srst => route_reset, -- Reset FIFO for every packet
din => din_route,
wr_en => wr_en_route,
rd_en => rd_en_route_array(j)(i),
--- Output Ports ---
dout => data(j)(i),
full => full_route,
empty => empty_route,
valid => valid_route_array(j)(i),
data_count => count_route
);
route_reset <= reset or packet_start;
end generate;
end generate;
genAggregatedFIFOs : for i in 7 downto 0 generate
signal pointer : integer := 0;
signal din : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0');
signal wr_en, rd_en, full, empty, almost_empty, valid : std_logic := '0';
signal dout : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0');
signal data_count : std_logic_vector(5 downto 0);
signal all_links_reset : std_logic := '0';
begin
pIteratePointer : process(clk_p)
begin
if rising_edge(clk_p) then
-- Loop pointer over all the links
if pointer = N_LINKS - 1 then
pointer <= 0;
else
pointer <= pointer + 1;
end if;
-- Readout value of FIFO which is currently pointed to
rd_en_route_array(i) <= (others => '0');
rd_en_route_array(i)(pointer) <= valid_route_array(i)(pointer);
din <= data(i)(pointer);
-- If counter is at the end of a packet, then start to readout the contents of the aggregated FIFOs
if counter = 48 then
rd_en <= '1';
end if;
if rd_en = '1' then
if almost_empty = '1' then
rd_en <= '0';
end if;
end if;
if valid = '1' then
links_out(i).valid <= '1';
links_out(i).data <= dout;
links_out(i).strobe <= '1';
else
links_out(i).valid <= '0';
links_out(i).data <= (others => '0');
links_out(i).strobe <= '1';
end if;
wr_en <= valid_route_array(i)(pointer);
end if;
end process;
AllLinksFIFOInstance : link_agg_all_links_fifo
PORT MAP (
--- Input Ports ---
clk => clk_p,
srst => all_links_reset, -- Reset FIFO on every packet
din => din,
wr_en => wr_en,
rd_en => rd_en,
--- Output Ports ---
dout => dout,
full => full,
empty => empty,
almost_empty => almost_empty,
valid => valid,
data_count => data_count
);
all_links_reset <= packet_start or reset;
end generate;
pReadoutReset : process(clk_p)
begin
if rising_edge(clk_p) then
if packet_start = '1' then
counter <= 0;
else
counter <= counter + 1;
end if;
-- If counter is at the end of a packet, then start to readout the contents of the aggregated FIFOs
readout_reset <= '0';
if counter = 64 then
counter <= counter;
elsif counter = 48 then
readout_reset <= '1';
end if;
end if;
end process pReadoutReset;
end uncompressed;
......@@ -7,7 +7,7 @@ use work.gbt_module_constants.all;
use work.dtc_link_maps.all;
entity LinkCombiner is
entity LinkCombinerCore is
generic (
N_INPUT_LINKS : integer := 8;
N_OUTPUT_LINKS : integer := 1
......@@ -29,9 +29,9 @@ entity LinkCombiner is
debug_super_id : out std_logic_vector(31 downto 0);
debug_fifo : out std_logic_vector(31 downto 0) := (others => '0')
);
end LinkCombiner;
end LinkCombinerCore;
architecture Behavioral of LinkCombiner is
architecture Behavioral of LinkCombinerCore is
constant cWordWidth : integer := 64;
constant cOutputWordWidth : integer := 64;
......
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.emp_data_types.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.front_end_data_types.all;
use work.gbt_module_constants.all;
use work.dtc_link_maps.all;
entity LinkCombinerIPBus is
generic (
N_INPUT_LINKS : integer := 8
);
port (
--- Input Ports ---
clk_p : in std_logic;
reset : in std_logic;
links_in : in ldata(N_INPUT_LINKS - 1 downto 0);
packet_start : in std_logic;
header_in : in tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0')));
lff : in std_logic;
--- Ouput Ports ---
links_out : out ldata(1 - 1 downto 0);
--- IPBus Ports ---
ipb_clk : in std_logic;
ipb_rst : in std_logic;
ipb_in : in ipb_wbus;
ipb_out : out ipb_rbus
);
end LinkCombinerIPBus;
architecture Behavioral of LinkCombinerIPBus is
signal link_combiner_debug : lword := LWORD_NULL;
signal link_combiner_rd_en : std_logic_vector(0 downto 0) := "0";
signal link_combiner_debug_super_id : std_logic_vector(31 downto 0);
signal masked_stubs : ldata(cNumberOfFEModules - 1 downto 0) := (others => LWORD_NULL);
signal masked_input : ldata(8 - 1 downto 0) := (others => LWORD_NULL);
signal control_registers : ipb_reg_v(2 - 1 downto 0) := (others => (others => '0'));
begin
--==============================--
-- IPBus
--==============================--
--==============================--
ControlInstance: entity work.ipbus_ctrlreg_v
--==============================--
generic map(
N_CTRL => 2,
N_STAT => 0
)
port map(
clk => ipb_clk,
reset => ipb_rst,
ipbus_in => ipb_in,
ipbus_out => ipb_out,
-- d => link_aggregator_status_registers,
q => control_registers
);
--==============================--
pInputLinkMask: process(clk_p)
--==============================--
begin
if rising_edge(clk_p) then
for i in 0 to N_INPUT_LINKS - 1 loop
if control_registers(0)(i) = '1' then
masked_input(i) <= links_in(i);
else
masked_input(i) <= LWORD_NULL;
end if;
end loop;
end if;
end process pInputLinkMask;
--==============================--
pReadEnable: process(clk_p)
--==============================--
begin
if rising_edge(clk_p) then
for i in 0 downto 0 loop
link_combiner_rd_en(i) <= not lff and control_registers(0)(N_INPUT_LINKS + 2 - 1);
end loop;
end if;
end process pReadEnable;
--==============================--
LinkCombinerInstance : entity work.LinkCombinerCore
--==============================--
generic map (
N_INPUT_LINKS => 8
)
port map (
--- Input Ports ---
clk_p => clk_p,
reset => reset,
output_reset => control_registers(0)(N_INPUT_LINKS + 1 - 1),
output_rd_en => link_combiner_rd_en,
links_in => masked_input,
packet_start => packet_start,
header_in => header_in,
header_user_bits => control_registers(1),
--- Output Ports ---
links_out => links_out
--- Debug Ports ---
-- debug => link_combiner_debug,
-- debug_super_id => link_combiner_debug_super_id,
-- debug_fifo => link_aggregator_status_registers(2)
);
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.emp_data_types.all;
use work.ipbus.all;
use work.ipbus_reg_types.all;
use work.ipbus_decode_mprocessor.all;
use work.dtc_link_maps.all;
use work.front_end_data_types.all;
use work.gbt_module_constants.all;
use work.mprocessor_constants.all;
entity MProcessor is
generic (
N_LINKS : integer
);
port (
--- Input Ports ---
clk_p : in std_logic;
links_in : in ldata(N_LINKS - 1 downto 0);
header_in : in tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0')));
header_start_array : in tHeaderStartArray := (others => (others => '0'));
gbe_backpressure : in std_logic := '0';
--- Output Ports ---
link_out : out lword := LWORD_NULL;
--- IPBus Ports ---
ipb_clk : in std_logic;
ipb_rst : in std_logic;
ipb_in : in ipb_wbus;
ipb_out : out ipb_rbus
);
end MProcessor;
architecture Behavorial of MProcessor is
signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0);
signal packet_start : std_logic := '0';
signal readout_reset : std_logic := '0';
signal aggregated_stubs : ldata(7 downto 0) := (others => LWORD_NULL);
signal link_aggregator_input : ldata(5 downto 0) := (others => LWORD_NULL);
signal eth_link_out : ldata(0 downto 0) := (others => LWORD_NULL);
signal status_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0'));
signal control_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0'));
begin
--==============================--
-- IPBus fabric
--==============================--
--==============================--
fabric: entity work.ipbus_fabric_sel
--==============================--
generic map(
NSLV => N_SLAVES,
SEL_WIDTH => IPBUS_SEL_WIDTH
)
port map(
ipb_in => ipb_in,
ipb_out => ipb_out,
sel => ipbus_sel_mprocessor(ipb_in.ipb_addr),
ipb_to_slaves => ipb_to_slaves,
ipb_from_slaves => ipb_from_slaves
);
--==============================--
MProcessorControlInstance: entity work.ipbus_ctrlreg_v
--==============================--
generic map(
N_CTRL => 1,
N_STAT => 1
)
port map(
clk => ipb_clk,
reset => ipb_rst,
ipbus_in => ipb_to_slaves(N_SLV_CSR),
ipbus_out => ipb_from_slaves(N_SLV_CSR),
d => status_registers,
q => control_registers
);
--==============================--
LinkAggregatorInstance: entity work.LinkAggregatorIPBus
--==============================--
generic map (
N_LINKS => 6
)
port map (
--- Input Ports ---
clk_p => clk_p,
packet_start => packet_start,
links_in => link_aggregator_input,
--- Output Ports ---
links_out => aggregated_stubs,
readout_reset => readout_reset,
--- IPBus Ports ---
ipb_clk => ipb_clk,
ipb_rst => ipb_rst,
ipb_in => ipb_to_slaves(N_SLV_LINK_AGGREGATOR),
ipb_out => ipb_from_slaves(N_SLV_LINK_AGGREGATOR)
);
--==============================--
LinkCombinerInstance : entity work.LinkCombinerIPBus
--==============================--
generic map (
N_INPUT_LINKS => 8
)
port map (
--- Input Ports ---
clk_p => clk_p,
reset => readout_reset,
links_in => aggregated_stubs,
packet_start => packet_start,
header_in => header_in,
lff => gbe_backpressure,
--- Output Ports ---
links_out => eth_link_out,
--- IPBus Ports ---
ipb_clk => ipb_clk,
ipb_rst => ipb_rst,
ipb_in => ipb_to_slaves(N_SLV_LINK_COMBINER),
ipb_out => ipb_from_slaves(N_SLV_LINK_COMBINER)
);
-- --==============================--
-- TrackReconstructorInstance: entity work.TrackReconstructor
-- --==============================--
-- port map(
-- clk_p => clk_p,
-- reset => readout_reset,
-- stubs_in => aggregated_stubs(0)
-- );
link_aggregator_input(N_LINKS - 1 downto 0) <= links_in;
link_out <= eth_link_out(0);
status_registers(0)(0) <= gbe_backpressure;
packet_start <= header_start_array(to_integer(unsigned(control_registers(0)(2 downto 0))))(0);
end Behavorial;
......@@ -15,32 +15,33 @@ use work.ipbus_decode_emp_payload.all;
use work.dtc_link_maps.all;
use work.front_end_data_types.all;
use work.gbt_module_constants.all;
use work.mprocessor_constants.all;
entity emp_payload is
port(
--- Input Ports ---
clk_p : in std_logic;
clk40 : in std_logic := '0';
clk_payload : in std_logic_vector(2 downto 0);
rst_payload : in std_logic_vector(2 downto 0);
rst_loc : in std_logic_vector(N_REGION - 1 downto 0);
clken_loc : in std_logic_vector(N_REGION - 1 downto 0);
ctrs : in ttc_stuff_array;
d : in ldata(4 * N_REGION - 1 downto 0);
clk_p : in std_logic;
clk40 : in std_logic := '0';
clk_payload : in std_logic_vector(2 downto 0);
rst_payload : in std_logic_vector(2 downto 0);
rst_loc : in std_logic_vector(N_REGION - 1 downto 0);
clken_loc : in std_logic_vector(N_REGION - 1 downto 0);
ctrs : in ttc_stuff_array;
d : in ldata(4 * N_REGION - 1 downto 0);
--- Output Ports ---
bc0 : out std_logic;
gpio : out std_logic_vector(29 downto 0);
gpio_en : out std_logic_vector(29 downto 0);
q : out ldata(4 * N_REGION - 1 downto 0);
bc0 : out std_logic;
gpio : out std_logic_vector(29 downto 0);
gpio_en : out std_logic_vector(29 downto 0);
q : out ldata(4 * N_REGION - 1 downto 0);
--- IPBus Ports ---
clk : in std_logic;
rst : in std_logic;
ipb_in : in ipb_wbus;
ipb_out : out ipb_rbus;
clk : in std_logic;
rst : in std_logic;
ipb_in : in ipb_wbus;
ipb_out : out ipb_rbus;
-- KH
ldata_out : out lword;
lff : in std_logic
gbe_q : out ldata := (others => LWORD_NULL);
gbe_backpressure : in std_logic_vector(1 downto 0)
);
end emp_payload;
......@@ -49,60 +50,59 @@ architecture rtl of emp_payload is
-- IPBus fabric
signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0);
signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0);
signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0);
signal channel_sel : ipb_reg_v(0 downto 0);
signal link_aggr_control : ipb_reg_v(0 downto 0);
signal channel_sel : ipb_reg_v(0 downto 0);
signal mproc_channel_sel : ipb_reg_v(0 downto 0);
signal link_aggr_control : ipb_reg_v(0 downto 0);
-- FE data extraction and monitoring
signal ipb_chain : ipbdc_bus_array(cNumberOfFEModules downto 0);
signal stubs : ldata(cNumberOfFEModules - 1 downto 0);
signal ipb_chain : ipbdc_bus_array(cNumberOfFEModules downto 0);
signal stubs : ldata(cNumberOfFEModules - 1 downto 0);
signal linksout : ldata(cNumberOfFEModules - 1 downto 0);
signal linkor : lword := LWORD_NULL;
signal linksout : ldata(cNumberOfFEModules - 1 downto 0);
signal linkor : lword := LWORD_NULL;
-- Histogrammer
constant N_CTRL_HIST : integer := 2;
constant N_STAT_HIST : integer := 2;
constant bin_width : integer := 32;
constant input_width : integer := 9;
signal status_registers : ipb_reg_v(N_STAT_HIST - 1 downto 0) := (others => (others => '0'));
signal control_registers : ipb_reg_v(N_CTRL_HIST - 1 downto 0) := (others => (others => '0'));
signal link_aggregator_status_registers : ipb_reg_v(4 - 1 downto 0) := (others => (others => '0'));
signal link_aggregator_control_registers : ipb_reg_v(4 - 1 downto 0) := (others => (others => '0'));
signal trigger_window_lower : std_logic_vector(31 downto 0) := (others => '0');
signal trigger_window_upper : std_logic_vector(3 downto 0) := (others => '0');
signal trigger_window : std_logic_vector(36 - 1 downto 0) := X"0ffffffff";
signal max_value0, max_value1 : std_logic_vector(bin_width - 1 downto 0) := (others => '0');
signal histogram_reset : std_logic := '0';
signal hist0_stub, hist1_stub : lword := LWORD_NULL;
signal histogram_sel : integer := 0;
signal histogram_enable : std_logic := '0';
type tHeaderStartArray is array(cNumberOfFEModules - 1 downto 0) of std_logic_vector(1 downto 0);
signal header_start_array : tHeaderStartArray := (others => (others => '0'));
signal aggregated_stubs : ldata(7 downto 0) := (others => LWORD_NULL);
signal eth_link_out : ldata(0 downto 0) := (others => LWORD_NULL);
signal readout_reset : std_logic := '0';
signal header_array : tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0')));
signal link_combiner_debug : lword := LWORD_NULL;
signal link_combiner_rd_en : std_logic_vector(0 downto 0) := "0";
signal link_combiner_debug_super_id : std_logic_vector(31 downto 0);
signal masked_stubs : ldata(cNumberOfFEModules - 1 downto 0) := (others => LWORD_NULL);
signal link_combiner_input : ldata(8 - 1 downto 0) := (others => LWORD_NULL);
signal packet_start : std_logic := '0';
constant N_CTRL_HIST : integer := 2;
constant N_STAT_HIST : integer := 2;
begin
constant bin_width : integer := 32;
constant input_width : integer := 9;
signal status_registers : ipb_reg_v(N_STAT_HIST - 1 downto 0) := (others => (others => '0'));
signal control_registers : ipb_reg_v(N_CTRL_HIST - 1 downto 0) := (others => (others => '0'));
signal mprocessor_status_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0'));
signal mprocessor_control_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0'));
signal trigger_window_lower : std_logic_vector(31 downto 0) := (others => '0');
signal trigger_window_upper : std_logic_vector(3 downto 0) := (others => '0');
signal trigger_window : std_logic_vector(36 - 1 downto 0) := X"0ffffffff";
signal max_value0, max_value1 : std_logic_vector(bin_width - 1 downto 0) := (others => '0');
signal histogram_reset : std_logic := '0';
signal hist0_stub, hist1_stub : lword := LWORD_NULL;
signal histogram_sel : integer := 0;
signal histogram_enable : std_logic := '0';
signal header_start_array : tHeaderStartArray := (others => (others => '0'));
signal aggregated_stubs : ldata(7 downto 0) := (others => LWORD_NULL);
signal eth_link_out : ldata(0 downto 0) := (others => LWORD_NULL);
signal readout_reset : std_logic := '0';
signal header_array : tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0')));
signal link_combiner_debug_super_id : std_logic_vector(31 downto 0);
signal packet_start : std_logic := '0';
-- MProcessor
constant cNumberOfMProcessors : integer := 1;
signal mprocessor_ipb_chain : ipbdc_bus_array(cNumberOfMProcessors downto 0);
begin
--==============================--
-- IPBus fabric
--==============================--
......@@ -125,7 +125,7 @@ port map(
--==============================--
channel_ctrl: entity work.ipbus_reg_v
fe_channel_ctrl: entity work.ipbus_reg_v
--==============================--
generic map(
N_REG => 1
......@@ -139,6 +139,21 @@ port map(
qmask => (0 => X"0000007f")
);
--==============================--
mproc_channel_ctrl: entity work.ipbus_reg_v
--==============================--
generic map(
N_REG => 1
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipb_to_slaves(N_SLV_MPROC_CTRL),
ipbus_out => ipb_from_slaves(N_SLV_MPROC_CTRL),
q => mproc_channel_sel,
qmask => (0 => X"0000007f")
);
--==============================--
channel_select: entity work.ipbus_dc_fabric_sel
......@@ -208,19 +223,14 @@ begin
ipb_out => ipb_from_channel,
--- Debug Ports ---
debug_header_start => header_start_array(i),
debug_header_match => q(i+20).data(5 downto 4),
debug_aligner_state => q(i+20).data(13 downto 8)
debug_header_match => q(i+30).data(5 downto 4),
debug_aligner_state => q(i+30).data(13 downto 8)
);
q(i+20).valid <= '1';
q(i+20).strobe <= '1';
q(i+20).data(1 downto 0) <= header_start_array(i);
q(i+20).data(63 downto 14) <= stubs(i).data(49 downto 0);
end generate;
linkor.data(63 downto 0) <= linksout(0).data(63 downto 0) or linksout(1).data(63 downto 0) or linksout(2).data(63 downto 0) or linksout(3).data(63 downto 0);
linkor.data(63 downto 0) <= linksout(0).data(63 downto 0) or linksout(1).data(63 downto 0) or linksout(2).data(63 downto 0) or linksout(3).data(63 downto 0); --or linksout(4).data(63 downto 0) or linksout(5).data(63 downto 0);
--==============================--
hack: for i in 0 to cNumberOfFEModules - 1 generate
--==============================--
......@@ -263,20 +273,6 @@ histogram_sel <= to_integer(unsigned(control_registers(1)(15 downto 5)))
trigger_window <= trigger_window_upper & trigger_window_lower;
--==============================--
pRouteStubsToOutput: process(clk_p)
--==============================--
begin
if rising_edge(clk_p) then
for i in 0 to cNumberOfFEModules - 1 loop
q(cDTCOutputLinkMap(i)).valid <= stubs(i).valid;
q(cDTCOutputLinkMap(i)).data <= stubs(i).data;
q(cDTCOutputLinkMap(i)).strobe <= '1';
end loop;
end if;
end process;
--==============================--
pHistogram: process(clk_p)
--==============================--
......@@ -362,135 +358,71 @@ port map(
--==============================--
--==============================--
pInputLinkMask: process(clk_p)
--==============================--
begin
if rising_edge(clk_p) then
for i in 0 to cNumberOfFEModules - 1 loop
if link_aggregator_control_registers(2)(i) = '1' then
masked_stubs(i) <= stubs(i);
else
masked_stubs(i) <= LWORD_NULL;
end if;
end loop;
end if;
end process;
--==============================--
pLinkCombinerInputLinkMask: process(clk_p)
--==============================--
begin
if rising_edge(clk_p) then
for i in 0 to 8 - 1 loop
if link_aggregator_control_registers(2)(cNumberOfFEModules + i) = '1' then
link_combiner_input(i) <= aggregated_stubs(i);
else
link_combiner_input(i) <= LWORD_NULL;
end if;
end loop;
end if;
end process;
--==============================--
LinkAggregatorInstance: entity work.LinkAggregator(compressed)
--==============================--
generic map (
N_LINKS => cNumberOfFEModules
)
port map (
--- Input Ports ---
clk_p => clk_p,
reset => link_aggregator_control_registers(0)(0),
packet_start => packet_start,
links_in => masked_stubs,
--- Output Ports ---
links_out => aggregated_stubs,
readout_reset => readout_reset,
--- Debug Ports ---
status_bits => link_aggregator_status_registers(3)(15 downto 0)
);
q(31 downto 24) <= aggregated_stubs;
packet_start <= header_start_array(to_integer(unsigned(link_aggregator_control_registers(2)(cNumberOfFEModules + 8 + 1 downto cNumberOfFEModules + 8))))(0);
--==============================--
LinkAggregatorControlInstance: entity work.ipbus_ctrlreg_v
mprocessor_channel_select: entity work.ipbus_dc_fabric_sel
--==============================--
generic map(
N_CTRL => 4,
N_STAT => 4
SEL_WIDTH => 7
)
port map(
clk => clk,
reset => rst,
ipbus_in => ipb_to_slaves(N_SLV_LINK_AGGR),
ipbus_out => ipb_from_slaves(N_SLV_LINK_AGGR),
d => link_aggregator_status_registers,
q => link_aggregator_control_registers
);
--==============================--
LinkCombinerInstance : entity work.LinkCombiner
--==============================--
generic map (
N_INPUT_LINKS => 8,
N_OUTPUT_LINKS => 1
)
port map (
--- Input Ports ---
clk_p => clk_p,
reset => readout_reset,
output_reset => link_aggregator_control_registers(1)(0),
output_rd_en => link_combiner_rd_en,
links_in => link_combiner_input,
packet_start => packet_start,
header_in => header_array,
header_user_bits => link_aggregator_control_registers(3),
--- Output Ports ---
links_out => eth_link_out,
--- Debug Ports ---
debug => link_combiner_debug,
debug_super_id => link_combiner_debug_super_id,
debug_fifo => link_aggregator_status_registers(2)
clk => clk,
rst => rst,
sel => mproc_channel_sel(0)(6 downto 0),
ipb_in => ipb_to_slaves(N_SLV_MPROCESSOR),
ipb_out => ipb_from_slaves(N_SLV_MPROCESSOR),
ipbdc_out => mprocessor_ipb_chain(0),
ipbdc_in => mprocessor_ipb_chain(cNumberOfMProcessors)
);
q(32).valid <= eth_link_out(0).valid;
q(32).strobe <= '1';
q(32).start <= '0';
q(32).data <= eth_link_out(0).data;
q(33) <= link_combiner_debug;
link_aggregator_status_registers(0) <= link_combiner_debug_super_id;
link_aggregator_status_registers(1)(0) <= lff;
genMProcessors : for i in 0 to cNumberOfMProcessors - 1 generate
signal ipb_to_channel : ipb_wbus;
signal ipb_from_channel : ipb_rbus;
constant cNumberofInputLinks : integer := 4;
pLinkCombinerReadEnable: process(clk_p)
begin
if rising_edge(clk_p) then
for i in 0 downto 0 loop
link_combiner_rd_en(i) <= not lff and link_aggregator_control_registers(1)(1);
end loop;
end if;
end process pLinkCombinerReadEnable;
ldata_out <= eth_link_out(0);
-- --==============================--
-- TrackReconstructorInstance: entity work.TrackReconstructor
-- --==============================--
-- port map(
-- clk_p => clk_p,
-- reset => readout_reset,
-- stubs_in => aggregated_stubs(0)
-- );
--==============================--
channel_node: entity work.ipbus_dc_node
--==============================--
generic map(
I_SLV => i,
SEL_WIDTH => 7,
PIPELINE => false
)
port map(
clk => clk,
rst => rst,
ipb_out => ipb_to_channel,
ipb_in => ipb_from_channel,
ipbdc_in => mprocessor_ipb_chain(i),
ipbdc_out => mprocessor_ipb_chain(i + 1)
);
--==============================--
MProcessorInstance: entity work.MProcessor
--==============================--
generic map(
N_LINKS => cNumberofInputLinks
)
port map(
--- Input Ports ---
clk_p => clk_p,
links_in => stubs(cNumberofInputLinks*i + (cNumberofInputLinks - 1) downto cNumberofInputLinks*i),
header_in => header_array,
header_start_array => header_start_array,
gbe_backpressure => gbe_backpressure(i),
--- Output Ports ---
link_out => gbe_q(i),
--- IPBus Ports ---
ipb_clk => clk,
ipb_rst => rst,
ipb_in => ipb_to_channel,
ipb_out => ipb_from_channel
);
end generate genMProcessors;
bc0 <= '0';
gpio <= (others => '0');
gpio_en <= (others => '0');
end rtl;
......@@ -35,8 +35,8 @@ package emp_project_decl is
-- 0 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 225 -- Right Column
-- 1 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 226
2 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 227
3 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 228
-- 4 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 229
3 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 228
4 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 229
5 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 230
6 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 231
7 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 232
......@@ -59,12 +59,14 @@ package emp_project_decl is
-- for data framer (ic_simple, no_ec, n_ec_spare, ec_broadcast)
constant REGION_DATA_FRAMER_CONF : region_data_framer_conf_array_t := (
2 => ( 0=>(false, true, 0, false), 1=>(false, true, 0, false), 2=>(false, true, 0, false), 3=>(false, true, 0, false)),
3 => ( 0=>(false, true, 0, false), 1=>(false, true, 0, false), 2=>(false, true, 0, false), 3=>(false, true, 0, false)),
others => kDummyRegionDataFramer
);
-- for lpgbt
constant REGION_LPGBT_CONF : region_lpgbt_conf_array_t := (
2 => (FEC5, DATARATE_5G12, PCS),
3 => (FEC5, DATARATE_5G12, PCS),
others => kDummyRegionLpgbt
);
......
--
-- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
--
-- Dave Newbold, February 2011
library IEEE;
......@@ -14,17 +17,18 @@ package ipbus_decode_emp_payload is
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_emp_payload(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL (Mon Oct 11 10:15:52 2021)
-- START automatically generated VHDL (Thu Sep 1 14:33:48 2022)
constant N_SLV_FE_CTRL: integer := 0;
constant N_SLV_CSR: integer := 1;
constant N_SLV_FE_CHAN: integer := 2;
constant N_SLV_LINK_AGGR: integer := 3;
constant N_SLV_MEM1: integer := 4;
constant N_SLV_MEM2: integer := 5;
constant N_SLAVES: integer := 6;
constant N_SLV_MPROC_CTRL: integer := 3;
constant N_SLV_MPROCESSOR: integer := 4;
constant N_SLV_MEM1: integer := 5;
constant N_SLV_MEM2: integer := 6;
constant N_SLAVES: integer := 7;
-- END automatically generated VHDL
end ipbus_decode_emp_payload;
package body ipbus_decode_emp_payload is
......@@ -33,19 +37,21 @@ package body ipbus_decode_emp_payload is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL (Mon Oct 11 10:15:52 2021)
if std_match(addr, "------------------00----00---0--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FE_CTRL, IPBUS_SEL_WIDTH)); -- fe_ctrl / base 0x00000000 / mask 0x000030c4
elsif std_match(addr, "------------------00----00---1--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000004 / mask 0x000030c4
elsif std_match(addr, "------------------00----01------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FE_CHAN, IPBUS_SEL_WIDTH)); -- fe_chan / base 0x00000040 / mask 0x000030c0
elsif std_match(addr, "------------------00----10------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_LINK_AGGR, IPBUS_SEL_WIDTH)); -- link_aggr / base 0x00000080 / mask 0x000030c0
elsif std_match(addr, "------------------01------------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_MEM1, IPBUS_SEL_WIDTH)); -- mem1 / base 0x00001000 / mask 0x00003000
elsif std_match(addr, "------------------10------------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_MEM2, IPBUS_SEL_WIDTH)); -- mem2 / base 0x00002000 / mask 0x00003000
-- START automatically generated VHDL (Thu Sep 1 14:33:48 2022)
if std_match(addr, "------------------00--0000000000") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FE_CTRL, IPBUS_SEL_WIDTH)); -- fe_ctrl / base 0x00000000 / mask 0x000033ff
elsif std_match(addr, "------------------00--00000001--") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000004 / mask 0x000033fc
elsif std_match(addr, "------------------00--0001------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_FE_CHAN, IPBUS_SEL_WIDTH)); -- fe_chan / base 0x00000040 / mask 0x000033c0
elsif std_match(addr, "------------------00--0111111111") then
sel := ipbus_sel_t(to_unsigned(N_SLV_MPROC_CTRL, IPBUS_SEL_WIDTH)); -- mproc_ctrl / base 0x000001ff / mask 0x000033ff
elsif std_match(addr, "------------------00--100-------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_MPROCESSOR, IPBUS_SEL_WIDTH)); -- mprocessor / base 0x00000200 / mask 0x00003380
elsif std_match(addr, "------------------01--0---------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_MEM1, IPBUS_SEL_WIDTH)); -- mem1 / base 0x00001000 / mask 0x00003200
elsif std_match(addr, "------------------10--0---------") then
sel := ipbus_sel_t(to_unsigned(N_SLV_MEM2, IPBUS_SEL_WIDTH)); -- mem2 / base 0x00002000 / mask 0x00003200
-- END automatically generated VHDL
else
......
-- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_link_aggregator is
constant IPBUS_SEL_WIDTH: positive := 2;
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_link_aggregator(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL (Fri Aug 26 18:31:19 2022)
constant N_SLV_CHAN_SEL: integer := 0;
constant N_SLV_CONTROL: integer := 1;
constant N_SLV_MONITORING: integer := 2;
constant N_SLAVES: integer := 3;
-- END automatically generated VHDL
end ipbus_decode_link_aggregator;
package body ipbus_decode_link_aggregator is
function ipbus_sel_link_aggregator(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL (Fri Aug 26 18:31:19 2022)
if std_match(addr, "----------------------------0--0") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CHAN_SEL, IPBUS_SEL_WIDTH)); -- chan_sel / base 0x00000000 / mask 0x00000009
elsif std_match(addr, "----------------------------0--1") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CONTROL, IPBUS_SEL_WIDTH)); -- control / base 0x00000001 / mask 0x00000009
elsif std_match(addr, "----------------------------1---") then
sel := ipbus_sel_t(to_unsigned(N_SLV_MONITORING, IPBUS_SEL_WIDTH)); -- monitoring / base 0x00000008 / mask 0x00000008
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_link_aggregator;
end ipbus_decode_link_aggregator;
-- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
package ipbus_decode_mprocessor is
constant IPBUS_SEL_WIDTH: positive := 2;
subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0);
function ipbus_sel_mprocessor(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t;
-- START automatically generated VHDL (Fri Aug 26 18:31:27 2022)
constant N_SLV_LINK_AGGREGATOR: integer := 0;
constant N_SLV_LINK_COMBINER: integer := 1;
constant N_SLV_CSR: integer := 2;
constant N_SLAVES: integer := 3;
-- END automatically generated VHDL
end ipbus_decode_mprocessor;
package body ipbus_decode_mprocessor is
function ipbus_sel_mprocessor(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is
variable sel: ipbus_sel_t;
begin
-- START automatically generated VHDL (Fri Aug 26 18:31:27 2022)
if std_match(addr, "--------------------------0-----") then
sel := ipbus_sel_t(to_unsigned(N_SLV_LINK_AGGREGATOR, IPBUS_SEL_WIDTH)); -- link_aggregator / base 0x00000000 / mask 0x00000020
elsif std_match(addr, "--------------------------1---0-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_LINK_COMBINER, IPBUS_SEL_WIDTH)); -- link_combiner / base 0x00000020 / mask 0x00000022
elsif std_match(addr, "--------------------------1---1-") then
sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000022 / mask 0x00000022
-- END automatically generated VHDL
else
sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH));
end if;
return sel;
end function ipbus_sel_mprocessor;
end ipbus_decode_mprocessor;
......@@ -10,5 +10,5 @@ package dtc_link_maps is
constant cDTCInputLinkMap : tDTCInputLinkMap := (8, 9, 10, 11);
type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer;
constant cDTCOutputLinkMap : tDTCOutputLinkMap := (12, 13, 14, 15);
constant cDTCOutputLinkMap : tDTCOutputLinkMap := (16, 17, 18, 19);
end package dtc_link_maps;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment