01 -- Sync Field Detector 02 LIBRARY ieee; 03 USE ieee.std_logic_1164.ALL; 04 USE ieee.std_logic_arith.ALL; 05 USE ieee.std_logic_unsigned.ALL; 06 07 ENTITY chksync IS 08 PORT ( din : IN STD_LOGIC; 09 clk : IN STD_LOGIC; 10 reset : IN STD_LOGIC; 11 enable : OUT STD_LOGIC; 12 bitout : OUT STD_LOGIC); 13 END chksync; 14 15 ARCHITECTURE a OF chksync IS 16 SIGNAL syncbuffer : STD_LOGIC_VECTOR(7 DOWNTO 0); 17 SIGNAL start : STD_LOGIC; 18 BEGIN 19 main : PROCESS(din, clk, reset) 20 VARIABLE sync : STD_LOGIC_VECTOR(7 DOWNTO 0); 21 BEGIN 22 IF (reset = '1') THEN 23 syncbuffer <= "11111111"; 24 start <= '0'; 25 ELSIF (clk'EVENT AND clk = '1') THEN -- everything at clock edge 26 sync(7 DOWNTO 1) := syncbuffer(6 DOWNTO 0); 27 sync(0) := din; 28 IF ((sync = "01010100") AND (start = '0')) THEN 29 bitout <= sync(7); 30 enable <= '1'; 31 start <= '1'; 32 syncbuffer <= sync; 33 ELSIF ((sync /= "01010100") AND (start = '0')) THEN 34 enable <= '0'; 35 syncbuffer <= sync; 36 ELSIF (start = '1') THEN 37 bitout <= sync(7); 38 enable <= '1'; 39 syncbuffer <= sync; 40 END IF; 41 END IF; 42 END PROCESS main; 43 END a;
01 ///////////////////////////////////////////////////////////////////
02 //
03 // Synchronize Inputs
04 //
05
06 // First synchronize to the local system clock to
07 // avoid metastability outside the sync block (*_s0).
08 // Then make sure we see the signal for at least two
09 // clock cycles stable to avoid glitches and noise
10
11 always @ ( posedge clk )rxd_s0 <= rxd ;
12 always @ ( posedge clk )rxd_s1 <= rxd_s0 ;
13 always @ ( posedge clk ) // Avoid detecting Line Glitches and noise
14 if ( rxd_s0 && rxd_s1 )rxd_s <= 1'b1 ;
15 else
16 if ( ! rxd_s0 && ! rxd_s1 )rxd_s <= 1'b0 ;
17
18 always @ ( posedge clk )rxdp_s0 <= rxdp ;
19 always @ ( posedge clk )rxdp_s1 <= rxdp_s0 ;
20 always @ ( posedge clk )rxdp_s_r <= rxdp_s0 & rxdp_s1 ;
21 always @ ( posedge clk )rxdp_s <= ( rxdp_s0 & rxdp_s1 ) | rxdp_s_r ; // Avoid detecting Line Glitches and noise
22
23 always @ ( posedge clk )rxdn_s0 <= rxdn ;
24 always @ ( posedge clk )rxdn_s1 <= rxdn_s0 ;
25 always @ ( posedge clk )rxdn_s_r <= rxdn_s0 & rxdn_s1 ;
26 always @ ( posedge clk )rxdn_s <= ( rxdn_s0 & rxdn_s1 ) | rxdn_s_r ; // Avoid detecting Line Glitches and noise
27
28 assign k = ! rxdp_s & rxdn_s ;
29 assign j = rxdp_s & ! rxdn_s ;
30 assign se0 = ! rxdp_s & ! rxdn_s ;
31
32 always @ ( posedge clk )if ( fs_ce )se0_s <= se0 ;
33
34 ///////////////////////////////////////////////////////////////////
35 //
36 // DPLL
37 //
38
39 // This design uses a clock enable to do 12Mhz timing and not a
40 // real 12Mhz clock. Everything always runs at 48Mhz. We want to
41 // make sure however, that the clock enable is always exactly in
42 // the middle between two virtual 12Mhz rising edges.
43 // We monitor rxdp and rxdn for any changes and do the appropiate
44 // adjustments.
45 // In addition to the locking done in the dpll FSM, we adjust the
46 // final latch enable to compensate for various sync registers ...
47
48 // Allow lockinf only when we are receiving
49 assign lock_en = rx_en ;
50
51 always @ ( posedge clk )rxd_r <= rxd_s ;
52
53 // Edge detector
54 assign change = rxd_r != rxd_s ;
55
56 // DPLL FSM
57 `ifdef USB_ASYNC_REST
58 always @ ( posedge clk or negedge rst )
59 `else
60 always @ ( posedge clk )
61 `endif
62 if ( ! rst )dpll_state <= 2'h1 ;
63 else dpll_state <= dpll_next_state ;
64
65 always @ ( dpll_state or lock_en or change )
66 begin
67 fs_ce_d = 1'b0 ;
68 case ( dpll_state ) // synopsys full_case parallel_case
69 2'h0 :
70 if ( lock_en && change )dpll_next_state = 2'h0 ;
71 else dpll_next_state = 2'h1 ;
72 2'h1 : begin
73 fs_ce_d = 1'b1 ;
74 if ( lock_en && change )dpll_next_state = 2'h3 ;
75 else dpll_next_state = 2'h2 ;
76 end
77 2'h2 :
78 if ( lock_en && change )dpll_next_state = 2'h0 ;
79 else dpll_next_state = 2'h3 ;
80 2'h3 :
81 if ( lock_en && change )dpll_next_state = 2'h0 ;
82 else dpll_next_state = 2'h0 ;
83 endcase
84 end
85
86 // Compensate for sync registers at the input - allign full speed
87 // clock enable to be in the middle between two bit changes ...
88 reg fs_ce_r1 , fs_ce_r2 ;
89
90 always @ ( posedge clk )fs_ce_r1 <= fs_ce_d ;
91 always @ ( posedge clk )fs_ce_r2 <= fs_ce_r1 ;
92 always @ ( posedge clk )fs_ce <= fs_ce_r2 ;
93
94
95 ///////////////////////////////////////////////////////////////////
96 //
97 // Find Sync Pattern FSM
98 //
99
100 parameter FS_IDLE = 3'h0 ,
101 K1 = 3'h1 ,
102 J1 = 3'h2 ,
103 K2 = 3'h3 ,
104 J2 = 3'h4 ,
105 K3 = 3'h5 ,
106 J3 = 3'h6 ,
107 K4 = 3'h7 ;
108
109 `ifdef USB_ASYNC_REST
110 always @ ( posedge clk or negedge rst )
111 `else
112 always @ ( posedge clk )
113 `endif
114 if ( ! rst )fs_state <= FS_IDLE ;
115 else fs_state <= fs_next_state ;
116
117 always @ ( fs_state or fs_ce or k or j or rx_en or rx_active or se0 or se0_s )
118 begin
119 synced_d = 1'b0 ;
120 sync_err_d = 1'b0 ;
121 fs_next_state = fs_state ;
122 if ( fs_ce && ! rx_active && ! se0 && ! se0_s )
123 case ( fs_state ) // synopsys full_case parallel_case
124 FS_IDLE :
125 begin
126 if ( k && rx_en )fs_next_state = K1 ;
127 end
128 K1 :
129 begin
130 if ( j && rx_en )fs_next_state = J1 ;
131 else
132 begin
133 sync_err_d = 1'b1 ;
134 fs_next_state = FS_IDLE ;
135 end
136 end
137 J1 :
138 begin
139 if ( k && rx_en )fs_next_state = K2 ;
140 else
141 begin
142 sync_err_d = 1'b1 ;
143 fs_next_state = FS_IDLE ;
144 end
145 end
146 K2 :
147 begin
148 if ( j && rx_en )fs_next_state = J2 ;
149 else
150 begin
151 sync_err_d = 1'b1 ;
152 fs_next_state = FS_IDLE ;
153 end
154 end
155 J2 :
156 begin
157 if ( k && rx_en )fs_next_state = K3 ;
158 else
159 begin
160 sync_err_d = 1'b1 ;
161 fs_next_state = FS_IDLE ;
162 end
163 end
164 K3 :
165 begin
166 if ( j && rx_en )fs_next_state = J3 ;
167 else
168 if ( k && rx_en )
169 begin
170 fs_next_state = FS_IDLE ; // Allow missing first K-J
171 synced_d = 1'b1 ;
172 end
173 else
174 begin
175 sync_err_d = 1'b1 ;
176 fs_next_state = FS_IDLE ;
177 end
178 end
179 J3 :
180 begin
181 if ( k && rx_en )fs_next_state = K4 ;
182 else
183 begin
184 sync_err_d = 1'b1 ;
185 fs_next_state = FS_IDLE ;
186 end
187 end
188 K4 :
189 begin
190 if ( k )synced_d = 1'b1 ;
191 fs_next_state = FS_IDLE ;
192 end
193 endcase
194 end
---------------------------------------------------------------
01
02 /* Find sync pattern */
03
04 parameter FS_IDLE = 4'h0;
05 parameter K1 = 4'h1;
06 parameter J1 = 4'h2;
07 parameter K2 = 4'h3;
08 parameter J2 = 4'h4;
09 parameter K3 = 4'h5;
10 parameter J3 = 4'h6;
11 parameter K4 = 4'h7;
12 parameter K5 = 4'h8;
13
14 reg [3:0] fs_state;
15 reg [3:0] fs_next_state;
16
17 reg [5:0] fs_timeout_counter;
18 reg fs_timeout;
19 always @(posedge usb_clk) begin
20 if(rxreset|eop_detected) begin
21 fs_timeout_counter <= 6'd0;
22 fs_timeout <= 1'b0;
23 end else begin
24 if((fs_state != fs_next_state) | (fs_state == FS_IDLE))
25 fs_timeout_counter <= 6'd0;
26 else
27 fs_timeout_counter <= fs_timeout_counter + 6'd1;
28 if(low_speed)
29 fs_timeout <= fs_timeout_counter == 6'd63;
30 else
31 fs_timeout <= fs_timeout_counter == 6'd7;
32 end
33 end
34
35 always @(posedge usb_clk) begin
36 if(rxreset|eop_detected|fs_timeout)
37 fs_state <= FS_IDLE;
38 else
39 fs_state <= fs_next_state;
40 end
41
42 always @(*) begin
43 startrx = 1'b0;
44 fs_next_state = fs_state;
45
46 case(fs_state)
47 FS_IDLE: if(~rx_corrected & ~rx_active)
48 fs_next_state = K1;
49 K1: if(rx_corrected)
50 fs_next_state = J1;
51 J1: if(~rx_corrected)
52 fs_next_state = K2;
53 K2: if(rx_corrected)
54 fs_next_state = J2;
55 J2: if(~rx_corrected)
56 fs_next_state = K3;
57 K3: if(rx_corrected)
58 fs_next_state = J3;
59 J3: if(~rx_corrected)
60 fs_next_state = K4;
61 K4: if(dpll_ce) begin
62 if(~rx_corrected)
63 fs_next_state = K5;
64 else
65 fs_next_state = FS_IDLE;
66 end
67 K5: if(dpll_ce) begin
68 if(~rx_corrected)
69 startrx = 1'b1;
70 fs_next_state = FS_IDLE;
71 end
72 endcase
73 end