---------------------------------------------------------------------------- -- Lawrence Berkeley National Laboratory (c) 1997 -- BaBar Trigger Electronics ---------------------------------------------------------------------------- -- Description: -- Fast control FPGA: contains the generic fast control interface, used on -- all boards. This FPGA recieves commands on the 60Mbit clink, and -- translates those to board level signal. It also controlls the serial -- dlink, to send data out. -- A command and status register (csr) as well as status LED drivers -- are on chip. ---------------------------------------------------------------------------- -- Structure: -- top -- csr_reg -- command and status register -- clink_ctl -- top level portmap for the clink control logic blocks. -- consider changing to nfl -- clk_divide -- clock divide and trigger time tag counter, reset on sync. -- dlink_ctl -- top level portmap for the dlink control logic blocks. -- consider changing to nfl -- l1_fifo -- dual port memory, read and write pointer controller. -- Total size is 32bit x 4 deep. Stores trigger data. -- gen_led -- drive status LEDs ---------------------------------------------------------------------------- -- Timing: -- Entire design runs synchronously at 60 MHz ---------------------------------------------------------------------------- -- Author: Armin Karcher -- History: -- Karcher 03/97 - First Version -- Karcher 6/4/97 - Added FF on data lines for DIN/DOUT -- Karcher 6/30/97 - Added dclk_in/out, rx_signal_detect_n, glink_reset_n -- Karcher 3-12-97 - CHanged data_width timing -- Karcher 12-11-98 - Finished block write, added opcode 14 for -- input Fifo reframe. externally this signal runs on -- the sync line to input control. -- Fixed read event variable latency bug. ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; ---------------------------------------------------------------------------- --PORT DECLARATION ---------------------------------------------------------------------------- entity top is port( clk : in std_logic; -- clk60 input, distributed rst : in std_logic; -- global reset o_mem_act : in std_logic; -- output memory active i_mem_act : in std_logic; -- input memory active lock : in std_logic; -- glink locked g_sync : in std_logic; -- glink synced st_spare1 : in std_logic; -- status spare st_spare2 : in std_logic; -- status spare lst_data : in std_logic; -- last data word dt_pres : in std_logic; -- data present (valid) clink : in std_logic; -- clink serial data in cmd_str_30 : out std_logic; -- command strobe aligned to -- clock 30 cmd_str_60 : out std_logic; -- command strobe blk_str : out std_logic; -- block address strobe ad_str : out std_logic; -- address strobe wr_dt_str : out std_logic; -- write data strobe rd_dt_str : out std_logic; -- read data strobe l1 : out std_logic; -- level 1 accept rd_evt : out std_logic; -- read event cal_str : out std_logic; -- calibration strobe sync : out std_logic; -- sync usr_rst : out std_logic; -- user reset start_pl : out std_logic; -- start record/playback inc_add : out std_logic; -- increment address data_width : out std_logic; -- data width (one or two words) op_mode : out std_logic_vector(3 downto 0); -- run/non-run mode daq_format : out std_logic_vector(1 downto 0); -- daq data format in_play_rec : out std_logic; -- input memory direction en_in_mem : out std_logic; -- enable input memory out_play_rec : out std_logic; -- output memory direction en_out_mem : out std_logic; -- enable output memory p_r_mode : out std_logic; -- playback/record mode -- (once-through/continuous) ct_spare1 : out std_logic; -- control spare ct_spare2 : out std_logic; -- control spare clk30_in : out std_logic_vector(3 downto 0); -- clock 30 out clk15 : out std_logic; -- clock 15 out clk8 : out std_logic; -- clock 8 out clk4 : out std_logic; -- clock 4 out clk2 : out std_logic; -- clock 4 out dlink : out std_logic; -- dlink serial data out next_data : out std_logic; -- next data word buf_add0 : out std_logic_vector(3 downto 0); -- read/write buf_add1 : out std_logic_vector(3 downto 0); -- pointers data_io : inout std_logic_vector(15 downto 0); -- data bus soft_led : out std_logic_vector(3 downto 0); -- software LED out run_mode_led : out std_logic; -- run mode led non_run_mode_led : out std_logic; -- non run mode led raw_data_led : out std_logic; -- raw data format led one_word_data_led : out std_logic; -- one word data format two_word_data_led : out std_logic; -- two word data format in_play_rec_led : out std_logic; -- input mem. direction en_in_mem_led : out std_logic; -- input memory enable out_play_rec_led : out std_logic; -- output mem. direction en_out_mem_led : out std_logic; -- output memory enable single_mode_led : out std_logic; -- single mode led continuous_mode_led : out std_logic; -- continuous mode led glink_not_ready_led : out std_logic; -- glink not ready led glink_not_sync_led : out std_logic; -- glink not synced led i_mem_act_led : out std_logic; -- input memory active o_mem_act_led : out std_logic; -- output memory active rx_signal_detect_n : in std_logic; -- finisar signal detect -- on tsf boards only glink_reset_n : out std_logic; -- glink reset, will be -- used on tsf only dclk_in : in std_logic; -- no-connect, may be dclk_out : out std_logic; -- used to adjust skew done : inout std_logic; -- no-connect, neded to spare1 : inout std_logic; -- match vhdl/comp port spare2 : inout std_logic -- maps. ); end top; architecture rtl of top is ---------------------------------------------------------------------------- --SIGNAL DECLARATION ---------------------------------------------------------------------------- signal hdr : std_logic_vector(31 downto 0); -- rd_evt header signal csr_val : std_logic_vector(15 downto 0); -- csr register value signal data_bus_i_l: std_logic_vector(15 downto 0); -- clink data, latched signal data_bus_o_l: std_logic_vector(15 downto 0);-- data to clink, latched signal data_bus_o: std_logic_vector(15 downto 0); -- data from clink signal data_bus_i: std_logic_vector(15 downto 0); -- data to dlink signal sel_csr: std_logic_vector(2 downto 0); -- selects csr register signal cmd : std_logic_vector(4 downto 0); -- command signal tag : std_logic_vector(4 downto 0); -- sub command signal ctr : std_logic_vector(4 downto 0); -- trigger counter/clk divider signal wr_buf1 : std_logic_vector(1 downto 0); -- write pointer signal rd_buf1 : std_logic_vector(1 downto 0); -- read pointer signal wr_buf2 : std_logic_vector(1 downto 0); -- write pointer signal rd_buf2 : std_logic_vector(1 downto 0); -- read pointer signal reg_rd : std_logic; -- csr register read signal reg_wr : std_logic; -- csr register write signal r_w : std_logic; -- internal data bus direction signal adv_cmd_str : std_logic; -- command strobe tick 13 signal cmd_str_i : std_logic; -- command strobe tick 14 signal rd_dt_str_i : std_logic; -- read data strobe signal wr_dt_str_i : std_logic; -- write data strobe signal blk_str_i : std_logic; -- block address strobe signal ad_str_i : std_logic; -- address strobe signal rd_evt_i : std_logic; -- read event signal clr_rd : std_logic; -- clear readout signal sync_i : std_logic; -- sync signal reframe : std_logic; -- clear input fifo signal l1_i : std_logic; -- level 1 accept signal inc_add_i : std_logic; -- increment address signal increment_add : std_logic; -- increment address -- for address counter signal dt_lng : std_logic; -- data long (2 words) signal rd_blk : std_logic; -- read block signal blk_done : std_logic; -- block done signal rd_inc : std_logic; -- increment block counter during read signal dl_rd : std_logic; -- read event pending, busy signal tri_en : std_logic; -- internal data bus tristate signal led : std_logic_vector(3 downto 0); -- soft led register signal clk_30 : std_logic_vector(4 downto 0); -- clock 30 signal gsrnet : std_logic; ---------------------------------------------------------------------------- --COMPONENT DECLARATION ---------------------------------------------------------------------------- --following are for orca parts component gsr port( gsr : in std_ulogic ); end component; component ibtpu port( i : in std_ulogic; o : out std_ulogic ); end component; component csr_reg port (clk : in std_logic; rst : in std_logic; reg_rd : in std_logic; reg_wr : in std_logic; ad_str : in std_logic; blk_str : in std_logic; cmd_str : in std_logic; inc_add : in std_logic; increment_add : in std_logic; o_mem_act : in std_logic; i_mem_act : in std_logic; lock : in std_logic; g_sync : in std_logic; st_spare1 : in std_logic; st_spare2 : in std_logic; data_in : in std_logic_vector(15 downto 0); csr_en : in std_logic_vector(2 downto 0); led : out std_logic_vector(3 downto 0); reg_val_out : out std_logic_vector(15 downto 0); data_out : out std_logic_vector(15 downto 0) ); end component; component clink_ctl port( clk : in std_logic; rst : in std_logic; clk_30 : in std_logic; clink : in std_logic; rd_inc : in std_logic; -- next word during block read r_w_out : out std_logic; data_out : out std_logic_vector(15 downto 0); adv_cmd_str : out std_logic; cmd_str_30 : out std_logic; cmd_str : out std_logic; blk_str : out std_logic; ad_str : out std_logic; wr_dt_str : out std_logic; rd_dt_str : out std_logic; clr_rd : out std_logic; l1 : out std_logic; rd_evt : out std_logic; cal_str : out std_logic; sync : out std_logic; reframe : out std_logic; -- clear input fifo usr_rst : out std_logic; start_pl : out std_logic; reg_rd : out std_logic; reg_wr : out std_logic; inc_add : out std_logic; increment_add : out std_logic; dt_lng : out std_logic; rd_blk : out std_logic; -- read block blk_done : out std_logic; -- read block done sel_csr : out std_logic_vector(2 downto 0); cmd : out std_logic_vector(4 downto 0); tag : out std_logic_vector(4 downto 0) ); end component; component clk_divide port( clk : in std_logic; -- clk60 input, distributed rst : in std_logic; -- global reset sync : in std_logic; -- sync command, resets counter adv_cmd_str : in std_logic; -- this strobe qualifies sync one -- tick before the actual cmd_str clk_30 : out std_logic_vector(4 downto 0); -- lower speed clocks clk_15 : out std_logic; -- lower speed clocks clk_8 : out std_logic; -- lower speed clocks clk_4 : out std_logic; -- lower speed clocks clk_2 : out std_logic; -- lower speed clocks ctr : out std_logic_vector(4 downto 0) -- trigger time tag ); end component; component dlink_ctl port( clk : in std_logic; rst : in std_logic; clk_30 : in std_logic; lst_data : in std_logic; rd_blk : in std_logic; -- block read blk_done : in std_logic; -- block done dt_pres : in std_logic; reg_data_vld : in std_logic; dt_lng : in std_logic; rd_evt_i : in std_logic; cmd_str : in std_logic; rd_dt_str : in std_logic; -- read data strobe data_bus_i : in std_logic_vector(15 downto 0); hdr : in std_logic_vector(31 downto 0); cmd : in std_logic_vector(4 downto 0); tag : in std_logic_vector(4 downto 0); st_spare1 : in std_logic; -- board ID st_spare2 : in std_logic; -- board ID dlink : out std_logic; rd_inc : out std_logic; -- increment block counter dl_rd : out std_logic; next_data : out std_logic ); end component; component l1_fifo port (clk : in std_logic; rst : in std_logic; adv_cmd_str : in std_logic; cmd_str : in std_logic; l1 : in std_logic; rd_evt : in std_logic; clr_rd : in std_logic; tag : in std_logic_vector(4 downto 0); ctr : in std_logic_vector(4 downto 0); csr_val : in std_logic_vector(15 downto 0); wr_buf1 : out std_logic_vector(1 downto 0); rd_buf1 : out std_logic_vector(1 downto 0); wr_buf2 : out std_logic_vector(1 downto 0); rd_buf2 : out std_logic_vector(1 downto 0); data_out: out std_logic_vector(31 downto 0) ); end component; component gen_led port( led : in std_logic_vector(3 downto 0); -- software LEDs op_mode : in std_logic; -- operation mode (run/non-run) daq_format : in std_logic_vector(1 downto 0); -- daq data format in_play_rec : in std_logic; -- input memory direction en_in_mem : in std_logic; -- input memory enable out_play_rec : in std_logic; -- output memory direction en_out_mem : in std_logic; -- output memory enable p_r_mode : in std_logic; -- play/record mode -- (single/continuous) lock : in std_logic; -- glink locked g_sync : in std_logic; -- glink synced o_mem_act : in std_logic; -- output memory active i_mem_act : in std_logic; -- input memory active soft_led : out std_logic_vector(3 downto 0); -- software LED out run_mode_led : out std_logic; -- run mode led non_run_mode_led : out std_logic; -- non run mode led raw_data_led : out std_logic; -- raw data format led one_word_data_led : out std_logic; -- one word data format two_word_data_led : out std_logic; -- two word data format in_play_rec_led : out std_logic; -- input mem. direction en_in_mem_led : out std_logic; -- input memory enable out_play_rec_led : out std_logic; -- output mem. direction en_out_mem_led : out std_logic; -- output memory enable single_mode_led : out std_logic; -- single mode led continuous_mode_led : out std_logic; -- continuous mode led glink_not_ready_led : out std_logic; -- glink not ready led glink_not_sync_led : out std_logic; -- glink not synced led i_mem_act_led : out std_logic; -- input memory active o_mem_act_led : out std_logic -- output memory active ); end component; begin ---------------------------------------------------------------------------- --COMPONENT INSTANTIATION ---------------------------------------------------------------------------- --orca parts gsr0 : gsr port map (gsr => gsrnet); rstn : ibtpu port map (i => rst, o => gsrnet); top_clink: clink_ctl port map(clk,rst,clk_30(4), clink, rd_inc, r_w, data_bus_o , adv_cmd_str,cmd_str_30,cmd_str_i, blk_str_i,ad_str_i,wr_dt_str_i ,rd_dt_str_i, clr_rd,l1_i,rd_evt_i,cal_str,sync_i,reframe,usr_rst,start_pl, reg_rd,reg_wr, inc_add_i,increment_add, dt_lng,rd_blk,blk_done, sel_csr, cmd,tag ); top_reg: csr_reg port map(clk,rst, reg_rd,reg_wr,ad_str_i,blk_str_i,cmd_str_i, inc_add_i,increment_add,o_mem_act,i_mem_act, lock,g_sync,st_spare1,st_spare2, data_bus_o, sel_csr, led,csr_val,data_bus_i); top_divide: clk_divide port map( clk ,rst,sync_i,adv_cmd_str, clk_30,clk15,clk8,clk4,clk2,ctr ); top_dlink:dlink_ctl port map(clk,rst,clk_30(4), lst_data,rd_blk,blk_done,dt_pres,reg_rd,dt_lng, rd_evt_i,cmd_str_i,rd_dt_str_i, data_bus_i,hdr,cmd,tag,st_spare1,st_spare2, dlink,rd_inc,dl_rd,next_data); top_l1_fifo: l1_fifo port map(clk,rst, adv_cmd_str,cmd_str_i, l1_i,rd_evt_i,clr_rd, tag,ctr,csr_val, wr_buf1,rd_buf1,wr_buf2,rd_buf2,hdr); top_lede: gen_led port map(led,csr_val(0),csr_val(4 downto 3),csr_val(6),csr_val(5), csr_val(8),csr_val(7),csr_val(9), lock,g_sync,o_mem_act,i_mem_act, soft_led, run_mode_led,non_run_mode_led, raw_data_led,one_word_data_led,two_word_data_led, in_play_rec_led,en_in_mem_led,out_play_rec_led,en_out_mem_led, single_mode_led,continuous_mode_led, glink_not_ready_led,glink_not_sync_led, i_mem_act_led,o_mem_act_led ); ---------------------------------------------------------------------------- --PROCESS DECLARATION ---------------------------------------------------------------------------- ff: process (clk,rst) begin if (rst = '1') then tri_en <= '0'; data_bus_i_l <= "0000000000000000"; data_bus_o_l <= "0000000000000000"; rd_dt_str <= '0'; wr_dt_str <= '0'; blk_str <= '0'; ad_str <= '0'; data_width <= '0'; elsif (clk'event and clk = '1' ) then tri_en <= (r_w OR dl_rd ); data_bus_i_l <= data_io; data_bus_o_l <= data_bus_o; rd_dt_str <= rd_dt_str_i; wr_dt_str <= wr_dt_str_i; blk_str <= blk_str_i; ad_str <= ad_str_i; data_width <= dt_lng; end if; end process; tristate1: process (tri_en,data_bus_o_l) begin if (tri_en ='0') then data_io <= data_bus_o_l; else data_io <= "ZZZZZZZZZZZZZZZZ"; end if; end process; tristate2: process (tri_en,data_bus_i_l) begin if (tri_en ='0') then data_bus_i <= "ZZZZZZZZZZZZZZZZ"; else data_bus_i <= data_bus_i_l; end if; end process; ---------------------------------------------------------------------------- --OUTPUT ASSIGNMENTS ---------------------------------------------------------------------------- cmd_str_60 <= cmd_str_i; sync <= reframe; rd_evt <= rd_evt_i; l1 <= l1_i; clk30_in <= clk_30(3 downto 0); op_mode(0) <= csr_val(0); op_mode(1) <= csr_val(0); op_mode(2) <= csr_val(0); op_mode(3) <= csr_val(0); ct_spare1 <= csr_val(1); ct_spare2 <= csr_val(2); daq_format <= csr_val(4 downto 3); in_play_rec <= csr_val(6); en_in_mem <= csr_val(5); out_play_rec <= csr_val(8); en_out_mem <= csr_val(7); p_r_mode <= csr_val(9); buf_add0(3 downto 2) <= wr_buf1; buf_add1(3 downto 2) <= wr_buf2; buf_add0(1 downto 0) <= rd_buf1; buf_add1(1 downto 0) <= rd_buf2; inc_add <= inc_add_i; end rtl;