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

Subversion Repositories usb11

[/] [usb11/] [trunk/] [rtl/] [systemc/] [usb_rx_phy.cpp] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfoltran
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  USB RX PHY                                                 ////
4
////                                                             ////
5
////  SystemC Version: usb_rx_phy.cpp                            ////
6
////  Author: Alfredo Luiz Foltran Fialho                        ////
7
////          alfoltran@ig.com.br                                ////
8
////                                                             ////
9
////                                                             ////
10
/////////////////////////////////////////////////////////////////////
11
////                                                             ////
12
//// Verilog Version: usb_rx_phy.v                               ////
13
//// Copyright (C) 2000-2002 Rudolf Usselmann                    ////
14
////                         www.asics.ws                        ////
15
////                         rudi@asics.ws                       ////
16
////                                                             ////
17
//// This source file may be used and distributed without        ////
18
//// restriction provided that this copyright statement is not   ////
19
//// removed from the file and that any derivative work contains ////
20
//// the original copyright notice and the associated disclaimer.////
21
////                                                             ////
22
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
23
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
24
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
25
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
26
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
27
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
28
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
29
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
30
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
31
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
32
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
33
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
34
//// POSSIBILITY OF SUCH DAMAGE.                                 ////
35
////                                                             ////
36
/////////////////////////////////////////////////////////////////////
37
 
38
#include "systemc.h"
39
#include "usb_rx_phy.h"
40
 
41
#ifdef USB_SIMULATION
42
        void usb_rx_phy::rx_error_init(void) {
43
                RxError_o.write(false);
44
        }
45
#endif
46
 
47
void usb_rx_phy::misc_logic_up(void) {
48
        rx_en.write(RxEn_i.read());
49
}
50
 
51
void usb_rx_phy::misc_logic_RxActive_up(void) {
52
        RxActive_o.write(rx_active.read());
53
}
54
 
55
void usb_rx_phy::misc_logic_RxValid_up(void) {
56
        RxValid_o.write(rx_valid.read());
57
}
58
 
59
void usb_rx_phy::misc_logic_DataIn_up(void) {
60
        DataIn_o.write(hold_reg.read());
61
}
62
 
63
void usb_rx_phy::misc_logic_LineState_up(void) {
64
        LineState.write(((sc_uint<1>)rxdp_s1.read(), (sc_uint<1>)rxdn_s1.read()));
65
}
66
 
67
// First synchronize to the local system clock to
68
// avoid metastability outside the sync block (*_s1)
69
// Second synchronise to the internal bit clock (*_s)
70
void usb_rx_phy::si_up1(void) {
71
        rxd_t1.write(rxd.read());
72
        rxdp_t1.write(rxdp.read());
73
        rxdn_t1.write(rxdn.read());
74
}
75
 
76
void usb_rx_phy::si_up2(void) {
77
        rxd_s1.write(rxd_t1.read());
78
        rxdp_s1.write(rxdp_t1.read());
79
        rxdn_s1.write(rxdn_t1.read());
80
}
81
 
82
void usb_rx_phy::si_up3(void) {
83
        rxd_s.write(rxd_s1.read());
84
        rxdp_s.write(rxdp_s1.read());
85
        rxdn_s.write(rxdn_s1.read());
86
}
87
 
88
void usb_rx_phy::si_up4(void) {
89
        k.write(!rxdp_s.read() &&  rxdn_s.read());
90
        j.write(rxdp_s.read() && !rxdn_s.read());
91
        se0.write(!rxdp_s.read() && !rxdn_s.read());
92
}
93
 
94
// This design uses a clock enable to do 12Mhz timing and not a
95
// real 12Mhz clock. Everything always runs at 48Mhz. We want to
96
// make sure however, that the clock enable is always exactly in
97
// the middle between two virtual 12Mhz rising edges.
98
// We monitor rxdp and rxdn for any changes and do the appropiate
99
// adjustments.
100
// In addition to the locking done in the dpll FSM, we adjust the
101
// final latch enable to compensate for various sync registers ...
102
 
