1 | library IEEE;
|
---|
2 | use IEEE.STD_LOGIC_1164.ALL;
|
---|
3 | use IEEE.STD_LOGIC_ARITH.ALL;
|
---|
4 | use IEEE.std_logic_signed.all;
|
---|
5 |
|
---|
6 | library fact_fad_lib;
|
---|
7 | use fact_fad_lib.fad_definitions.all;
|
---|
8 |
|
---|
9 |
|
---|
10 | ENTITY drs_pulser is
|
---|
11 | port (
|
---|
12 | -- input CLK; RSRLOAD and SRCLK are derived from this signal
|
---|
13 | CLK : in std_logic;
|
---|
14 | -- async reset;
|
---|
15 | reset : in std_logic;
|
---|
16 |
|
---|
17 | start_endless_mode : in std_logic;
|
---|
18 | start_read_stop_pos_mode : in std_logic;
|
---|
19 |
|
---|
20 | SROUT_in_0 : in std_logic;
|
---|
21 | SROUT_in_1 : in std_logic;
|
---|
22 | SROUT_in_2 : in std_logic;
|
---|
23 | SROUT_in_3 : in std_logic;
|
---|
24 |
|
---|
25 | -- stop_pos_0 : out std_logic_vector(9 downto 0);
|
---|
26 | -- stop_pos_1 : out std_logic_vector(9 downto 0);
|
---|
27 | -- stop_pos_2 : out std_logic_vector(9 downto 0);
|
---|
28 | -- stop_pos_3 : out std_logic_vector(9 downto 0);
|
---|
29 | stop_pos : out drs_s_cell_array_type;
|
---|
30 | stop_pos_valid : out std_logic;
|
---|
31 |
|
---|
32 | RSRLOAD : out std_logic;
|
---|
33 | SRCLK : out std_logic;
|
---|
34 | busy :out std_logic
|
---|
35 | );
|
---|
36 | end drs_pulser;
|
---|
37 |
|
---|
38 |
|
---|
39 | ARCHITECTURE behavior of drs_pulser IS
|
---|
40 |
|
---|
41 | type states is (idle, started_endless, started_read_stop_pos , waiting_e, waiting_r, running_e, running_r);
|
---|
42 | signal current_state : states := idle;
|
---|
43 | signal next_state : states := idle;
|
---|
44 | signal CEN,LEN : std_logic;
|
---|
45 |
|
---|
46 |
|
---|
47 | signal local_roi : std_logic_vector (9 downto 0):= (others => '0');
|
---|
48 |
|
---|
49 | signal flag_read_stop_pos : std_logic := '0';
|
---|
50 |
|
---|
51 | signal cell_cntr : std_logic_vector (9 downto 0);
|
---|
52 | signal cc_en : std_logic;
|
---|
53 | signal cc_reset : std_logic;
|
---|
54 |
|
---|
55 | signal wait_cntr : std_logic_vector (2 downto 0);
|
---|
56 | signal wc_en : std_logic;
|
---|
57 | signal wc_reset : std_logic;
|
---|
58 |
|
---|
59 | signal int_stop_pos_0 : std_logic_vector(9 downto 0) := (others => '0');
|
---|
60 | signal int_stop_pos_1 : std_logic_vector(9 downto 0) := (others => '0');
|
---|
61 | signal int_stop_pos_2 : std_logic_vector(9 downto 0) := (others => '0');
|
---|
62 | signal int_stop_pos_3 : std_logic_vector(9 downto 0) := (others => '0');
|
---|
63 |
|
---|
64 | begin
|
---|
65 | RSRLOAD <= (LEN and CLK);
|
---|
66 | SRCLK <= (CEN and CLK);
|
---|
67 | stop_pos(0) <= int_stop_pos_0;
|
---|
68 | stop_pos(1) <= int_stop_pos_1;
|
---|
69 | stop_pos(2) <= int_stop_pos_2;
|
---|
70 | stop_pos(3) <= int_stop_pos_3;
|
---|
71 |
|
---|
72 |
|
---|
73 |
|
---|
74 | state_register: process(clk, reset)
|
---|
75 | begin
|
---|
76 | IF reset = '1' THEN
|
---|
77 | current_state <= idle ;
|
---|
78 | ELSIF clk = '0' and clk'event THEN -- ! falling edge !
|
---|
79 | current_state <= next_state ;
|
---|
80 | END IF;
|
---|
81 | end process state_register;
|
---|
82 |
|
---|
83 | --Folgezustandsberechnung asynchron
|
---|
84 | transition: process(current_state,
|
---|
85 | start_endless_mode,
|
---|
86 | start_read_stop_pos_mode,
|
---|
87 | wait_cntr,
|
---|
88 | cell_cntr,
|
---|
89 | local_roi)
|
---|
90 | begin
|
---|
91 | CASE current_state IS
|
---|
92 | WHEN idle =>
|
---|
93 | if start_endless_mode = '1' then
|
---|
94 | next_state <= started_endless ;
|
---|
95 | elsif start_read_stop_pos_mode = '1' then
|
---|
96 | next_state <= started_read_stop_pos ;
|
---|
97 | end if;
|
---|
98 |
|
---|
99 | WHEN started_endless =>
|
---|
100 | if cell_cntr = conv_std_logic_vector(1,10) then
|
---|
101 | next_state <= waiting_e;
|
---|
102 | end if;
|
---|
103 |
|
---|
104 |
|
---|
105 |
|
---|
106 | WHEN started_read_stop_pos =>
|
---|
107 | if cell_cntr = conv_std_logic_vector(1,10) then
|
---|
108 | next_state <= waiting_r;
|
---|
109 | end if;
|
---|
110 |
|
---|
111 | WHEN waiting_e =>
|
---|
112 | if wait_cntr = conv_std_logic_vector(0,3) then
|
---|
113 | next_state <= running_e;
|
---|
114 | else
|
---|
115 | next_state <= waiting_e;
|
---|
116 | end if;
|
---|
117 |
|
---|
118 | WHEN waiting_r =>
|
---|
119 | if wait_cntr = conv_std_logic_vector(0,3) then
|
---|
120 | next_state <= running_r;
|
---|
121 | end if;
|
---|
122 |
|
---|
123 |
|
---|
124 | WHEN running_e =>
|
---|
125 | IF (start_endless_mode = '0') THEN
|
---|
126 | next_state <= idle;
|
---|
127 | END IF;
|
---|
128 |
|
---|
129 | WHEN running_r =>
|
---|
130 | if cell_cntr >= local_roi THEN
|
---|
131 | next_state <= idle;
|
---|
132 | end if;
|
---|
133 | END CASE;
|
---|
134 | end process transition;
|
---|
135 |
|
---|
136 | output_proc: process(current_state) --Ausgangsberechnung synchron, da current_state sich nur synchron aendert
|
---|
137 | begin
|
---|
138 | case current_state is
|
---|
139 |
|
---|
140 | when idle =>
|
---|
141 | local_roi <= (others => '0');
|
---|
142 | flag_read_stop_pos <= '0';
|
---|
143 | stop_pos_valid <= '1';
|
---|
144 | LEN <= '0'; CEN <= '0';
|
---|
145 | busy <= '0';
|
---|
146 | cc_en <= '0'; cc_reset <= '1';
|
---|
147 | wc_en <= '0'; wc_reset <= '0';
|
---|
148 |
|
---|
149 | when started_endless =>
|
---|
150 | local_roi <= "0111111111";
|
---|
151 | flag_read_stop_pos <= '0';
|
---|
152 | stop_pos_valid <= '0';
|
---|
153 | LEN <= '1'; CEN <= '0';
|
---|
154 | busy <= '1';
|
---|
155 | cc_en <= '1'; cc_reset <= '0';
|
---|
156 | wc_en <= '0'; wc_reset <= '1';
|
---|
157 |
|
---|
158 | when started_read_stop_pos =>
|
---|
159 | local_roi <= conv_std_logic_vector(11,10);
|
---|
160 | flag_read_stop_pos <= '1';
|
---|
161 | stop_pos_valid <= '0';
|
---|
162 | LEN <= '1'; CEN <= '0';
|
---|
163 | busy <= '1';
|
---|
164 | cc_en <= '1'; cc_reset <= '0';
|
---|
165 | wc_en <= '0'; wc_reset <= '1';
|
---|
166 |
|
---|
167 | when waiting_e | waiting_r =>
|
---|
168 | local_roi <= local_roi;
|
---|
169 | stop_pos_valid <= '0';
|
---|
170 | busy <= '1';
|
---|
171 | LEN <= '0'; CEN <= '0';
|
---|
172 | cc_en <= '0'; cc_reset <= '0';
|
---|
173 | wc_en <= '1'; wc_reset <= '0';
|
---|
174 |
|
---|
175 | when running_e =>
|
---|
176 | flag_read_stop_pos <= '0';
|
---|
177 | stop_pos_valid <= '0';
|
---|
178 | LEN <= '0'; CEN <= '1';
|
---|
179 | cc_en <= '1'; cc_reset <= '0';
|
---|
180 | wc_en <= '0'; wc_reset <= '0';
|
---|
181 | busy <= '1';
|
---|
182 |
|
---|
183 | when running_r =>
|
---|
184 | flag_read_stop_pos <= '1';
|
---|
185 | stop_pos_valid <= '0';
|
---|
186 | LEN <= '0'; CEN <= '1';
|
---|
187 | cc_en <= '1'; cc_reset <= '0';
|
---|
188 | wc_en <= '0'; wc_reset <= '0';
|
---|
189 | busy <= '1';
|
---|
190 | end case;
|
---|
191 | end process output_proc;
|
---|
192 |
|
---|
193 |
|
---|
194 | cellcounter: process (clk, cc_reset) begin
|
---|
195 |
|
---|
196 | if (cc_reset = '1') then
|
---|
197 | cell_cntr <= (others=>'0');
|
---|
198 | elsif (rising_edge(clk)) then
|
---|
199 | if (cc_en = '1') then
|
---|
200 | cell_cntr <= cell_cntr + 1;
|
---|
201 | end if;
|
---|
202 | end if;
|
---|
203 |
|
---|
204 | end process cellcounter;
|
---|
205 |
|
---|
206 |
|
---|
207 | waitcounter: process (clk, wc_reset) begin
|
---|
208 | if (wc_reset = '1') then
|
---|
209 | wait_cntr <= "011"; -- RSRLOAD -> warte 3 -> SRCLK
|
---|
210 | elsif (rising_edge(clk)) then
|
---|
211 | if (wc_en = '1') then
|
---|
212 | wait_cntr <= wait_cntr - 1;
|
---|
213 | end if;
|
---|
214 | end if;
|
---|
215 | end process waitcounter;
|
---|
216 |
|
---|
217 | -- laut DRS4_rev09.pdf Seite 13 Figure 15
|
---|
218 | -- funktioniert das auslesen der Stop bzw. Startadresse so:
|
---|
219 | -- Sende 1x RSRLOAD- und mind. 9 SRCLK- pulse und sample SROUT zur
|
---|
220 | -- steigenden Flanke von SRCLK.
|
---|
221 | -- MSB first LSB last, kommen dann die 10 bits,
|
---|
222 | -- die die Stopposition darstellen.
|
---|
223 | --
|
---|
224 | -- diese Architecture liefert immer dann eine steigende Flanke
|
---|
225 | -- auf RSRCLK, wenn CLK eine steigende Flanke hat und CEN='1' ist.
|
---|
226 | -- Die an SROUT zur steigenden Flanke anliegenden Werte werden wie in einem Schieberegister
|
---|
227 | -- Schritt fuer Schritt in die stop_pos_x vectoren geschoben.
|
---|
228 | --
|
---|
229 | -- wenn sie 10 schritte weit reingschoben wurden, ist der process fertig.
|
---|
230 | -- es gibt keinen eigenen counter fuer die 10 schritte, der cell counter kann hier
|
---|
231 | -- missbraucht werden.
|
---|
232 | --
|
---|
233 | -- da der process eine steigende flanke auf SRCLK braucht um SROUT zu sampeln
|
---|
234 | -- wird im Prinzip ein Puls aud SRCLK *zuviel* erzeugt, das ist aber egal...
|
---|
235 | --
|
---|
236 | stop_pos_reader: process (CEN, clk, flag_read_stop_pos)
|
---|
237 | begin
|
---|
238 | IF (flag_read_stop_pos = '1') THEN -- nur wenn ich im read_stop_mode bin, laeuft dieser process
|
---|
239 | IF (CEN = '1') THEN -- nur wenn CEN='1' ist kommen SRCLK pulse raus.
|
---|
240 | IF (rising_edge(CLK)) THEN -- wenn steigende Flanke, dann SROUT samplen.
|
---|
241 | int_stop_pos_0 <= int_stop_pos_0(8 downto 0) & SROUT_in_0;
|
---|
242 | int_stop_pos_1 <= int_stop_pos_1(8 downto 0) & SROUT_in_1;
|
---|
243 | int_stop_pos_2 <= int_stop_pos_2(8 downto 0) & SROUT_in_2;
|
---|
244 | int_stop_pos_3 <= int_stop_pos_3(8 downto 0) & SROUT_in_3;
|
---|
245 |
|
---|
246 | END IF; -- rising edge CLK
|
---|
247 | END IF; -- CEN ='1'
|
---|
248 | END IF; -- flag_read_stop_pos = '1'
|
---|
249 | end process stop_pos_reader;
|
---|
250 |
|
---|
251 | end behavior; |
---|