Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / inband_lib / tx_packer.v
1 module tx_packer
2    (     //FX2 Side
3                         input bus_reset, 
4                         input usbclk, 
5                         input WR_fx2, 
6                         input [15:0]usbdata,
7                         
8                         // TX Side
9                         input reset,
10                         input txclk,
11                         output reg [31:0] usbdata_final,
12                         output reg WR_final);
13
14         reg [8:0] write_count;
15
16         /* Fix FX2 bug */
17         always @(posedge usbclk)
18         begin
19         if(bus_reset)        // Use bus reset because this is on usbclk
20                 write_count <= #1 0;
21         else if(WR_fx2 & ~write_count[8])
22                 write_count <= #1 write_count + 9'd1;
23         else
24                 write_count <= #1 WR_fx2 ? write_count : 9'b0;
25         end
26         
27         reg WR_fx2_fixed;
28         reg [15:0]usbdata_fixed;
29         
30         always @(posedge usbclk) 
31         begin
32            WR_fx2_fixed <= WR_fx2 & ~write_count[8];
33            usbdata_fixed <= usbdata;
34         end
35
36         /* Used to convert 16 bits bus_data to the 32 bits wide fifo */
37     reg                             word_complete ;
38     reg     [15:0]                              usbdata_delayed ;
39     reg                             writing ;
40         wire    [31:0]                                  usbdata_packed ;    
41         wire                                                    WR_packed ;
42    
43     always @(posedge usbclk)
44     begin
45         if (bus_reset)
46           begin
47             word_complete <= 0 ;
48             writing <= 0 ;
49           end
50         else if (WR_fx2_fixed)
51           begin
52             writing <= 1 ;
53             if (word_complete)
54                 word_complete <= 0 ;
55             else
56               begin
57                 usbdata_delayed <= usbdata_fixed ;
58                 word_complete <= 1 ;
59               end
60           end
61         else
62             writing <= 0 ;
63         end
64     
65         assign usbdata_packed = {usbdata_fixed, usbdata_delayed} ;
66     assign WR_packed = word_complete & writing ;
67
68         /* Make sure data are sync with usbclk */
69         reg [31:0]usbdata_usbclk;
70         reg WR_usbclk; 
71     
72     always @(posedge usbclk)
73     begin
74         if (WR_packed)
75                 usbdata_usbclk <= usbdata_packed;
76         WR_usbclk <= WR_packed;
77     end
78
79         /* Cross clock boundaries */
80         reg [31:0] usbdata_tx ;
81         reg WR_tx;
82     reg WR_1;
83     reg WR_2;
84   
85         always @(posedge txclk) usbdata_tx <= usbdata_usbclk;
86
87     always @(posedge txclk) 
88         if (reset)
89                 WR_1 <= 0;
90         else
91                 WR_1 <= WR_usbclk;
92
93     always @(posedge txclk) 
94         if (reset)
95                 WR_2 <= 0;
96         else
97                 WR_2 <= WR_1;
98
99         always @(posedge txclk)
100         begin
101                 if (reset)
102                         WR_tx <= 0;
103                 else
104                    WR_tx <= WR_1 & ~WR_2;
105         end
106         
107         always @(posedge txclk)
108         begin
109            if (reset)
110               WR_final <= 0;
111            else
112            begin
113               WR_final <= WR_tx; 
114               if (WR_tx)
115                  usbdata_final <= usbdata_tx;
116            end
117         end
118
119 endmodule