1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
`default_nettype none
module usb_packet_fifo2(reset, usb_clock, fpga_clock, write_enable, write_data,
read_enable, skip_packet, read_data, have_space, pkt_waiting, tx_empty) ;
/* Module parameters */
parameter LOG2_N = 2 ;
parameter BUS_WIDTH = 16 ;
parameter FIFO_WIDTH = 32 ;
input wire reset;
input wire usb_clock ;
input wire fpga_clock ;
input wire write_enable ;
input wire [BUS_WIDTH-1:0] write_data ;
input wire read_enable ;
input wire skip_packet ;
output wire [FIFO_WIDTH-1:0] read_data ;
output wire have_space ;
output wire pkt_waiting ;
output wire tx_empty;
/* Variable for generate statement */
genvar i ;
/* Local wires for FIFO connections */
wire [2**LOG2_N-1:0] fifo_resets ;
reg [2**LOG2_N-1:0] fifo_we ;
wire [2**LOG2_N-1:0] fifo_re ;
reg [FIFO_WIDTH-1:0] fifo_wdata[2**LOG2_N-1:0] ;
wire [FIFO_WIDTH-1:0] fifo_rdata[2**LOG2_N-1:0] ;
wire [2**LOG2_N-1:0] fifo_rempty ;
wire [2**LOG2_N-1:0] fifo_rfull ;
wire [2**LOG2_N-1:0] fifo_wempty ;
wire [2**LOG2_N-1:0] fifo_wfull ;
/* FIFO Select for read and write ports */
reg [LOG2_N-1:0] fifo_rselect ;
reg [LOG2_N-1:0] fifo_wselect ;
/* Used to convert 16 bits usbdata to the 32 bits wide fifo */
reg word_complete ;
reg [BUS_WIDTH-1:0] write_data_delayed ;
/* Assign have_space to empty flag of currently selected write FIFO */
assign have_space = fifo_wempty[fifo_wselect] ;
/* Assign pkt_waiting to full flag of currently selected read FIFO */
assign pkt_waiting = fifo_rfull[fifo_rselect] ;
/* Assign the read_data to the output of the currently selected FIFO */
assign read_data = fifo_rdata[fifo_rselect] ;
/* Figure out if we're all empty */
assign tx_empty = !(~fifo_rempty) ;
/* Increment fifo_rselect here */
always @(posedge fpga_clock)
begin
if (reset)
fifo_rselect <= {2**LOG2_N{1'b0}} ;
if (fifo_rempty[fifo_rselect])
fifo_rselect <= fifo_rselect + 1 ;
if (skip_packet)
fifo_rselect <= fifo_rselect + 1 ;
end
/* Increment fifo_wselect and pack data into 32 bits block */
always @(posedge usb_clock, reset)
begin
if (reset)
begin
fifo_wselect <= {2**LOG2_N{1'b0}} ;
word_complete <= 0;
end
if (fifo_wfull[fifo_wselect])
fifo_wselect <= fifo_wselect + 1 ;
if (write_enable)
begin
word_complete <= ~word_complete ;
if (word_complete)
fifo_wdata[fifo_wselect] <= {write_data_delayed, write_data} ;
else
write_data_delayed <= write_data ;
/* Avoid to continue to write in the previous fifo when we have
just swichted to the next one */
fifo_we[fifo_wselect-1] <= 0 ;
fifo_we[fifo_wselect] <= write_enable & word_complete ;
end
end
/* Generate all the single packet FIFOs */
generate
for( i = 0 ; i < 2**LOG2_N ; i = i + 1 )
begin : generate_single_packet_fifos
assign fifo_re[i] = (fifo_rselect == i) ? read_enable : 1'b0 ;
assign fifo_resets[i] = (fifo_rselect == i) ? skip_packet : 1'b0 ;
fifo_512 single_packet_fifo(.wrclk ( usb_clock ),
.rdclk ( fpga_clock ),
.aclr ( fifo_resets[i] ),
.wrreq ( fifo_we[i] ),
.data ( fifo_wdata[i] ),
.rdreq ( fifo_re[i] ),
.q ( fifo_rdata[i] ),
.rdfull ( fifo_rfull[i] ),
.rdempty( fifo_rempty[i] ),
.wrfull ( fifo_wfull[i] ),
.wrempty( fifo_wempty[i] ) ) ;
end
endgenerate
endmodule
|