source: trunk/Octopus/usb_fifo.v

Last change on this file was 102, checked in by demin, 14 years ago

initial commit

File size: 2.8 KB
Line 
1module usb_fifo
2 (
3 input wire usb_clock,
4 inout wire [7:0] usb_data,
5 input wire usb_full, usb_empty,
6 output wire usb_wrreq, usb_rdreq, usb_rden, usb_pktend,
7 output wire [1:0] usb_addr,
8
9 input wire clock,
10 input wire tx_wrreq, rx_rdreq,
11 input wire [7:0] tx_data,
12 output wire tx_full, rx_empty,
13 output wire [7:0] rx_q
14 );
15
16 wire int_rx_full, int_tx_empty;
17 wire rx_ready, tx_ready;
18 wire int_rdreq, int_wrreq, int_pktend;
19 reg is_rx_addr_ok;
20 reg [8:0] byte_counter;
21 reg [4:0] idle_counter;
22
23 wire [7:0] int_rx_data = usb_data;
24 wire [7:0] int_tx_q;
25
26 dcfifo #(
27 .intended_device_family("Cyclone III"),
28 .lpm_numwords(16),
29 .lpm_showahead("ON"),
30 .lpm_type("dcfifo"),
31 .lpm_width(8),
32 .lpm_widthu(4),
33 .rdsync_delaypipe(4),
34 .wrsync_delaypipe(4),
35 .overflow_checking("ON"),
36 .underflow_checking("ON"),
37 .use_eab("OFF")) fifo_tx (
38 .data(tx_data),
39 .rdclk(usb_clock),
40 .rdreq(int_wrreq),
41 .wrclk(clock),
42 .wrreq(tx_wrreq),
43 .q(int_tx_q),
44 .rdempty(int_tx_empty),
45 .wrfull(tx_full),
46 .aclr(),
47 .rdfull(),
48 .rdusedw(),
49 .wrempty(),
50 .wrusedw());
51
52 dcfifo #(
53 .intended_device_family("Cyclone III"),
54 .lpm_numwords(16),
55 .lpm_showahead("ON"),
56 .lpm_type("dcfifo"),
57 .lpm_width(8),
58 .lpm_widthu(4),
59 .rdsync_delaypipe(4),
60 .wrsync_delaypipe(4),
61 .overflow_checking("ON"),
62 .underflow_checking("ON"),
63 .use_eab("OFF")) fifo_rx (
64 .data(int_rx_data),
65 .rdclk(clock),
66 .rdreq(rx_rdreq),
67 .wrclk(usb_clock),
68 .wrreq(int_rdreq),
69 .q(rx_q),
70 .rdempty(rx_empty),
71 .wrfull(int_rx_full),
72 .aclr(),
73 .rdfull(),
74 .rdusedw(),
75 .wrempty(),
76 .wrusedw());
77
78 assign rx_ready = (~usb_empty) & (~int_rx_full) & (~int_pktend);
79 assign tx_ready = (~rx_ready) & (~usb_full) & (~int_tx_empty) & (~int_pktend);
80
81 assign int_rdreq = (rx_ready) & (is_rx_addr_ok);
82 assign int_wrreq = (tx_ready) & (~is_rx_addr_ok);
83
84 assign int_pktend = (&idle_counter);
85
86 always @ (posedge usb_clock)
87 begin
88 // respect 1 clock delay between fifo selection
89 // and data transfer operations
90 is_rx_addr_ok <= rx_ready;
91
92 // assert pktend if buffer contains unsent data
93 // and fifo_tx_unit stays empty for more than 30 clocks
94 if (int_pktend)
95 begin
96 byte_counter <= 9'd0;
97 idle_counter <= 5'd0;
98 end
99 else if (int_wrreq)
100 begin
101 byte_counter <= byte_counter + 9'd1;
102 idle_counter <= 5'd0;
103 end
104 else if ((|byte_counter) & (int_tx_empty) & (~rx_ready))
105 begin
106 byte_counter <= byte_counter;
107 idle_counter <= idle_counter + 5'd1;
108 end
109
110 end
111
112 assign usb_pktend = int_pktend;
113 assign usb_rdreq = int_rdreq;
114 assign usb_wrreq = int_wrreq;
115 assign usb_rden = int_rdreq;
116 assign usb_addr = {1'b1, ~rx_ready};
117 assign usb_data = int_wrreq ? int_tx_q : 8'bz;
118
119endmodule
Note: See TracBrowser for help on using the repository browser.