OpenCores
URL https://opencores.org/ocsvn/aes3rx/aes3rx/trunk

Subversion Repositories aes3rx

[/] [aes3rx/] [trunk/] [rtl/] [vhdl/] [aes3rx.vhd] - Blame information for rev 8

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 nohous
----------------------------------------------------------------------------------
2
-- Company:  Czech Television
3
-- Engineer: Petr Nohavica
4
-- 
5
-- Create Date:    09:02:45 05/09/2009 
6
-- Module Name:    aes3rx - Behavioral 
7
-- Project Name:   AES3 minimalistic receiver
8
-- Target Devices: Spartan 3
9 7 nohous
-- Tool versions:  ISE 10.1
10
----------------------------------------------------------------------------------
11 8 nohous
 
12
library IEEE;
13
use IEEE.STD_LOGIC_1164.ALL;
14
use IEEE.STD_LOGIC_ARITH.ALL;
15
use IEEE.STD_LOGIC_UNSIGNED.ALL;
16
 
17
entity aes3rx is
18
   generic (
19
      reg_width : integer := 5
20
   );
21
   port (
22
      clk       : in  std_logic; -- master clock
23
      aes3      : in  std_logic; -- input 
24
      reset : in  std_logic; -- synchronous reset
25
 
26
      sdata : out std_logic := '0'; -- output serial data
27
      sclk  : out std_logic := '0'; -- output serial data clock
28
      bsync     : out std_logic := '0'; -- block start (high when Z subframe is being transmitted)
29
      fsync     : out std_logic := '0'; -- frame sync (high for channel A, low for B)
30
      active: out std_logic := '0'  -- receiver has valid data on its outputs
31
   );
32
end aes3rx;
33
 
34
architecture Behavioral of aes3rx is
35
   constant X_PREAMBLE          : std_logic_vector(7 downto 0) := "01000111"; -- X preamble bit sequence
36
   constant Y_PREAMBLE          : std_logic_vector(7 downto 0) := "00100111"; -- Y preamble bit sequence
37
   constant Z_PREAMBLE          : std_logic_vector(7 downto 0) := "00010111"; -- Z preamble bit sequence
38
 
39
   signal aes3_sync                     : std_logic_vector(3 downto 0) := (others => '0'); -- input shift reg for double sampling, change detection and input delaying
40
   signal change                                : std_logic := '0'; -- signal signifying a change on the input
41
   signal aes3_clk                      : std_logic := '0'; -- recovered clock signal (actually a stream of pulses on supposed clock edges for implementation on single edge driven FFs)
42
   signal decoder_shift         : std_logic_vector(7 downto 0) := (others => '0'); -- decoder shift reg for preamble detection and logical state decoding
43
   signal align_counter         : std_logic := '0'; -- 1 bit counter reset on preamble detection, provides correct bit alignement for decoder
44
   signal clk_counter           : std_logic_vector(reg_width - 1 downto 0) := (others => '0'); -- counter for aes3 clock regeneration
45
   signal dur_counter           : std_logic_vector(reg_width + 1 downto 0) := (others => '0'); -- counts durration (in clk periods) of current input invariant state (i.e. from "edge to edge")
46
   signal upd_timer                     : std_logic_vector(5 downto 0) := (others => '0'); -- timer counting input changes
47
   signal reg_reset                     : std_logic := '0'; -- resets reg_shortest on upd_timer overflow
48
   signal reg_shortest          : std_logic_vector(reg_width - 1 downto 0) := (others => '1'); -- stores durration of shortest measured input invariant state
49
   signal reg_shortest_ref : std_logic_vector(reg_width - 1 downto 0) := (others => '1'); -- copied from reg_shortest on update counter overflow, serves as reference for aes3 clock regeneration
50
 
51
   signal sdata_int                     : std_logic := '0'; -- internal sdata signal
52
   signal bsync_int                     : std_logic := '0'; -- internal bsync signal
53
   signal fsync_int                     : std_logic := '0'; -- internal fsync signal
54
   signal active_int                    : std_logic := '0'; -- internal active signal
55
   signal sync_ok                               : std_logic := '0'; -- set high on preamble detection, set low on timeout
56
   signal timeout                               : std_logic := '1'; -- when input pulse is too long, set high
