---------------------------------------------------------------------------- -- Lawrence Berkeley National Laboratory (c) 1997 -- BaBar Trigger Electronics ---------------------------------------------------------------------------- -- Description: -- State machine, controlling the latching of commands and data, as well -- as the strobe timing. ---------------------------------------------------------------------------- -- Structure: -- sm: -- state machine body: 4 tag (subcommand) states, 16 data states and -- 4 end states. The machine starts, runs through the tag states if -- a 1 is recieved on the clink. After the tag states the already -- decoded command causes a jump to the end state, or normal operation. -- The state machine can loop several times over all 16 data states, -- before terminating by going through the 4 end stages, and -- returning to idle. -- output:- output generator for latches. Output is one tick after the state. -- g_out:-- output generator for comand strobe. ---------------------------------------------------------------------------- -- Timing: -- adv_cmd_str is generated in state 12 after the first bit of command is -- recieved, this is the 4th state after the start bit '1' was in shift -- register bit three. The strobe is sent out on the 13th cycle after -- the begin of the command. -- Shift register bit three was chosen as startup bit for the state -- machine, since this allowed earliest possible latching of the -- 5 bit command, thereby leaving several cycles for decoding. ---------------------------------------------------------------------------- -- Author: Armin Karcher -- History: -- Karcher 03/97 - First Version ---------------------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; ---------------------------------------------------------------------------- --PORT DECLARATION ---------------------------------------------------------------------------- entity sm0_clink is port( clk : in std_logic; -- clk60 input, distributed rst : in std_logic; -- global reset shift_3 : in std_logic; -- shift register bit 3 (see timing) cmd_ext : in std_logic; -- external command (generate c_str) cmd_end : in std_logic; -- command end; terminate transfer cycle cmd_lng : in std_logic; -- command long; do not terminate after state t3 nxt_wrd : out std_logic; -- one data word has been recieved adv_cmd_str : out std_logic; -- command strobe (see timing) latch_dt_out : out std_logic; -- latch data latch_t : out std_logic; -- latch trigger tag/sub command latch_cmd : out std_logic -- latch command ); end sm0_clink; architecture rtl of sm0_clink is ---------------------------------------------------------------------------- --SIGNAL DECLARATION ---------------------------------------------------------------------------- type states is (idle,c_latch,t0,t1,t2,t3,t_latch,e1,e2,e3,e4, a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a_latch); signal state : states; signal c_str : std_logic; -- command strobe (see timing) signal latch_dt : std_logic; -- latch data begin ---------------------------------------------------------------------------- --PROCESS DECLARATION ---------------------------------------------------------------------------- --process sm: glitch free Mealy state machine sm: process (clk,rst) begin if (rst = '1') then -- reset all variables state <= idle; elsif (clk'event and clk = '1') then -- rising edge case state is when idle => if (shift_3 = '1') then state <= c_latch; end if; when c_latch => state <= t0; when t0 => state <= t1; when t1 => state <= t2; when t2 => state <= t3; when t3 => state <= t_latch; when t_latch => if (cmd_lng = '0') then state <= e1; else state <= a0; end if; when a0 => state <= a1; when a1 => state <= a2; when a2 => state <= a3; when a3 => state <= a4; when a4 => state <= a5; when a5 => state <= a6; when a6 => state <= a7; when a7 => state <= a8; when a8 => state <= a9; when a9 => state <= a10; when a10 => state <= a11; when a11 => state <= a12; when a12 => state <= a13; when a13 => state <= a14; when a14 => state <= a_latch; when a_latch => if (cmd_end = '1') then state <= e1; else state <= a0; end if; when e1 => state <= e2; when e2 => state <= e3; when e3 => state <= e4; when e4 => state <= idle; when others => state <= idle; end case; end if; end process sm; output: process (state,clk,rst) begin if (rst = '1') then -- reset all variables nxt_wrd <= '0'; latch_cmd <= '0'; latch_dt <= '0'; latch_t <= '0'; elsif (clk'event and clk = '1') then -- rising edge nxt_wrd <= latch_dt AND NOT cmd_end; case state is when c_latch => latch_cmd <= '1'; latch_dt <= '0'; latch_t <= '0'; when t_latch => latch_cmd <= '0'; latch_dt <= '0'; latch_t <= '1'; when a_latch => latch_cmd <= '0'; latch_dt <= '1'; latch_t <= '0'; when others => latch_cmd <= '0'; latch_dt <= '0'; latch_t <= '0'; end case; end if; end process output; g_out: process (clk,rst) begin if (rst = '1') then -- reset all variables c_str <= '0'; elsif (clk'event and clk = '1') then -- rising edge if (state = t3) then c_str <= cmd_ext; -- output on tick 13 after recieving the 0 else c_str <= '0'; end if; end if; end process g_out; ---------------------------------------------------------------------------- --OUTPUT ASSIGNMENTS ---------------------------------------------------------------------------- latch_dt_out <= latch_dt; adv_cmd_str <= c_str; end rtl;