- Module Name: serdes_sfp_0_extclock
- Core Name: PCS
- LPC file : serdes_sfp_0_extclock.lpc
- Parameter File : serdes_sfp_0_extclock.pp
- Command line: /opt/lattice/ispLEVER7.2/isptools/ispfpga/bin/lin/orcapp -Fmaco serdes_sfp_0_extclock.pp
- Return Value:
-
-
- Module PCS has been generated in /home/hadaq/jan/cvs/trbnet/media_interfaces/ecp2m_sfp/. successfully!
+SCUBA, Version ispLever_v72_SP2_Build (23)
+Fri Jul 10 17:06:38 2009
+
+Copyright (c) 1991-1994 by NeoCAD Inc. All rights reserved.
+Copyright (c) 1995 AT&T Corp. All rights reserved.
+Copyright (c) 1995-2001 Lucent Technologies Inc. All rights reserved.
+Copyright (c) 2001 Agere Systems All rights reserved.
+Copyright (c) 2002-2008 Lattice Semiconductor Corporation, All rights reserved.
+
+BEGIN SCUBA Module Synthesis
+
+ Issued command : /opt/lattice/ispLEVER7.2/isptools/ispfpga/bin/lin/scuba -w -n test -lang vhdl -synth synplify -bus_exp 7 -bb -arch ep5m00 -type fifodc -addr_width 9 -data_width 36 -num_words 512 -rdata_width 18 -no_enable -pe -1 -pf -1 -e
+ Circuit name : test
+ Module type : ebfifo
+ Module Version : 5.2
+ Ports :
+ Inputs : Data[35:0], WrClock, RdClock, WrEn, RdEn, Reset, RPReset
+ Outputs : Q[17:0], Empty, Full
+ I/O buffer : not inserted
+ EDIF output : suppressed
+ VHDL output : test.vhd
+ VHDL template : test_tmpl.vhd
+ VHDL testbench : tb_test_tmpl.vhd
+ VHDL purpose : for synthesis and simulation
+ Bus notation : big endian
+ Report output : test.srp
+ Estimated Resource Usage:
+ LUT : 104
+ EBR : 1
+ Reg : 107
+
+END SCUBA Module Synthesis
+SCUBA, Version ispLever_v72_SP2_Build (23)
+Fri Jul 10 17:07:18 2009
+
+Copyright (c) 1991-1994 by NeoCAD Inc. All rights reserved.
+Copyright (c) 1995 AT&T Corp. All rights reserved.
+Copyright (c) 1995-2001 Lucent Technologies Inc. All rights reserved.
+Copyright (c) 2001 Agere Systems All rights reserved.
+Copyright (c) 2002-2008 Lattice Semiconductor Corporation, All rights reserved.
+
+BEGIN SCUBA Module Synthesis
+
+ Issued command : /opt/lattice/ispLEVER7.2/isptools/ispfpga/bin/lin/scuba -w -n test -lang vhdl -synth synplify -bus_exp 7 -bb -arch ep5m00 -type fifodc -addr_width 11 -data_width 8 -num_words 2048 -rdata_width 16 -no_enable -pe -1 -pf -1 -e
+ Circuit name : test
+ Module type : ebfifo
+ Module Version : 5.2
+ Ports :
+ Inputs : Data[7:0], WrClock, RdClock, WrEn, RdEn, Reset, RPReset
+ Outputs : Q[15:0], Empty, Full
+ I/O buffer : not inserted
+ EDIF output : suppressed
+ VHDL output : test.vhd
+ VHDL template : test_tmpl.vhd
+ VHDL testbench : tb_test_tmpl.vhd
+ VHDL purpose : for synthesis and simulation
+ Bus notation : big endian
+ Report output : test.srp
+ Estimated Resource Usage:
+ LUT : 114
+ EBR : 1
+ Reg : 117
+
+END SCUBA Module Synthesis
-/home/hadaq/.isplever_lin/ispcpld/bin/hdl2jhd -tfi -mod serdes_sfp_0_extclock -ext readme -out serdes_sfp_0_extclock -tpl serdes_sfp_0_extclock.tft serdes_sfp_0_extclock.vhd
-
-Done successfully!
-- Placer Directives
attribute HGROUP : string;
-- for whole architecture
- attribute HGROUP of med_ecp_sfp : architecture is "MEDIA_INTERFACE_group";
+ attribute HGROUP of med_ecp_sfp : architecture is "media_interface_group";
+ attribute syn_sharing : string;
+ attribute syn_sharing of med_ecp_sfp : architecture is "off";
component serdes_sfp_0
port(
signal led_counter : std_logic_vector(17 downto 0);
signal rx_led : std_logic;
signal tx_led : std_logic;
+ attribute syn_keep : boolean;
+ attribute syn_keep of led_counter : signal is true;
signal reset_i : std_logic;
signal pwr_up : std_logic;
signal comb_rx_data : std_logic_vector(4*16 downto 0); -- original signals from SFP
signal comb_rx_k : std_logic_vector(7 downto 0); -- original signals from SFP
signal ff_rxhalfclk : std_logic_vector(3 downto 0);
+ signal ff_rxhalfclk_falling: std_logic_vector(3 downto 0);
signal ff_txhalfclk : std_logic;
--rx fifo signals
signal fifo_rx_rd_en : std_logic_vector(3 downto 0);
signal last_fifo_tx_empty : std_logic_vector(3 downto 0);
--link status
signal rx_k_q : std_logic_vector(4*2-1 downto 0);
- signal tx_k_q : std_logic_vector(4*2-1 downto 0);
signal ffs_plol : std_logic;
signal quad_rst : std_logic_vector(3 downto 0);
signal tx_allow : std_logic_vector(3 downto 0);
signal rx_allow : std_logic_vector(3 downto 0);
signal rx_allow_qrx : std_logic_vector(3 downto 0);
- signal tx_allow_qtx : std_logic_vector(3 downto 0);
+-- signal tx_allow_qtx : std_logic_vector(3 downto 0);
signal rx_allow_q : std_logic_vector(3 downto 0); -- clock domain changed signal
signal tx_allow_q : std_logic_vector(3 downto 0);
signal swap_bytes : std_logic_vector(3 downto 0);
+ signal swap_bytes_qrx : std_logic_vector(3 downto 0);
signal FSM_STAT_DEBUG : std_logic_vector(4*32-1 downto 0);
signal FSM_STAT_OP : std_logic_vector(4*16-1 downto 0);
signal FSM_CTRL_OP : std_logic_vector(4*16-1 downto 0);
--------------------------------------------------------------------------
--- Main control state machine, startup control for SFP
+-- Clock Domain Transfers, Input Synchronizer
--------------------------------------------------------------------------
+ gen_data_lines : for i in 0 to 3 generate
-- Input synchronizer
-
- gen_data_lines : for i in 0 to 3 generate
THE_SFP_STATUS_SYNC: signal_sync
generic map(
DEPTH => 3,
D_OUT(1) => sfp_los(i)
);
- -- Transfering the komma delimiter in the *training* phase
+-- Transfering the komma delimiter in the *training* phase
THE_RX_K_SYNC: signal_sync
generic map(
DEPTH => 3,
D_OUT => rx_k_q(i*2+1 downto i*2)
);
- THE_TX_K_SYNC: signal_sync
- generic map(
- DEPTH => 3,
- WIDTH => 2
- )
- port map(
- RESET => reset_i(i),
- D_IN => tx_k(i*2+1 downto i*2),
- CLK0 => ff_txhalfclk,
- CLK1 => SYSCLK,
- D_OUT => tx_k_q(i*2+1 downto i*2)
- );
-
- -- delay line for RX_K and RX_DATA (directly from SFP to fabric logic)
+-- registers for RX_K and RX_DATA between serdes and internal logic
THE_RX_DATA_DELAY: signal_sync
generic map(
DEPTH => 2,
- WIDTH => 16
+ WIDTH => 18
)
port map(
RESET => reset_i(i),
- D_IN => comb_rx_data(i*16+15 downto i*16),
+ D_IN(15 downto 0) => comb_rx_data(i*16+15 downto i*16),
+ D_IN(17 downto 16)=> comb_rx_k(i*2+1 downto i*2),
CLK0 => ff_rxhalfclk(i),
CLK1 => ff_rxhalfclk(i),
- D_OUT => rx_data(i*16+15 downto i*16)
+ D_OUT(15 downto 0) => rx_data(i*16+15 downto i*16),
+ D_OUT(17 downto 16) => rx_k(i*2+1 downto i*2)
);
- THE_RX_K_DELAY: signal_sync
- generic map(
- DEPTH => 2,
- WIDTH => 2
- )
- port map(
- RESET => reset_i(i),
- D_IN => comb_rx_k(i*2+1 downto i*2),
- CLK0 => ff_rxhalfclk(i),
- CLK1 => ff_rxhalfclk(i),
- D_OUT => rx_k(i*2+1 downto i*2)
- );
-
- THE_RX_ALLOW_SYNC: signal_sync -- really needed?!?
+--delay signals for sending and receiving data
+ THE_RX_ALLOW_SYNC: signal_sync
generic map(
DEPTH => 2,
WIDTH => 2
D_OUT(1) => tx_allow_q(i)
);
- THE_RX_ALLOW_SYNC_RX: signal_sync -- really needed?!?
+--transfer rx enable signal to rx clock domain
+ THE_RX_ALLOW_SYNC_RX: signal_sync
generic map(
DEPTH => 2,
- WIDTH => 1
+ WIDTH => 2
)
port map(
RESET => reset_i(i),
D_IN(0) => rx_allow(i),
+ D_IN(1) => swap_bytes(i),
CLK0 => ff_rxhalfclk(i),
CLK1 => ff_rxhalfclk(i),
- D_OUT(0) => rx_allow_qrx(i)
+ D_OUT(0) => rx_allow_qrx(i),
+ D_OUT(1) => swap_bytes_qrx(i)
);
- THE_TX_ALLOW_SYNC_TX: signal_sync -- really needed?!?
- generic map(
- DEPTH => 2,
- WIDTH => 1
- )
- port map(
- RESET => reset_i(i),
- D_IN(0) => tx_allow(i),
- CLK0 => ff_txhalfclk,
- CLK1 => ff_txhalfclk,
- D_OUT(0) => tx_allow_qtx(i)
- );
- ----------------------------------------------------------------------------------------------------------
- -- NEW STATEMACHINE START
- ----------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------
+-- Link State Machine: Resets for Serdes, enable signals for internal logic
+----------------------------------------------------------------------------------------------------------
THE_SFP_LSM: trb_net16_lsm_sfp
port map(
SYSCLK => SYSCLK,
sd_txdis_out <= quad_rst(0);
- ----------------------------------------------------------------------------------------------------------
- -- NEW STATEMACHINE STOP
- ----------------------------------------------------------------------------------------------------------
end generate;
-
+---------------------------------------------------------------------
-- Instantiation of serdes module
+-- two different connection schemes to adapt to pcb layouts
+---------------------------------------------------------------------
+
gen_normal_serdes : if REVERSE_ORDER = c_NO generate
THE_SERDES: serdes_sfp_full_quad
port map(
fifo_rx_reset(i) <= reset_i(i) or not rx_allow_q(i);
fifo_rx_rd_en(i) <= '1';
- -- Received bytes need to be swapped if the SerDes is "off by one" in its internal 8bit path
+---------------------------------------------------------------------
+-- Received bytes need to be swapped if the SerDes is "off by one" in its internal 8bit path
+---------------------------------------------------------------------
+
THE_BYTE_SWAP_PROC: process( ff_rxhalfclk )
begin
if( rising_edge(ff_rxhalfclk(i)) ) then
last_rx(9*i+8 downto 9*i) <= rx_k(i*2+1) & rx_data(i*16+15 downto i*16+8);
- if( swap_bytes(i) = '0' ) then
+ if( swap_bytes_qrx(i) = '0' ) then
fifo_rx_din(i*18+17 downto i*18) <= rx_k(i*2+1) & rx_k(i*2) & rx_data(i*16+15 downto i*16+8)
& rx_data(i*16+7 downto i*16);
fifo_rx_wr_en(i) <= not rx_k(i*2) and rx_allow_qrx(i) and link_ok(i);
end if;
end process;
+
+---------------------------------------------------------------------
+--Output to Internal Logic)
+---------------------------------------------------------------------
+
buf_med_data_out(i*16+15 downto i*16) <= fifo_rx_dout(i*18+15 downto i*18);
buf_med_dataready_out(i) <= not fifo_rx_dout(i*18+17) and not fifo_rx_dout(i*18+16)
and not last_fifo_rx_empty(i) and rx_allow_q(i);
end if;
end process;
- --rx packet counter
- ---------------------
+
+---------------------------------------------------------------------
+--rx packet counter
+---------------------------------------------------------------------
THE_RX_PACKETS_PROC: process( SYSCLK )
begin
if( rising_edge(SYSCLK) ) then
end if;
end process;
+---------------------------------------------------------------------
--TX Fifo & Data output to Serdes
----------------------
+---------------------------------------------------------------------
+
THE_FIFO_FPGA_TO_SFP: trb_net_fifo_16bit_bram_dualport
generic map(
USE_STATUS_FLAGS => c_NO
fifo_tx_reset(i) <= reset_i(i) or not tx_allow_q(i);
fifo_tx_din(i*18+17 downto i*18) <= med_packet_num_in(i*3+2) & med_packet_num_in(i*3+0)& med_data_in(i*16+15 downto i*16);
fifo_tx_wr_en(i) <= med_dataready_in(i) and tx_allow(i);
- fifo_tx_rd_en(i) <= tx_allow_qtx(i);
+ fifo_tx_rd_en(i) <= '1';
begin
if( rising_edge(ff_txhalfclk) ) then
last_fifo_tx_empty(i) <= fifo_tx_empty(i);
- if( (last_fifo_tx_empty(i) = '1') or (tx_allow_qtx(i) = '0') ) then
+ if( (last_fifo_tx_empty(i) = '1') ) then -- or (tx_allow_qtx(i) = '0')
tx_data(i*16+15 downto i*16) <= x"c5bc";
tx_k(i*2+1 downto i*2) <= "01";
else
-
+---------------------------------------------------------------------
--LED Signals
----------------------
+---------------------------------------------------------------------
+
THE_TX_RX_LED_PROC: process( SYSCLK )
begin
if( rising_edge(SYSCLK) ) then
-
if ( buf_med_dataready_out(i) = '1' ) then
rx_led(i) <= '1';
elsif( led_counter = 0 ) then
rx_led(i) <= '0';
end if;
- if( tx_k_q(i*2) = '0') then
+ if( fifo_tx_wr_en(i) = '0') then
tx_led(i) <= '1';
elsif led_counter = 0 then
tx_led(i) <= '0';
end if;
end process;
+---------------------------------------------------------------------
+--Status Information
+---------------------------------------------------------------------
+
+
STAT_OP(i*16+9 downto i*16+0) <= FSM_STAT_OP(i*16+9 downto i*16+0);
STAT_OP(i*16+10) <= rx_led(i);
STAT_OP(i*16+11) <= tx_led(i);
signal global_time : std_logic_vector(31 downto 0);
signal local_time : std_logic_vector(7 downto 0);
signal timer_us_tick : std_logic;
-
+ signal stat_ipu_fsm : std_logic_vector(15 downto 0);
begin
STAT_DEBUG => HUBLOGIC_IPU_STAT_DEBUG(31 downto 0),
STAT_POINTS_locked => buf_STAT_POINTS_locked((i+1)*32-1 downto i*32),
STAT_ERRORBITS => open, --HUB_STAT_ERRORBITS(i+1)*32-1 downto i*32),
+ STAT_FSM => stat_ipu_fsm,
CTRL_activepoints => HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32)
);
buf_HUB_STAT_CHANNEL((i+1)*16-1 downto i*16) <= (others => '0');
--Status Registers
buf_HC_STAT_REGS(4*32-1 downto 0) <= buf_STAT_POINTS_locked;
buf_HC_STAT_REGS(5*32-1 downto 4*32) <= HUB_MED_CONNECTED;
- buf_HC_STAT_REGS(8*32-1 downto 5*32) <= (others => '0'); --unused regs
+ buf_HC_STAT_REGS(5*32+15 downto 5*32) <= stat_ipu_fsm;
+ buf_HC_STAT_REGS(8*32-1 downto 5*32+16) <= (others => '0'); --unused regs
PROC_LED : process(CLK)
begin
STAT_DEBUG : out std_logic_vector (31 downto 0);
STAT_POINTS_locked : out std_logic_vector (31 downto 0);
STAT_ERRORBITS : out std_logic_vector (31 downto 0);
+ STAT_FSM : out std_logic_vector (15 downto 0);
CTRL_activepoints : in std_logic_vector (31 downto 0) := (others => '1')
);
end component;
STAT_DEBUG : out std_logic_vector (31 downto 0);
STAT_POINTS_locked : out std_logic_vector (31 downto 0);
STAT_ERRORBITS : out std_logic_vector (31 downto 0);
+ STAT_FSM : out std_logic_vector (15 downto 0);
CTRL_activepoints : in std_logic_vector (31 downto 0) := (others => '1')
);
end entity;
signal last_reply_adder_ready: std_logic;
signal last_comb_reply_pool_dataready : std_logic;
+ signal evt_code_mismatch : std_logic;
+ signal evt_number_mismatch : std_logic;
+ signal enable_packing : std_logic;
begin
- INIT_POOL_SBUF: trb_net16_sbuf
- generic map (
- Version => std_SBUF_VERSION
- )
- port map (
- CLK => CLK,
- RESET => RESET,
- CLK_EN => CLK_EN,
- COMB_DATAREADY_IN => INIT_muxed_DATAREADY,
- COMB_next_READ_OUT => comb_INIT_next_read,
- COMB_READ_IN => INIT_muxed_READ,
- COMB_DATA_IN => INIT_muxed_DATA,
- COMB_PACKET_NUM_IN => INIT_muxed_PACKET_NUM,
- SYN_DATAREADY_OUT => INIT_POOL_DATAREADY,
- SYN_DATA_OUT => INIT_POOL_DATA,
- SYN_PACKET_NUM_OUT => INIT_POOL_PACKET_NUM,
- SYN_READ_IN => INIT_POOL_READ
- );
-
- process(CLK)
- begin
- if rising_edge(CLK) then
- if RESET = '1' then
- INIT_muxed_READ <= '0';
- else
- INIT_muxed_READ <= comb_INIT_next_read;
- end if;
- end if;
- end process;
-
+----------------------------------
+--Arbiter choosing init point
+----------------------------------
---choosing reply point
INIT_ARBITER: trb_net_priority_arbiter
generic map (WIDTH => POINT_NUMBER)
port map (
init_arbiter_CLK_EN <= not locked;
init_arbiter_ENABLE <= not init_locked;
+----------------------------------
--Datapool for Init-Channel
+----------------------------------
INIT_muxed_DATAREADY <= or_all(INIT_DATAREADY_IN and buf_INIT_READ_OUT) and not init_locked and INIT_muxed_READ;
INIT_POOL_READ <= and_all(INIT_READ_IN or init_has_read_from_pool or locking_point or not real_activepoints);
INIT_READ_OUT <= buf_INIT_READ_OUT;
end generate;
+----------------------------------
+--Data Pool on Init Channel
+----------------------------------
+ INIT_POOL_SBUF: trb_net16_sbuf
+ generic map (
+ Version => std_SBUF_VERSION
+ )
+ port map (
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ COMB_DATAREADY_IN => INIT_muxed_DATAREADY,
+ COMB_next_READ_OUT => comb_INIT_next_read,
+ COMB_READ_IN => INIT_muxed_READ,
+ COMB_DATA_IN => INIT_muxed_DATA,
+ COMB_PACKET_NUM_IN => INIT_muxed_PACKET_NUM,
+ SYN_DATAREADY_OUT => INIT_POOL_DATAREADY,
+ SYN_DATA_OUT => INIT_POOL_DATA,
+ SYN_PACKET_NUM_OUT => INIT_POOL_PACKET_NUM,
+ SYN_READ_IN => INIT_POOL_READ
+ );
+
+ process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if RESET = '1' then
+ INIT_muxed_READ <= '0';
+ else
+ INIT_muxed_READ <= comb_INIT_next_read;
+ end if;
+ end if;
+ end process;
+
+
--init_has_read signal
gen_hasread: for i in 0 to POINT_NUMBER-1 generate
process(CLK)
end process;
end generate;
---signals to obufs
+----------------------------------
+--Data Output to init Obufs
+----------------------------------
gen_init_data_out: for i in 0 to POINT_NUMBER-1 generate
INIT_DATAREADY_OUT(i) <= INIT_POOL_DATAREADY and not init_has_read_from_pool(i) and real_activepoints(i) and not locking_point(i);
INIT_DATA_OUT((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH) <= INIT_POOL_DATA;
end generate;
---locked signals
---locked: transfer is running
---init_locked: waiting for reply channel to finish
+----------------------------------
+--Hub Locks - locked while a transfer is running, init_locked after trm on init has been received
+----------------------------------
get_locked <= INIT_muxed_DATAREADY;
next_locked <= (get_locked or locked) and not release_locked;
end if;
end process;
---saving necessary data
----------------------------------
+--Save current packet type on init channel
+----------------------------------
+
save_INIT_TYPE : process(CLK)
begin
if rising_edge(CLK) then
else saved_INIT_TYPE;
+----------------------------------
+--save event information
+----------------------------------
save_INIT_PACKET : process(CLK)
begin
end generate;
REPLY_READ_OUT <= buf_REPLY_READ_OUT;
- send_reply_trm <= and_all(got_trm);
+
+
+
+----------------------------------
--save current packet type & set markers for special words
----------------------------------------------------------
reg_current_reply_reading_TRM(i) <= current_reply_reading_TRM(i);
reg_current_reply_reading_HDR(i) <= current_reply_reading_HDR(i);
reg_current_reply_reading_DHDR(i) <= current_reply_reading_DHDR(i);
- if (current_reply_reading_DHDR(i) = '1' and REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1 downto i*c_NUM_WIDTH) = "00")
- or current_reply_reading_HDR(i) = '1' then
- reg_current_reply_auto_reading_DHDR(i) <= '1';
- else
- reg_current_reply_auto_reading_DHDR(i) <= '0';
- end if;
+ end if;
+ end process;
+
+ PROC_auto_read_DHDR : process(current_reply_reading_DHDR, current_reply_reading_HDR, REPLY_PACKET_NUM_IN)
+ begin
+ if (current_reply_reading_DHDR(i) = '1' and REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) = '0')
+ or current_reply_reading_HDR(i) = '1' then
+ reg_current_reply_auto_reading_DHDR(i) <= '1';
+ else
+ reg_current_reply_auto_reading_DHDR(i) <= '0';
end if;
end process;
end generate;
- process(current_reply_packet_type, reply_arbiter_result)
- begin
- current_muxed_reading_DAT <= '0';
- gen_current_reading_dat : for i in 0 to POINT_NUMBER-1 loop
- if reply_arbiter_result(i) = '1' then
- if current_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_DAT then
- current_muxed_reading_DAT <= '1';
- end if;
- end if;
- end loop;
- end process;
+-- process(current_reply_packet_type, reply_arbiter_result)
+-- begin
+-- current_muxed_reading_DAT <= '0';
+-- gen_current_reading_dat : for i in 0 to POINT_NUMBER-1 loop
+-- if reply_arbiter_result(i) = '1' then
+-- if current_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_DAT then
+-- current_muxed_reading_DAT <= '1';
+-- end if;
+-- end if;
+-- end loop;
+-- end process;
+
+----------------------------------
--saving (D)HDR
-------------------------
gen_saving_dhdr : for i in 0 to POINT_NUMBER-1 generate
+----------------------------------
--reading and merging TRM
----------------------------------
gen_combining_trm : for j in 0 to c_DATA_WIDTH-1 generate
end process;
end generate;
+----------------------------------
--read overhead data
---------------------
+----------------------------------
process(RESET, send_reply_trm, REPLY_PACKET_NUM_IN, REPLY_DATAREADY_IN, REPLY_DATA_IN, start_read_padding,
saved_reading_padding)
+----------------------------------
--real_activepoints can be set between transfers only, but can be cleared at any time
----------------------------------
gen_real_activepoints : process (CLK)
end process;
+----------------------------------
--count received TRM
----------------------------------
gen_got_trm : process(CLK)
end if;
end process;
+ send_reply_trm <= and_all(got_trm);
+
+
gen_got_dhdr : process(CLK)
begin
if rising_edge(CLK) then
end process;
+----------------------------------
--REPLY Counters
----------------------------------
- --counter for 16bit words
+--counter for 16bit words
gen_packet_counter : process(CLK)
begin
if rising_edge(CLK) then
end if;
end process;
- --counts 32bit words
+--counts 32bit data words
gen_data_counter : process(CLK)
begin
if rising_edge(CLK) then
end if;
end process;
+----------------------------------
--REPLY select input
----------------------------------
REPLY_ARBITER: trb_net_priority_arbiter
---REPLY mux
+----------------------------------
+--Muxing Reply data
----------------------------------
gen_reply_mux1 : for i in 0 to c_DATA_WIDTH-1 generate
data_mux : process(REPLY_DATA_IN, REPLY_MUX_reading)
end process;
end generate;
+
+--Muxed data is ready, when the selected port has data, and this is neither padding, H0 nor termination.
+--
comb_REPLY_muxed_DATAREADY <= or_all(reply_arbiter_result and REPLY_DATAREADY_IN and not reg_current_reply_reading_trm
and not reply_reading_H0 and not saved_reading_padding)
and REPLY_POOL_next_read;
- --reg_current_reply_reading_trm can be used instead of current_reply_reading_trm since
- -- reply_reading_H0 is checked!
---temporary! no real compare is done!
-reply_compare_finished <= reply_compare_start;
+----------------------------------
+--Compare Event Information
+----------------------------------
+
+
+ PROC_COMPARE : process(CLK)
+ variable tmp_code, tmp_number, tmp_pack : std_logic;
+ begin
+ if rising_edge(CLK) then
+ reply_compare_finished <= '0';
+ tmp_code := '0';
+ tmp_pack := '1';
+ tmp_number := '0';
+ if reply_compare_start = '1' then
+ if last_dhdr_addr = "100" then --upper part
+ for i in 0 to POINT_NUMBER-1 loop
+ if last_dhdr_data(i*16+12) = '0' and reply_adder_val_enable(i) = '1' then
+ tmp_pack := '0';
+ end if;
+ if last_dhdr_data(i*16+7 downto i*16) /= evt_random_code and reply_adder_val_enable(i) = '1' then
+ tmp_code := '1';
+ end if;
+ end loop;
+ enable_packing <= tmp_pack;
+ evt_code_mismatch <= tmp_code;
+ reply_compare_finished <= '1';
+ elsif last_dhdr_addr = "101" then
+ for i in 0 to POINT_NUMBER-1 loop
+ if last_dhdr_data(i*16+15 downto i*16) /= evt_number and reply_adder_val_enable(i) = '1' then
+ tmp_number := '1';
+ end if;
+ end loop;
+ evt_number_mismatch <= tmp_number;
+ reply_compare_finished <= '1';
+ end if;
+ elsif locked = '0' then
+ evt_code_mismatch <= '0';
+ enable_packing <= '0';
+ evt_number_mismatch <= '0';
+ end if;
+ end if;
+ end process;
+
+----------------------------------
--REPLY POOL state machine
----------------------------------
reply_state_machine : process(REPLY_POOL_next_READ, current_state, packet_counter,
reply_combined_trm_F3, reply_compare_finished, reg_current_reply_reading_hdr,
reply_adder_final_result, reg_current_reply_reading_dhdr,
evt_seqnr, evt_dtype, evt_random_code, evt_number, number_of_replies,
- reply_data_counter, current_point_length,
+ reply_data_counter, current_point_length, enable_packing,
reply_arbiter_result, reply_reading_f2,current_reply_reading_trm)
begin
release_locked <= '0';
case current_state is
when IDLE => --wait for init transfer
next_waiting_for_DHDR_word <= not (locking_point or not real_activepoints);
- reply_arbiter_enable <= '0';
next_current_waiting_for_reply <= not (locking_point or not real_activepoints);
if locked = '1' then
next_state <= WAIT_FOR_REPLY; --WAIT_FOR_HDR_DATA;
last_dhdr_addr <= "010";
comb_REPLY_POOL_DATAREADY <= '0';
next_reply_adder_final_result <= std_logic_vector(unsigned(reply_adder_result) - number_of_replies + 2);
- if last_reply_adder_ready = '1' then --packet_counter = c_F2
+ if last_reply_adder_ready = '1' then
comb_REPLY_POOL_DATA <= reply_adder_final_result;
comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read;
end if;
when c_F0 =>
last_dhdr_addr <= "100";
next_reply_compare_start <= '1';
+ comb_REPLY_POOL_DATA <= "0001" & evt_dtype & evt_random_code;
if reply_compare_finished = '1' then
comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read;
- comb_REPLY_POOL_DATA <= "0001" & evt_dtype & evt_random_code;
+ next_reply_compare_start <= '0';
last_dhdr_addr <= "101";
end if;
when c_F1 =>
next_reply_compare_start <= '1';
comb_REPLY_POOL_DATA <= evt_number;
if reply_compare_finished = '1' then
+ next_reply_compare_start <= '0';
comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read;
last_dhdr_addr <= "110";
end if;
if REPLY_POOL_next_read = '1' then
next_state <= SENDING_DATA;
reply_arbiter_CLK_EN <= '1';
+ reply_arbiter_CLK_EN <= '1';
reply_arbiter_enable <= '1';
last_dhdr_addr <= "110";
reply_data_counter_reset <= '1';
--either padding or trm follows. So: start reading in any case.
start_read_padding <= reply_arbiter_result;
elsif or_all(current_reply_reading_TRM and reply_arbiter_result) = '1' then
--- elsif or_all(reply_arbiter_result and REPLY_DATAREADY_IN)='1' then
reply_data_counter_reset <= '1';
reply_arbiter_CLK_EN <= '1';
end if;
end process;
+----------------------------------
--REPLY sbuf
---------------
+----------------------------------
REPLY_POOL_SBUF: trb_net16_sbuf
generic map (
SYN_READ_IN => REPLY_POOL_READ
);
+----------------------------------
--REPLY output
---------------
+----------------------------------
gen_reply_data_out: for i in 0 to POINT_NUMBER-1 generate
REPLY_DATAREADY_OUT(i) <= REPLY_POOL_DATAREADY and locking_point(i);
-----------------------
+----------------------------------
--Debugging
-----------------------
+----------------------------------
STAT_DEBUG(0) <= got_trm(0);
STAT_DEBUG(1) <= got_trm(1);
STAT_POINTS_locked(31 downto POINT_NUMBER) <= (others => '0');
STAT_ERRORBITS <= REPLY_combined_trm_F1 & REPLY_combined_trm_F2;
-
+ STAT_FSM(7 downto 0) <= reply_fsm_state;
+ STAT_FSM(8) <= reply_adder_start;
+ STAT_FSM(9) <= reply_compare_start;
+ STAT_FSM(12 downto 10)<= packet_counter;
+ STAT_FSM(15 downto 13)<= last_dhdr_addr;
end architecture;
signal second_word_waiting : std_logic;
signal last_second_word_waiting : std_logic;
signal make_compare : std_logic;
- signal mismatch_number : std_logic;
- signal mismatch_random : std_logic;
- signal mismatch_type : std_logic;
- signal mismatch_length : std_logic;
+ signal evt_number_mismatch : std_logic;
+ signal evt_code_mismatch : std_logic;
begin
buf_API_READ_OUT <= '1';
first_ipu_read <= '0';
make_compare <= '0';
- update_buffers <= '0';
+ update_buffers <= '0';
case state is
when START =>
buf_API_SEND_OUT <= '0';
update_buffers <= '1'; -- store length and error pattern on separate ports
state <= MAKE_DHDR;
dhdr_counter <= (others => '0');
+ make_compare <= '1';
buf_API_DATA_OUT <= IPU_DATA_IN(31 downto 16);
end if;
when MAKE_DHDR => -- send DHDR packet
buf_API_SEND_OUT <= '1';
buf_API_DATAREADY_OUT <= '1';
- make_compare <= '1';
if buf_API_DATAREADY_OUT = '1' and API_READ_IN = '1' then
dhdr_counter <= dhdr_counter + 1;
case dhdr_counter is
buf_API_DATA_OUT <= reg_IPU_DATA;
end if;
-
-
if saved_IPU_READOUT_FINISHED_IN = '1' and waiting_word = '0' and IPU_DATAREADY_IN = '0' and buf_API_DATAREADY_OUT = '0' then
state <= START;
end if;
if saved_IPU_READOUT_FINISHED_IN = '1' or IPU_READOUT_FINISHED_IN = '1' then
update_buffers <= '1';
end if;
+
when others =>
state <= START;
end case;
elsif update_buffers = '1' then
buf_IPU_LENGTH_IN <= IPU_LENGTH_IN;
buf_IPU_ERROR_PATTERN_IN <= IPU_ERROR_PATTERN_IN;
+ buf_IPU_ERROR_PATTERN_IN(16) <= evt_number_mismatch;
+ buf_IPU_ERROR_PATTERN_IN(17) <= evt_code_mismatch;
end if;
end if;
end process;
end if;
end process;
+
+---------------------------------------------------------------------
+--Compare event information
+---------------------------------------------------------------------
+ PROC_compare : process(CLK)
+ begin
+ if rising_edge(CLK) then
+ if buf_START_READOUT = '0' then
+ evt_number_mismatch <= '0';
+ evt_code_mismatch <= '0';
+ elsif make_compare = '1' then
+ if reg_IPU_DATA(15 downto 0) /= buf_NUMBER then
+ evt_number_mismatch <= '1';
+ end if;
+ if reg_IPU_DATA(23 downto 16) /= buf_RND_CODE then
+ evt_code_mismatch <= '1';
+ end if;
+ end if;
+ end if;
+ end process;
+
+
---------------------------------------------------------------------
--User finished readout yet?
---------------------------------------------------------------------