57
begin
58
 
59
   ------------------------------------------
60
   -- input_shift_reg_proc
61
   -- Carries out input double sampling in 
62
   -- order to avoid metastable states on FFs
63
   -- and creation of delayed signals for
64
   -- change detector (1 clk period) and 
65
   -- decoder (2 clk periods)
66
   ------------------------------------------
67
   input_shift_reg_proc: process (clk)
68
   begin
69
      if clk'event and clk = '1' then
70
         if reset = '1' then
71
            aes3_sync <= (others => '0');
72
         else
73
            aes3_sync <= aes3 & aes3_sync(3 downto 1); -- synthetizes  shift reg
74
         end if;
75
      end if;
76
   end process;
77
 
78
   ------------------------------------------
79
   -- change_detect_proc
80
   -- Detects edge on sampled input in the 
81
   -- way of comparsion of delayed input 
82
   -- and current state on XOR gate
83
   ------------------------------------------   
84
   change_detect_proc: process (clk)
85
   begin
86
      if clk'event and clk = '1' then
87
         if reset = '1' then
88
            change <= '0';
89
         else
90
            change <= '0';
91
            if aes3_sync(2) /= aes3_sync(1) then
92
               change <= '1';
93
            end if;
94
         end if;
95
      end if;
96
   end process;
97
 
98
   ------------------------------------------
99
   -- shortest_pulse_dur_cnt_proc
100
   -- dur_counter counts number of clocks 
101
   -- between two input transitions and thus 
102
   -- effeciently measuring input pulse 
103
   -- (relative) durration. When input 
104
   -- changes its state, counter value is 
105
   -- compared with reg_shortest and if 
106
   -- counter's value is smaller than
107
   -- register's one, reg_shortest is updated
108
   -- from the counter.
109
   ------------------------------------------   
110
 
111
   shortest_pulse_dur_cnt_proc: process (clk)
112
   begin
113
      if clk'event and clk = '1' then
114
         if reset = '1' then
115
            reg_shortest <= (others => '1');
116
            dur_counter <= (others => '0');
117
         else
118
            if change = '1' then
119
               timeout <= '0';
120
               if dur_counter < reg_shortest then
121
                  reg_shortest <= dur_counter(reg_width - 1 downto 0);
122
               end if;
123
               dur_counter <= (others => '0');
124
            elsif dur_counter = 2**(reg_width + 2) - 1 then
125
               timeout <= '1';
126
            else
127
               dur_counter <= dur_counter + 1;
128
            end if;
129
            if reg_reset = '1' then
130
               reg_shortest <= (others => '1');
131
            end if;
132
         end if;
133
      end if;
134
   end process;
135 7 nohous
 
136 8 nohous
   ------------------------------------------
137
   -- register_update_timer_proc
138
   -- upd_timer is incremented by one when 
139
   -- change is detected on input. When 63 
140
   -- changes count is reached, reg_shortest 
141
   -- is copied to reg_shortest_ref and 
142
   -- reg_reset (which resets reg_shortest
143
   -- in shortest_pulse_dur_cnt_proc) is 
144
   -- raised. 63 change count guarantees that
145
   -- there was at least one "short" pulse
146
   -- on input.
147
   ------------------------------------------
148
   register_update_timer_proc: process (clk)
149
   begin
150
      if clk'event and clk = '1' then
151
         reg_reset <= '0';
152
         if reset = '1' then
153
            reg_shortest_ref <= (others => '1');
154
            upd_timer <= (others => '0');
155
         else
156
            if change = '1' then
157
               if upd_timer = 63 then
158
                  reg_shortest_ref <= reg_shortest;
159
                  reg_reset <= '1';
160
               end if;
161
               upd_timer <= upd_timer + 1;
162
            end if;
163
         end if;
164
      end if;
165
   end process;
166 7 nohous
 
167 8 nohous
   ------------------------------------------
168
   -- aes3_clk_regen_proc
169
   -- Process regenerating clock from input.
170
   -- When clk_counter counts to zero, pulse
171
   -- one master clock period wide is created 
172
   -- on aes3_clk and counter is loaded with 
173
   -- reg_shortest_ref, which stores 
174
   -- supposed input clock half period 
