blob: abe1dd5678d1f35603ae3111df1e9fcafce5fc49 (
plain)
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
module usb_fifo_writer
#(parameter BUS_WIDTH = 16,
parameter NUM_CHAN = 2,
parameter FIFO_WIDTH = 32)
( //FX2 Side
input bus_reset,
input usbclk,
input WR_fx2,
input [15:0]usbdata,
// TX Side
input reset,
input txclk,
output reg [NUM_CHAN:0] WR_channel,
output reg [FIFO_WIDTH-1:0] ram_data,
output reg [NUM_CHAN:0] WR_done_channel );
reg [8:0] write_count;
/* Fix FX2 bug */
always @(posedge usbclk)
if(bus_reset) // Use bus reset because this is on usbclk
write_count <= #1 0;
else if(WR_fx2 & ~write_count[8])
write_count <= #1 write_count + 9'd1;
else
write_count <= #1 WR_fx2 ? write_count : 9'b0;
reg WR_fx2_fixed;
reg [15:0]usbdata_fixed;
always @(posedge usbclk)
begin
WR_fx2_fixed <= WR_fx2 & ~write_count[8];
usbdata_fixed <= usbdata;
end
/* Used to convert 16 bits bus_data to the 32 bits wide fifo */
reg word_complete ;
reg [BUS_WIDTH-1:0] usbdata_delayed ;
reg writing ;
wire [FIFO_WIDTH-1:0] usbdata_packed ;
wire WR_packed ;
always @(posedge usbclk)
begin
if (bus_reset)
begin
word_complete <= 0 ;
writing <= 0 ;
end
else if (WR_fx2_fixed)
begin
writing <= 1 ;
if (word_complete)
word_complete <= 0 ;
else
begin
usbdata_delayed <= usbdata_fixed ;
word_complete <= 1 ;
end
end
else
writing <= 0 ;
end
assign usbdata_packed = {usbdata_fixed, usbdata_delayed} ;
assign WR_packed = word_complete & writing ;
/* Make sure data are sync with usbclk */
reg [31:0]usbdata_usbclk;
reg WR_usbclk;
always @(posedge usbclk)
begin
if (WR_packed)
usbdata_usbclk <= usbdata_packed;
WR_usbclk <= WR_packed;
end
/* Cross clock boundaries */
reg [FIFO_WIDTH-1:0] usbdata_tx ;
reg WR_tx;
reg WR_1;
reg WR_2;
reg [31:0] usbdata_final;
reg WR_final;
always @(posedge txclk) usbdata_tx <= usbdata_usbclk;
always @(posedge txclk)
if (reset)
WR_1 <= 0;
else
WR_1 <= WR_usbclk;
always @(posedge txclk)
if (reset)
WR_2 <= 0;
else
WR_2 <= WR_1;
always @(posedge txclk)
begin
if (reset)
WR_tx <= 0;
else
WR_tx <= WR_1 & ~WR_2;
end
always @(posedge txclk)
begin
if (reset)
WR_final <= 0;
else
begin
WR_final <= WR_tx;
if (WR_tx)
usbdata_final <= usbdata_tx;
end
end
/* Parse header and forward to ram */
reg [3:0]reader_state;
reg [4:0]channel ;
reg [9:0]read_length ;
parameter IDLE = 4'd0;
parameter HEADER = 4'd1;
parameter WAIT = 4'd2;
parameter FORWARD = 4'd3;
`define CHANNEL 20:16
`define PKT_SIZE 512
always @(posedge txclk)
begin
if (reset)
begin
reader_state <= 0;
WR_channel <= 0;
WR_done_channel <= 0;
end
else
case (reader_state)
IDLE: begin
if (WR_final)
reader_state <= HEADER;
end
// Store channel and forware header
HEADER: begin
channel <= (usbdata_final[`CHANNEL] == 5'h1f ? NUM_CHAN : usbdata_final[`CHANNEL]) ;
WR_channel[(usbdata_final[`CHANNEL] == 5'h1f ? NUM_CHAN : usbdata_final[`CHANNEL])] <= 1;
//channel <= usbdata_final[`CHANNEL] ;
//WR_channel[usbdata_final[`CHANNEL]] <= 1;
ram_data <= usbdata_final;
read_length <= 10'd4 ;
reader_state <= WAIT;
end
WAIT: begin
WR_channel[channel] <= 0;
if (read_length == `PKT_SIZE)
reader_state <= IDLE;
else if (WR_final)
reader_state <= FORWARD;
end
FORWARD: begin
WR_channel[channel] <= 1;
ram_data <= usbdata_final;
read_length <= read_length + 10'd4;
reader_state <= WAIT;
end
endcase
end
endmodule
|