source: trunk/MultiChannelUSB/usb_fifo.v@ 40

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

several minor fixes

File size: 2.1 KB
RevLine 
[27]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,
[36]13 output wire [7:0] rx_q
[27]14 );
15
[33]16 wire int_rx_full, int_tx_empty;
[36]17 wire rx_ready, tx_ready;
[33]18 wire int_rdreq, int_wrreq, int_pktend;
19 reg is_rx_addr_ok;
[30]20 reg [8:0] byte_counter;
21 reg [4:0] idle_counter;
[27]22
[33]23 wire [7:0] int_rx_data = usb_data;
24 wire [7:0] int_tx_q;
[31]25
[27]26 fifo32x8 fifo_tx_unit (
27 .aclr(aclr),
28 .data(tx_data),
29 .rdclk(usb_clk),
[31]30 .rdreq(int_wrreq),
[27]31 .wrclk(clk),
32 .wrreq(tx_wrreq),
[33]33 .q(int_tx_q),
34 .rdempty(int_tx_empty),
[27]35 .wrfull(tx_full));
36
37 fifo32x8 fifo_rx_unit (
38 .aclr(aclr),
[33]39 .data(int_rx_data),
[27]40 .rdclk(clk),
41 .rdreq(rx_rdreq),
42 .wrclk(usb_clk),
[31]43 .wrreq(int_rdreq),
[33]44 .q(rx_q),
[27]45 .rdempty(rx_empty),
[33]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);
[31]50
[33]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
[30]56 always @ (posedge usb_clk)
[27]57 begin
[33]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)
[30]65 begin
66 byte_counter <= 9'd0;
67 idle_counter <= 5'd0;
68 end
[33]69 else if (int_wrreq)
[30]70 begin
71 byte_counter <= byte_counter + 9'd1;
72 idle_counter <= 5'd0;
73 end
[33]74 else if ((|byte_counter) & (int_tx_empty) & (~rx_ready))
[30]75 begin
76 byte_counter <= byte_counter;
77 idle_counter <= idle_counter + 5'd1;
78 end
[33]79
[27]80 end
81
[33]82 assign usb_pktend = int_pktend;
[31]83 assign usb_rdreq = int_rdreq;
84 assign usb_wrreq = int_wrreq;
[33]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;
[27]88
[33]89endmodule
Note: See TracBrowser for help on using the repository browser.