103
// Allow lockinf only when we are receiving
104
void usb_rx_phy::dpll_up1(void) {
105
        lock_en.write(rx_en.read());
106
}
107
 
108
// Edge detector
109
void usb_rx_phy::dpll_up2(void) {
110
        rxdp_s1r.write(rxdp_s1.read());
111
        rxdn_s1r.write(rxdn_s1.read());
112
}
113
 
114
void usb_rx_phy::dpll_up3(void) {
115
        change.write((rxdp_s1r.read() != rxdp_s1.read()) || (rxdn_s1r.read() != rxdn_s1.read()));
116
}
117
 
118
// DPLL FSM
119
void usb_rx_phy::dpll_up4(void) {
120
        if (!rst.read())
121
                dpll_state.write(1);
122
        else
123
                dpll_state.write(dpll_next_state.read());
124
}
125
 
126
// Compensate for sync registers at the input - allign full speed
127
// clock enable to be in the middle between two bit changes ...
128
void usb_rx_phy::dpll_up5(void) {
129
        fs_ce_r1.write(fs_ce_d.read());
130
}
131
 
132
void usb_rx_phy::dpll_up6(void) {
133
        fs_ce_r2.write(fs_ce_r1.read());
134
}
135
 
136
void usb_rx_phy::dpll_up7(void) {
137
        fs_ce_r3.write(fs_ce_r2.read());
138
}
139
 
140
void usb_rx_phy::dpll_up8(void) {
141
        fs_ce.write(fs_ce_r3.read());
142
}
143
 
144
void usb_rx_phy::dpll_statemachine(void) {
145
        fs_ce_d.write(false);
146
        switch (dpll_state.read()) {// synopsys full_case parallel_case
147
                case 0:  if (lock_en.read() && change.read())
148
                                        dpll_next_state.write(0);
149
                                else
150
                                        dpll_next_state.write(1);
151
                                break;
152
                case 1: fs_ce_d.write(true);
153
                                if (lock_en.read() && change.read())
154
                                        //dpll_next_state.write(0);
155
                                        dpll_next_state.write(3);
156
                                else
157
                                        dpll_next_state.write(2);
158
                                break;
159
                case 2: if (lock_en.read() && change.read())
160
                                        dpll_next_state = 0;
161
                                else
162
                                        dpll_next_state = 3;
163
                                break;
164
                case 3: //if (lock_en.read() && change.read())
165
                                        dpll_next_state.write(0);
166
                                //else
167
                                        //dpll_next_state.write(0);
168
                                break;
169
        }
170
}
171
 
172
void usb_rx_phy::fsp_up(void) {
173
        if(!rst.read())
174
                fs_state.write(FS_IDLE);
175
        else
176
                fs_state.write(fs_next_state.read());
177
}
178
 
179
void usb_rx_phy::fsp_statemachine(void) {
180
        synced_d.write(false);
181
        fs_next_state.write(fs_state.read());
182
        if (fs_ce.read())
183
                switch (fs_state.read()) {// synopsys full_case parallel_case
184
                        case FS_IDLE:   if (k.read() && rx_en.read())
185
                                                        fs_next_state.write(K1);
186
                                                break;
187
                        case K1:                if (j.read() && rx_en.read())
188
                                                        fs_next_state.write(J1);
189
                                                else
190
                                                        fs_next_state.write(FS_IDLE);
191
                                                break;
192
                        case J1:                if (k.read() && rx_en.read())
193
                                                        fs_next_state.write(K2);
194
                                                else
195
                                                        fs_next_state.write(FS_IDLE);
196
                                                break;
197
                        case K2:                if (j.read() && rx_en.read())
198
                                                        fs_next_state.write(J2);
199
                                                else
200
                                                        fs_next_state.write(FS_IDLE);
201
                                                break;
202
                        case J2:                if (k.read() && rx_en.read())
203
                                                        fs_next_state.write(K3);
204
                                                else
205
                                                        fs_next_state.write(FS_IDLE);
206
                                                break;
207
                        case K3:                if (j.read() && rx_en.read())
208
                                                        fs_next_state.write(J3);
209
                                                else if (k.read() && rx_en.read())
210
                                                        fs_next_state.write(K4);                // Allow missing one J
211
                                                else
212
                                                        fs_next_state.write(FS_IDLE);
213
                                                break;
214
                        case J3:                if (k.read() && rx_en.read())
215
                                                        fs_next_state.write(K4);
216
                                                else
217
                                                        fs_next_state.write(FS_IDLE);
218
                                                break;
219
                        case K4:                if (k.read())
220
                                                                synced_d.write(true);
221
                                                fs_next_state.write(FS_IDLE);
222
                                                break;
223
                }
224
}
225
 
