source: trunk/MultiChannelUSB/usb_fifo.v@ 43

Last change on this file since 43 was 36, checked in by demin, 15 years ago

several minor fixes

File size: 2.1 KB
Line 
1module usb_fifo
2 (
3 input wire usb_clk,
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 clk, aclr,
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 fifo32x8 fifo_tx_unit (
27 .aclr(aclr),
28 .data(tx_data),
29 .rdclk(usb_clk),
30 .rdreq(int_wrreq),
31 .wrclk(clk),
32 .wrreq(tx_wrreq),
33 .q(int_tx_q),
34 .rdempty(int_tx_empty),
35 .wrfull(tx_full));
36
37 fifo32x8 fifo_rx_unit (
38 .aclr(aclr),
39 .data(int_rx_data),
40 .rdclk(clk),
41 .rdreq(rx_rdreq),
42 .wrclk(usb_clk),
43 .wrreq(int_rdreq),
44 .q(rx_q),
45 .rdempty(rx_empty),
46 .wrfull(int_rx_full));
47
48 assign rx_ready = (~usb_empty) & (~int_rx_full) & (~int_pktend);
49 assign tx_ready = (~rx_ready) & (~usb_full) & (~int_tx_empty) & (~int_pktend);
50
51 assign int_rdreq = (rx_ready) & (is_rx_addr_ok);
52 assign int_wrreq = (tx_ready) & (~is_rx_addr_ok);
53
54 assign int_pktend = (&idle_counter);
55
56 always @ (posedge usb_clk)
57 begin
58 // respect 1 clock delay between fifo selection
59 // and data transfer operations
60 is_rx_addr_ok <= rx_ready;
61
62 // assert pktend if buffer contains unsent data
63 // and fifo_tx_unit stays empty for more than 30 clocks
64 if (int_pktend)
65 begin
66 byte_counter <= 9'd0;
67 idle_counter <= 5'd0;
68 end
69 else if (int_wrreq)
70 begin
71 byte_counter <= byte_counter + 9'd1;
72 idle_counter <= 5'd0;
73 end
74 else if ((|byte_counter) & (int_tx_empty) & (~rx_ready))
75 begin
76 byte_counter <= byte_counter;
77 idle_counter <= idle_counter + 5'd1;
78 end
79
80 end
81
82 assign usb_pktend = int_pktend;
83 assign usb_rdreq = int_rdreq;
84 assign usb_wrreq = int_wrreq;
85 assign usb_rden = int_rdreq;
86 assign usb_addr = {1'b1, ~rx_ready};
87 assign usb_data = int_wrreq ? int_tx_q : 8'bz;
88
89endmodule
Note: See TracBrowser for help on using the repository browser.