注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
shangdawei的个人空间 https://home.eeworld.com.cn/space-uid-180876.html [收藏] [复制] [分享] [RSS]
日志

USB Sync Field Detector

已有 8233 次阅读2010-12-31 17:42

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
评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章