source: firmware/FTU/rs485/FTU_rs485_interpreter.vhd@ 10102

Last change on this file since 10102 was 10051, checked in by weitzel, 14 years ago
some code cleaning and more comments for FTU firmware
File size: 11.3 KB
Line 
1----------------------------------------------------------------------------------
2-- Company: ETH Zurich, Institute for Particle Physics
3-- Engineer: Q. Weitzel, P. Vogler
4--
5-- Create Date: 09/13/2010
6-- Design Name:
7-- Module Name: FTU_rs485_interpreter - Behavioral
8-- Project Name:
9-- Target Devices:
10-- Tool versions:
11-- Description: command interpreter of FTU RS485 module
12--
13-- Dependencies:
14--
15-- Revision:
16-- Revision 0.01 - File Created
17-- Additional Comments:
18--
19----------------------------------------------------------------------------------
20
21library IEEE;
22use IEEE.STD_LOGIC_1164.ALL;
23use IEEE.STD_LOGIC_ARITH.ALL;
24use IEEE.STD_LOGIC_UNSIGNED.ALL;
25
26library ftu_definitions;
27USE ftu_definitions.ftu_array_types.all;
28USE ftu_definitions.ftu_constants.all;
29
30---- Uncomment the following library declaration if instantiating
31---- any Xilinx primitives in this code.
32--library UNISIM;
33--use UNISIM.VComponents.all;
34
35entity FTU_rs485_interpreter is
36 port(
37 clk : IN std_logic;
38 data_block : IN std_logic_vector(RS485_BLOCK_WIDTH - 1 downto 0);
39 block_valid : IN std_logic;
40 brd_add : IN std_logic_vector(5 downto 0);
41 crc_error_cnt : OUT integer range 0 to 255 := 0;
42 int_new_DACs : OUT std_logic := '0';
43 int_new_enables : OUT std_logic := '0';
44 int_new_prescaling : OUT std_logic := '0';
45 int_read_rates : OUT std_logic := '0';
46 int_read_DACs : OUT std_logic := '0';
47 int_read_enables : OUT std_logic := '0';
48 int_read_prescaling : OUT std_logic := '0';
49 int_ping_pong : OUT std_logic := '0';
50 dac_array_rs485_out : OUT dac_array_type;
51 enable_array_rs485_out : OUT enable_array_type;
52 prescaling_rs485_out : OUT STD_LOGIC_VECTOR(7 downto 0)
53 );
54end FTU_rs485_interpreter;
55
56architecture Behavioral of FTU_rs485_interpreter is
57
58 signal block_valid_sr : std_logic_vector(3 downto 0) := (others => '0');
59 signal reset_crc_sig : std_logic := '0';
60 signal crc_enable_sig : std_logic := '0';
61 signal crc_match_sig : std_logic := '0';
62 signal data_block_sig : std_logic_vector(RS485_BLOCK_WIDTH - 1 downto 0) := (others => '0');
63 signal crc_error_cntr : integer range 0 to 255 := 0;
64
65 signal dac_array_rs485_out_sig : dac_array_type := DEFAULT_DAC;
66 signal enable_array_rs485_out_sig : enable_array_type := DEFAULT_ENABLE;
67 signal prescaling_rs485_out_sig : STD_LOGIC_VECTOR(7 downto 0) := conv_std_logic_vector(DEFAULT_PRESCALING,8);
68
69 type FTU_rs485_interpreter_StateType is (INIT, WAIT_FOR_DATA, WAIT_CRC, CHECK_CRC, CHECK_HEADER, DECODE);
70 signal FTU_rs485_interpreter_State : FTU_rs485_interpreter_StateType;
71
72 component ucrc_par
73 generic(
74 POLYNOMIAL : std_logic_vector;
75 INIT_VALUE : std_logic_vector;
76 DATA_WIDTH : integer range 2 to 256;
77 SYNC_RESET : integer range 0 to 1
78 );
79 port(
80 clk_i : in std_logic;
81 rst_i : in std_logic;
82 clken_i : in std_logic;
83 data_i : in std_logic_vector(DATA_WIDTH - 1 downto 0);
84 match_o : out std_logic;
85 crc_o : out std_logic_vector(POLYNOMIAL'length - 1 downto 0)
86 );
87 end component;
88
89begin
90
91 Inst_ucrc_par : ucrc_par
92 generic map(
93 POLYNOMIAL => CRC_POLYNOMIAL,
94 INIT_VALUE => CRC_INIT_VALUE,
95 DATA_WIDTH => 224,
96 SYNC_RESET => 1
97 )
98 port map(
99 clk_i => clk,
100 rst_i => reset_crc_sig,
101 clken_i => crc_enable_sig,
102 data_i => data_block_sig,
103 match_o => crc_match_sig,
104 crc_o => open
105 );
106
107 FTU_rs485_interpreter_FSM: process (clk)
108 begin
109 if Rising_edge(clk) then
110 case FTU_rs485_interpreter_State is
111
112 when INIT => -- reset CRC register
113 reset_crc_sig <= '1';
114 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
115
116 when WAIT_FOR_DATA => -- default state, waiting for valid 28-byte block
117 block_valid_sr <= block_valid_sr(2 downto 0) & block_valid;
118 int_new_DACs <= '0';
119 int_new_enables <= '0';
120 int_new_prescaling <= '0';
121 int_read_rates <= '0';
122 int_read_DACs <= '0';
123 int_read_enables <= '0';
124 int_read_prescaling <= '0';
125 int_ping_pong <= '0';
126 if (block_valid_sr(3 downto 2) = "01") then -- rising edge of valid signal
127 crc_enable_sig <= '1';
128 data_block_sig <= data_block;
129 FTU_rs485_interpreter_State <= WAIT_CRC;
130 else
131 crc_enable_sig <= '0';
132 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
133 end if;
134 reset_crc_sig <= '0';
135
136 when WAIT_CRC => -- wait one cycle for CRC calculation
137 crc_enable_sig <= '0';
138 FTU_rs485_interpreter_State <= CHECK_CRC;
139
140 when CHECK_CRC => -- check whether CRC matches
141 reset_crc_sig <= '1';
142 if (crc_match_sig = '1') then
143 FTU_rs485_interpreter_State <= CHECK_HEADER;
144 crc_error_cnt <= crc_error_cntr;
145 crc_error_cntr <= 0;
146 else
147 if crc_error_cntr < 255 then
148 crc_error_cntr <= crc_error_cntr + 1;
149 end if;
150 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
151 end if;
152
153 when CHECK_HEADER => -- check start delimiter and addresses
154 int_new_DACs <= '0';
155 int_new_enables <= '0';
156 int_new_prescaling <= '0';
157 int_read_rates <= '0';
158 int_read_DACs <= '0';
159 int_read_enables <= '0';
160 int_read_prescaling <= '0';
161 int_ping_pong <= '0';
162 if (data_block(7 downto 0) = RS485_START_DELIM) and
163 (data_block(15 downto 8) = ("00" & brd_add)) and
164 (data_block(23 downto 16) = FTM_ADDRESS) then
165 FTU_rs485_interpreter_State <= DECODE;
166 else
167 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
168 end if;
169 reset_crc_sig <= '0';
170
171 when DECODE => -- decode instruction
172 if(data_block(39 downto 32) = "00000000") then -- set DACs
173 int_new_DACs <= '1';
174 int_new_enables <= '0';
175 int_new_prescaling <= '0';
176 int_read_rates <= '0';
177 int_read_DACs <= '0';
178 int_read_enables <= '0';
179 int_read_prescaling <= '0';
180 int_ping_pong <= '0';
181 dac_array_rs485_out_sig <= (conv_integer(unsigned(data_block(51 downto 40))),
182 conv_integer(unsigned(data_block(67 downto 56))),
183 conv_integer(unsigned(data_block(83 downto 72))),
184 conv_integer(unsigned(data_block(99 downto 88))),
185 DEFAULT_DAC(4),
186 DEFAULT_DAC(5),
187 DEFAULT_DAC(6),
188 conv_integer(unsigned(data_block(115 downto 104)))
189 );
190 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
191 elsif (data_block(39 downto 32) = "00000001") then -- read DACs
192 int_new_DACs <= '0';
193 int_new_enables <= '0';
194 int_new_prescaling <= '0';
195 int_read_rates <= '0';
196 int_read_DACs <= '1';
197 int_read_enables <= '0';
198 int_read_prescaling <= '0';
199 int_ping_pong <= '0';
200 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
201 elsif (data_block(39 downto 32) = "00000010") then -- read rates
202 int_new_DACs <= '0';
203 int_new_enables <= '0';
204 int_new_prescaling <= '0';
205 int_read_rates <= '1';
206 int_read_DACs <= '0';
207 int_read_enables <= '0';
208 int_read_prescaling <= '0';
209 int_ping_pong <= '0';
210 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
211 elsif (data_block(39 downto 32) = "00000011") then -- set enables
212 int_new_DACs <= '0';
213 int_new_enables <= '1';
214 int_new_prescaling <= '0';
215 int_read_rates <= '0';
216 int_read_DACs <= '0';
217 int_read_enables <= '0';
218 int_read_prescaling <= '0';
219 int_ping_pong <= '0';
220 enable_array_rs485_out_sig <= (data_block(55 downto 40),
221 data_block(71 downto 56),
222 data_block(87 downto 72),
223 data_block(103 downto 88)
224 );
225 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
226 elsif (data_block(39 downto 32) = "00000100") then -- read enables
227 int_new_DACs <= '0';
228 int_new_enables <= '0';
229 int_new_prescaling <= '0';
230 int_read_rates <= '0';
231 int_read_DACs <= '0';
232 int_read_enables <= '1';
233 int_read_prescaling <= '0';
234 int_ping_pong <= '0';
235 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
236 elsif (data_block(39 downto 32) = "00000110") then -- set counter mode
237 int_new_DACs <= '0';
238 int_new_enables <= '0';
239 int_new_prescaling <= '1';
240 int_read_rates <= '0';
241 int_read_DACs <= '0';
242 int_read_enables <= '0';
243 int_read_prescaling <= '0';
244 int_ping_pong <= '0';
245 prescaling_rs485_out_sig <= data_block(47 downto 40);
246 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
247 elsif (data_block(39 downto 32) = "00000111") then -- read counter mode
248 int_new_DACs <= '0';
249 int_new_enables <= '0';
250 int_new_prescaling <= '0';
251 int_read_rates <= '0';
252 int_read_DACs <= '0';
253 int_read_enables <= '0';
254 int_read_prescaling <= '1';
255 int_ping_pong <= '0';
256 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
257 elsif (data_block(39 downto 32) = "00000101") then -- ping pong
258 int_new_DACs <= '0';
259 int_new_enables <= '0';
260 int_new_prescaling <= '0';
261 int_read_rates <= '0';
262 int_read_DACs <= '0';
263 int_read_enables <= '0';
264 int_read_prescaling <= '0';
265 int_ping_pong <= '1';
266 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
267 else
268 int_new_DACs <= '0';
269 int_new_enables <= '0';
270 int_new_prescaling <= '0';
271 int_read_rates <= '0';
272 int_read_DACs <= '0';
273 int_read_enables <= '0';
274 int_read_prescaling <= '0';
275 int_ping_pong <= '0';
276 FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
277 end if;
278
279 end case;
280 end if;
281 end process FTU_rs485_interpreter_FSM;
282
283 dac_array_rs485_out <= dac_array_rs485_out_sig;
284 enable_array_rs485_out <= enable_array_rs485_out_sig;
285 prescaling_rs485_out <= prescaling_rs485_out_sig;
286
287end Behavioral;
Note: See TracBrowser for help on using the repository browser.