175
   -- (relatively to master clock, indeed).
176
   -- When change on input is detected, 
177
   -- clk_counter is loaded with approx. half 
178
   -- of reg_shortest_reg, thus ensuring that
179
   -- next pulse will be generated in the
180
   -- middle of input invariant state and
181
   -- aes3_clk is effectively resynchronized 
182
   -- with input. aes3_clk is then
183
   -- delayed by approx. one half of shortest
184
   -- input pulse with respect to input 
185
   -- changes to provide decoder ideal 
186
   -- sampling moments and to ensure that, 
187
   -- when there are no transitions on input
188
   -- (and aes3_clk is in "free run"),
189
   -- there will be accurate clock pulse 
190
   -- count generated.
191
   ------------------------------------------
192
   aes3_clk_regen_proc: process (clk)
193
   begin
194
   if clk'event and clk = '1' then
195
      if reset = '1' then
196
         clk_counter <= (others => '0');
197
         aes3_clk <= '0';
198
      else
199
         clk_counter <= clk_counter - 1;
200
         aes3_clk <= '0';
201
         if change = '1' then
202
            clk_counter <= '0' & reg_shortest_ref(reg_width - 1 downto 1);
203
         elsif clk_counter = 0 then
204
            clk_counter <= reg_shortest_ref;
205
            aes3_clk <= '1';
206
         end if;
207
      end if;
208
   end if;
209
   end process;
210 7 nohous
 
211 8 nohous
   ------------------------------------------
212
   -- decoder_shift_reg_proc
213
   -- Eight bit shift register for preamble
214
   -- detection and decoder functionality.
215
   ------------------------------------------   
216
   decoder_shift_reg_proc: process (clk)
217
   begin
218
      if clk'event and clk = '1' then
219
         if reset = '1' then
220
            decoder_shift <= (others => '0');
221
         elsif aes3_clk = '1' then
222
            decoder_shift <= aes3_sync(0) & decoder_shift(7  downto 1);
223
         end if;
224
      end if;
225
   end process;
226
 
227
   ------------------------------------------
228
   -- decoder_proc
229
   -- Compares shift register with preamble
230
   -- bit sequences and when one is detected,
231
   -- accoridngly changes sync signals and
232
   -- resets bit alignment counter 
233
   -- (align_counter). Data is decoded when
234
   -- align_counter is high.
235
   ------------------------------------------
236
   decoder_proc: process (clk)
237
   begin
238
      if clk'event and clk = '1' then
239
         if reset = '1' then
240
            fsync_int <= '0';
241
            bsync_int <= '0';
242
            sync_ok <= '0';
243
            align_counter <= '0';
244
         else
245
            if timeout = '1' then
246
               sync_ok <= '0';
247
            end if;
248
            if aes3_clk = '1' then
249
               align_counter <= not align_counter;
250
               if decoder_shift = X_PREAMBLE or decoder_shift = not X_PREAMBLE then
251
                  fsync_int <= '1';
252
                  bsync_int <= '0';
253
                  sync_ok <= '1';
254
                  align_counter <= '0';
255
               elsif decoder_shift = Y_PREAMBLE or decoder_shift = not Y_PREAMBLE then
256
                  fsync_int <= '0';
257
                  bsync_int <= '0';
258
                  sync_ok <= '1';
259
                  align_counter <= '0';
260
               elsif decoder_shift = Z_PREAMBLE or decoder_shift = not Z_PREAMBLE then
261
                  fsync_int <= '1';
262
                  bsync_int <= '1';
263
                  sync_ok <= '1';
264
                  align_counter <= '0';
265
               end if;
266
               if align_counter = '1' then
267
                  if decoder_shift(1) = decoder_shift(0) then
268
                     sdata_int <= '0';
269
                  else
270
                     sdata_int <= '1';
271
                  end if;
272
               end if;
273
            end if;
274
         end if;
275
      end if;
276
   end process;
277
 
278
   active_int <= sync_ok and not timeout and not reset;
279
   sclk <= align_counter and active_int;
280
   sdata <= sdata_int and active_int;
281
   fsync <= fsync_int and active_int;
282
   bsync <= bsync_int and active_int;
283
   active <= active_int;
284
 
285
end Behavioral;
286
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.