source: firmware/FAD/FACT_FAD_20MHz_VAR_PS/FACT_FAD_lib/hdl/phase_shifter.vhd.bak @ 10129

Last change on this file since 10129 was 10129, checked in by neise, 10 years ago
checking before change of Event Header structure. added REFCLK counter and ADC CLK PS output. In case of missing REFCLK, DENEABLE should be pulled low. (untested)
File size: 4.4 KB
Line 
1--
2-- phase_shifter.vhd
3--
4-- implements interface between w5300_modul.vhd
5-- and clock_generator_variable_PS_struct.vhd
6--
7--
8--
9library ieee;
10use ieee.std_logic_1164.all;
11use IEEE.NUMERIC_STD.all;
12
13library FACT_FAD_lib;
14use FACT_FAD_lib.fad_definitions.all;
15
16
17ENTITY phase_shifter IS
18
19        PORT(
20                CLK : IN std_logic;
21                rst : in std_logic; --asynch in of DCM
22               
23                -- interface to: clock_generator_variable_PS_struct.vhd
24                PSCLK : OUT std_logic;
25                PSEN : OUT std_logic := '0';
26                PSINCDEC : OUT std_logic := '1'; -- default is 'incrementing'
27                PSDONE : IN std_logic; -- will pulse once, if phase shifting was done.
28                LOCKED : IN std_logic;
29               
30               
31                -- interface to: w5300_modul.vhd
32                shift_phase : IN std_logic;
33                direction : IN std_logic; -- corresponds to 'PSINCDEC'
34
35                -- status:
36                shifting : OUT std_logic := '0';
37                ready : OUT std_logic := '0';
38                offset : OUT std_logic_vector (7 DOWNTO 0) := (OTHERS => '0');
39                DCM_locked : OUT std_logic
40               
41        );
42END phase_shifter;
43
44-- usage:
45-- w5300_modul will set 'direction' to desired direction and pulse 'shift_phase' once
46-- to initiate a phase shifting process.
47-- while phase shifting, 'shifting' will show '1' and further pulses will be discarded.
48-- 'offset' shows the number of phase_shift steps that have been performed.
49-- ready is high, when DCM is LOCKED and not phase_shifting.
50-- DCM_status is a copy, of the STATUS input.
51-- DCM_locked is a copy of LOCKED
52--
53-- how it works internally:
54-- PSCLK is connected to clk, always.
55--
56-- main FSM goes from init to ready, when LOCKED is high.
57-- main FSM goes from ready to shifting, when shift_phase goes high.
58--              when in shifting:
59--                      PSINCDEC is set to 'direction'
60--                      PSEN is set high
61--                      shifting is set high
62--                      next state waiting-for-done is entered
63--
64--              when in waiting-for-done:
65--                      PSEN is set low
66--                      if PSDONE is found to be high.
67--                      shifting is set low and state ready is entered.
68--
69--      whenever LOCKED goes low FSM enters 'init' state
70--              when in init state:
71--                      'ready' is set low
72
73architecture first_behave of phase_shifter is
74  constant OFFS_MIN : integer := -128;
75  constant OFFS_MAX : integer := 127;
76   
77        type states is (INIT, READY_STATE, SHIFTING_STATE, WAITINGFORDONE);
78        signal state,next_state : states := INIT;
79       
80        signal local_direction : std_logic;
81        signal offset_int : integer range OFFS_MIN to OFFS_MAX := 0;
82       
83       
84
85begin
86
87-- concurrent statements:
88DCM_locked <= LOCKED;
89PSCLK <= CLK;
90offset <= std_logic_vector(to_signed(offset_int,8));
91
92  -- MAIN FSM: go to next state if rising edge, or to INIT if LOCKED not high.
93  FSM_Registers: process(CLK, LOCKED, rst)
94  begin
95    if Rising_edge(rst) then
96      state <= INIT;
97    elsif LOCKED = '0' then
98      state <= INIT;
99    elsif Rising_edge(CLK) then
100      state <= next_state;
101    end if;
102  end process;
103
104  -- MAIN FSM
105  FSM_logic: process(state, PSDONE, LOCKED, shift_phase, direction, local_direction)
106  begin
107    next_state <= state;
108    case state is
109       
110        -- INIT state: here the FSM is idling, when LOCKED is not HIGH.
111    when INIT =>
112    ready <= '0';
113    offset_int <= 0;
114                shifting <= '0';
115                PSEN <= '0';
116                if (LOCKED = '1') then
117                        next_state <= READY_STATE;
118                else
119                        next_state <= INIT;
120                end if;
121       
122        -- READY_STATE state: here FSM is waiting for the 'shift_phase' to go high
123    when READY_STATE =>
124        ready <= '1';
125                shifting <= '0';
126                PSEN <= '0';
127        if (shift_phase = '1') then
128                        next_state <= SHIFTING_STATE;
129                        local_direction <= direction; -- direction is sampled, once 'shift_phase' goes high
130        else
131                        next_state <= READY_STATE;
132        end if;
133       
134        -- SHIFTING_STATE state: PSENC is set HIGH here and set low in the next state.
135        when SHIFTING_STATE =>
136                ready <= '1';
137                shifting <= '1';
138                PSEN <= '1';
139                PSINCDEC <= local_direction; -- this is the value of 'direction', when 'shift_phase' went up.
140                next_state <= WAITINGFORDONE;
141       
142        -- WAITINGFORDONE state: PSENC is set LOW, ensuring that is was high only one clock cycle.
143        when WAITINGFORDONE =>
144                ready <= '1';
145                shifting <= '1';
146                PSEN <= '0';
147        if (PSDONE = '1') then
148                             next_state <= READY_STATE;
149                             if (local_direction = '1') then
150                               if (offset_int < OFFS_MAX) then
151                                 offset_int <= offset_int + 1;
152                               end if;
153                             else
154                               if (offset_int > OFFS_MIN) then
155                                 offset_int <= offset_int - 1;
156                               end if;
157                             end if;
158        else
159                             next_state <= WAITINGFORDONE;
160        end if;
161       
162    end case;
163  end process;
164
165
166
167end first_behave;
Note: See TracBrowser for help on using the repository browser.