---------------------------------------------------------------------------- -- Lawrence Berkeley National Laboratory (c) 1997 -- BaBar Trigger Electronics ---------------------------------------------------------------------------- -- Description: -- The csr_reg consists of the main csr register, the software led register, -- the address and block address registers. The 10 writable bits of the csr -- register are grouped in 4 groups for write access. -- All 16 bits are read as a single word. -- The address is incremented during "read with address increment" cycles. -- New address is valid 3 ticks after the command strobe. ---------------------------------------------------------------------------- -- Structure: -- wr_reg: -- write to the 10 writable bits of the csr register, csr_en -- selects which of the four groups is written. -- wr_addr: -- write address, increment during "read with increment". -- cnt: -- additional logic for address counter. -- wr_blkl: -- write block address. -- del_en: -- decodes which register is read. -- tristate1-4 -- drive register contents during read, tristate otherwise. ---------------------------------------------------------------------------- -- Timing: -- data is valid one tick after the reg_rd strobe, for one tick only ---------------------------------------------------------------------------- -- Author: Armin Karcher -- History: -- Karcher 03/97 - First Version -- Karcher 6/4/97 - added FFs for status lines -- Karcher 8/25/97 - address latching on write ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; ---------------------------------------------------------------------------- --PORT DECLARATION ---------------------------------------------------------------------------- entity csr_reg is port (clk : in std_logic; -- clk60 input, distributed rst : in std_logic; -- global reset reg_rd : in std_logic; -- read csr register strobe reg_wr : in std_logic; -- write csr register strobe ad_str : in std_logic; -- address strobe (write address reg.) blk_str : in std_logic; -- block address strobe -- (write block address register) cmd_str : in std_logic; -- command strobe inc_add : in std_logic; -- Increment Address (cmd_str qualifier) increment_add : in std_logic; -- Increment Address counter enable o_mem_act : in std_logic; -- output memory active (status input) i_mem_act : in std_logic; -- input memory active (status input) lock : in std_logic; -- glink lock (glink ready status) g_sync : in std_logic; -- glink synced (fifo contents valid) st_spare1 : in std_logic; -- status input spare st_spare2 : in std_logic; -- status input spare data_in : in std_logic_vector(15 downto 0); -- data input csr_en : in std_logic_vector(2 downto 0); -- enable register led : out std_logic_vector(3 downto 0); -- software led values reg_val_out : out std_logic_vector(15 downto 0); -- csr register -- contents, will be latched in trigger FIFO. data_out : out std_logic_vector(15 downto 0) --read data out ); end csr_reg; architecture rtl of csr_reg is ---------------------------------------------------------------------------- --SIGNAL DECLARATION ---------------------------------------------------------------------------- signal reg_val: std_logic_vector(15 downto 0); -- csr register contents signal addr_reg: std_logic_vector(15 downto 0); -- address register contents signal blk_reg: std_logic_vector(15 downto 0); -- block ad. register contents signal led_i: std_logic_vector(3 downto 0); -- software led register contents signal tri_en1: std_logic; -- drive csr data out signal tri_en2: std_logic; -- drive software led data out signal tri_en3: std_logic; -- drive address data out signal tri_en4: std_logic; -- drive block address data out signal en_ct: std_logic; -- enable address counter signal a2: std_logic; -- logic and of address bits, used for counter signal a4: std_logic; signal a6: std_logic; signal a8: std_logic; signal a10: std_logic; signal a12: std_logic; signal a14: std_logic; begin ---------------------------------------------------------------------------- --PROCESS DECLARATION ---------------------------------------------------------------------------- wr_reg: process (clk,rst,reg_wr,csr_en,data_in) begin if (rst = '1') then reg_val(9 downto 0) <= "0000000000"; led_i <= "0000"; elsif (clk'event and clk = '1') then if (reg_wr = '1') then if ( csr_en = "001") then reg_val(2 downto 0) <= data_in(2 downto 0); end if; if ( csr_en = "010") then reg_val(4 downto 3) <= data_in(1 downto 0); end if; if ( csr_en = "011") then reg_val(5) <= data_in(0); reg_val(6) <= data_in(1); reg_val(7) <= data_in(2); reg_val(8) <= data_in(3); end if; if ( csr_en = "100") then reg_val(9) <= data_in(0); end if; if ( csr_en = "101") then led_i <= data_in(3 downto 0); end if; end if; end if; end process; wr_addr: process (clk,rst,ad_str,data_in) begin if (rst = '1') then addr_reg <= "0000000000000000"; elsif (clk'event and clk = '1') then if (ad_str = '1') then addr_reg <= data_in; elsif (increment_add = '1') then addr_reg(0) <= NOT addr_reg(0); addr_reg(1) <= addr_reg(0) XOR addr_reg(1); addr_reg(2) <= (addr_reg(0) AND addr_reg(1)) XOR addr_reg(2); addr_reg(3) <= a2 XOR addr_reg(3); addr_reg(4) <= (a2 AND addr_reg(3)) XOR addr_reg(4); addr_reg(5) <= (a4 ) XOR addr_reg(5); addr_reg(6) <= (a4 AND addr_reg(5)) XOR addr_reg(6); addr_reg(7) <= (a6 ) XOR addr_reg(7); addr_reg(8) <= (a6 AND addr_reg(7)) XOR addr_reg(8); addr_reg(9) <= (a8) XOR addr_reg(9); addr_reg(10) <= (a8 AND addr_reg(9)) XOR addr_reg(10); addr_reg(11) <= (a10) XOR addr_reg(11); addr_reg(12) <= (a10 AND addr_reg(11)) XOR addr_reg(12); addr_reg(13) <= (a12) XOR addr_reg(13); addr_reg(14) <= (a12 AND addr_reg(13)) XOR addr_reg(14); addr_reg(15) <= (a14) XOR addr_reg(15); end if; end if; end process; cnt : process (clk,rst) begin if (rst = '1') then en_ct <= '0'; a2 <= '0'; a4 <= '0'; a6 <= '0'; a8 <= '0'; a10 <= '0'; a12 <= '0'; a14 <= '0'; elsif (clk'event and clk = '1') then en_ct <= cmd_str AND inc_add; a2 <= addr_reg(0) AND addr_reg(1) AND addr_reg(2); a4 <= a2 AND addr_reg(3) AND addr_reg(4); a6 <= a4 AND addr_reg(5) AND addr_reg(6); a8 <= a6 AND addr_reg(7) AND addr_reg(8); a10 <= a8 AND addr_reg(9) AND addr_reg(10); a12 <= a10 AND addr_reg(11) AND addr_reg(12); a14 <= a12 AND addr_reg(13) AND addr_reg(14); end if; end process; wr_blk: process (clk,rst,blk_str,data_in) begin if (rst = '1') then blk_reg <= "0000000000000000"; elsif (clk'event and clk = '1') then if (blk_str = '1') then blk_reg <= data_in; end if; end if; end process; ltch: process (clk,rst,lock,g_sync,i_mem_act,o_mem_act,st_spare1,st_spare2) begin if (rst = '1') then reg_val(10) <= '0'; reg_val(11) <= '0'; reg_val(12) <= '0'; reg_val(13) <= '0'; reg_val(14) <= '0'; reg_val(15) <= '0'; elsif (clk'event and clk = '1') then reg_val(10) <= lock; reg_val(11) <= g_sync; reg_val(12) <= i_mem_act; reg_val(13) <= o_mem_act; reg_val(14) <= st_spare1; reg_val(15) <= st_spare2; end if; end process; del_en: process (clk,rst) begin if (rst = '1') then tri_en1 <= '0'; tri_en2 <= '0'; tri_en3 <= '0'; tri_en4 <= '0'; elsif (clk'event and clk = '1') then if (reg_rd = '1' AND csr_en = "001") then tri_en1 <= '1'; tri_en2 <= '0'; tri_en3 <= '0'; tri_en4 <= '0'; elsif (reg_rd = '1' AND csr_en = "010") then tri_en1 <= '0'; tri_en2 <= '1'; tri_en3 <= '0'; tri_en4 <= '0'; elsif (reg_rd = '1' AND csr_en = "011") then tri_en1 <= '0'; tri_en2 <= '0'; tri_en3 <= '1'; tri_en4 <= '0'; elsif (reg_rd = '1' AND csr_en = "100") then tri_en1 <= '0'; tri_en2 <= '0'; tri_en3 <= '0'; tri_en4 <= '1'; else tri_en1 <= '0'; tri_en2 <= '0'; tri_en3 <= '0'; tri_en4 <= '0'; end if; end if; end process; tristate1: process (tri_en1,reg_val) begin if (tri_en1 = '1') then data_out <= reg_val; else data_out <= "ZZZZZZZZZZZZZZZZ"; end if; end process; tristate2: process (tri_en2,led_i) begin if (tri_en2 = '1') then data_out(3 downto 0) <= led_i; data_out(15 downto 4) <= "000000000000"; else data_out <= "ZZZZZZZZZZZZZZZZ"; end if; end process; tristate3: process (tri_en3,addr_reg) begin if (tri_en3 = '1') then data_out <= addr_reg; else data_out <= "ZZZZZZZZZZZZZZZZ"; end if; end process; tristate4: process (tri_en4,blk_reg) begin if (tri_en4 = '1') then data_out <= blk_reg; else data_out <= "ZZZZZZZZZZZZZZZZ"; end if; end process; reg_val_out <= reg_val; ---------------------------------------------------------------------------- --OUTPUT ASSIGNMENTS ---------------------------------------------------------------------------- led <= led_i; end rtl;