--3456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 ------------------------------------------------------------------------------------------ -- Filename : glink_asic.vhdl -- -- AUTHORS : Haifeng Wu, University of Chicago -- -- Ambreesh Gupta, University of Chicago -- -- Kelby Anderson, University of Chicago -- -- DESCRIPTION: -- -- Interface Card Controller VHDL code. -- -- -- -- VERSION HISTORY: -- -- 7/6/2000 : Version 0.01; -- -- 7/12/2000 : Version 0.02; -- -- 7/17/2000 : Version 1.0, for each frame, data number is set at first -- -- data frame; -- -- 7/18/2000 : Version 2.0, data number is changable on event base; -- -- HP_FLAG is delayed. -- -- 7/20/2000 : Version 3.0, use dff to set data number -- -- 7/21/2000 : Version 4.0, ctrl word is corrected by force -- -- HP_D(16) <= HP_FLAG; -- -- 7/24/2000 : Version 5.0, add slink start word:0x11111110, and -- -- stop word:0xfffffff0. -- -- 7/25/2000 : Version 6.0, enable flow control and TTC channel -- -- selection. -- -- 7/26/2000 : Version 7.0, add fifo auto reset function. -- -- 7/28/2000 : Version 8.0, enhance TTC channel selection. -- -- 7/31/2000 : Version 9.0, enhance data format -- -- 8/03/2000 : Version 9.1, enable succesive event -- -- 8/09/2000 : Version 9.9, correct dmu consequence. -- -- 26/11/2000: link_reset implemented, and channels within dmu are -- -- corrected -- -- 26/11/2000: flow_ctrl function was removed. -- -- 28/11/2000: test mode implemented. -- -- 12/12/2000: muti confirmation of start and end of event; it needs at -- -- least 3 digital board -- -- 1/23/2001 : code for 16 bit 3.3v glink chip -- -- 2/14/2001 : Initial steps to move to 3.3v glink chip - -- -- Implement 16 bit CRC checksum. -- -- -- -- 1/15/2001 : lots of clocking changes. -- -- Address clocks and memory fetchs are now clocked on different edges -- -- signal names changed to correspond to 3.3v serializer convension -- -- vote change to allow one active board to start -- -- clocking through memory input now done with digitizer (TTC) -- -- clock selected from board 3,2,or 5 -- -- logic improved for choosing which TTC clock to send to digitizers -- -- global CRC and digitizer serial stream CRC checking made to work -- -- start ctrl word = 51115110 since only 14 bits sent by serializer -- -- for control words 11111110 ends up 51115110 at the LDC anyway -- -- -- kja -- -- 8/13/2002 : modified for rotating use of memory - max of 14 samples -- -- -- kja -- -- 4/2/2003 : modified overflow blocks event from writing to memory -- -- test() lines used to set 8 or 16 buffers -- -- 6 samples + header + crc = 8 max if 16 buffers used -- -- 14 samples + header + crc = 16 max if 8 buffers used -- -- --kja -- -- e2o implemented as state machine -- kja -- -- ------------------------------------------------------------------------------------------ library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library lpm; use lpm.lpm_components.all; entity glink_asic is port( DataIN : in std_logic_vector(31 downto 0); WenIN : in std_logic_vector(7 downto 0); CtrlIN : in std_logic_vector(7 downto 0); ClkIN : in std_logic_vector(7 downto 0); TestIN : in std_logic_vector(5 downto 0); ResetIN : in std_logic_vector(5 downto 0); TTC_chkb: in std_logic; TTC_chka: in std_logic; TTC_en: out std_logic; Flow_ctrl: out std_logic; TX : out std_logic_vector(15 downto 0); TXCNTL : out std_logic; TXDATA : out std_logic; TXFLAG : out std_logic; TXFLGENB : out std_logic; TXCLK : out std_logic; LOCKED: in std_logic; TXDIV0: out std_logic; TXDIV1: out std_logic; ESMPXENB : out std_logic; TCLKENB : out std_logic; Ready : in std_logic; -------------------------------------------------------------------------------- --***************************************************************************** -- some signal for test --------------------------------------------------------------------------------- TP1: out std_logic; TP2: out std_logic; TP3: out std_logic; TP4: out std_logic; TP5: out std_logic; TP6: out std_logic; TP7: out std_logic; TP8: out std_logic; TP9: out std_logic; ----------------------------------------- end of test point---------------------- Clock : in std_logic); end glink_asic; architecture a of glink_asic is ------------------------------------------------------------------------------------------ -- Initialize components ------------------------------------------------------------------------------------------ COMPONENT s2p_sort PORT( clki, di0, di1, weni, clr, data_now : in STD_LOGIC; dready : out STD_LOGIC; do : out std_logic_vector(31 downto 0)); END COMPONENT; COMPONENT CRC16 PORT( crc_clk, crc_step, crc_start : in std_logic; crc_data : in std_logic_vector(31 downto 0); crc_error : out std_logic_vector(31 downto 0)); END COMPONENT; COMPONENT vote PORT( poll : in std_logic_vector(5 downto 0); result : out STD_LOGIC); END COMPONENT; COMPONENT e2o PORT( reset : in std_logic; en : in std_logic; data1 : in std_logic_vector(31 downto 0); data2 : in std_logic_vector(31 downto 0); data3 : in std_logic_vector(31 downto 0); data4 : in std_logic_vector(31 downto 0); data5 : in std_logic_vector(31 downto 0); data6 : in std_logic_vector(31 downto 0); data7 : in std_logic_vector(31 downto 0); data8 : in std_logic_vector(31 downto 0); data_out : out std_logic_vector(31 downto 0); data_en : out std_logic; clk_op : in std_logic); END COMPONENT; COMPONENT crctx PORT( CLK : in std_logic; TX_D_IN : in std_logic_vector (15 downto 0); TX_D : out std_logic_vector (15 downto 0); TX_DATA_IN : in std_logic; TX_DATA : out std_logic; TX_CNTL_IN : in std_logic; TX_CNTL : out std_logic; TX_FLAG_IN : in std_logic; TX_FLAG : out std_logic ); END COMPONENT; type op_state is (idle, startHI, startLO, txingHI, txingLO, cmd_tx, crc_tx, txeflg1, txeflg2, stopHI, stopLO); type ttc_state is (wait1_ttc, count_ttc, chk_ttc, select_ttc, wait2_ttc, wait3_ttc); type dclk_state is (wait1_dclk, chk_dclk, wait2_dclk); signal current_state: op_state; signal next_state : op_state; signal now_ttc : ttc_state; signal next_ttc : ttc_state; signal now_dclk : dclk_state; signal next_dclk : dclk_state; signal reset_all: std_logic; signal data_read_clr: std_logic; signal data_read_num: std_logic_vector(10 downto 0); signal mem1_raddr: std_logic_vector(9 downto 0); signal mem2_raddr: std_logic_vector(9 downto 0); signal mem1_waddr: std_logic_vector(9 downto 0); signal mem2_waddr: std_logic_vector(9 downto 0); signal wblock: std_logic_vector(3 downto 0); signal rblock: std_logic_vector(3 downto 0); signal fullmk: std_logic_vector(15 downto 0); signal fl0: std_logic_vector(0 downto 0); signal fl1: std_logic_vector(0 downto 0); signal fl2: std_logic_vector(0 downto 0); signal fl3: std_logic_vector(0 downto 0); signal fl4: std_logic_vector(0 downto 0); signal fl5: std_logic_vector(0 downto 0); signal fl6: std_logic_vector(0 downto 0); signal fl7: std_logic_vector(0 downto 0); signal fl8: std_logic_vector(0 downto 0); signal fl9: std_logic_vector(0 downto 0); signal fl10: std_logic_vector(0 downto 0); signal fl11: std_logic_vector(0 downto 0); signal fl12: std_logic_vector(0 downto 0); signal fl13: std_logic_vector(0 downto 0); signal fl14: std_logic_vector(0 downto 0); signal fl15: std_logic_vector(0 downto 0); signal lgate: std_logic; signal clrf0: std_logic; signal setf0: std_logic; signal clrf1: std_logic; signal setf1: std_logic; signal clrf2: std_logic; signal setf2: std_logic; signal clrf3: std_logic; signal setf3: std_logic; signal clrf4: std_logic; signal setf4: std_logic; signal clrf5: std_logic; signal setf5: std_logic; signal clrf6: std_logic; signal setf6: std_logic; signal clrf7: std_logic; signal setf7: std_logic; signal clrf8: std_logic; signal setf8: std_logic; signal clrf9: std_logic; signal setf9: std_logic; signal clrf10: std_logic; signal setf10: std_logic; signal clrf11: std_logic; signal setf11: std_logic; signal clrf12: std_logic; signal setf12: std_logic; signal clrf13: std_logic; signal setf13: std_logic; signal clrf14: std_logic; signal setf14: std_logic; signal clrf15: std_logic; signal setf15: std_logic; signal rhold: std_logic; signal wren: std_logic_vector(7 downto 0); signal fifo_data: std_logic_vector(31 downto 0); signal da: std_logic; signal da2: std_logic; signal da3: std_logic; signal da5: std_logic; signal clr2: std_logic; signal clr3: std_logic; signal clr5: std_logic; signal latch2: std_logic; signal latch3: std_logic; signal latch5: std_logic; signal data_num2: std_logic_vector(11 downto 0); signal data_num3: std_logic_vector(11 downto 0); signal data_num5: std_logic_vector(11 downto 0); signal clk_out: std_logic; signal clkb_out: std_logic; signal clk2_out: std_logic; signal clk2b_out: std_logic; signal clk4_out: std_logic; signal clk4b_out: std_logic; signal clk_pipe: std_logic; signal clk2: std_logic; signal clk2b: std_logic; signal ctrl_n: std_logic; signal ctrl_n1: std_logic; signal ctrl_n2: std_logic; signal ctrl_n3: std_logic; signal ctrl_n4: std_logic; signal ctrl_n5: std_logic; signal data_now: std_logic; signal data_set: std_logic_vector(3 downto 0); signal data_set_clr: std_logic; signal data4read: std_logic_vector(10 downto 0); signal reg_in1: std_logic_vector( 31 downto 0); signal reg_in2: std_logic_vector( 31 downto 0); signal reg_in3: std_logic_vector( 31 downto 0); signal reg_in4: std_logic_vector( 31 downto 0); signal reg_in5: std_logic_vector( 31 downto 0); signal reg_in6: std_logic_vector( 31 downto 0); signal reg_in7: std_logic_vector( 31 downto 0); signal reg_in8: std_logic_vector( 31 downto 0); signal reg_in9: std_logic_vector( 31 downto 0); signal reg_in10: std_logic_vector( 31 downto 0); signal reg_in11: std_logic_vector( 31 downto 0); signal reg_in12: std_logic_vector( 31 downto 0); signal reg_in13: std_logic_vector( 31 downto 0); signal reg_in14: std_logic_vector( 31 downto 0); signal reg_in15: std_logic_vector( 31 downto 0); signal reg_in16: std_logic_vector( 31 downto 0); signal data_en: std_logic_vector( 15 downto 0); signal fifo_in_data1: std_logic_vector(31 downto 0); signal fifo_in_data2: std_logic_vector(31 downto 0); signal fifo_out_data1: std_logic_vector(31 downto 0); signal fifo_out_data2: std_logic_vector(31 downto 0); signal aux_out_data1: std_logic_vector(31 downto 0); signal aux_out_data2: std_logic_vector(31 downto 0); signal reg_out: std_logic_vector(31 downto 0); signal fifo_wren1: std_logic; signal fifo_wren2: std_logic; signal fifo_rden1: std_logic; signal fifo_rden2: std_logic; signal fifo_wren1a: std_logic; signal fifo_wren2a: std_logic; signal fifo_wren1b: std_logic; signal fifo_wren1c: std_logic; signal fifo_wren1d: std_logic; signal fifo_rden1a: std_logic; signal fifo_rden2a: std_logic; signal packr_num: std_logic_vector(2 downto 0); signal pack_ready: std_logic; signal pack_ready8: std_logic; signal pack_ready16: std_logic; signal tx_en: std_logic; signal read_ready: std_logic; signal reading: std_logic; signal reading1: std_logic; signal reading2: std_logic; signal reading3: std_logic; signal reading1b: std_logic; signal reading2b: std_logic; -- signal temp_count2: std_logic_vector(3 downto 0); -- signal temp_count3: std_logic_vector(3 downto 0); -- signal temp_clr1: std_logic; -- signal temp_clr2: std_logic; -- signal temp_clr3: std_logic; signal packr_clr: std_logic; signal temp_ena3: std_logic; signal data_txed: std_logic; signal buff_out: std_logic_vector(15 downto 0); signal buff_sav: std_logic_vector(15 downto 0); signal buff_crc: std_logic_vector(31 downto 0); signal packr_num0: std_logic; signal packr_num0b: std_logic; signal packr_num1: std_logic; signal packr_num1b: std_logic; signal link_reset: std_logic; signal clkb_pipe: std_logic; signal ttc_enable: std_logic; signal ttc_clr: std_logic; constant startwHI : std_logic_vector := "0101000100010001"; -- 5111 constant startwLO : std_logic_vector := "0101000100010000"; -- 5110 -- using 51115110 for start word 11111110 does not work as serializer -- only sends 16 bits in control mode and 11111110 becomes 51115110 at LDC -- so I send 51115110 in the first place to avoid confusion - kja constant stopwHI : std_logic_vector := "1111111111111111"; -- word to send constant stopwLO : std_logic_vector := "1111111111110000"; -- these words. -- constant m1 : std_logic_vector := "11111111111111111111111111111111"; constant crc_cnst: std_logic_vector := "0000000000000000"; constant cmd_word: std_logic_vector := "0000000000000011"; constant ttc_limit: std_logic_vector := "011000"; constant ttc_limitl: std_logic_vector := "010111"; constant ttc_limith: std_logic_vector := "011001"; signal crc_word: std_logic_vector(31 downto 0); signal crc_rst: std_logic; signal crc_cal: std_logic; signal cha_count: std_logic_vector(5 downto 0); signal chb_count: std_logic_vector(5 downto 0); signal clk3_count: std_logic_vector(5 downto 0); signal clk2_count: std_logic_vector(5 downto 0); signal clk5_count: std_logic_vector(5 downto 0); signal b3s2 : std_logic; signal b3s5 : std_logic; signal b2s3 : std_logic; signal b2s5 : std_logic; signal b5s2 : std_logic; signal b5s3 : std_logic; signal clk3_ok : std_logic; signal clk2_ok : std_logic; signal clk5_ok : std_logic; signal period: std_logic_vector(5 downto 0); signal period2: std_logic_vector(5 downto 0); signal cha_ok: std_logic; signal cha_okl: std_logic; signal cha_okh: std_logic; signal chb_ok: std_logic; signal chb_okl: std_logic; signal chb_okh: std_logic; signal ah_ok: std_logic; signal al_ok: std_logic; signal bh_ok: std_logic; signal bl_ok: std_logic; signal ttc_done : std_logic; signal csel_enable : std_logic; signal fifo_clr: std_logic; signal fw1: std_logic; signal fw2: std_logic; signal fw3: std_logic; signal read_done1: std_logic; signal read_done2: std_logic; signal wide1: std_logic_vector(7 downto 0); signal wide2: std_logic_vector(7 downto 0); signal up_count1: std_logic_vector(2 downto 0); signal bot_count1: std_logic_vector(4 downto 0); signal up_count2: std_logic_vector(2 downto 0); signal bot_count2: std_logic_vector(4 downto 0); signal up1: std_logic; signal up2: std_logic; signal bot_clr1: std_logic; signal bot_clr2: std_logic; signal up_clr1: std_logic; signal up_clr2: std_logic; signal ttc_clkb: std_logic_vector(7 downto 0); signal dig_start: std_logic_vector(5 downto 0); signal dig_stop: std_logic_vector(5 downto 0); signal dig_now: std_logic_vector(5 downto 0); signal event_coming: std_logic; signal event_now: std_logic; signal dig_dnum2: std_logic_vector(7 downto 0); signal dig_dnum3: std_logic_vector(7 downto 0); signal dig_dnum5: std_logic_vector(7 downto 0); signal data_enx: std_logic; signal HP_DATA_IN, HP_CNTL_IN, HP_FLAG_IN : std_logic; signal Data : std_logic_vector(31 downto 0); signal Ctrl : std_logic_vector(7 downto 0); signal Clk : std_logic_vector(7 downto 0); signal Reset: std_logic_vector(5 downto 0); signal Test : std_logic_vector(5 downto 0); signal cstart : std_logic; signal cstep : std_logic; signal cerror : std_logic_vector(31 downto 0); signal stopit : std_logic; signal idle_now : std_logic; signal e2o_reset : std_logic; signal inc_wbk : std_logic; signal inc_ovf : std_logic; signal inc_ena : std_logic; signal set_full : std_logic; signal overflow : std_logic; signal overflow16 : std_logic; signal overflow8 : std_logic; signal wn1 : std_logic; signal wn2 : std_logic; signal erflg : std_logic; signal mode8 : std_logic; signal mode16 : std_logic; signal ov0 : std_logic; signal ov1 : std_logic; signal ov2 : std_logic; signal ov3 : std_logic; signal ov4 : std_logic; signal ov5 : std_logic; signal ov6 : std_logic; signal ov7 : std_logic; signal ov8 : std_logic; signal ov9 : std_logic; signal ov10 : std_logic; signal ov11 : std_logic; signal ov12 : std_logic; signal ov13 : std_logic; signal ov14 : std_logic; signal ov15 : std_logic; signal cclk : std_logic_vector(1 downto 0); signal cclko : std_logic_vector(1 downto 0); signal ReadyB : std_logic; signal init_ena : std_logic; signal init_wait : std_logic_vector(15 downto 0); signal aux_wn1 : std_logic; signal aux_wn2 : std_logic; signal aux_rmem1 : std_logic; signal aux_rmem2 : std_logic; signal aux1_waddr : std_logic_vector(6 downto 0); signal aux2_waddr : std_logic_vector(6 downto 0); signal aux1_raddr : std_logic_vector(6 downto 0); signal aux2_raddr : std_logic_vector(6 downto 0); signal aux_wmem : std_logic; signal fifo_r1 : std_logic; signal fifo_r2 : std_logic; signal arm1 : std_logic; signal arm2 : std_logic; begin --- --- FOR the prototype version of INTERFACE card, first input of the LVDS drivers -- are inverted. Below is a temporary correction for that. --- -- DATA Data(0) <= DataIN(0); Data(1) <= DataIN(1); Data(2) <= DataIN(2); Data(3) <= DataIN(3); Data(4) <= DataIN(4); Data(5) <= DataIN(5); Data(6) <= DataIN(6); Data(7) <= DataIN(7); Data(8) <= DataIN(8); Data(9) <= DataIN(9); Data(10) <= DataIN(10); Data(11) <= DataIN(11); Data(12) <= DataIN(12); Data(13) <= DataIN(13); Data(14) <= DataIN(14); Data(15) <= DataIN(15); Data(16) <= DataIN(16); Data(17) <= DataIN(17); Data(18) <= DataIN(18); Data(19) <= DataIN(19); Data(20) <= DataIN(20); Data(21) <= DataIN(21); Data(22) <= DataIN(22); Data(23) <= DataIN(23); Data(24) <= DataIN(24); Data(25) <= DataIN(25); Data(26) <= DataIN(26); Data(27) <= DataIN(27); Data(28) <= DataIN(28); Data(29) <= DataIN(29); Data(30) <= DataIN(30); Data(31) <= DataIN(31); -- write enable wren(0) <= not WenIN(0); wren(1) <= not WenIN(1); wren(2) <= not WenIN(2); wren(3) <= not WenIN(3); wren(4) <= not WenIN(4); wren(5) <= not WenIN(5); wren(6) <= not WenIN(6); wren(7) <= not WenIN(7); -- CTRL Ctrl(0) <= not CtrlIN(0); Ctrl(1) <= not CtrlIN(1); Ctrl(2) <= not CtrlIN(2); Ctrl(3) <= not CtrlIN(3); Ctrl(4) <= not CtrlIN(4); Ctrl(5) <= not CtrlIN(5); Ctrl(6) <= not CtrlIN(6); Ctrl(7) <= not CtrlIN(7); --CLOCK Clk(0) <= not ClkIN(0); Clk(1) <= not ClkIN(1); Clk(2) <= not ClkIN(2); Clk(3) <= not ClkIN(3); Clk(4) <= not ClkIN(4); Clk(5) <= not ClkIN(5); Clk(6) <= not ClkIN(6); Clk(7) <= not ClkIN(7); -- RESET Reset(0) <= ResetIN(0); Reset(1) <= ResetIN(1); Reset(2) <= ResetIN(2); Reset(3) <= ResetIN(3); Reset(4) <= ResetIN(4); Reset(5) <= ResetIN(5); -- TEST Test(0) <= TestIN(0); Test(1) <= TestIN(1); Test(2) <= TestIN(2); Test(3) <= TestIN(3); Test(4) <= TestIN(4); Test(5) <= TestIN(5); -- Test(i) set low on command to digitizers digitixers -- 2 of 6 inputs are low mode8=0 otherwise Mode8=1 mode_select: vote port map (poll => Test(5 downto 0), result => mode8); mode16 <= not mode8; -- if mode16 = 1 use 16 buffers ----------------------------------------------------------------------------------------- -- Mark the start of digitizers - use 3 digitizers that can supply global clock -- Before every data frame the digitizer send a control signal with data bits set high ----------------------------------------------------------------------------------------- dig_start(0) <= wren(2) and Ctrl(2) and Data(8) and Data(9); dig_start(1) <= wren(2) and Ctrl(2) and Data(10) and Data(11); dig_start(2) <= wren(3) and Ctrl(3) and Data(12) and Data(13); dig_start(3) <= wren(3) and Ctrl(3) and Data(14) and Data(15); dig_start(4) <= wren(5) and Ctrl(5) and Data(20) and Data(21); dig_start(5) <= wren(5) and Ctrl(5) and Data(22) and Data(23); ----------------------------------------------------------------------------------------- -- Mark the stop of digitizers - use 3 digitizers that can supply global clock -- At the end of data frame, the digitizer sends a control signal with data bits set low ----------------------------------------------------------------------------------------- process (Clk(2)) begin if(Clk(2)'event and Clk(2) = '1') then dig_stop(0) <= wren(2) and Ctrl(2) and (not Data(8)) and (not Data(9)); end if; end process; process (Clk(2)) begin if(Clk(2)'event and Clk(2) = '1') then dig_stop(1) <= wren(2) and Ctrl(2) and (not Data(10)) and (not Data(11)); end if; end process; process (Clk(3)) begin if(Clk(3)'event and Clk(3) = '1') then dig_stop(2) <= wren(3) and Ctrl(3) and (not Data(12)) and (not Data(13)); end if; end process; process (Clk(3)) begin if(Clk(3)'event and Clk(3) = '1') then dig_stop(3) <= wren(3) and Ctrl(3) and (not Data(14)) and (not Data(15)); end if; end process; process (Clk(5)) begin if(Clk(5)'event and Clk(5) = '1') then dig_stop(4) <= wren(5) and Ctrl(5) and (not Data(20)) and (not Data(21)); end if; end process; process (Clk(5)) begin if(Clk(5)'event and Clk(5) = '1') then dig_stop(5) <= wren(5) and Ctrl(5) and (not Data(22)) and (not Data(23)); end if; end process; ----------------------------------------------------------------------------------------- -- Mark the event of digitizers ----------------------------------------------------------------------------------------- process (dig_stop, dig_start) begin if (dig_stop(0) = '1' or reset_all = '1') then dig_now(0) <= '1'; elsif dig_start(0) = '1' then dig_now(0) <= '0'; -- effictive low; end if; if (dig_stop(1) = '1' or reset_all = '1') then dig_now(1) <= '1'; elsif dig_start(1) = '1' then dig_now(1) <= '0'; -- effictive low; end if; if (dig_stop(2) = '1' or reset_all = '1') then dig_now(2) <= '1'; elsif dig_start(2) = '1' then dig_now(2) <= '0'; -- effictive low; end if; if (dig_stop(3) = '1' or reset_all = '1') then dig_now(3) <= '1'; elsif dig_start(3) = '1' then dig_now(3) <= '0'; -- effictive low; end if; if (dig_stop(4) = '1' or reset_all = '1') then dig_now(4) <= '1'; elsif dig_start(4) = '1' then dig_now(4) <= '0'; -- effictive low; end if; if (dig_stop(5) = '1' or reset_all = '1') then dig_now(5) <= '1'; elsif dig_start(5) = '1' then dig_now(5) <= '0'; -- effictive low; end if; end process; -- 2 of 6 inputs are low event_coming=0 otherwise event_coming=1 slink_evnt: vote port map (poll => dig_now(5 downto 0), result => event_coming); event_now <= not event_coming; -- effective high. ----------------------------------------------------------------------------------------- -- time_controller provide global control signal -- ctrl_n is used as global ctrl signals -- ctrl_n1, ctrl_n2, ctrl_n3, ctrl_n4 and ctrl_n5 are delays of original ctrl_n signal ----------------------------------------------------------------------------------------- ctrl_n <= event_now; process ( clk_pipe, ctrl_n ) begin if ( clk_pipe'event and clk_pipe = '1') then ctrl_n1 <= ctrl_n; ctrl_n2 <= ctrl_n1; ctrl_n3 <= ctrl_n2; ctrl_n4 <= ctrl_n3; ctrl_n5 <= ctrl_n4; end if; end process; ---------------------------------------------------------------------------------------- -- generate reset singal for the chip; -- reset_all is the global reset signal; ---------------------------------------------------------------------------------------- slink_reset: vote port map (poll => Reset(5 downto 0), result => link_reset); reset_all <= (not Ready) or (not link_reset); -- system reset = configuration done or link reset. process(clkb_pipe) begin if(clkb_pipe'event and clkb_pipe = '1') then end if; end process; process (fifo_wren1,fifo_wren2,clk2b,clk2) begin fw1 <= fifo_wren1 or fifo_wren2; if(clk2'event and clk2 = '1') then fw2 <= fw1; fw3 <= fw2; end if; end process; fifo_clr <= (not fifo_wren1a) or reset_all; inc_wbk <= fifo_wren1c and (not fifo_wren1b); inc_ena <= not overflow; inc_ovf <= fifo_wren1d and not fifo_wren1c; set_full <= fifo_wren1a and (not fifo_wren1) and (not overflow); wblock_count: lpm_counter generic map (LPM_WIDTH =>4) port map (clock => inc_wbk, clk_en => inc_ena, -- aset => reset_all, aclr => reset_all, q => wblock); rblock_count: lpm_counter generic map (LPM_WIDTH =>4) port map (clock => read_done2, clk_en => rhold, aclr => reset_all, q => rblock); process(wblock,fullmk) begin if(wblock = "0000" and fullmk(0) = '1') then ov0 <= '1'; else ov0 <= '0'; end if; if(wblock = "0001" and fullmk(1) = '1') then ov1 <= '1'; else ov1 <= '0'; end if; if(wblock = "0010" and fullmk(2) = '1') then ov2 <= '1'; else ov2 <= '0'; end if; if(wblock = "0011" and fullmk(3) = '1') then ov3 <= '1'; else ov3 <= '0'; end if; if(wblock = "0100" and fullmk(4) = '1') then ov4 <= '1'; else ov4 <= '0'; end if; if(wblock = "0101" and fullmk(5) = '1') then ov5 <= '1'; else ov5 <= '0'; end if; if(wblock = "0110" and fullmk(6) = '1') then ov6 <= '1'; else ov6 <= '0'; end if; if(wblock = "0111" and fullmk(7) = '1') then ov7 <= '1'; else ov7 <= '0'; end if; if(wblock = "1000" and fullmk(8) = '1') then ov8 <= '1'; else ov8 <= '0'; end if; if(wblock = "1001" and fullmk(9) = '1') then ov9 <= '1'; else ov9 <= '0'; end if; if(wblock = "1010" and fullmk(10) = '1') then ov10 <= '1'; else ov10 <= '0'; end if; if(wblock = "1011" and fullmk(11) = '1') then ov11 <= '1'; else ov11 <= '0'; end if; if(wblock = "1100" and fullmk(12) = '1') then ov12 <= '1'; else ov12 <= '0'; end if; if(wblock = "1101" and fullmk(13) = '1') then ov13 <= '1'; else ov13 <= '0'; end if; if(wblock = "1110" and fullmk(14) = '1') then ov14 <= '1'; else ov14 <= '0'; end if; if(wblock = "1111" and fullmk(15) = '1') then ov15 <= '1'; else ov15 <= '0'; end if; end process; process(inc_ovf) begin if(inc_ovf'event and inc_ovf = '0') then overflow <= ov0 or ov1 or ov2 or ov3 or ov4 or ov5 or ov6 or ov7 or ov8 or ov9 or ov10 or ov11 or ov12 or ov13 or ov14 or ov15; end if; end process; -- fullmk marks blocks of data that are filled but not yet transmitted. lgate <= '0'; process(rblock,wblock,read_done1,set_full) begin if(reset_all = '1' or ((rblock = "0000") and (read_done1 = '1'))) then clrf0 <= '1'; else clrf0 <= '0'; end if; if( (wblock = "0000") and (set_full = '1') ) then setf0 <= '1'; else setf0 <= '0'; end if; if(reset_all = '1' or ((rblock = "0001") and (read_done1 = '1'))) then clrf1 <= '1'; else clrf1 <= '0'; end if; if( (wblock = "0001") and (set_full = '1') ) then setf1 <= '1'; else setf1 <= '0'; end if; if(reset_all = '1' or ((rblock = "0010") and (read_done1 = '1'))) then clrf2 <= '1'; else clrf2 <= '0'; end if; if( (wblock = "0010") and (set_full = '1') ) then setf2 <= '1'; else setf2 <= '0'; end if; if(reset_all = '1' or ((rblock = "0011") and (read_done1 = '1'))) then clrf3 <= '1'; else clrf3 <= '0'; end if; if( (wblock = "0011") and (set_full = '1') ) then setf3 <= '1'; else setf3 <= '0'; end if; if(reset_all = '1' or ((rblock = "0100") and (read_done1 = '1'))) then clrf4 <= '1'; else clrf4 <= '0'; end if; if( (wblock = "0100") and (set_full = '1') ) then setf4 <= '1'; else setf4 <= '0'; end if; if(reset_all = '1' or ((rblock = "0101") and (read_done1 = '1'))) then clrf5 <= '1'; else clrf5 <= '0'; end if; if( (wblock = "0101") and (set_full = '1') ) then setf5 <= '1'; else setf5 <= '0'; end if; if(reset_all = '1' or ((rblock = "0110") and (read_done1 = '1'))) then clrf6 <= '1'; else clrf6 <= '0'; end if; if( (wblock = "0110") and (set_full = '1') ) then setf6 <= '1'; else setf6 <= '0'; end if; if(reset_all = '1' or ((rblock = "0111") and (read_done1 = '1'))) then clrf7 <= '1'; else clrf7 <= '0'; end if; if( (wblock = "0111") and (set_full = '1') ) then setf7 <= '1'; else setf7 <= '0'; end if; end process; process(rblock,wblock,read_done1,set_full) begin if(reset_all = '1' or ((rblock = "1000") and (read_done1 = '1'))) then clrf8 <= '1'; else clrf8 <= '0'; end if; if( (wblock = "1000") and (set_full = '1') ) then setf8 <= '1'; else setf8 <= '0'; end if; if(reset_all = '1' or ((rblock = "1001") and (read_done1 = '1'))) then clrf9 <= '1'; else clrf9 <= '0'; end if; if( (wblock = "1001") and (set_full = '1') ) then setf9 <= '1'; else setf9 <= '0'; end if; if(reset_all = '1' or ((rblock = "1010") and (read_done1 = '1'))) then clrf10 <= '1'; else clrf10 <= '0'; end if; if( (wblock = "1010") and (set_full = '1') ) then setf10 <= '1'; else setf10 <= '0'; end if; if(reset_all = '1' or ((rblock = "1011") and (read_done1 = '1'))) then clrf11 <= '1'; else clrf11 <= '0'; end if; if( (wblock = "1011") and (set_full = '1') ) then setf11 <= '1'; else setf11 <= '0'; end if; if(reset_all = '1' or ((rblock = "1100") and (read_done1 = '1'))) then clrf12 <= '1'; else clrf12 <= '0'; end if; if( (wblock = "1100") and (set_full = '1') ) then setf12 <= '1'; else setf12 <= '0'; end if; if(reset_all = '1' or ((rblock = "1101") and (read_done1 = '1'))) then clrf13 <= '1'; else clrf13 <= '0'; end if; if( (wblock = "1101") and (set_full = '1') ) then setf13 <= '1'; else setf13 <= '0'; end if; if(reset_all = '1' or ((rblock = "1110") and (read_done1 = '1'))) then clrf14 <= '1'; else clrf14 <= '0'; end if; if( (wblock = "1110") and (set_full = '1') ) then setf14 <= '1'; else setf14 <= '0'; end if; if(reset_all = '1' or ((rblock = "1111") and (read_done1 = '1'))) then clrf15 <= '1'; else clrf15 <= '0'; end if; if( (wblock = "1111") and (set_full = '1') ) then setf15 <= '1'; else setf15 <= '0'; end if; end process; process(mode16) begin if(mode16 = '1') then fullmk(0) <= fl0(0); fullmk(1) <= fl1(0); fullmk(2) <= fl2(0); fullmk(3) <= fl3(0); fullmk(4) <= fl4(0); fullmk(5) <= fl5(0); fullmk(6) <= fl6(0); fullmk(7) <= fl7(0); fullmk(8) <= fl8(0); fullmk(9) <= fl9(0); fullmk(10) <= fl10(0); fullmk(11) <= fl11(0); fullmk(12) <= fl12(0); fullmk(13) <= fl13(0); fullmk(14) <= fl14(0); fullmk(15) <= fl15(0); end if; if(mode16 = '0') then fullmk(0) <= fl0(0) or fl8(0); fullmk(1) <= fl1(0) or fl9(0); fullmk(2) <= fl2(0) or fl10(0); fullmk(3) <= fl3(0) or fl11(0); fullmk(4) <= fl4(0) or fl12(0); fullmk(5) <= fl5(0) or fl13(0); fullmk(6) <= fl6(0) or fl14(0); fullmk(7) <= fl7(0) or fl15(0); end if; end process; full0: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf0, aset => setf0, q => fl0); full1: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf1, aset => setf1, q => fl1); full2: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf2, aset => setf2, q => fl2); full3: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf3, aset => setf3, q => fl3); full4: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf4, aset => setf4, q => fl4); full5: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf5, aset => setf5, q => fl5); full6: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf6, aset => setf6, q => fl6); full7: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf7, aset => setf7, q => fl7); full8: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf8, aset => setf8, q => fl8); full9: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf9, aset => setf9, q => fl9); full10: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf10, aset => setf10, q => fl10); full11: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf11, aset => setf11, q => fl11); full12: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf12, aset => setf12, q => fl12); full13: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf13, aset => setf13, q => fl13); full14: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf14, aset => setf14, q => fl14); full15: lpm_latch generic map(LPM_WIDTH=>1) port map (gate => lgate, aclr => clrf15, aset => setf15, q => fl15); ------------------------------------------------------------------------------------------ -- this block to generate data_now signal, data_now is used in s2p_sort component ------------------------------------------------------------------------------------------ data_set_clr <= reset_all or (not event_now); data_begin_counter: lpm_counter generic map (LPM_WIDTH => 4) port map ( clock => clk_pipe, clk_en => event_now, aclr => data_set_clr, q => data_set); process ( data_set, data_set_clr) begin if ( data_set = "1100" ) then data_now <= '1'; elsif (data_set_clr = '1') then data_now <= '0'; end if; end process; --------------end of data_now block ---------------------------------- ---------------------------------------------------------------------- -- this block counts the data numbers of a frame ---------------------------------------------------------------------- da2 <= wren(2) and not Ctrl(2); -- just count data bits da3 <= wren(3) and not Ctrl(3); -- not control words da5 <= wren(5) and not Ctrl(5); -- write enable high & control low clr2 <= wren(2) and Ctrl(2) and Data(8) and Data(9); clr3 <= wren(3) and Ctrl(3) and Data(12) and Data(13); clr5 <= wren(5) and Ctrl(5) and Data(20) and Data(21); latch2 <= wren(2) and Ctrl(2) and (not Data(8)) and (not Data(9)); latch3 <= wren(3) and Ctrl(3) and (not Data(12)) and (not Data(13)); latch5 <= wren(5) and Ctrl(5) and (not Data(20)) and (not Data(21)); data_num_counter2: lpm_counter generic map (LPM_WIDTH =>12) port map ( clock => Clk(2), clk_en => da2, aclr => clr2, q => data_num2); data_num_counter3: lpm_counter generic map (LPM_WIDTH =>12) port map ( clock => Clk(3), clk_en => da3, aclr => clr3, q => data_num3); data_num_counter4: lpm_counter generic map (LPM_WIDTH =>12) port map ( clock => Clk(5), clk_en => da5, aclr => clr5, q => data_num5); process (da,reset_all) begin if (reset_all = '1') then dig_dnum2( 6 downto 0) <= "0000000"; dig_dnum3( 6 downto 0) <= "0000000"; dig_dnum5( 6 downto 0) <= "0000000"; elsif ( da'event and da = '0') then dig_dnum2(7 downto 0) <= data_num2(11 downto 4); -- divide by 16 for (2 bits each) dig_dnum3(7 downto 0) <= data_num3(11 downto 4); -- number of 32 bit words dig_dnum5(7 downto 0) <= data_num5(11 downto 4); -- read in from each s2p_sort end if; end process; process (dig_dnum2,dig_dnum3,dig_dnum5) begin -- use boards 3, 2, 5, 6, 1 in that order data4read(2 downto 0) <= "000"; -- multiply by 8 (8 tileDMU chips supplying words if ( clk3_ok = '1') then data4read(10 downto 3) <= dig_dnum3(7 downto 0); -- number of 32 bit words to process data_enx <= data_en(6); da <= latch3; elsif( clk2_ok = '1') then data4read(10 downto 3) <= dig_dnum2(7 downto 0); data_enx <= data_en(4); da <= latch2; elsif(clk5_ok = '1') then data4read(10 downto 3) <= dig_dnum5(7 downto 0); data_enx <= data_en(10); da <= latch5; else data4read(10 downto 3) <= dig_dnum3(7 downto 0); data_enx <= data_en(6); da <= latch3; end if; end process; -------------- end of this block ------------------------------------------------ ----test point for debug TP1 <= overflow; TP2 <= erflg; TP3 <= aux_rmem1; TP4 <= aux_rmem2; TP5 <= fifo_rden1; TP6 <= fifo_rden2; TP7 <= reading; TP8 <= wn1; TP9 <= wn2; process (wblock,rblock,reading,fifo_wren1) begin if(wblock = rblock) then if(reading='1' and wn1='1') then erflg <= '1'; else erflg <= '0'; end if; end if; end process; --********************************************************************************* -- following 16 input convert serial data from 16 DMU to paralell --*********************************************************************************** input1: s2p_sort port map ( clki => Clk(0), di0 => Data(0), di1 => Data(1), weni => wren(0), clr => reset_all, data_now => data_now, dready => data_en(0), do => reg_in1); input2: s2p_sort port map ( clki => Clk(0), di0 => Data(2), di1 => Data(3), weni => wren(0), clr => reset_all, data_now => data_now, dready => data_en(1), do => reg_in2); input3: s2p_sort port map ( clki => Clk(1), di0 => Data(4), di1 => Data(5), weni => wren(1), clr => reset_all, data_now => data_now, dready => data_en(2), do => reg_in3); input4: s2p_sort port map ( clki => Clk(1), di0 => Data(6), di1 => Data(7), weni => wren(1), clr => reset_all, data_now => data_now, dready => data_en(3), do => reg_in4); input5: s2p_sort port map ( clki => Clk(2), di0 => Data(8), di1 => Data(9), weni => wren(2), clr => reset_all, data_now => data_now, dready => data_en(4), do => reg_in5); input6: s2p_sort port map ( clki => Clk(2), di0 => Data(10), di1 => Data(11), weni => wren(2), clr => reset_all, data_now => data_now, dready => data_en(5), do => reg_in6); input7: s2p_sort port map ( clki => Clk(3), di0 => Data(12), di1 => Data(13), weni => wren(3), clr => reset_all, data_now => data_now, dready => data_en(6), do => reg_in7); input8: s2p_sort port map ( clki => Clk(3), di0 => Data(14), di1 => Data(15), weni => wren(3), clr => reset_all, data_now => data_now, dready => data_en(7), do => reg_in8); input9: s2p_sort port map ( clki => Clk(4), di0 => Data(16), di1 => Data(17), weni => wren(4), clr => reset_all, data_now => data_now, dready => data_en(8), do => reg_in9); input10: s2p_sort port map ( clki => Clk(4), di0 => Data(18), di1 => Data(19), weni => wren(4), clr => reset_all, data_now => data_now, dready => data_en(9), do => reg_in10); input11: s2p_sort port map ( clki => Clk(5), di0 => Data(20), di1 => Data(21), weni => wren(5), clr => reset_all, data_now => data_now, dready => data_en(10), do => reg_in11); input12: s2p_sort port map ( clki => Clk(5), di0 => Data(22), di1 => Data(23), weni => wren(5), clr => reset_all, data_now => data_now, dready => data_en(11), do => reg_in12); input13: s2p_sort port map ( clki => Clk(6), di0 => Data(24), di1 => Data(25), weni => wren(6), clr => reset_all, data_now => data_now, dready => data_en(12), do => reg_in13); input14: s2p_sort port map ( clki => Clk(6), di0 => Data(26), di1 => Data(27), weni => wren(6), clr => reset_all, data_now => data_now, dready => data_en(13), do => reg_in14); input15: s2p_sort port map ( clki => Clk(7), di0 => Data(28), di1 => Data(29), weni => wren(7), clr => reset_all, data_now => data_now, dready => data_en(14), do => reg_in15); input16: s2p_sort port map ( clki => Clk(7), di0 => Data(30), di1 => Data(31), weni => wren(7), clr => reset_all, data_now => data_now, dready => data_en(15), do => reg_in16); --***************************************************************************** -- two pipes line, pipe1 and pipe2 -- each pipe accepts data from one half of the draw --***************************************************************************** e2o_reset <= reset_all; pipe1: e2o port map ( reset => e2o_reset, en => data_enx, data1 => reg_in2, data2 => reg_in1, data3 => reg_in4, data4 => reg_in3, data5 => reg_in6, data6 => reg_in5, data7 => reg_in8, data8 => reg_in7, data_out => fifo_in_data1, data_en => fifo_wren1, clk_op => clk2b); pipe2: e2o port map ( reset => e2o_reset, en => data_enx, data1 => reg_in15, data2 => reg_in16, data3 => reg_in13, data4 => reg_in14, data5 => reg_in11, data6 => reg_in12, data7 => reg_in9, data8 => reg_in10, data_out => fifo_in_data2, data_en => fifo_wren2, clk_op => clk2b); aux_wmem <= (mode16 and wide1(6)) or (mode8 and wide1(7)); wn1 <= fifo_wren1 and (not overflow) and (not aux_wmem); wn2 <= fifo_wren2 and (not overflow) and (not aux_wmem); aux_wn1 <= fifo_wren1 and (not overflow) and aux_wmem; aux_wn2 <= fifo_wren2 and (not overflow) and aux_wmem; fifo1: lpm_ram_dp generic map ( LPM_WIDTH => 32, LPM_WIDTHAD => 10, LPM_NUMWORDS => 1024 ) port map ( data => fifo_in_data1, wren => wn1, wrclock => clk2, wraddress => mem1_waddr, rdaddress => mem1_raddr, rdclock => clk2_out, rden => fifo_rden1, q => fifo_out_data1); fifo2: lpm_ram_dp generic map ( LPM_WIDTH => 32, LPM_WIDTHAD => 10, LPM_NUMWORDS => 1024 ) port map ( data => fifo_in_data2, wren => wn2, wrclock => clk2, wraddress => mem2_waddr, rdaddress => mem2_raddr, rdclock => clk2_out, rden => fifo_rden2, q => fifo_out_data2 ); aux1: lpm_ram_dp generic map ( LPM_WIDTH => 32, LPM_WIDTHAD => 7, LPM_NUMWORDS => 128 ) port map ( data => fifo_in_data1, wren => aux_wn1, wrclock => clk2, -- kja wraddress => aux1_waddr, rdaddress => aux1_raddr, rdclock => clk2_out, --kja rden => fifo_rden1, q => aux_out_data1); aux2: lpm_ram_dp generic map ( LPM_WIDTH => 32, LPM_WIDTHAD => 7, LPM_NUMWORDS => 128 ) port map ( data => fifo_in_data2, wren => aux_wn2, wrclock => clk2, -- kja wraddress => aux2_waddr, rdaddress => aux2_raddr, rdclock => clk2_out, --kja rden => fifo_rden2, q => aux_out_data2 ); --------------------------------------------------------------------------------- -- address calculation of memory --------------------------------------------------------------------------------- process(clk2_out) begin if(clk2_out'event and clk2_out = '1') then fifo_rden1a <= fifo_rden1; fifo_rden2a <= fifo_rden2; end if; end process; process(clk2) begin if(clk2'event and clk2 = '1') then fifo_wren1a <= fifo_wren1; fifo_wren2a <= fifo_wren2; fifo_wren1c <= fifo_wren1b; end if; end process; process (clk2b) begin if(clk2b'event and clk2b = '1') then fifo_wren1b <= fifo_wren1a; fifo_wren1d <= fifo_wren1c; end if; end process; -- delay address inc till first word stored width1_count: lpm_counter generic map (LPM_WIDTH =>8) port map (clock => clk2b, clk_en => fifo_wren1a, aclr => fifo_clr, q => wide1); -- word count of e2o sending to memory 1 width2_count: lpm_counter generic map (LPM_WIDTH =>8) port map (clock => clk2b, clk_en => fifo_wren2a, aclr => fifo_clr, q => wide2); -- word count of e2o sending to memory 2 process(mode16) begin if(mode16 = '1') then -- 16 buffers mem1_waddr(3 downto 0) <= wblock(3 downto 0); -- current block address mem1_waddr(6 downto 4) <= wide1(2 downto 0); -- TILEdmu address bits memory 1 mem1_waddr(9 downto 7) <= wide1(5 downto 3); -- word within a TILEdmu block memory 1 mem2_waddr(3 downto 0) <= wblock(3 downto 0); -- current block address mem2_waddr(6 downto 4) <= wide2(2 downto 0); -- TILEdmu address bits memory 2 mem2_waddr(9 downto 7) <= wide2(5 downto 3); -- word within a TILEdmu block memory 2 mem1_raddr(3 downto 0) <= rblock(3 downto 0); -- current read block address mem1_raddr(6 downto 4) <= up_count1(2 downto 0); -- TILEdmu block address - memory1 mem1_raddr(9 downto 7) <= bot_count1(2 downto 0); -- word within a TILEdmu block - memory1 mem2_raddr(3 downto 0) <= rblock(3 downto 0); -- current read block address mem2_raddr(6 downto 4) <= up_count2(2 downto 0); -- TILEdmu block address - memory2 mem2_raddr(9 downto 7) <= bot_count2(2 downto 0); -- word within a TILEdmu block - memory2 aux1_waddr(3 downto 0) <= wblock(3 downto 0); aux1_waddr(6 downto 4) <= wide1(2 downto 0); aux2_waddr(3 downto 0) <= wblock(3 downto 0); aux2_waddr(6 downto 4) <= wide2(2 downto 0); aux1_raddr(3 downto 0) <= rblock(3 downto 0); aux1_raddr(6 downto 4) <= up_count1(2 downto 0); aux2_raddr(3 downto 0) <= rblock(3 downto 0); aux2_raddr(6 downto 4) <= up_count2(2 downto 0); else -- 8 buffers mem1_waddr(2 downto 0) <= wblock(2 downto 0); -- current block address mem1_waddr(5 downto 3) <= wide1(2 downto 0); -- TILEdmu address bits memory 1 mem1_waddr(9 downto 6) <= wide1(6 downto 3); -- word within a TILEdmu block memory 1 mem2_waddr(2 downto 0) <= wblock(2 downto 0); -- current block address mem2_waddr(5 downto 3) <= wide2(2 downto 0); -- TILEdmu address bits memory 2 mem2_waddr(9 downto 6) <= wide2(6 downto 3); -- word within a TILEdmu block memory 2 mem1_raddr(2 downto 0) <= rblock(2 downto 0); -- current read block address mem1_raddr(5 downto 3) <= up_count1(2 downto 0); -- TILEdmu block address - memory1 mem1_raddr(9 downto 6) <= bot_count1(3 downto 0); -- word within a TILEdmu block - memory1 mem2_raddr(2 downto 0) <= rblock(2 downto 0); -- current read block address mem2_raddr(5 downto 3) <= up_count2(2 downto 0); -- TILEdmu block address - memory2 mem2_raddr(9 downto 6) <= bot_count2(3 downto 0); -- word within a TILEdmu block - memory2 aux1_waddr(2 downto 0) <= wblock(2 downto 0); aux1_waddr(6 downto 3) <= wide1(3 downto 0); aux2_waddr(3 downto 0) <= wblock(3 downto 0); aux2_waddr(6 downto 3) <= wide2(3 downto 0); aux1_raddr(2 downto 0) <= rblock(2 downto 0); aux1_raddr(5 downto 3) <= up_count1(2 downto 0); aux1_raddr(6) <= bot_count1(0); aux2_raddr(2 downto 0) <= rblock(2 downto 0); aux2_raddr(5 downto 3) <= up_count2(2 downto 0); aux2_raddr(6) <= bot_count2(0); end if; end process; mem1bot_count: lpm_counter generic map (LPM_WIDTH =>5) port map (clock => clk2b_out, clk_en => fifo_rden1a, aclr => bot_clr1, q => bot_count1); mem1up_count: lpm_counter generic map (LPM_WIDTH =>3) port map (clock => up1, clk_en => fifo_rden1a, aclr => up_clr1, q => up_count1); mem2bot_count: lpm_counter generic map (LPM_WIDTH =>5) port map (clock => clk2b_out, clk_en => fifo_rden2a, aclr => bot_clr2, q => bot_count2); mem2up_count: lpm_counter generic map (LPM_WIDTH =>3) port map (clock => up2, clk_en => fifo_rden2a, aclr => up_clr2, q => up_count2); bot_clr1 <= reset_all or read_done2 or up1; bot_clr2 <= reset_all or read_done2 or up2; up_clr1 <= reset_all or read_done2; up_clr2 <= reset_all or read_done2; -- define up1 and up2 here mem1_cmp: lpm_compare generic map ( LPM_WIDTH =>5) -- up1 set when port map ( dataa => bot_count1, -- frame finishes datab => data4read(7 downto 3), -- words /frame aeb => up1 ); mem2_cmp: lpm_compare generic map ( LPM_WIDTH =>5) -- up2 set when port map ( dataa => bot_count2, -- frame finishes datab => data4read(7 downto 3), aeb => up2 ); ---- end of this block ---------------------------------------------------------- ---******************************************************************* -- select ttc channel; TTC_en = 1 select channel B, 0 select channel A --******************************************************************** ReadyB <= not Ready; period_wait: lpm_counter generic map (LPM_WIDTH =>16) port map (clock => clkb_out, clk_en => init_ena, aclr => ReadyB, q => init_wait); period_count: lpm_counter generic map (LPM_WIDTH =>6) port map (clock => clkb_out, clk_en => ttc_enable, aclr => ttc_clr, q => period); ttc_count1: lpm_counter generic map (LPM_WIDTH =>6) port map (clock => TTC_chka, clk_en => ttc_enable, aclr => ttc_clr, q => cha_count); ttc_count2: lpm_counter generic map (LPM_WIDTH =>6) port map (clock => TTC_chkb, clk_en => ttc_enable, aclr => ttc_clr, q => chb_count); ttc_compal: lpm_compare generic map ( LPM_WIDTH =>6) port map ( dataa => cha_count, datab => ttc_limit, ageb => cha_okl); ttc_compah: lpm_compare generic map ( LPM_WIDTH =>6) port map ( dataa => cha_count, datab => ttc_limit, aleb => cha_okh); cha_ok <= cha_okl and cha_okh; ttc_compbl: lpm_compare generic map ( LPM_WIDTH =>6) port map ( dataa => chb_count, datab => ttc_limitl, ageb => chb_okl); ttc_compbh: lpm_compare generic map ( LPM_WIDTH =>6) port map ( dataa => chb_count, datab => ttc_limith, aleb => chb_okh); chb_ok <= chb_okl and chb_okh; -- TTC select state machine init_ena <= not init_wait(15); process (ReadyB,clk_out) begin if(init_wait(15) = '0') then now_ttc <= wait1_ttc; elsif(clk_out'event and clk_out = '1') then now_ttc <= next_ttc; end if; end process; process (now_ttc) begin case now_ttc is when wait1_ttc => ttc_enable <= '0'; ttc_done <= '0'; ttc_clr <= '1'; next_ttc <= count_ttc; when count_ttc => ttc_enable <= '1'; ttc_clr <= '0'; next_ttc <= chk_ttc; when chk_ttc => if(period(4) = '0') then next_ttc <= chk_ttc; else next_ttc <= select_ttc; end if; when select_ttc => ttc_enable <= '0'; next_ttc <= wait2_ttc; when wait2_ttc => if(cha_ok = '0' and chb_ok = '0') then next_ttc <= wait1_ttc; else if(chb_ok = '1') then ttc_en <= '1'; -- select B elsif(cha_ok = '1') then ttc_en <= '0'; -- select A end if; next_ttc <= wait3_ttc; end if; when wait3_ttc => ttc_done <= '1'; next_ttc <= wait3_ttc; end case; end process; ---******************************************************************* -- select which digitizer clock to use for the pipeline --******************************************************************** period_count2: lpm_counter generic map (LPM_WIDTH =>6) port map (clock => clk_out, clk_en => csel_enable, aclr => reset_all, q => period2); dig_count3: lpm_counter generic map (LPM_WIDTH =>6) port map (clock => Clk(3), clk_en => csel_enable, aclr => reset_all, q => clk3_count); dig_count2: lpm_counter generic map (LPM_WIDTH =>6) port map (clock => Clk(2), clk_en => csel_enable, aclr => reset_all, q => clk2_count); dig_count5: lpm_counter generic map (LPM_WIDTH =>6) port map (clock => Clk(5), clk_en => csel_enable, aclr => reset_all, q => clk5_count); d32_comp: lpm_compare generic map ( LPM_WIDTH =>6) port map ( dataa => clk3_count, datab => clk2_count, ageb => b3s2, alb => b2s3); d26_comp: lpm_compare generic map ( LPM_WIDTH =>6) port map ( dataa => clk2_count, datab => clk5_count, ageb => b2s5, alb => b5s2); d36_comp: lpm_compare generic map ( LPM_WIDTH =>6) port map ( dataa => clk3_count, datab => clk5_count, ageb => b3s5, alb => b5s3); -- pipeline clock selection process(reset_all,ttc_done) begin if(reset_all = '1' or ttc_done = '0') then now_dclk <= wait1_dclk; elsif(clk_out'event and clk_out = '1') then now_dclk <= next_dclk; end if; end process; process(now_dclk) begin case now_dclk is when wait1_dclk => csel_enable <= '0'; if(ttc_done = '1') then next_dclk <= chk_dclk; else next_dclk <= wait1_dclk; end if; when chk_dclk => csel_enable <= '1'; if(period2(3) = '0') then next_dclk <= chk_dclk; else next_dclk <= wait2_dclk; end if; when wait2_dclk => csel_enable <= '0'; next_dclk <= wait2_dclk; end case; end process; clkset: process(b2s3,b2s5,b3s2,b3s5,b5s2,b5s3) begin if(b3s2 = '1' and b3s5 = '1') then clk3_ok <= '1'; clk2_ok <= '0'; clk5_ok <= '0'; clk_pipe <= not Clk(3); elsif(b2s3 = '1' and b2s5 = '1') then clk2_ok <= '1'; clk3_ok <= '0'; clk5_ok <= '0'; clk_pipe <= not Clk(2); elsif(b5s3 = '1' and b5s2 = '1') then clk5_ok <= '1'; clk2_ok <= '0'; clk3_ok <= '0'; clk_pipe <= not Clk(5); else -- default to Clk(3) clk3_ok <= '1'; clk2_ok <= '0'; clk5_ok <= '0'; clk_pipe <= not Clk(3); end if; end process clkset; -------------------end of this block --------------------------------------------- ------------------------------------------------------------------------------------------- -- output_controller: provide control signal for interface with glink ------------------------------------------------------------------------------------------- process(fullmk,mode16) begin if(fullmk = "0000000000000000") then pack_ready16 <= '0'; else pack_ready16 <= '1'; end if; if(fullmk(7 downto 0) = "00000000") then pack_ready8 <= '0'; else pack_ready8 <= '1'; end if; if(mode16 = '1') then pack_ready <= pack_ready16; else pack_ready <= pack_ready8; end if; end process; data_read_count: lpm_counter generic map (LPM_WIDTH =>11) -- count how many data read. port map (clock => clk2b_out, clk_en => reading, aclr => data_read_clr, q => data_read_num); package_comp: lpm_compare generic map ( LPM_WIDTH =>11) -- if data read equal data num port map ( dataa => data4read, -- then one fifo is read datab => data_read_num, aeb => data_txed); data_read_clr <= (reset_all or data_txed or rhold); tx_en <= pack_ready and LOCKED; -- after data is ready and glink is locked, then enable transmittion. process(packr_num1,aux_rmem1,aux_rmem2) begin if(packr_num1 = '1') then if(aux_rmem2 = '0') then reg_out <= fifo_out_data2; else reg_out <= aux_out_data2; end if; else if(aux_rmem1 = '0') then reg_out <= fifo_out_data1; else reg_out <= aux_out_data1; end if; end if; end process; --******************************************************************************-- -- this block to control sending the data word and control word using state machine --******************************************************************************-- crcdig: CRC16 port map ( crc_clk => clk_out, crc_step => cstep, crc_start => cstart, crc_data => buff_crc, crc_error => cerror); process(reset_all, clk_out) begin if (reset_all = '1') then current_state <= idle; elsif (clk_out'event and clk_out = '1' ) then current_state <= next_state; end if; end process; process (current_state) begin case current_state is when idle => idle_now <= '1'; cstart <= '0'; cstep <= '0'; read_done1 <= '0'; read_done2 <= '0'; HP_CNTL_IN <= '0'; HP_DATA_IN <= '0'; HP_FLAG_IN <= '0'; buff_out <= startwHI; if reading1b = '1' then next_state <= startHI; else next_state <= idle; end if; when startHI => idle_now <= '0'; cstart <= '1'; cstep <= '0'; HP_CNTL_IN <= '1'; HP_DATA_IN <= '1'; HP_FLAG_IN <= '0'; buff_out <= startwHI; next_state <= startLO; when startLO => HP_CNTL_IN <= '1'; HP_DATA_IN <= '1'; HP_FLAG_IN <= '0'; buff_out <= startwLO; cstart <= '1'; cstep <= '1'; next_state <= txingHI; when txingHI => cstart <= '0'; cstep <= '1'; HP_CNTL_IN <= '0'; HP_DATA_IN <= '1'; HP_FLAG_IN <= '0'; buff_out <= fifo_data(31 downto 16); buff_sav <= fifo_data(15 downto 0); buff_crc(31 downto 0) <= fifo_data(31 downto 0); next_state <= txingLO; when txingLO => cstep <= '0'; HP_CNTL_IN <= '0'; HP_DATA_IN <= '1'; HP_FLAG_IN <= '0'; buff_out <= buff_sav; if ( stopit = '1') then next_state <= txeflg1; else next_state <= txingHI; end if; when txeflg1 => HP_CNTL_IN <= '0'; HP_DATA_IN <= '1'; HP_FLAG_IN <= '0'; buff_out <= cerror(31 downto 16); next_state <= txeflg2; when txeflg2 => HP_CNTL_IN <= '0'; HP_DATA_IN <= '1'; HP_FLAG_IN <= '0'; buff_out <= cerror(15 downto 0); next_state <= cmd_tx; when cmd_tx => HP_CNTL_IN <= '0'; HP_DATA_IN <= '0'; -- idle word with no crc calc HP_FLAG_IN <= '1'; buff_out <= cmd_word; next_state <= crc_tx; when crc_tx => HP_CNTL_IN <= '0'; HP_DATA_IN <= '1'; -- return the crc word HP_FLAG_IN <= '1'; buff_out <= crc_cnst; next_state <= stopHI; read_done1 <= '1'; when stopHI => HP_CNTL_IN <= '1'; HP_DATA_IN <= '1'; HP_FLAG_IN <= '0'; buff_out <= stopwHI; next_state <= stopLO; read_done1 <= '0'; when stopLO => HP_CNTL_IN <= '1'; HP_DATA_IN <= '1'; read_done2 <= '1'; HP_FLAG_IN <= '0'; buff_out <= stopwLO; next_state <= idle; end case; end process; ------------------------------------------------------------------------------------------ -- delay signals ------------------------------------------------------------------------------------------ process (reading2,reading3) begin if(idle_now = '1' or reset_all = '1') then stopit <= '0'; elsif(reading2'event and reading2 = '0') then if(reading3 = '1') then stopit <= '1'; end if; end if; end process; process ( clk2_out ) begin if ( clk2_out'event and clk2_out = '1') then read_ready <= tx_en; reading1 <= reading; reading2 <= reading1b; reading3 <= reading2b; packr_num0 <= packr_num(0); packr_num1 <= packr_num0b; end if; end process; process (clk2b_out) begin if ( clk2b_out'event and clk2b_out = '1') then fifo_data <= reg_out; reading1b <= reading1; reading2b <= reading2; packr_num0b <= packr_num0; packr_num1b <= packr_num1; end if; end process; -----------------------------------end of this block -------------------------------------- process ( rhold,clk2b_out) begin if (rhold = '1' or reset_all = '1') then reading <= '0'; elsif (clk2b_out'event and clk2b_out = '1' ) then reading <= tx_en; end if; end process; process(packr_num) begin if(packr_num = "000") then fifo_rden1 <= reading; else fifo_rden1 <= '0'; end if; if(packr_num = "001") then fifo_rden2 <= reading; else fifo_rden2 <= '0'; end if; end process; process(clk2_out) begin if(clk2_out'event and clk2_out = '1') then arm1 <= (mode16 and bot_count1(3)) or (mode8 and bot_count1(4)); arm2 <= (mode16 and bot_count2(3)) or (mode8 and bot_count2(4)); end if; end process; process(clk2b_out) begin if(clk2b_out'event and clk2b_out = '1') then aux_rmem1 <= arm1; aux_rmem2 <= arm2; end if; end process; packr_count: lpm_counter generic map (LPM_WIDTH =>3) -- data frame read out counter port map (clock => data_txed, aclr => packr_clr, q => packr_num); packr_clr <= reset_all or read_done1; process(packr_num,reset_all,idle_now) begin if(packr_num = "010") then rhold <= '1'; elsif( idle_now = '1' or reset_all = '1') then rhold <= '0'; end if; end process; ------------------------------------------------------------------------------------------- -- other logics - half rate clocks etc. ------------------------------------------------------------------------------------------- clkb_pipe <= not clk_pipe; cclk_count: lpm_counter generic map (LPM_WIDTH =>2) port map (clock => clk_pipe, q => cclk); clk2 <= cclk(0); clk2b <= not clk2; clk_out <= Clock; clkb_out <= not clk_out; cclko_count: lpm_counter generic map (LPM_WIDTH =>2) port map (clock => clkb_out, q => cclko); clk2_out <= cclko(0); clk2b_out <= not clk2_out; clk4_out <= cclko(1); clk4b_out <= not clk4_out; ------------------------------------------------------------------------------------------- crccal : crctx port map ( CLK => clkb_out, TX_D_IN => buff_out, TX_D => TX, TX_DATA_IN => HP_DATA_IN, TX_DATA => TXDATA, TX_CNTL_IN => HP_CNTL_IN, TX_CNTL => TXCNTL, TX_FLAG_IN => HP_FLAG_IN, TX_FLAG => TXFLAG); TXFLGENB <= '1'; TXDIV0 <= '1'; TXDIV1 <= '0'; TXCLK <= clk_out; TCLKENB <='0'; ESMPXENB <='0'; -- kja end a;