source: firmware/FTM/ftu_control/FTM_ftu_rs485_interpreter.vhd @ 10232

Last change on this file since 10232 was 10232, checked in by weitzel, 9 years ago
bugfix in FTM_ftu_rs485_interpreter
File size: 7.9 KB
Line 
1----------------------------------------------------------------------------------
2-- Company:        ETH Zurich, Institute for Particle Physics
3-- Engineer:       Q. Weitzel
4--
5-- Create Date:    02/04/2011
6-- Design Name:
7-- Module Name:    FTM_ftu_rs485_interpreter - Behavioral
8-- Project Name:
9-- Target Devices:
10-- Tool versions:
11-- Description:    data interpreter of FTM RS485 module for FTU communication
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 ftm_definitions;
27USE ftm_definitions.ftm_array_types.all;
28USE ftm_definitions.ftm_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 FTM_ftu_rs485_interpreter is
36  port(
37    clk               : IN  std_logic;
38    data_block        : IN  std_logic_vector(FTU_RS485_BLOCK_WIDTH - 1 downto 0);  -- from receiver
39    block_valid       : IN  std_logic;  -- from receiver
40    crc               : IN  std_logic_vector(7 downto 0);  -- from ucrc_par
41    FTU_brd_add       : IN  std_logic_vector(5 downto 0);  -- from FTM_ftu_control FSM
42    FTU_command       : IN  std_logic_vector(7 downto 0);  -- from FTM_ftu_control FSM
43    reset_crc         : OUT std_logic := '0';
44    enable_crc        : OUT std_logic := '0';
45    FTU_answer_ok     : OUT std_logic := '0';
46    FTU_dac_array     : OUT FTU_dac_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0'), (others => '0'));
47    FTU_enable_array  : OUT FTU_enable_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0'));
48    FTU_rate_array    : OUT FTU_rate_array_type := ((others => '0'), (others => '0'), (others => '0'), (others => '0'), (others => '0'));
49    FTU_prescaling    : OUT std_logic_vector(7 downto 0) := (others => '0');
50    FTU_crc_error_cnt : OUT std_logic_vector(7 downto 0) := (others => '0');
51    FTU_dna           : OUT std_logic_vector(63 downto 0) := (others => '0')
52  );
53end FTM_ftu_rs485_interpreter;
54
55architecture Behavioral of FTM_ftu_rs485_interpreter is
56
57  signal block_valid_sr : std_logic_vector(3 downto 0) := (others => '0');
58 
59  type FTM_ftu_rs485_interpreter_StateType is (INIT, WAIT_FOR_DATA, WAIT_CRC, CHECK_CRC, CHECK_HEADER, CHECK_CMD, DECODE);
60  signal FTM_ftu_rs485_interpreter_State : FTM_ftu_rs485_interpreter_StateType;
61
62begin
63 
64  FTM_ftu_rs485_interpreter_FSM: process (clk)
65  begin
66    if Rising_edge(clk) then
67      case FTM_ftu_rs485_interpreter_State is
68
69        when INIT =>  -- reset CRC register
70          reset_crc <= '1';
71          FTU_answer_ok <= '0';
72          FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
73       
74        when WAIT_FOR_DATA => -- default state, waiting for valid 28-byte block
75          block_valid_sr <= block_valid_sr(2 downto 0) & block_valid;
76          if (block_valid_sr(3 downto 2) = "01") then  -- rising edge of valid signal
77            enable_crc <= '1';
78            FTM_ftu_rs485_interpreter_State <= WAIT_CRC;
79          else
80            enable_crc <= '0';
81            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
82          end if;
83          reset_crc <= '0';
84          FTU_answer_ok <= '0';
85
86        when WAIT_CRC =>  -- wait one cycle for CRC calculation
87          enable_crc <= '0';
88          FTU_answer_ok <= '0';
89          FTM_ftu_rs485_interpreter_State <= CHECK_CRC;
90         
91        when CHECK_CRC =>  -- check whether CRC matches
92          reset_crc <= '1';
93          FTU_answer_ok <= '0';
94          if ( crc = data_block((FTU_RS485_BLOCK_WIDTH - 1) downto (FTU_RS485_BLOCK_WIDTH - 8)) ) then
95            FTM_ftu_rs485_interpreter_State <= CHECK_HEADER;
96          else
97            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
98          end if;
99         
100        when CHECK_HEADER => -- check start delimiter and addresses
101          if (data_block(7 downto 0) = FTU_RS485_START_DELIM) and
102             (data_block(15 downto 8) = FTM_ADDRESS) and 
103             (data_block(23 downto 16) = ("00" & FTU_brd_add)) then
104            FTM_ftu_rs485_interpreter_State <= CHECK_CMD;
105          else
106            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
107          end if;
108          reset_crc <= '0';
109          FTU_answer_ok <= '0';
110
111        when CHECK_CMD => -- check command
112          reset_crc <= '0';
113          if (data_block(39 downto 32) = FTU_command) then
114            FTM_ftu_rs485_interpreter_State <= DECODE;
115            FTU_answer_ok <= '1';
116          else
117            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
118            FTU_answer_ok <= '0';
119          end if;
120         
121        when DECODE => -- decode instruction
122          FTU_answer_ok <= '0';
123          if(data_block(39 downto 32) = "00000000") then -- set DACs
124            FTU_dac_array <= (data_block( 55 downto  40),
125                              data_block( 71 downto  56),
126                              data_block( 87 downto  72),
127                              data_block(103 downto  88),
128                              data_block(119 downto 104)
129                              );
130            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
131          elsif (data_block(39 downto 32) = "00000001") then -- read DACs
132            FTU_dac_array <= (data_block( 55 downto  40),
133                              data_block( 71 downto  56),
134                              data_block( 87 downto  72),
135                              data_block(103 downto  88),
136                              data_block(119 downto 104)
137                              );
138            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
139          elsif (data_block(39 downto 32) = "00000010") then -- read rates
140            FTU_rate_array <= (data_block( 71 downto  40),
141                               data_block(103 downto  72),
142                               data_block(135 downto 104),
143                               data_block(167 downto 136),
144                               data_block(199 downto 168)                               
145                               );
146            FTU_crc_error_cnt <= data_block(215 downto 208);
147            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
148          elsif (data_block(39 downto 32) = "00000011") then -- set enables
149            FTU_enable_array <= (data_block( 55 downto 40),
150                                 data_block( 71 downto 56),
151                                 data_block( 87 downto 72),
152                                 data_block(103 downto 88)
153                                 );
154            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
155          elsif (data_block(39 downto 32) = "00000100") then -- read enables
156            FTU_enable_array <= (data_block( 55 downto 40),
157                                 data_block( 71 downto 56),
158                                 data_block( 87 downto 72),
159                                 data_block(103 downto 88)
160                                 );
161            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
162          elsif (data_block(39 downto 32) = "00000110") then -- set counter mode
163            FTU_prescaling <= data_block(47 downto 40);
164            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
165          elsif (data_block(39 downto 32) = "00000111") then -- read counter mode
166            FTU_prescaling <= data_block(47 downto 40);
167            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
168          elsif (data_block(39 downto 32) = "00000101") then -- ping pong
169            FTU_dna <= data_block(103 downto 40);
170            FTU_crc_error_cnt <= data_block(215 downto 208);
171            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
172          else
173            FTM_ftu_rs485_interpreter_State <= WAIT_FOR_DATA;
174          end if;
175         
176      end case;
177    end if;
178  end process FTM_ftu_rs485_interpreter_FSM;
179 
180end Behavioral;
Note: See TracBrowser for help on using the repository browser.