--------------------------------------------------------- -- DRAW CONTROL_BOARD No.1 VHDL Version 3.1b boards -- -- version 3.0 TTCrx chips Aug 2000 -- --------------------------------------------------------- LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_arith.ALL; ENTITY ab1_v3 IS PORT ( -- TTC INPUTS clock40: IN std_logic; clock40des1: IN std_logic; clock40des2: IN std_logic; brcststr1: IN std_logic; brcststr2: IN std_logic; ttcdata: IN std_logic_vector(7 DOWNTO 0); subadr: IN std_logic_vector(7 DOWNTO 0); dq: IN std_logic_vector(3 DOWNTO 0); datastr: IN std_logic; brcst2: IN std_logic; brcst3: IN std_logic; brcst4: IN std_logic; brcst5: IN std_logic; brcst6: IN std_logic; brcst7: IN std_logic; -- CANBUS INPUTS and OUTPUTS can_input: IN std_logic; can_output: OUT std_logic; can_enable: IN std_logic; can_clk: IN std_logic; can_reset: OUT std_logic; can_clk40: OUT std_logic; -- 3IN1 CONTROL LINES data_from_3in1: IN std_logic; enable: OUT std_logic; clock: OUT std_logic; multi_sel: OUT std_logic; rxw: OUT std_logic; back_load: OUT std_logic; data_to_3in1: OUT std_logic; tp: OUT std_logic; drw_sel: OUT std_logic; sel: OUT std_logic_vector(48 DOWNTO 37); -- CONTROL of DELAY TIMER on BOARD 1 dly_en: OUT std_logic; data_out_en: OUT std_logic; p: OUT std_logic_vector(7 DOWNTO 0); -- ETC -- sa: IN std_logic_vector(14 DOWNTO 6); test0: OUT std_logic; test1: OUT std_logic; test2: OUT std_logic; test3: OUT std_logic; test4: OUT std_logic; ss4: OUT std_logic; ss5: OUT std_logic; ss6: OUT std_logic; ss7: OUT std_logic; ss9: OUT std_logic; ss10: OUT std_logic; ss11: OUT std_logic; ss12: OUT std_logic; ss13: OUT std_logic; tube: out std_logic_vector(5 downto 0); por: IN std_logic ); END ab1_v3; architecture logic_layout of ab1_v3 is type cmd_state is (resting,strt1,strt2,lch1,lch2,lfcode,excmd1,excmd2,wait1, wait2,wait3,wait4,wait5); type sd_state is (free,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12, s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23, s24,s25,s26,s27,s28,s29); signal now_cmd : cmd_state; signal next_cmd : cmd_state; signal now_sd : sd_state; signal next_sd : sd_state; signal execute : std_logic; signal execute_latch : std_logic; signal smclk : std_logic; signal multi_sel_in : std_logic; signal shift_in : std_logic; signal start1 : std_logic; signal start2 : std_logic; signal strt_ttc : std_logic; signal strt_can : std_logic; signal latch_ext : std_logic; signal cmd_frame_q : std_logic_vector(15 DOWNTO 0); signal cmd_frame_d : std_logic_vector(15 DOWNTO 0); signal can_shft_q : std_logic_vector(15 DOWNTO 0); signal can_shft_d : std_logic_vector(15 DOWNTO 0); signal can_shft_clk : std_logic; signal can_rst_q : std_logic; signal can_rst_d : std_logic; signal can_rst_clk : std_logic; signal shft_q : std_logic_vector(12 DOWNTO 0); signal shft_d : std_logic_vector(12 DOWNTO 0); signal shft_clk : std_logic; signal f_q : std_logic_vector(3 DOWNTO 0); signal f_d : std_logic_vector(3 DOWNTO 0); signal f_clk : std_logic; signal clr_fq : std_logic; signal tb_q : std_logic_vector(5 downto 0); signal tb_d : std_logic_vector(5 downto 0); signal tb_clk : std_logic; signal mrb_q : std_logic_vector(2 downto 0); signal mrb_d : std_logic_vector(2 downto 0); signal mrb_clk0 : std_logic; signal mrb_clk1 : std_logic; signal mrb_clk2 : std_logic; signal ltch_d : std_logic_vector(12 downto 0); signal ltch_q : std_logic_vector(12 downto 0); signal ltch_clk : std_logic; signal ldstr : std_logic; signal lcanen : std_logic; signal cmd_state_output : std_logic_vector(8 downto 0); signal sd_state_output : std_logic_vector(5 downto 0); signal sd_reset : std_logic; signal drw_sel_net : std_logic; signal multi_sel_net : std_logic; signal bc0 : std_logic; signal bc1 : std_logic; signal bcup : std_logic; signal bcedge : std_logic; signal tpf_q : std_logic; signal tpf_d : std_logic; signal tpf_clk : std_logic; signal execute1 : std_logic; signal execute2 : std_logic; signal w1 : std_logic; signal st1 : std_logic; signal st2 : std_logic; signal flatch : std_logic; signal sending : std_logic; signal sreset : std_logic; signal clk_internal : std_logic; signal en : std_logic; signal clk : std_logic; signal dqall : std_logic; signal wt1 : std_logic; signal idle : std_logic; signal st12 : std_logic; signal zero : std_logic; signal one : std_logic; signal two : std_logic; signal smclk1 : std_logic; signal smclk2 : std_logic; begin can_clk40 <= clock40; ------------------- tp processing -------------------------------------- --- note tp on 3in1 card is inverted from tp here so charge injected when tp (here) goes high --- bc0 <= brcst6 and brcst7 and not(brcst2) and brcststr1; bc1 <= brcst6 and brcst7 and brcst2 and brcststr1; process (bc0,tpf_q) begin if (tpf_q = '1' or por = '0' or sd_reset = '1') then --- hold bcup = 1 till tp (here) goes high or reset--- bcup <= '0'; elsif (rising_edge(bc0)) then bcup <= '1'; end if; end process; process (tpf_clk,bcup,clock40des2,bc1) begin if(rising_edge(clock40des2)) then --- if bcup set, set bcedge on rising edge of clock40des2 --- bcedge <= bcup; --- so clock40des2 deskew controls time of charge injection --- end if; if (bcedge = '1') then --- set tp to 1 on edge of clock40des2 --- tpf_q <= '1'; elsif(bc1 = '1') then tpf_q <= '0'; elsif (rising_edge(tpf_clk)) then --- set tp from long command with no phase adjustment either state --- tpf_q <= tpf_d; end if; end process; tp <= tpf_q; tpf_clk <= '1' when ((execute2 = '1') and (f_q = "0000")) else '0'; ------------------- cmd state machine ------------------------------------ process(st1,st2,can_shft_q,subadr,ttcdata) begin if((st2 = '1') and (st1 = '0')) then cmd_frame_d <= can_shft_q; elsif((st1 = '1') and (st2 = '0')) then cmd_frame_d(15 downto 8) <= subadr(7 downto 0); cmd_frame_d(7 downto 0) <= ttcdata(7 downto 0); end if; end process; process (flatch) begin if (rising_edge(flatch)) then cmd_frame_q(15 downto 0) <= cmd_frame_d(15 downto 0); end if; end process; can_output <= can_shft_q(15); f_d <= cmd_frame_q(13 downto 10); process (f_clk,clr_fq) begin if(clr_fq = '1') then f_q(0) <= '0'; f_q(1) <= '0'; f_q(2) <= '0'; f_q(3) <= '0'; elsif (rising_edge(f_clk) ) then f_q <= f_d; end if; end process; process (dq) begin if((dq(0)='0') and (dq(1)='0') and (dq(2)='0') and (dq(3)='0') ) then dqall <= '1'; else dqall <= '0'; end if; end process; process (datastr,strt_ttc) begin if( (strt_ttc = '0') ) then ldstr <= '0'; elsif(rising_edge(datastr)) then ldstr <= '1'; end if; end process; process (can_enable,strt_can) begin if( strt_can = '0' ) then lcanen <= '0'; elsif( rising_edge(can_enable) ) then lcanen <= '1'; end if; end process; strt_can <= idle and (not sending); strt_ttc <= strt_can and dqall; start1 <= (ldstr and subadr(7) and subadr(6)) when (strt_ttc = '1') else '0'; start2 <= lcanen when (strt_can = '1') else '0'; process(clock40,por) begin if(por = '0') then --power on reset-- now_cmd <= resting; elsif (rising_edge(clock40) ) then now_cmd <= next_cmd; end if; end process; process (now_cmd,start1,start2) begin case now_cmd is when resting => if (start1 = '1') then next_cmd <= strt1; elsif (start2 = '1') then next_cmd <= strt2; else next_cmd <= resting; end if; when strt1 => next_cmd <= lch1; when strt2 => next_cmd <= lch2; when lch1 => next_cmd <= lfcode; when lch2 => next_cmd <= lfcode; when lfcode => next_cmd <= excmd1; when excmd1 => next_cmd <= excmd2; when excmd2 => next_cmd <= wait1; when wait1 => next_cmd <= wait2; when wait2 => next_cmd <= wait3; when wait3 => next_cmd <= wait4; when wait4 => next_cmd <= wait5; when wait5 => next_cmd <= resting; end case; end process; -- present_cmd : process (now_cmd) begin process (now_cmd) begin case now_cmd is when resting => cmd_state_output <= "100000000"; when strt1 => cmd_state_output <= "010000000"; when strt2 => cmd_state_output <= "001000000"; when lch1 => cmd_state_output <= "010100000"; when lch2 => cmd_state_output <= "001010000"; when lfcode => cmd_state_output <= "000001000"; when excmd1 => cmd_state_output <= "000000100"; when excmd2 => cmd_state_output <= "000000010"; when wait1 => cmd_state_output <= "000000011"; when wait2 => cmd_state_output <= "000000010"; when wait3 => cmd_state_output <= "000000010"; when wait4 => cmd_state_output <= "000000010"; when wait5 => cmd_state_output <= "000000010"; end case; -- end process present_cmd; end process; process (clock40) begin if(falling_edge(clock40) ) then execute1 <= cmd_state_output(2); execute2 <= cmd_state_output(1); st1 <= cmd_state_output(7); st2 <= cmd_state_output(6); flatch <= cmd_state_output(4) or cmd_state_output(5); f_clk <= cmd_state_output(3); idle <= cmd_state_output(8); wt1 <= cmd_state_output(0); end if; end process; ------------------- sd state machine (data to 3in1) -------------------- process (smclk,sd_reset,por) begin if (sd_reset = '1' or por = '0') then now_sd <= free; elsif (rising_edge(smclk) ) then now_sd <= next_sd; end if; end process; sd_reset <= '1' when (f_q = "0110") else '0'; can_rst_clk <= execute2 when (f_q = "0111") else '0'; can_rst_d <= cmd_frame_q(0); process(can_rst_clk,can_rst_d) begin if (rising_edge(can_rst_clk) ) then can_rst_q <= can_rst_d; end if; end process; can_reset <= can_rst_q; process (now_sd,execute_latch) begin case now_sd is when free => if (execute_latch = '1') then next_sd <= s1; else next_sd <= free; end if; when s1 => next_sd <= s2; when s2 => next_sd <= s3; when s3 => next_sd <= s4; when s4 => next_sd <= s5; when s5 => next_sd <= s6; when s6 => next_sd <= s7; when s7 => next_sd <= s8; when s8 => next_sd <= s9; when s9 => next_sd <= s10; when s10 => next_sd <= s11; when s11 => next_sd <= s12; when s12 => next_sd <= s13; when s13 => next_sd <= s14; when s14 => next_sd <= s15; when s15 => next_sd <= s16; when s16 => next_sd <= s17; when s17 => next_sd <= s18; when s18 => next_sd <= s19; when s19 => next_sd <= s20; when s20 => next_sd <= s21; when s21 => next_sd <= s22; when s22 => next_sd <= s23; when s23 => next_sd <= s24; when s24 => next_sd <= s25; when s25 => next_sd <= s26; when s26 => next_sd <= s27; when s27 => next_sd <= s28; when s28 => if(f_q = "0101") then next_sd <= s29; else next_sd <= free; end if; when s29 => next_sd <= free; end case; end process; process (now_sd) begin case now_sd is when free => sd_state_output <= "001000"; when s1 => if(f_q = "0101") then sd_state_output <= "011010"; else sd_state_output <= "011000"; end if; when s2 => sd_state_output <= "010100"; when s3 => sd_state_output <= "011010"; when s4 => sd_state_output <= "011100"; when s5 => sd_state_output <= "011010"; when s6 => sd_state_output <= "011100"; when s7 => sd_state_output <= "011010"; when s8 => sd_state_output <= "011100"; when s9 => sd_state_output <= "011010"; when s10 => sd_state_output <= "011100"; when s11 => sd_state_output <= "011010"; when s12 => sd_state_output <= "011100"; when s13 => sd_state_output <= "011010"; when s14 => sd_state_output <= "011100"; when s15 => sd_state_output <= "011010"; when s16 => sd_state_output <= "011100"; when s17 => sd_state_output <= "011010"; when s18 => sd_state_output <= "011100"; when s19 => sd_state_output <= "011010"; when s20 => sd_state_output <= "011100"; when s21 => sd_state_output <= "011010"; when s22 => sd_state_output <= "011100"; when s23 => sd_state_output <= "011010"; when s24 => sd_state_output <= "011100"; when s25 => sd_state_output <= "011010"; when s26 => sd_state_output <= "011100"; when s27 => sd_state_output <= "011001"; when s28 => sd_state_output <= "011000"; when s29 => sd_state_output <= "111000"; end case; end process; process(smclk) begin if(rising_edge(smclk2) ) then sending <= sd_state_output(4); sreset <= sd_state_output(3); clock <= sd_state_output(2); clk <= sd_state_output(2); clk_internal <= sd_state_output(1); en <= sd_state_output(0); clr_fq <= sd_state_output(5); end if; end process; -- note these are offset since the first clock downstroke xfers the q's to the next d's -- -- and no shift will take place -- this is a trick to make can software look natural -- -- this way 16 clock shifts gets things in the right place for can readout -- process (f_q,execute1,execute2,can_shft_q,shft_q,can_clk,can_input) begin if ((f_q = "0101") ) then can_shft_d(15) <= '0'; can_shft_d(14) <= '0'; can_shft_d(0) <= '0'; can_shft_d(13 downto 11) <= shft_q(2 downto 0); can_shft_d(10 downto 1) <= shft_q(12 downto 3); else can_shft_d(0) <= can_input; if(falling_edge(can_clk) ) then can_shft_d(15 downto 1) <= can_shft_q(14 downto 0); end if; end if; if( (f_q = "0101") ) then can_shft_clk <= en; else can_shft_clk <= can_clk; end if; end process; process (can_shft_clk) begin if (rising_edge(can_shft_clk) ) then can_shft_q <= can_shft_d; end if; end process; tb_clk <= execute2 when (f_q = "0001") else '0'; mrb_clk0 <= execute2 when (f_q = "0010") else '0'; mrb_clk1 <= execute2 when (f_q = "0011") else '0'; mrb_clk2 <= execute2 when (f_q = "0100") else '0'; tb_d <= cmd_frame_q(5 downto 0); mrb_d(0) <= cmd_frame_q(0); mrb_d(1) <= cmd_frame_q(0); mrb_d(2) <= cmd_frame_q(0); tpf_d <= cmd_frame_q(0); tube <= tb_q; multi_sel_in <= mrb_q(0); rxw <= mrb_q(1); back_load <= mrb_q(2); process (tb_clk) begin if (rising_edge(tb_clk) ) then tb_q <= tb_d; end if; end process; process (mrb_clk0) begin if (rising_edge(mrb_clk0) ) then mrb_q(0) <= mrb_d(0); end if; end process; process (mrb_clk1) begin if (rising_edge(mrb_clk1) ) then mrb_q(1) <= mrb_d(1); end if; end process; process (mrb_clk2) begin if (rising_edge(mrb_clk2) ) then mrb_q(2) <= mrb_d(2); end if; end process; process (shft_clk,shft_d) begin if (rising_edge(shft_clk) ) then shft_q <= shft_d; end if; end process; process (ltch_clk) begin if (rising_edge(ltch_clk) ) then ltch_q <= ltch_d; end if; end process; process (sending,data_from_3in1,shft_q,clk_internal, cmd_frame_q,execute1) begin data_to_3in1 <= shft_q(12); if(sending = '0') then shft_d(12 downto 3) <= cmd_frame_q(9 downto 0); shft_d(2 downto 0) <= cmd_frame_q(12 downto 10); shft_clk <= execute1 and f_q(3); else shft_d(0) <= data_from_3in1; shft_clk <= clk_internal; if( rising_edge(smclk1) ) then shft_d(12 downto 1) <= shft_q(11 downto 0); end if; end if; end process; process(f_q) begin if(f_q = "0101") then execute <= execute2; else execute <= execute2 and f_q(3); end if; end process; process(execute,sending) begin if(sending = '1') then execute_latch <= '0'; elsif(rising_edge(execute) )then execute_latch <= '1'; end if; end process; process (clock40) variable cnt : integer range 0 to 15; begin if (rising_edge(clock40) ) then cnt := cnt + 1; end if; if( cnt = 0 ) then zero <= '1'; else zero <= '0'; end if; if( cnt = 1 ) then one <= '1'; else one <= '0'; end if; if( cnt = 2 ) then two <= '1'; else two <= '0'; end if; end process; smclk <= zero and (not clock40); smclk1 <= one and (not clock40); smclk2 <= two and (not clock40); process(f_q) begin if(f_q = "0101") then enable <= '0'; else enable <= en; end if; end process; drw_sel <= '1'; drw_sel_net <= '1'; multi_sel <= multi_sel_in; multi_sel_net <= multi_sel_in; data_out_en <= '1'; sel(37) <= drw_sel_net when (tb_q = "100101") else '0'; sel(38) <= drw_sel_net when (tb_q = "100110") else '0'; sel(39) <= drw_sel_net when (tb_q = "100111") else '0'; sel(40) <= drw_sel_net when (tb_q = "101000") else '0'; sel(41) <= drw_sel_net when (tb_q = "101001") else '0'; sel(42) <= drw_sel_net when (tb_q = "101010") else '0'; sel(43) <= drw_sel_net when (tb_q = "101011") else '0'; sel(44) <= drw_sel_net when (tb_q = "101100") else '0'; sel(45) <= drw_sel_net when (tb_q = "101101") else '0'; sel(46) <= drw_sel_net when (tb_q = "101110") else '0'; sel(47) <= drw_sel_net when (tb_q = "101111") else '0'; sel(48) <= drw_sel_net when (tb_q = "110000") else '0'; shift_in <= (drw_sel_net or multi_sel_net) when (tb_q = "111000") else '0'; latch_ext <= (drw_sel_net or multi_sel_net) when (tb_q = "111001") else '0'; ltch_clk <= clk and shift_in; ltch_d(0) <= shft_q(12); ltch_d(12 downto 1) <= ltch_q(11 downto 0); p <= ltch_q(10 downto 3); dly_en <= latch_ext; -- etc test0 <= sending; test1 <= clk_internal; test2 <= shft_clk; test3 <= shft_d(0); test4 <= shft_q(0); ss4 <= can_rst_clk; ss5 <= zero; ss6 <= one; ss7 <= two; ss9 <= idle; ss10 <= dqall; ss11 <= start1; ss12 <= can_rst_d; ss13 <= brcst2 and brcst3 and brcst4 and brcst5 and clock40des2 and clock40des1 and brcststr2; end logic_layout;