distcheck fix for gr-gcell
[debian/gnuradio] / usrp / fpga / inband_lib / usb_fifo_writer.v
1
2 module usb_fifo_writer
3    #(parameter BUS_WIDTH = 16,
4      parameter NUM_CHAN = 2,
5      parameter FIFO_WIDTH = 32)
6    (     //FX2 Side
7                         input bus_reset, 
8                         input usbclk, 
9                         input WR_fx2, 
10                         input [15:0]usbdata,
11                         
12                         // TX Side
13                         input reset,
14                         input txclk,
15                         output reg [NUM_CHAN:0] WR_channel,
16                         output reg [FIFO_WIDTH-1:0] ram_data,
17                         output reg [NUM_CHAN:0] WR_done_channel );
18    
19
20         reg [8:0] write_count;
21
22         /* Fix FX2 bug */
23         always @(posedge usbclk)
24         if(bus_reset)        // Use bus reset because this is on usbclk
25                 write_count <= #1 0;
26         else if(WR_fx2 & ~write_count[8])
27                 write_count <= #1 write_count + 9'd1;
28         else
29                 write_count <= #1 WR_fx2 ? write_count : 9'b0;
30
31         reg WR_fx2_fixed;
32         reg [15:0]usbdata_fixed;
33         
34         always @(posedge usbclk) 
35         begin
36            WR_fx2_fixed <= WR_fx2 & ~write_count[8];
37            usbdata_fixed <= usbdata;
38         end
39
40         /* Used to convert 16 bits bus_data to the 32 bits wide fifo */
41     reg                             word_complete ;
42     reg     [BUS_WIDTH-1:0]         usbdata_delayed ;
43     reg                             writing ;
44         wire    [FIFO_WIDTH-1:0]                usbdata_packed ;    
45         wire                                                    WR_packed ;
46    
47     always @(posedge usbclk)
48     begin
49         if (bus_reset)
50           begin
51             word_complete <= 0 ;
52             writing <= 0 ;
53           end
54         else if (WR_fx2_fixed)
55           begin
56             writing <= 1 ;
57             if (word_complete)
58                 word_complete <= 0 ;
59             else
60               begin
61                 usbdata_delayed <= usbdata_fixed ;
62                 word_complete <= 1 ;
63               end
64           end
65         else
66             writing <= 0 ;
67         end
68     
69         assign usbdata_packed = {usbdata_fixed, usbdata_delayed} ;
70     assign WR_packed = word_complete & writing ;
71
72         /* Make sure data are sync with usbclk */
73         reg [31:0]usbdata_usbclk;
74         reg WR_usbclk; 
75     
76     always @(posedge usbclk)
77     begin
78         if (WR_packed)
79                 usbdata_usbclk <= usbdata_packed;
80         WR_usbclk <= WR_packed;
81     end
82
83         /* Cross clock boundaries */
84         reg [FIFO_WIDTH-1:0] usbdata_tx ;
85         reg WR_tx;
86     reg WR_1;
87     reg WR_2;
88         reg [31:0] usbdata_final;
89         reg WR_final;
90    
91         always @(posedge txclk) usbdata_tx <= usbdata_usbclk;
92
93     always @(posedge txclk) 
94         if (reset)
95                 WR_1 <= 0;
96         else
97                 WR_1 <= WR_usbclk;
98
99     always @(posedge txclk) 
100         if (reset)
101                 WR_2 <= 0;
102         else
103                 WR_2 <= WR_1;
104
105         always @(posedge txclk)
106         begin
107                 if (reset)
108                         WR_tx <= 0;
109                 else
110                    WR_tx <= WR_1 & ~WR_2;
111         end
112         
113         always @(posedge txclk)
114         begin
115            if (reset)
116               WR_final <= 0;
117            else
118            begin
119               WR_final <= WR_tx; 
120               if (WR_tx)
121                  usbdata_final <= usbdata_tx;
122            end
123         end
124              
125         /* Parse header and forward to ram */
126         reg [3:0]reader_state;
127         reg [4:0]channel ;
128         reg [9:0]read_length ;
129         
130         parameter IDLE = 4'd0;
131         parameter HEADER = 4'd1;
132         parameter WAIT = 4'd2;
133         parameter FORWARD = 4'd3;
134         
135         `define CHANNEL 20:16
136         `define PKT_SIZE 512
137         
138         always @(posedge txclk)
139         begin
140             if (reset)
141               begin
142                reader_state <= 0;
143                WR_channel <= 0;
144                WR_done_channel <= 0;
145               end
146               else
147                 case (reader_state)
148                 IDLE: begin
149                     if (WR_final)
150                         reader_state <= HEADER; 
151                     end
152                
153             // Store channel and forware header
154                 HEADER: begin
155                     channel <= (usbdata_final[`CHANNEL] == 5'h1f ? NUM_CHAN : usbdata_final[`CHANNEL]) ;
156                     WR_channel[(usbdata_final[`CHANNEL] == 5'h1f ? NUM_CHAN : usbdata_final[`CHANNEL])] <= 1;
157                                 //channel <= usbdata_final[`CHANNEL] ;
158                     //WR_channel[usbdata_final[`CHANNEL]] <= 1;
159                     ram_data <= usbdata_final;
160                                 read_length <= 10'd4 ;
161                                 
162                 reader_state <= WAIT;
163                 end
164                
165                 WAIT: begin
166                    WR_channel[channel] <= 0;
167         
168                            if (read_length == `PKT_SIZE)
169                        reader_state <= IDLE;
170                    else if (WR_final)
171                        reader_state <= FORWARD;
172                 end
173                
174                 FORWARD: begin
175                    WR_channel[channel] <= 1;
176                    ram_data <= usbdata_final;
177                    read_length <= read_length + 10'd4;
178                    
179                    reader_state <= WAIT;
180                 end
181                endcase
182         end
183 endmodule