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

Subversion Repositories ulpi_wrapper

[/] [ulpi_wrapper/] [trunk/] [testbench/] [ulpi_driver.cpp] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 ultra_embe
#include "ulpi_driver.h"
2
 
3
#define CMD_IDLE        0x0
4
#define CMD_XMIT        0x1
5
#define CMD_REG_WR      0x2
6
#define CMD_REG_RD      0x3
7
 
8
#define ULPI_CMD_H      7
9
#define ULPI_CMD_L      6
10
 
11
#define ULPI_ADDR_H     5
12
#define ULPI_ADDR_L     0
13
 
14
#define ULPI_PID_H      3
15
#define ULPI_PID_L      0
16
 
17
//-----------------------------------------------------------------
18
// reg_write
19
//-----------------------------------------------------------------
20
void ulpi_driver::reg_write(sc_uint <8> addr, sc_uint <8> data)
21
{
22
    m_reg[addr & (ULPI_REG_NUM-1)] = data;
23
}
24
//-----------------------------------------------------------------
25
// reg_read
26
//-----------------------------------------------------------------
27
sc_uint <8> ulpi_driver::reg_read(sc_uint <8> addr)
28
{
29
    return m_reg[addr & (ULPI_REG_NUM-1)];
30
}
31
//-----------------------------------------------------------------
32
// drive_rxcmd: Drive ULPI RX_CMD
33
//-----------------------------------------------------------------
34
void ulpi_driver::drive_rxcmd(sc_uint <2> linestate, bool rx_active, bool rx_error)
35
{
36
    sc_uint<8> data = 0;
37
 
38
    data.range(ULPI_RXCMD_LS_H, ULPI_RXCMD_LS_L) = linestate;
39
 
40
    if (rx_error)
41
        data.range(ULPI_RXCMD_RXEVENT_H, ULPI_RXCMD_RXEVENT_L) = ULPI_RXEVENT_ERROR;
42
    else if (rx_active)
43
        data.range(ULPI_RXCMD_RXEVENT_H, ULPI_RXCMD_RXEVENT_L) = ULPI_RXEVENT_ACTIVE;
44
    else
45
        data.range(ULPI_RXCMD_RXEVENT_H, ULPI_RXCMD_RXEVENT_L) = ULPI_RXEVENT_INACTIVE;
46
 
47
    // RX_CMD
48
    ulpi_dir_o.write(true);
49
    ulpi_nxt_o.write(false);
50
    ulpi_data_o.write(data);
51
 
52
    wait();
53
}
54
//-----------------------------------------------------------------
55
// drive_rxdata: Drive ULPI RX_DATA
56
//-----------------------------------------------------------------
57
void ulpi_driver::drive_rxdata(sc_uint <8> data)
58
{
59
    // RX_DATA
60
    ulpi_dir_o.write(true);
61
    ulpi_nxt_o.write(true);
62
    ulpi_data_o.write(data);
63
 
64
    wait();
65
}
66
//-----------------------------------------------------------------
67
// drive_output: Drive turnaround cycle (-> output)
68
//-----------------------------------------------------------------
69
void ulpi_driver::drive_output(bool rx_data)
70
{
71
    // Turnaround
72
    ulpi_dir_o.write(true);
73
    ulpi_nxt_o.write(rx_data);
74
    ulpi_data_o.write(0x00);
75
    wait();
76
    ulpi_nxt_o.write(false);
77
}
78
//-----------------------------------------------------------------
79
// drive_input: Drive turnaround cycle (-> input)
80
//-----------------------------------------------------------------
81
void ulpi_driver::drive_input(void)
82
{
83
    // Turnaround
84
    ulpi_dir_o.write(false);
85
    ulpi_nxt_o.write(false);
86
    ulpi_data_o.write(0x00);
87
 
88
    wait();
89
}
90
//-----------------------------------------------------------------
91
// drive
92
//-----------------------------------------------------------------
93
void ulpi_driver::drive(void)
94
{
95
    drive_input();
96
 
97
    // Wait until reset complete
98
    while (rst_i.read())
99
        wait();
100
 
101
    while (true)
102
    {
103
        // PHY -> LINK
104
        if (m_tx_fifo.num_available())
105
        {
106
            sc_uint <9> fifo_data;
107
            sc_uint <8> data;
108
            bool        last;
109
 
110
            // Turnaround
111
            drive_output(true);
112
 
113
            do
114
            {
115
                // RX_CMD
116
                if (!(rand() % 4))
117
                {
118
                    last = false;
119
 
120
                    // RX_CMD (RX_ACTIVE = 1)
121
                    drive_rxcmd(0x2, true, false);
122
                }
123
                // RX_DATA
124
                else
125
                {
126
                    last = tx_read(data);
127
                    drive_rxdata(data);
128
                }
129
            }
130
            while (!last);
131
 
132
            // RX_CMD (RX_ACTIVE = 0)
133
            drive_rxcmd(0x2, false, false);
134
 
135
            // Turnaround
136
            drive_input();
137
        }
138
        // LINK -> PHY
139
        else
140
        {
141
            sc_uint <8> data = ulpi_data_i.read();
142
            sc_uint <2> cmd  = data.range(ULPI_CMD_H,ULPI_CMD_L);
143
            sc_uint <6> addr = data.range(ULPI_ADDR_H,ULPI_ADDR_L);
144
            sc_uint <8> pid  = 0;
145
 
146
            pid.range(3,0)   = data.range(ULPI_PID_H,ULPI_PID_L);
147
            pid.range(7,4)   = ~data.range(ULPI_PID_H,ULPI_PID_L);
148
 
149
            // Register read
150
            if (cmd == CMD_REG_RD)
151
            {
152
                // Accept command
153
                ulpi_nxt_o.write(true);
154
                wait();
155
 
156
                // Turnaround
157
                drive_output(false);
158
 
159
                // Data
160
                data = reg_read(addr);
161
                ulpi_data_o.write(data);
162
                wait();
163
 
164
                // Turnaround
165
                drive_input();
166
            }
167
            // Not idle?
168
            else if (cmd != CMD_IDLE)
169
            {
170
                // Accept command
171
                ulpi_nxt_o.write(true);
172
                wait();
173
                ulpi_nxt_o.write(false);
174
 
175
                // Record PID for future use
176
                bool        last_valid = (cmd == CMD_XMIT);
177
                sc_uint <8> last_data  = pid;
178
 
179
                while (!ulpi_stp_i.read())
180
                {
181
                    // Random data accept delay
182
                    if (!(rand() % 4))
183
                    {
184
                        int wait_len = rand() % 8;
185
 
186
                        ulpi_nxt_o.write(false);
187
                        while (!ulpi_stp_i.read() && wait_len--)
188
                            wait(1);
189
 
190
                        if (ulpi_stp_i.read())
191
                            break;
192
                    }
193
 
194
                    ulpi_nxt_o.write(true);
195
                    wait();
196
                    ulpi_nxt_o.write(false);
197
 
198
                    if (ulpi_stp_i.read())
199
                        break;
200
 
201
                    sc_uint <8> data = ulpi_data_i.read();
202
 
203
                    // Transmit
204
                    if (cmd == CMD_XMIT)
205
                    {
206
                        if (last_valid)
207
                            rx_write(last_data, false);
208
 
209
                        last_valid = true;
210
                        last_data  = data;
211
                    }
212
                    // Register write
213
                    else if (cmd == CMD_REG_WR)
214
                    {
215
                        reg_write(addr, data);
216
                        addr += 1;
217
                    }
218
                }
219
 
220
                // Flush pending received byte
221
                if (last_valid)
222
                    rx_write(last_data, true);
223
            }
224
 
225
            wait();
226
        }
227
    }
228
}
229
//-----------------------------------------------------------------
230
// write
231
//-----------------------------------------------------------------
232
void ulpi_driver::write(sc_uint <8> data, bool last)
233
{
234
    sc_uint <9> fifo_data;
235
 
236
    fifo_data.range(7,0) = data;
237
    fifo_data.range(8,8) = last;
238
 
239
    m_tx_fifo.write(fifo_data);
240
}
241
//-----------------------------------------------------------------
242
// read
243
//-----------------------------------------------------------------
244
bool ulpi_driver::read(sc_uint <8> &data)
245
{
246
    sc_uint <9> fifo_data = m_rx_fifo.read();
247
    data = fifo_data.range(7,0);
248
    return (bool)fifo_data.range(8,8);
249
}
250
//-----------------------------------------------------------------
251
// rx_write
252
//-----------------------------------------------------------------
253
void ulpi_driver::rx_write(sc_uint <8> data, bool last)
254
{
255
    sc_uint <9> fifo_data;
256
 
257
    fifo_data.range(7,0) = data;
258
    fifo_data.range(8,8) = last;
259
 
260
    m_rx_fifo.write(fifo_data);
261
}
262
//-----------------------------------------------------------------
263
// tx_read
264
//-----------------------------------------------------------------
265
bool ulpi_driver::tx_read(sc_uint <8> &data)
266
{
267
    sc_uint <9> fifo_data = m_tx_fifo.read();
268
    data = fifo_data.range(7,0);
269
    return (bool)fifo_data.range(8,8);
270
}

powered by: WebSVN 2.1.0

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