226
void usb_rx_phy::gra_up1(void) {
227
        if (!rst.read())
228
                rx_active.write(false);
229
        else if (synced_d.read() && rx_en.read())
230
                rx_active.write(true);
231
        else if (se0.read() && rx_valid_r.read())
232
                rx_active.write(false);
233
}
234
 
235
void usb_rx_phy::gra_up2(void) {
236
        if (rx_valid.read())
237
                rx_valid_r.write(true);
238
        else if (fs_ce.read())
239
                rx_valid_r.write(false);
240
}
241
 
242
void usb_rx_phy::nrzi_up1(void) {
243
        if (fs_ce.read())
244
                sd_r.write(rxd_s.read());
245
}
246
 
247
void usb_rx_phy::nrzi_up2(void) {
248
        if (!rst.read())
249
                sd_nrzi.write(false);
250
        else if (rx_active.read() && fs_ce.read())
251
                sd_nrzi.write(!(rxd_s.read() ^ sd_r.read()));
252
}
253
 
254
void usb_rx_phy::bsd_up1(void) {
255
        if (!rst.read())
256
                one_cnt.write(0);
257
        else if (!shift_en.read())
258
                one_cnt.write(0);
259
        else if (fs_ce.read())
260
                if (!sd_nrzi.read() || drop_bit.read())
261
                        one_cnt.write(0);
262
                else
263
                        one_cnt.write(one_cnt.read() + 1);
264
}
265
 
266
void usb_rx_phy::bsd_up2(void) {
267
        drop_bit.write((one_cnt.read() == 6));
268
}
269
 
270
void usb_rx_phy::spc_up1(void) {
271
        if (fs_ce.read())
272
                shift_en.write(synced_d.read() || rx_active.read());
273
}
274
 
275
void usb_rx_phy::spc_up2(void) {
276
        if (fs_ce.read() && shift_en.read() && !drop_bit.read())
277
                hold_reg.write(((sc_uint<1>)sd_nrzi.read(), hold_reg.read().range(7, 1)));
278
}
279
 
280
void usb_rx_phy::grv_up1(void) {
281
        if (!rst.read())
282
                bit_cnt.write(0);
283
        else if (!shift_en.read())
284
                bit_cnt.write(0);
285
        else if (fs_ce.read() && !drop_bit.read())
286
                bit_cnt.write(bit_cnt.read() + 1);
287
}
288
 
289
void usb_rx_phy::grv_up2(void) {
290
        if (!rst.read())
291
                rx_valid1.write(false);
292
        else if (fs_ce.read() && !drop_bit.read() && (bit_cnt.read() == 7))
293
                rx_valid1.write(true);
294
        else if (rx_valid1.read() && fs_ce.read() && !drop_bit.read())
295
                rx_valid1.write(false);
296
}
297
 
298
void usb_rx_phy::grv_up3(void) {
299
        rx_valid.write(!drop_bit.read() && rx_valid1.read() && fs_ce.read());
300
}
301
 

powered by: WebSVN 2.1.0

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