source: PlatformSupport/CustomPeripherals/pcores/w3_ad_bridge_v3_03_b/hdl/verilog/w3_ad_bridge.v

Last change on this file was 5776, checked in by murphpo, 7 years ago

Updated w3_ad_bridge for better handling of TRXCLK phase differences across co-clocked interfaces

File size: 5.0 KB
Line 
1module w3_ad_bridge
2(
3    input sys_clk,
4    output samp_ce,
5   
6    // Enable (active-high) for AD_TXCLK output
7    // AD9963 TXCLK pin defaults to output, configured as input via SPI by ad_controller at boot
8    input ad_TXCLK_out_en,
9   
10    //RF Path A User Ports
11    output reg [0:11] user_RFA_RXD_I,
12    output reg [0:11] user_RFA_RXD_Q,
13
14    input [0:11] user_RFA_TXD_I,
15    input [0:11] user_RFA_TXD_Q,
16
17    input user_RFA_TXIQ,
18
19    //RF Path B User Ports
20    output reg [0:11] user_RFB_RXD_I,
21    output reg [0:11] user_RFB_RXD_Q,
22
23    input [0:11] user_RFB_TXD_I,
24    input [0:11] user_RFB_TXD_Q,
25
26    input user_RFB_TXIQ,
27
28    //RF Path A AD ports
29    output reg [0:11] ad_RFA_TXD,
30    output ad_RFA_TXIQ,
31    output ad_RFA_TXCLK,
32
33    input [0:11] ad_RFA_TRXD,
34    input ad_RFA_TRXIQ,
35    input ad_RFA_TRXCLK,
36
37    //RF Path B AD ports
38    output reg [0:11] ad_RFB_TXD,
39    output ad_RFB_TXIQ,
40    output ad_RFB_TXCLK,
41
42    input [0:11] ad_RFB_TRXD,
43    input ad_RFB_TRXIQ,
44    input ad_RFB_TRXCLK
45);
46
47parameter C_FAMILY = "virtex6";
48
49//Unsued in ref designs - pass through here
50assign ad_RFA_TXIQ = user_RFA_TXIQ;
51assign ad_RFB_TXIQ = user_RFB_TXIQ;
52
53reg ad_RFA_TRXCLK_d1, ad_RFA_TRXCLK_d2;
54reg ad_RFB_TRXCLK_d1, ad_RFB_TRXCLK_d2;
55
56reg ad_RFA_TRXCLK_pos, ad_RFA_TRXCLK_neg, ad_RFA_TRXCLK_neg_d1;
57reg ad_RFB_TRXCLK_pos, ad_RFB_TRXCLK_neg, ad_RFB_TRXCLK_neg_d1;
58
59reg [0:11] user_RFA_TXD_I_d;
60reg [0:11] user_RFA_TXD_Q_d;
61
62reg [0:11] user_RFB_TXD_I_d;
63reg [0:11] user_RFB_TXD_Q_d;
64
65reg [0:11] user_RFA_RXD_I_d, user_RFA_RXD_Q_d;
66reg [0:11] user_RFB_RXD_I_d, user_RFB_RXD_Q_d;
67
68wire rx_samp_reg_en_A, rx_samp_reg_en_B;
69
70always @(posedge sys_clk)
71begin
72    ad_RFA_TRXCLK_d1 <= ad_RFA_TRXCLK;
73    ad_RFA_TRXCLK_d2 <= ad_RFA_TRXCLK_d1;
74
75    ad_RFB_TRXCLK_d1 <= ad_RFB_TRXCLK;
76    ad_RFB_TRXCLK_d2 <= ad_RFB_TRXCLK_d1;
77
78    ad_RFA_TRXCLK_pos <= ad_RFA_TRXCLK_d1 & ~ad_RFA_TRXCLK_d2;
79
80    ad_RFB_TRXCLK_pos <= ad_RFB_TRXCLK_d1 & ~ad_RFB_TRXCLK_d2;
81   
82    ad_RFA_TRXCLK_neg <= ~ad_RFA_TRXCLK_d1 & ad_RFA_TRXCLK_d2;
83    ad_RFA_TRXCLK_neg_d1 <= ad_RFA_TRXCLK_neg;
84
85    ad_RFB_TRXCLK_neg <= ~ad_RFB_TRXCLK_d1 & ad_RFB_TRXCLK_d2;
86    ad_RFB_TRXCLK_neg_d1 <= ad_RFB_TRXCLK_neg;
87end
88
89// Tx sample capture
90always @(posedge sys_clk)
91begin
92    if(samp_ce)
93    begin
94        user_RFA_TXD_I_d <= user_RFA_TXD_I;
95        user_RFA_TXD_Q_d <= user_RFA_TXD_Q;
96        user_RFB_TXD_I_d <= user_RFB_TXD_I;
97        user_RFB_TXD_Q_d <= user_RFB_TXD_Q;
98    end
99    else
100    begin
101        user_RFA_TXD_I_d <= user_RFA_TXD_I_d;
102        user_RFA_TXD_Q_d <= user_RFA_TXD_Q_d;
103        user_RFB_TXD_I_d <= user_RFB_TXD_I_d;
104        user_RFB_TXD_Q_d <= user_RFB_TXD_Q_d;
105    end
106end
107
108// Rx sample capture
109always @(posedge sys_clk)
110begin
111    if(rx_samp_reg_en_A)
112    begin
113        user_RFA_RXD_I <= user_RFA_RXD_I_d;
114        user_RFA_RXD_Q <= user_RFA_RXD_Q_d;
115    end
116    else
117    begin
118        user_RFA_RXD_I <= user_RFA_RXD_I;
119        user_RFA_RXD_Q <= user_RFA_RXD_Q;
120    end
121end
122always @(posedge sys_clk)
123begin
124    if(rx_samp_reg_en_B)
125    begin
126        user_RFB_RXD_I <= user_RFB_RXD_I_d;
127        user_RFB_RXD_Q <= user_RFB_RXD_Q_d;
128    end
129    else
130    begin
131        user_RFB_RXD_I <= user_RFB_RXD_I;
132        user_RFB_RXD_Q <= user_RFB_RXD_Q;
133    end
134end
135
136// Sample enable output to PHY
137assign samp_ce = ad_RFA_TRXCLK_neg_d1;
138
139// Per-ADC sample enables
140assign rx_samp_reg_en_A = ad_RFA_TRXCLK_neg_d1;
141assign rx_samp_reg_en_B = ad_RFB_TRXCLK_neg_d1;
142
143wire ad_RFA_TXCLK_o;
144wire ad_RFB_TXCLK_o;
145
146// Use RF A TRXCLK to generate both TXCLK signals
147//  This allows single samp_ce to PHY Tx to generate valid
148//  sample streams for both Tx interfaces even when TRXCLK
149//  phases are different across interfaces
150assign ad_RFA_TXCLK_o = ~ad_RFA_TRXCLK_d1;
151assign ad_RFB_TXCLK_o = ~ad_RFA_TRXCLK_d1;
152
153OBUFT OBUFT_RFA_TXCLK (
154    .I(ad_RFA_TXCLK_o),
155    .T(~ad_TXCLK_out_en),
156    .O(ad_RFA_TXCLK)
157);
158OBUFT OBUFT_RFB_TXCLK (
159    .I(ad_RFB_TXCLK_o),
160    .T(~ad_TXCLK_out_en),
161    .O(ad_RFB_TXCLK)
162);
163
164
165always @(posedge sys_clk)
166begin
167    if(ad_RFA_TRXCLK_pos || ad_RFA_TRXCLK_neg)
168    begin
169        if(ad_RFA_TRXIQ)
170            user_RFA_RXD_I_d <= ad_RFA_TRXD;
171        else
172            user_RFA_RXD_Q_d <= ad_RFA_TRXD;
173    end
174    else
175    begin
176        user_RFA_RXD_I_d <= user_RFA_RXD_I_d;
177        user_RFA_RXD_Q_d <= user_RFA_RXD_Q_d;
178    end
179end
180
181// Tx PHY uses samp_ce to generate samples; use same source (RFA_TRXCLK) to drive those samples
182//  to both DACs. This may introduce a half-sample delay between RFA and RFB but will at least
183//  ensure the sequence of IQ values written to TXD is valid for both converters.
184always @(posedge sys_clk)
185begin
186    if(ad_RFA_TRXCLK_pos)
187    begin
188        ad_RFA_TXD <= user_RFA_TXD_I_d;
189        ad_RFB_TXD <= user_RFB_TXD_I_d;
190    end
191    else if(ad_RFA_TRXCLK_neg)
192    begin
193        ad_RFA_TXD <= user_RFA_TXD_Q_d;
194        ad_RFB_TXD <= user_RFB_TXD_Q_d;
195    end
196    else
197    begin
198        ad_RFA_TXD <= ad_RFA_TXD;
199        ad_RFB_TXD <= ad_RFB_TXD;
200    end
201end
202
203always @(posedge sys_clk)
204begin
205    if(ad_RFB_TRXCLK_pos || ad_RFB_TRXCLK_neg)
206    begin
207        if(ad_RFB_TRXIQ)
208            user_RFB_RXD_I_d <= ad_RFB_TRXD;
209        else
210            user_RFB_RXD_Q_d <= ad_RFB_TRXD;
211    end
212    else
213    begin
214        user_RFB_RXD_I_d <= user_RFB_RXD_I_d;
215        user_RFB_RXD_Q_d <= user_RFB_RXD_Q_d;
216    end
217end
218/*
219always @(posedge sys_clk)
220begin
221    if(ad_RFB_TRXCLK_pos)
222    begin
223        ad_RFB_TXD <= user_RFB_TXD_I_d;
224    end
225    else if(ad_RFB_TRXCLK_neg)
226    begin
227        ad_RFB_TXD <= user_RFB_TXD_Q_d;
228    end
229    else
230    begin
231        ad_RFB_TXD <= ad_RFB_TXD;
232    end
233end
234*/
235endmodule
Note: See TracBrowser for help on using the repository browser.