1 |
2 |
alfoltran |
/////////////////////////////////////////////////////////////////////
|
2 |
|
|
//// ////
|
3 |
|
|
//// USB Control Endpoint (Endpoint Zero) ////
|
4 |
|
|
//// Internal Setup Engine ////
|
5 |
|
|
//// ////
|
6 |
|
|
//// SystemC Version: usb_ep0.cpp ////
|
7 |
|
|
//// Author: Alfredo Luiz Foltran Fialho ////
|
8 |
|
|
//// alfoltran@ig.com.br ////
|
9 |
|
|
//// ////
|
10 |
|
|
//// ////
|
11 |
|
|
/////////////////////////////////////////////////////////////////////
|
12 |
|
|
//// ////
|
13 |
|
|
//// Verilog Version: usb1_ctrl.v ////
|
14 |
|
|
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
15 |
|
|
//// www.asics.ws ////
|
16 |
|
|
//// rudi@asics.ws ////
|
17 |
|
|
//// ////
|
18 |
|
|
//// This source file may be used and distributed without ////
|
19 |
|
|
//// restriction provided that this copyright statement is not ////
|
20 |
|
|
//// removed from the file and that any derivative work contains ////
|
21 |
|
|
//// the original copyright notice and the associated disclaimer.////
|
22 |
|
|
//// ////
|
23 |
|
|
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
24 |
|
|
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
25 |
|
|
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
26 |
|
|
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
27 |
|
|
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
28 |
|
|
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
29 |
|
|
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
30 |
|
|
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
31 |
|
|
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
32 |
|
|
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
33 |
|
|
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
34 |
|
|
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
35 |
|
|
//// POSSIBILITY OF SUCH DAMAGE. ////
|
36 |
|
|
//// ////
|
37 |
|
|
/////////////////////////////////////////////////////////////////////
|
38 |
|
|
|
39 |
|
|
#include "systemc.h"
|
40 |
|
|
#include "usb_ep0.h"
|
41 |
|
|
|
42 |
|
|
void usb_ep0::ep0_re_up(void) {
|
43 |
|
|
ep0_re.write(fifo_re1.read());
|
44 |
|
|
}
|
45 |
|
|
|
46 |
|
|
void usb_ep0::fifo_empty_up(void) {
|
47 |
|
|
fifo_empty.write(ep0_stat.read()[1]);
|
48 |
|
|
}
|
49 |
|
|
|
50 |
|
|
void usb_ep0::fifo_full_up(void) {
|
51 |
|
|
fifo_full.write(ep0_stat.read()[2]);
|
52 |
|
|
}
|
53 |
|
|
|
54 |
|
|
// For this implementation we do not implement HALT for the
|
55 |
|
|
// device nor for any of the endpoints. This is useless for
|
56 |
|
|
// this device, but can be added here later ...
|
57 |
|
|
// FYI, we report device/endpoint errors via interrupts,
|
58 |
|
|
// instead of halting the entire or part of the device, much
|
59 |
|
|
// nicer for non-critical errors
|
60 |
|
|
void usb_ep0::clr_halt_up(void) {
|
61 |
|
|
clr_halt.write(ctrl_setup.read());
|
62 |
|
|
}
|
63 |
|
|
|
64 |
|
|
void usb_ep0::addressed_up(void) {
|
65 |
|
|
if (!rst.read())
|
66 |
|
|
addressed.write(false);
|
67 |
|
|
else if (set_address.read())
|
68 |
|
|
addressed.write(true);
|
69 |
|
|
}
|
70 |
|
|
|
71 |
|
|
void usb_ep0::configured_up(void) {
|
72 |
|
|
if (!rst.read())
|
73 |
|
|
configured.write(false);
|
74 |
|
|
else if (set_config.read())
|
75 |
|
|
configured.write(true);
|
76 |
|
|
}
|
77 |
|
|
|
78 |
|
|
void usb_ep0::halt_up(void) {
|
79 |
|
|
if (!rst.read())
|
80 |
|
|
halt.write(false);
|
81 |
|
|
else if (clr_halt.read())
|
82 |
|
|
halt.write(false);
|
83 |
|
|
else if (set_halt.read())
|
84 |
|
|
halt.write(true);
|
85 |
|
|
}
|
86 |
|
|
|
87 |
|
|
void usb_ep0::rom_adr_up1(void) {
|
88 |
|
|
sc_uint<4> sel1, sel2;
|
89 |
|
|
|
90 |
|
|
sel1 = wValue.read().range(11, 8);
|
91 |
|
|
sel2 = wValue.read().range(3, 0);
|
92 |
|
|
|
93 |
|
|
switch (sel1) {// synopsys full_case parallel_case
|
94 |
|
|
case 1: rom_start_d.write(ROM_START0); break;
|
95 |
|
|
case 2: rom_start_d.write(ROM_START1); break;
|
96 |
|
|
case 3: switch (sel2) {// synopsys full_case parallel_case
|
97 |
|
|
case 0: rom_start_d.write(ROM_START2A); break;
|
98 |
|
|
case 1: rom_start_d.write(ROM_START2B); break;
|
99 |
|
|
case 2: rom_start_d.write(ROM_START2C); break;
|
100 |
|
|
case 3: rom_start_d.write(ROM_START2D); break;
|
101 |
|
|
default:rom_start_d.write(ROM_START2A); break;
|
102 |
|
|
}
|
103 |
|
|
break;
|
104 |
|
|
default:rom_start_d.write(0); break;
|
105 |
|
|
}
|
106 |
|
|
}
|
107 |
|
|
|
108 |
|
|
void usb_ep0::rom_adr_up2(void) {
|
109 |
|
|
if (!rst.read())
|
110 |
|
|
rom_adr.write(0);
|
111 |
|
|
else if (rom_sel.read() && !rom_sel_r.read())
|
112 |
|
|
rom_adr.write(rom_start_d.read());
|
113 |
|
|
else if (rom_sel.read() && !fifo_full.read())
|
114 |
|
|
rom_adr.write(rom_adr.read() + 1);
|
115 |
|
|
}
|
116 |
|
|
|
117 |
|
|
void usb_ep0::rom_size_up1(void) {
|
118 |
|
|
sc_uint<4> sel1, sel2;
|
119 |
|
|
|
120 |
|
|
sel1 = wValue.read().range(11, 8);
|
121 |
|
|
sel2 = wValue.read().range(3, 0);
|
122 |
|
|
|
123 |
|
|
switch (sel1) {// synopsys full_case parallel_case
|
124 |
|
|
case 1: rom_size_dd.write(ROM_SIZE0); break;
|
125 |
|
|
case 2: rom_size_dd.write(ROM_SIZE1); break;
|
126 |
|
|
case 3: switch (sel2) {// synopsys full_case parallel_case
|
127 |
|
|
case 0: rom_size_dd.write(ROM_SIZE2A); break;
|
128 |
|
|
case 1: rom_size_dd.write(ROM_SIZE2B); break;
|
129 |
|
|
case 2: rom_size_dd.write(ROM_SIZE2C); break;
|
130 |
|
|
case 3: rom_size_dd.write(ROM_SIZE2D); break;
|
131 |
|
|
default:rom_size_dd.write(ROM_SIZE2A); break;
|
132 |
|
|
}
|
133 |
|
|
break;
|
134 |
|
|
default:rom_size_dd.write(1); break;
|
135 |
|
|
}
|
136 |
|
|
}
|
137 |
|
|
|
138 |
|
|
void usb_ep0::rom_size_up2(void) {
|
139 |
|
|
rom_size_d.write(((rom_size_dd.read() > wLength.read().range(6, 0)) ?
|
140 |
|
|
wLength.read().range(6, 0) : rom_size_dd.read()));
|
141 |
|
|
}
|
142 |
|
|
|
143 |
|
|
void usb_ep0::rom_size_up3(void) {
|
144 |
|
|
if (!rst.read())
|
145 |
|
|
rom_size.write(0);
|
146 |
|
|
else if (rom_sel.read() && !rom_sel_r.read())
|
147 |
|
|
rom_size.write(rom_size_d.read());
|
148 |
|
|
else if (rom_sel.read() && !fifo_full.read())
|
149 |
|
|
rom_size.write(rom_size.read() - 1);
|
150 |
|
|
}
|
151 |
|
|
|
152 |
|
|
void usb_ep0::rom_sel_up(void) {
|
153 |
|
|
rom_sel_r.write(rom_sel.read());
|
154 |
|
|
}
|
155 |
|
|
|
156 |
|
|
void usb_ep0::fifo_we_rom_up1(void) {
|
157 |
|
|
fifo_we_rom_r.write(rom_sel.read());
|
158 |
|
|
}
|
159 |
|
|
|
160 |
|
|
void usb_ep0::fifo_we_rom_up2(void) {
|
161 |
|
|
fifo_we_rom_r2.write(fifo_we_rom_r.read());
|
162 |
|
|
}
|
163 |
|
|
|
164 |
|
|
void usb_ep0::fifo_we_rom_up3(void) {
|
165 |
|
|
fifo_we_rom.write(rom_sel.read() && fifo_we_rom_r2.read());
|
166 |
|
|
}
|
167 |
|
|
|
168 |
|
|
void usb_ep0::rom_done_up(void) {
|
169 |
|
|
rom_done.write((rom_size.read() == 0) && !(rom_sel.read() && !rom_sel_r.read()));
|
170 |
|
|
}
|
171 |
|
|
|
172 |
|
|
void usb_ep0::fifo_re_up(void) {
|
173 |
|
|
fifo_re1.write(get_hdr.read() && !fifo_empty.read());
|
174 |
|
|
}
|
175 |
|
|
|
176 |
|
|
void usb_ep0::adv_up(void) {
|
177 |
|
|
adv.write(get_hdr.read() && !fifo_empty.read() && !adv.read());
|
178 |
|
|
}
|
179 |
|
|
|
180 |
|
|
void usb_ep0::le_up(void) {
|
181 |
|
|
if (!rst.read())
|
182 |
|
|
le.write(0);
|
183 |
|
|
else if (!get_hdr.read())
|
184 |
|
|
le.write(0);
|
185 |
|
|
#ifdef USB_SIMULATION
|
186 |
|
|
else if (!le.read().or_reduce())
|
187 |
|
|
#else
|
188 |
|
|
else if (!(le.read()[7] || le.read()[6] || le.read()[5] || le.read()[4] ||
|
189 |
|
|
le.read()[3] || le.read()[2] || le.read()[1] || le.read()[0]))
|
190 |
|
|
#endif
|
191 |
|
|
le.write(1);
|
192 |
|
|
else if (adv.read())
|
193 |
|
|
le.write(((sc_uint<7>)le.read().range(6, 0), (sc_uint<1>)0));
|
194 |
|
|
}
|
195 |
|
|
|
196 |
|
|
void usb_ep0::hdr_deco0(void) {
|
197 |
|
|
if (le.read()[0])
|
198 |
|
|
hdr0.write(ep0_din.read());
|
199 |
|
|
}
|
200 |
|
|
|
201 |
|
|
void usb_ep0::hdr_deco1(void) {
|
202 |
|
|
if (le.read()[1])
|
203 |
|
|
hdr1.write(ep0_din.read());
|
204 |
|
|
}
|
205 |
|
|
|
206 |
|
|
void usb_ep0::hdr_deco2(void) {
|
207 |
|
|
if (le.read()[2])
|
208 |
|
|
hdr2.write(ep0_din.read());
|
209 |
|
|
}
|
210 |
|
|
|
211 |
|
|
void usb_ep0::hdr_deco3(void) {
|
212 |
|
|
if (le.read()[3])
|
213 |
|
|
hdr3.write(ep0_din.read());
|
214 |
|
|
}
|
215 |
|
|
|
216 |
|
|
void usb_ep0::hdr_deco4(void) {
|
217 |
|
|
if (le.read()[4])
|
218 |
|
|
hdr4.write(ep0_din.read());
|
219 |
|
|
}
|
220 |
|
|
|
221 |
|
|
void usb_ep0::hdr_deco5(void) {
|
222 |
|
|
if (le.read()[5])
|
223 |
|
|
hdr5.write(ep0_din.read());
|
224 |
|
|
}
|
225 |
|
|
|
226 |
|
|
void usb_ep0::hdr_deco6(void) {
|
227 |
|
|
if (le.read()[6])
|
228 |
|
|
hdr6.write(ep0_din.read());
|
229 |
|
|
}
|
230 |
|
|
|
231 |
|
|
void usb_ep0::hdr_deco7(void) {
|
232 |
|
|
if (le.read()[7])
|
233 |
|
|
hdr7.write(ep0_din.read());
|
234 |
|
|
}
|
235 |
|
|
|
236 |
|
|
void usb_ep0::hdr_done_up(void) {
|
237 |
|
|
hdr_done.write(le.read()[7] && adv.read());
|
238 |
|
|
}
|
239 |
|
|
|
240 |
|
|
void usb_ep0::high_sel_up(void) {
|
241 |
|
|
high_sel.write(write_done_r.read());
|
242 |
|
|
}
|
243 |
|
|
|
244 |
|
|
void usb_ep0::ep0_dout_up(void) {
|
245 |
|
|
switch (data_sel.read()) {// synopsys full_case parallel_case
|
246 |
|
|
case ZERO_DATA: ep0_dout.write(((rom_sel.read()) ? rom_data.read() : (sc_uint<8>)0)); break;
|
247 |
|
|
case ZERO_ONE_DATA: ep0_dout.write(((high_sel.read()) ? (sc_uint<8>)1 : (sc_uint<8>)0)); break;
|
248 |
|
|
case CONFIG_DATA: ep0_dout.write(((sc_uint<7>)0, (sc_uint<1>)configured.read())); break; // Is configured?
|
249 |
|
|
case SYNC_FRAME_DATA: ep0_dout.write((high_sel.read()) ?
|
250 |
|
|
((sc_uint<5>)0, (sc_uint<3>)frame_no.read().range(10, 8)) :
|
251 |
|
|
frame_no.read().range(7, 0)); break;
|
252 |
|
|
case VEND_DATA: ep0_dout.write(((high_sel.read()) ?
|
253 |
|
|
vendor_data.read().range(15, 8) :
|
254 |
|
|
vendor_data.read().range(7, 0))); break;
|
255 |
|
|
}
|
256 |
|
|
}
|
257 |
|
|
|
258 |
|
|
void usb_ep0::ep0_we_up(void) {
|
259 |
|
|
ep0_we.write(fifo_we_d.read() || fifo_we_rom.read());
|
260 |
|
|
}
|
261 |
|
|
|
262 |
|
|
void usb_ep0::ep0_size_up(void) {
|
263 |
|
|
if (in_size_0.read())
|
264 |
|
|
ep0_size.write(0);
|
265 |
|
|
else if (in_size_1.read())
|
266 |
|
|
ep0_size.write(1);
|
267 |
|
|
else if (in_size_2.read())
|
268 |
|
|
ep0_size.write(2);
|
269 |
|
|
else if (rom_sel.read())
|
270 |
|
|
ep0_size.write(((sc_uint<1>)0, (sc_uint<7>)rom_size_d.read()));
|
271 |
|
|
}
|
272 |
|
|
|
273 |
|
|
void usb_ep0::write_done_up1(void) {
|
274 |
|
|
write_done_r.write(in_size_2.read() && !fifo_full.read() && fifo_we_d.read() &&
|
275 |
|
|
!write_done_r.read() && !write_done.read());
|
276 |
|
|
}
|
277 |
|
|
|
278 |
|
|
void usb_ep0::write_done_up2(void) {
|
279 |
|
|
write_done.write(in_size_2.read() && !fifo_full.read() && fifo_we_d.read() &&
|
280 |
|
|
write_done_r.read() && !write_done.read());
|
281 |
|
|
}
|
282 |
|
|
|
283 |
|
|
void usb_ep0::bmReqType_up(void) {
|
284 |
|
|
bmReqType.write(hdr0.read());
|
285 |
|
|
}
|
286 |
|
|
|
287 |
|
|
void usb_ep0::bmReqType_Decoder(void) {
|
288 |
|
|
bm_req_dir.write(bmReqType.read()[7]); // 0: Host to device; 1: Device to host
|
289 |
|
|
bm_req_type.write(bmReqType.read().range(6, 5)); // 0: Standard; 1: Class; 2: Vendor; 3: RESERVED
|
290 |
|
|
bm_req_recp.write(bmReqType.read().range(4, 0)); // 0: Device; 1: Interface; 2: Endpoint; 3: Other
|
291 |
|
|
// 4..31: RESERVED
|
292 |
|
|
}
|
293 |
|
|
|
294 |
|
|
void usb_ep0::bRequest_up(void) {
|
295 |
|
|
bRequest.write(hdr1.read());
|
296 |
|
|
}
|
297 |
|
|
|
298 |
|
|
void usb_ep0::wValue_up(void) {
|
299 |
|
|
wValue.write(((sc_uint<8>)hdr3.read(), (sc_uint<8>)hdr2.read()));
|
300 |
|
|
}
|
301 |
|
|
|
302 |
|
|
void usb_ep0::wIndex_up(void) {
|
303 |
|
|
wIndex.write(((sc_uint<8>)hdr5.read(), (sc_uint<8>)hdr4.read()));
|
304 |
|
|
}
|
305 |
|
|
|
306 |
|
|
void usb_ep0::wLength_up(void) {
|
307 |
|
|
wLength.write(((sc_uint<8>)hdr7.read(), (sc_uint<8>)hdr6.read()));
|
308 |
|
|
}
|
309 |
|
|
|
310 |
|
|
void usb_ep0::hdr_done_r_up(void) {
|
311 |
|
|
hdr_done_r.write(hdr_done.read());
|
312 |
|
|
}
|
313 |
|
|
|
314 |
|
|
// Standard commands that MUST support
|
315 |
|
|
void usb_ep0::get_status_up(void) {
|
316 |
|
|
get_status.write(hdr_done.read() && (bRequest.read() == GET_STATUS) && (bm_req_type.read() == 0));
|
317 |
|
|
}
|
318 |
|
|
|
319 |
|
|
void usb_ep0::clear_feature_up(void) {
|
320 |
|
|
clear_feature.write(hdr_done.read() && (bRequest.read() == CLEAR_FEATURE) && (bm_req_type.read() == 0));
|
321 |
|
|
}
|
322 |
|
|
|
323 |
|
|
void usb_ep0::set_feature_up(void) {
|
324 |
|
|
set_feature.write(hdr_done.read() && (bRequest.read() == SET_FEATURE) && (bm_req_type.read() == 0));
|
325 |
|
|
}
|
326 |
|
|
|
327 |
|
|
void usb_ep0::set_address_up(void) {
|
328 |
|
|
set_address.write(hdr_done.read() && (bRequest.read() == SET_ADDRESS) && (bm_req_type.read() == 0));
|
329 |
|
|
}
|
330 |
|
|
|
331 |
|
|
void usb_ep0::get_descriptor_up(void) {
|
332 |
|
|
get_descriptor.write(hdr_done.read() && (bRequest.read() == GET_DESCRIPTOR) && (bm_req_type.read() == 0));
|
333 |
|
|
}
|
334 |
|
|
|
335 |
|
|
void usb_ep0::set_descriptor_up(void) {
|
336 |
|
|
set_descriptor.write(hdr_done.read() && (bRequest.read() == SET_DESCRIPTOR) && (bm_req_type.read() == 0));
|
337 |
|
|
}
|
338 |
|
|
|
339 |
|
|
void usb_ep0::get_config_up(void) {
|
340 |
|
|
get_config.write(hdr_done.read() && (bRequest.read() == GET_CONFIG) && (bm_req_type.read() == 0));
|
341 |
|
|
}
|
342 |
|
|
|
343 |
|
|
void usb_ep0::set_config_up(void) {
|
344 |
|
|
set_config.write(hdr_done.read() && (bRequest.read() == SET_CONFIG) && (bm_req_type.read() == 0));
|
345 |
|
|
}
|
346 |
|
|
|
347 |
|
|
void usb_ep0::get_interface_up(void) {
|
348 |
|
|
get_interface.write(hdr_done.read() && (bRequest.read() == GET_INTERFACE) && (bm_req_type.read() == 0));
|
349 |
|
|
}
|
350 |
|
|
|
351 |
|
|
void usb_ep0::set_interface_up(void) {
|
352 |
|
|
set_interface.write(hdr_done.read() && (bRequest.read() == SET_INTERFACE) && (bm_req_type.read() == 0));
|
353 |
|
|
}
|
354 |
|
|
|
355 |
|
|
void usb_ep0::synch_frame_up(void) {
|
356 |
|
|
synch_frame.write(hdr_done.read() && (bRequest.read() == SYNCH_FRAME) && (bm_req_type.read() == 0));
|
357 |
|
|
}
|
358 |
|
|
|
359 |
|
|
void usb_ep0::v_set_int_up(void) {
|
360 |
|
|
v_set_int.write(hdr_done.read() && (bRequest.read() == V_SET_INT) && (bm_req_type.read() == 2));
|
361 |
|
|
}
|
362 |
|
|
|
363 |
|
|
void usb_ep0::v_set_feature_up(void) {
|
364 |
|
|
v_set_feature.write(hdr_done.read() && (bRequest.read() == SET_FEATURE) && (bm_req_type.read() == 2));
|
365 |
|
|
}
|
366 |
|
|
|
367 |
|
|
void usb_ep0::v_get_status_up(void) {
|
368 |
|
|
v_get_status.write(hdr_done.read() && (bRequest.read() == GET_STATUS) && (bm_req_type.read() == 2));
|
369 |
|
|
}
|
370 |
|
|
|
371 |
|
|
// A config err must cause the device to send a STALL for an ACK
|
372 |
|
|
void usb_ep0::config_err_up(void) {
|
373 |
|
|
config_err.write(hdr_done_r.read() && !(get_status.read() || clear_feature.read() ||
|
374 |
|
|
set_feature.read() || set_address.read() || get_descriptor.read() ||
|
375 |
|
|
set_descriptor.read() || get_config.read() || set_config.read() ||
|
376 |
|
|
get_interface.read() || set_interface.read() || synch_frame.read() ||
|
377 |
|
|
v_set_int.read() || v_set_feature.read() || v_get_status.read()));
|
378 |
|
|
}
|
379 |
|
|
|
380 |
|
|
void usb_ep0::send_stall_up(void) {
|
381 |
|
|
send_stall.write(config_err.read());
|
382 |
|
|
}
|
383 |
|
|
|
384 |
|
|
// Set address
|
385 |
|
|
void usb_ep0::set_adr_pending_up(void) {
|
386 |
|
|
if (!rst.read())
|
387 |
|
|
set_adr_pending.write(false);
|
388 |
|
|
else if (ctrl_in.read() || ctrl_out.read() || ctrl_setup.read())
|
389 |
|
|
set_adr_pending.write(false);
|
390 |
|
|
else if (set_address.read())
|
391 |
|
|
set_adr_pending.write(true);
|
392 |
|
|
|
393 |
|
|
}
|
394 |
|
|
|
395 |
|
|
void usb_ep0::funct_adr_tmp_up(void) {
|
396 |
|
|
if (!rst.read())
|
397 |
|
|
funct_adr_tmp.write(0);
|
398 |
|
|
else if (set_address.read())
|
399 |
|
|
funct_adr_tmp.write(wValue.read().range(6, 0));
|
400 |
|
|
}
|
401 |
|
|
|
402 |
|
|
void usb_ep0::funct_adr_up(void) {
|
403 |
|
|
if (!rst.read())
|
404 |
|
|
funct_adr.write(0);
|
405 |
|
|
else if (set_adr_pending.read() && ctrl_in.read())
|
406 |
|
|
funct_adr.write(funct_adr_tmp.read());
|
407 |
|
|
}
|
408 |
|
|
|
409 |
|
|
// Main FSM
|
410 |
|
|
void usb_ep0::state_up(void) {
|
411 |
|
|
if (!rst.read())
|
412 |
|
|
state.write(EP0_IDLE);
|
413 |
|
|
else
|
414 |
|
|
state.write(next_state.read());
|
415 |
|
|
}
|
416 |
|
|
|
417 |
|
|
void usb_ep0::ep0_statemachine(void) {
|
418 |
|
|
next_state.write(state.read());
|
419 |
|
|
get_hdr.write(false);
|
420 |
|
|
data_sel.write(ZERO_DATA);
|
421 |
|
|
fifo_we_d.write(false);
|
422 |
|
|
in_size_0.write(false);
|
423 |
|
|
in_size_1.write(false);
|
424 |
|
|
in_size_2.write(false);
|
425 |
|
|
rom_sel.write(false);
|
426 |
|
|
|
427 |
|
|
switch (state.read()) {// synopsys full_case parallel_case
|
428 |
|
|
case EP0_IDLE: // Wait for setup token
|
429 |
|
|
|
430 |
|
|
///////////////////////////////////////////////////////////////////////
|
431 |
|
|
//
|
432 |
|
|
// DEBUG INFORMATIONS
|
433 |
|
|
//
|
434 |
|
|
///////////////////////////////////////////////////////////////////////
|
435 |
|
|
|
436 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
437 |
|
|
cout << "EP0: Entered state IDLE (" << sc_simulation_time() << ")" << endl;
|
438 |
|
|
#endif
|
439 |
|
|
|
440 |
|
|
///////////////////////////////////////////////////////////////////////
|
441 |
|
|
|
442 |
|
|
if (ctrl_setup.read())
|
443 |
|
|
next_state.write(EP0_GET_HDR);
|
444 |
|
|
if (get_status.read())
|
445 |
|
|
next_state.write(EP0_GET_STATUS);
|
446 |
|
|
if (clear_feature.read())
|
447 |
|
|
next_state.write(EP0_CLEAR_FEATURE);
|
448 |
|
|
if (set_feature.read())
|
449 |
|
|
next_state.write(EP0_SET_FEATURE);
|
450 |
|
|
if (set_address.read())
|
451 |
|
|
next_state.write(EP0_SET_ADDRESS);
|
452 |
|
|
if (get_descriptor.read())
|
453 |
|
|
next_state.write(EP0_GET_DESCRIPTOR);
|
454 |
|
|
if (set_descriptor.read())
|
455 |
|
|
next_state.write(EP0_SET_DESCRIPTOR);
|
456 |
|
|
if (get_config.read())
|
457 |
|
|
next_state.write(EP0_GET_CONFIG);
|
458 |
|
|
if (set_config.read())
|
459 |
|
|
next_state.write(EP0_SET_CONFIG);
|
460 |
|
|
if (get_interface.read())
|
461 |
|
|
next_state.write(EP0_GET_INTERFACE);
|
462 |
|
|
if (set_interface.read())
|
463 |
|
|
next_state.write(EP0_SET_INTERFACE);
|
464 |
|
|
if (synch_frame.read())
|
465 |
|
|
next_state.write(EP0_SYNCH_FRAME);
|
466 |
|
|
if (v_set_int.read())
|
467 |
|
|
next_state.write(EP0_V_SET_INT);
|
468 |
|
|
if (v_set_feature.read())
|
469 |
|
|
next_state.write(EP0_V_SET_INT);
|
470 |
|
|
if (v_get_status.read())
|
471 |
|
|
next_state.write(EP0_V_GET_STATUS);
|
472 |
|
|
break;
|
473 |
|
|
|
474 |
|
|
case EP0_GET_HDR: // Retrieve setup header
|
475 |
|
|
|
476 |
|
|
///////////////////////////////////////////////////////////////////////
|
477 |
|
|
//
|
478 |
|
|
// DEBUG INFORMATIONS
|
479 |
|
|
//
|
480 |
|
|
///////////////////////////////////////////////////////////////////////
|
481 |
|
|
|
482 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
483 |
|
|
cout << "EP0: Entered state GET_HDR (" << sc_simulation_time() << ")" << endl;
|
484 |
|
|
#endif
|
485 |
|
|
|
486 |
|
|
///////////////////////////////////////////////////////////////////////
|
487 |
|
|
|
488 |
|
|
get_hdr.write(true);
|
489 |
|
|
if (hdr_done.read())
|
490 |
|
|
next_state.write(EP0_IDLE);
|
491 |
|
|
break;
|
492 |
|
|
|
493 |
|
|
case EP0_GET_STATUS: // Actions for supported commands
|
494 |
|
|
|
495 |
|
|
///////////////////////////////////////////////////////////////////////
|
496 |
|
|
//
|
497 |
|
|
// DEBUG INFORMATIONS
|
498 |
|
|
//
|
499 |
|
|
///////////////////////////////////////////////////////////////////////
|
500 |
|
|
|
501 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
502 |
|
|
cout << "EP0: Entered state GET_STATUS (" << sc_simulation_time() << ")" << endl;
|
503 |
|
|
#endif
|
504 |
|
|
|
505 |
|
|
///////////////////////////////////////////////////////////////////////
|
506 |
|
|
|
507 |
|
|
// Return to host
|
508 |
|
|
// 1 for device
|
509 |
|
|
// 0 for interface
|
510 |
|
|
// 0 for endpoint
|
511 |
|
|
if (bm_req_recp.read() == 0)
|
512 |
|
|
data_sel.write(ZERO_ONE_DATA);
|
513 |
|
|
else
|
514 |
|
|
data_sel.write(ZERO_DATA);
|
515 |
|
|
|
516 |
|
|
in_size_2.write(true);
|
517 |
|
|
if (!fifo_full.read()) {
|
518 |
|
|
fifo_we_d.write(true);
|
519 |
|
|
if (write_done_r.read())
|
520 |
|
|
next_state.write(EP0_WAIT_IN_DATA);
|
521 |
|
|
}
|
522 |
|
|
break;
|
523 |
|
|
|
524 |
|
|
case EP0_V_GET_STATUS:
|
525 |
|
|
|
526 |
|
|
///////////////////////////////////////////////////////////////////////
|
527 |
|
|
//
|
528 |
|
|
// DEBUG INFORMATIONS
|
529 |
|
|
//
|
530 |
|
|
///////////////////////////////////////////////////////////////////////
|
531 |
|
|
|
532 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
533 |
|
|
cout << "EP0: Entered state V_GET_STATUS (" << sc_simulation_time() << ")" << endl;
|
534 |
|
|
#endif
|
535 |
|
|
|
536 |
|
|
///////////////////////////////////////////////////////////////////////
|
537 |
|
|
|
538 |
|
|
data_sel.write(VEND_DATA);
|
539 |
|
|
in_size_2.write(true);
|
540 |
|
|
if (!fifo_full.read()) {
|
541 |
|
|
fifo_we_d.write(true);
|
542 |
|
|
if (write_done_r.read())
|
543 |
|
|
next_state.write(EP0_WAIT_IN_DATA);
|
544 |
|
|
}
|
545 |
|
|
break;
|
546 |
|
|
|
547 |
|
|
case EP0_CLEAR_FEATURE:
|
548 |
|
|
|
549 |
|
|
///////////////////////////////////////////////////////////////////////
|
550 |
|
|
//
|
551 |
|
|
// DEBUG INFORMATIONS
|
552 |
|
|
//
|
553 |
|
|
///////////////////////////////////////////////////////////////////////
|
554 |
|
|
|
555 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
556 |
|
|
cout << "EP0: Entered state CLEAR_FEATURE (" << sc_simulation_time() << ")" << endl;
|
557 |
|
|
#endif
|
558 |
|
|
|
559 |
|
|
///////////////////////////////////////////////////////////////////////
|
560 |
|
|
|
561 |
|
|
// Just ignore this for now
|
562 |
|
|
next_state.write(EP0_STATUS_IN);
|
563 |
|
|
break;
|
564 |
|
|
|
565 |
|
|
case EP0_SET_FEATURE:
|
566 |
|
|
|
567 |
|
|
///////////////////////////////////////////////////////////////////////
|
568 |
|
|
//
|
569 |
|
|
// DEBUG INFORMATIONS
|
570 |
|
|
//
|
571 |
|
|
///////////////////////////////////////////////////////////////////////
|
572 |
|
|
|
573 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
574 |
|
|
cout << "EP0: Entered state SET_FEATURE (" << sc_simulation_time() << ")" << endl;
|
575 |
|
|
#endif
|
576 |
|
|
|
577 |
|
|
///////////////////////////////////////////////////////////////////////
|
578 |
|
|
|
579 |
|
|
// Just ignore this for now
|
580 |
|
|
next_state.write(EP0_STATUS_IN);
|
581 |
|
|
break;
|
582 |
|
|
|
583 |
|
|
case EP0_SET_ADDRESS:
|
584 |
|
|
|
585 |
|
|
///////////////////////////////////////////////////////////////////////
|
586 |
|
|
//
|
587 |
|
|
// DEBUG INFORMATIONS
|
588 |
|
|
//
|
589 |
|
|
///////////////////////////////////////////////////////////////////////
|
590 |
|
|
|
591 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
592 |
|
|
cout << "EP0: Entered state SET_ADDRESS (" << sc_simulation_time() << ")" << endl;
|
593 |
|
|
#endif
|
594 |
|
|
|
595 |
|
|
///////////////////////////////////////////////////////////////////////
|
596 |
|
|
|
597 |
|
|
// Done elsewhere
|
598 |
|
|
next_state.write(EP0_STATUS_IN);
|
599 |
|
|
break;
|
600 |
|
|
|
601 |
|
|
case EP0_GET_DESCRIPTOR:
|
602 |
|
|
|
603 |
|
|
///////////////////////////////////////////////////////////////////////
|
604 |
|
|
//
|
605 |
|
|
// DEBUG INFORMATIONS
|
606 |
|
|
//
|
607 |
|
|
///////////////////////////////////////////////////////////////////////
|
608 |
|
|
|
609 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
610 |
|
|
cout << "EP0: Entered state GET_DESCRIPTOR (" << sc_simulation_time() << ")" << endl;
|
611 |
|
|
#endif
|
612 |
|
|
|
613 |
|
|
///////////////////////////////////////////////////////////////////////
|
614 |
|
|
|
615 |
|
|
if ((wValue.read().range(15, 8) == 1) ||
|
616 |
|
|
(wValue.read().range(15, 8) == 2) ||
|
617 |
|
|
(wValue.read().range(15, 8) == 3))
|
618 |
|
|
rom_sel.write(true);
|
619 |
|
|
else
|
620 |
|
|
next_state.write(EP0_IDLE);
|
621 |
|
|
|
622 |
|
|
if (rom_done.read())
|
623 |
|
|
next_state.write(EP0_IDLE);
|
624 |
|
|
break;
|
625 |
|
|
|
626 |
|
|
case EP0_SET_DESCRIPTOR:
|
627 |
|
|
|
628 |
|
|
///////////////////////////////////////////////////////////////////////
|
629 |
|
|
//
|
630 |
|
|
// DEBUG INFORMATIONS
|
631 |
|
|
//
|
632 |
|
|
///////////////////////////////////////////////////////////////////////
|
633 |
|
|
|
634 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
635 |
|
|
cout << "EP0: Entered state SET_DESCRIPTOR (" << sc_simulation_time() << ")" << endl;
|
636 |
|
|
#endif
|
637 |
|
|
|
638 |
|
|
///////////////////////////////////////////////////////////////////////
|
639 |
|
|
|
640 |
|
|
// This doesn't do anything since we do not support
|
641 |
|
|
// setting the descriptor
|
642 |
|
|
next_state.write(EP0_IDLE);
|
643 |
|
|
break;
|
644 |
|
|
|
645 |
|
|
case EP0_GET_CONFIG:
|
646 |
|
|
|
647 |
|
|
///////////////////////////////////////////////////////////////////////
|
648 |
|
|
//
|
649 |
|
|
// DEBUG INFORMATIONS
|
650 |
|
|
//
|
651 |
|
|
///////////////////////////////////////////////////////////////////////
|
652 |
|
|
|
653 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
654 |
|
|
cout << "EP0: Entered state GET_CONFIG (" << sc_simulation_time() << ")" << endl;
|
655 |
|
|
#endif
|
656 |
|
|
|
657 |
|
|
///////////////////////////////////////////////////////////////////////
|
658 |
|
|
|
659 |
|
|
// Send one byte back that indicates current status
|
660 |
|
|
in_size_1.write(true);
|
661 |
|
|
data_sel.write(CONFIG_DATA);
|
662 |
|
|
if (!fifo_full.read()) {
|
663 |
|
|
fifo_we_d.write(true);
|
664 |
|
|
next_state.write(EP0_WAIT_IN_DATA);
|
665 |
|
|
}
|
666 |
|
|
break;
|
667 |
|
|
|
668 |
|
|
case EP0_SET_CONFIG:
|
669 |
|
|
|
670 |
|
|
///////////////////////////////////////////////////////////////////////
|
671 |
|
|
//
|
672 |
|
|
// DEBUG INFORMATIONS
|
673 |
|
|
//
|
674 |
|
|
///////////////////////////////////////////////////////////////////////
|
675 |
|
|
|
676 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
677 |
|
|
cout << "EP0: Entered state SET_CONFIG (" << sc_simulation_time() << ")" << endl;
|
678 |
|
|
#endif
|
679 |
|
|
|
680 |
|
|
///////////////////////////////////////////////////////////////////////
|
681 |
|
|
|
682 |
|
|
// Done elsewhere
|
683 |
|
|
next_state.write(EP0_STATUS_IN);
|
684 |
|
|
break;
|
685 |
|
|
|
686 |
|
|
case EP0_GET_INTERFACE:
|
687 |
|
|
|
688 |
|
|
///////////////////////////////////////////////////////////////////////
|
689 |
|
|
//
|
690 |
|
|
// DEBUG INFORMATIONS
|
691 |
|
|
//
|
692 |
|
|
///////////////////////////////////////////////////////////////////////
|
693 |
|
|
|
694 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
695 |
|
|
cout << "EP0: Entered state GET_INTERFACE (" << sc_simulation_time() << ")" << endl;
|
696 |
|
|
#endif
|
697 |
|
|
|
698 |
|
|
///////////////////////////////////////////////////////////////////////
|
699 |
|
|
|
700 |
|
|
// Return interface 0
|
701 |
|
|
in_size_1.write(true);
|
702 |
|
|
if (!fifo_full.read()) {
|
703 |
|
|
fifo_we_d.write(true);
|
704 |
|
|
next_state.write(EP0_WAIT_IN_DATA);
|
705 |
|
|
}
|
706 |
|
|
break;
|
707 |
|
|
|
708 |
|
|
case EP0_SET_INTERFACE:
|
709 |
|
|
|
710 |
|
|
///////////////////////////////////////////////////////////////////////
|
711 |
|
|
//
|
712 |
|
|
// DEBUG INFORMATIONS
|
713 |
|
|
//
|
714 |
|
|
///////////////////////////////////////////////////////////////////////
|
715 |
|
|
|
716 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
717 |
|
|
cout << "EP0: Entered state SET_INTERFACE (" << sc_simulation_time() << ")" << endl;
|
718 |
|
|
#endif
|
719 |
|
|
|
720 |
|
|
///////////////////////////////////////////////////////////////////////
|
721 |
|
|
|
722 |
|
|
// Just ignore this for now
|
723 |
|
|
next_state.write(EP0_STATUS_IN);
|
724 |
|
|
break;
|
725 |
|
|
|
726 |
|
|
case EP0_SYNCH_FRAME:
|
727 |
|
|
|
728 |
|
|
///////////////////////////////////////////////////////////////////////
|
729 |
|
|
//
|
730 |
|
|
// DEBUG INFORMATIONS
|
731 |
|
|
//
|
732 |
|
|
///////////////////////////////////////////////////////////////////////
|
733 |
|
|
|
734 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
735 |
|
|
cout << "EP0: Entered state SYNCH_FRAME (" << sc_simulation_time() << ")" << endl;
|
736 |
|
|
#endif
|
737 |
|
|
|
738 |
|
|
///////////////////////////////////////////////////////////////////////
|
739 |
|
|
|
740 |
|
|
// Return Frame current frame number
|
741 |
|
|
data_sel.write(SYNC_FRAME_DATA);
|
742 |
|
|
in_size_2.write(true);
|
743 |
|
|
if (!fifo_full.read()) {
|
744 |
|
|
fifo_we_d.write(true);
|
745 |
|
|
if (write_done_r.read())
|
746 |
|
|
next_state.write(EP0_WAIT_IN_DATA);
|
747 |
|
|
}
|
748 |
|
|
break;
|
749 |
|
|
|
750 |
|
|
case EP0_V_SET_INT:
|
751 |
|
|
|
752 |
|
|
///////////////////////////////////////////////////////////////////////
|
753 |
|
|
//
|
754 |
|
|
// DEBUG INFORMATIONS
|
755 |
|
|
//
|
756 |
|
|
///////////////////////////////////////////////////////////////////////
|
757 |
|
|
|
758 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
759 |
|
|
cout << "EP0: Entered state V_SET_INT (" << sc_simulation_time() << ")" << endl;
|
760 |
|
|
#endif
|
761 |
|
|
|
762 |
|
|
///////////////////////////////////////////////////////////////////////
|
763 |
|
|
|
764 |
|
|
// Done elsewhere
|
765 |
|
|
next_state.write(EP0_STATUS_IN);
|
766 |
|
|
break;
|
767 |
|
|
|
768 |
|
|
case EP0_WAIT_IN_DATA:
|
769 |
|
|
|
770 |
|
|
///////////////////////////////////////////////////////////////////////
|
771 |
|
|
//
|
772 |
|
|
// DEBUG INFORMATIONS
|
773 |
|
|
//
|
774 |
|
|
///////////////////////////////////////////////////////////////////////
|
775 |
|
|
|
776 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
777 |
|
|
cout << "EP0: Entered state WAIT_IN_DATA (" << sc_simulation_time() << ")" << endl;
|
778 |
|
|
#endif
|
779 |
|
|
|
780 |
|
|
///////////////////////////////////////////////////////////////////////
|
781 |
|
|
|
782 |
|
|
if (ctrl_in.read())
|
783 |
|
|
next_state.write(EP0_STATUS_OUT);
|
784 |
|
|
break;
|
785 |
|
|
|
786 |
|
|
case EP0_STATUS_IN:
|
787 |
|
|
|
788 |
|
|
///////////////////////////////////////////////////////////////////////
|
789 |
|
|
//
|
790 |
|
|
// DEBUG INFORMATIONS
|
791 |
|
|
//
|
792 |
|
|
///////////////////////////////////////////////////////////////////////
|
793 |
|
|
|
794 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
795 |
|
|
cout << "EP0: Entered state STATUS_IN (" << sc_simulation_time() << ")" << endl;
|
796 |
|
|
#endif
|
797 |
|
|
|
798 |
|
|
///////////////////////////////////////////////////////////////////////
|
799 |
|
|
|
800 |
|
|
in_size_0.write(true);
|
801 |
|
|
if (ctrl_in.read())
|
802 |
|
|
next_state.write(EP0_IDLE);
|
803 |
|
|
break;
|
804 |
|
|
|
805 |
|
|
case EP0_STATUS_OUT:
|
806 |
|
|
|
807 |
|
|
///////////////////////////////////////////////////////////////////////
|
808 |
|
|
//
|
809 |
|
|
// DEBUG INFORMATIONS
|
810 |
|
|
//
|
811 |
|
|
///////////////////////////////////////////////////////////////////////
|
812 |
|
|
|
813 |
|
|
#ifdef USBF_VERBOSE_DEBUG
|
814 |
|
|
cout << "EP0: Entered state STATUS_OUT (" << sc_simulation_time() << ")" << endl;
|
815 |
|
|
#endif
|
816 |
|
|
|
817 |
|
|
///////////////////////////////////////////////////////////////////////
|
818 |
|
|
|
819 |
|
|
if (ctrl_out.read())
|
820 |
|
|
next_state.write(EP0_IDLE);
|
821 |
|
|
break;
|
822 |
|
|
}
|
823 |
|
|
}
|
824 |
|
|
|