Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top...
[debian/gnuradio] / usrp2 / fpga / sdr_lib / dsp_core_tx.v
1
2 `define DSP_CORE_TX_BASE 128
3
4 module dsp_core_tx
5   (input clk, input rst,
6    input set_stb, input [7:0] set_addr, input [31:0] set_data,
7
8    output reg [15:0] dac_a,
9    output reg [15:0] dac_b,
10
11    // To tx_control
12    input [31:0] sample,
13    input run,
14    output strobe,
15    output [31:0] debug
16    );
17
18    wire [15:0] i, q, scale_i, scale_q;
19    wire [31:0] phase_inc;
20    reg [31:0]  phase;
21    wire [7:0]  interp_rate;
22
23    wire        enable_hb1, enable_hb2;
24
25    setting_reg #(.my_addr(`DSP_CORE_TX_BASE+0)) sr_0
26      (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
27       .in(set_data),.out(phase_inc),.changed());
28
29    setting_reg #(.my_addr(`DSP_CORE_TX_BASE+1)) sr_1
30      (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
31       .in(set_data),.out({scale_i,scale_q}),.changed());
32    
33    setting_reg #(.my_addr(`DSP_CORE_TX_BASE+2)) sr_2
34      (.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr),
35       .in(set_data),.out({enable_hb1, enable_hb2, interp_rate}),.changed());
36
37    // Strobes are all now delayed by 1 cycle for timing reasons
38    wire        strobe_cic_pre, strobe_hb1_pre, strobe_hb2_pre;
39    reg         strobe_cic = 1;
40    reg         strobe_hb1 = 1;
41    reg         strobe_hb2 = 1;
42    
43    cic_strober #(.WIDTH(8))
44      cic_strober(.clock(clk),.reset(rst),.enable(run),.rate(interp_rate),
45                  .strobe_fast(1),.strobe_slow(strobe_cic_pre) );
46    cic_strober #(.WIDTH(2))
47      hb2_strober(.clock(clk),.reset(rst),.enable(run),.rate(enable_hb2 ? 2 : 1),
48                  .strobe_fast(strobe_cic_pre),.strobe_slow(strobe_hb2_pre) );
49    cic_strober #(.WIDTH(2))
50      hb1_strober(.clock(clk),.reset(rst),.enable(run),.rate(enable_hb1 ? 2 : 1),
51                  .strobe_fast(strobe_hb2_pre),.strobe_slow(strobe_hb1_pre) );
52    
53    always @(posedge clk) strobe_hb1 <= strobe_hb1_pre;
54    always @(posedge clk) strobe_hb2 <= strobe_hb2_pre;
55    always @(posedge clk) strobe_cic <= strobe_cic_pre;
56
57    // DDC
58    always @(posedge clk)
59      if(rst)
60        phase <= 0;
61      else if(run)
62        phase <= phase + phase_inc;
63    
64    wire        signed [17:0] da, db;
65    wire        signed [35:0] prod_i, prod_q;
66
67    wire [17:0] bb_i = {sample[31:16],2'b0};
68    wire [17:0] bb_q = {sample[15:0],2'b0};
69    wire [17:0] i_interp, q_interp;
70
71    wire [17:0] hb1_i, hb1_q, hb2_i, hb2_q;
72
73    wire [7:0]  cpo = enable_hb2 ? ({interp_rate,1'b0}) : interp_rate;
74    // Note that max CIC rate is 128, which would give an overflow on cpo if enable_hb2 is true,
75    //   but the default case inside hb_interp handles this
76    
77    hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_i
78      (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_i),.stb_out(strobe_hb2),.data_out(hb1_i));
79    hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_q
80      (.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_q),.stb_out(strobe_hb2),.data_out(hb1_q));
81    
82    small_hb_int #(.WIDTH(18)) small_hb_interp_i
83      (.clk(clk),.rst(rst),.bypass(~enable_hb2),.stb_in(strobe_hb2),.data_in(hb1_i),
84       .output_rate(interp_rate),.stb_out(strobe_cic),.data_out(hb2_i));
85    small_hb_int #(.WIDTH(18)) small_hb_interp_q
86      (.clk(clk),.rst(rst),.bypass(~enable_hb2),.stb_in(strobe_hb2),.data_in(hb1_q),
87       .output_rate(interp_rate),.stb_out(strobe_cic),.data_out(hb2_q));
88    
89    cic_interp  #(.bw(18),.N(4),.log2_of_max_rate(7))
90      cic_interp_i(.clock(clk),.reset(rst),.enable(run),.rate(interp_rate),
91                   .strobe_in(strobe_cic),.strobe_out(1),
92                   .signal_in(hb2_i),.signal_out(i_interp));
93    
94    cic_interp  #(.bw(18),.N(4),.log2_of_max_rate(7))
95      cic_interp_q(.clock(clk),.reset(rst),.enable(run),.rate(interp_rate),
96                   .strobe_in(strobe_cic),.strobe_out(1),
97                   .signal_in(hb2_q),.signal_out(q_interp));
98
99    assign      strobe = strobe_hb1;
100                    
101    cordic #(.bitwidth(18),.zwidth(16))
102      cordic(.clock(clk), .reset(rst), .enable(run),
103             .xi(i_interp),.yi(q_interp),.zi(phase[31:16]),
104             .xo(da),.yo(db),.zo() );
105    
106    MULT18X18S MULT18X18S_inst 
107      (.P(prod_i),    // 36-bit multiplier output
108       .A(da),    // 18-bit multiplier input
109       .B({{2{scale_i[15]}},scale_i}),    // 18-bit multiplier input
110       .C(clk),    // Clock input
111       .CE(1),  // Clock enable input
112       .R(rst)     // Synchronous reset input
113       );
114    
115    MULT18X18S MULT18X18S_inst_2 
116      (.P(prod_q),    // 36-bit multiplier output
117       .A(db),    // 18-bit multiplier input
118       .B({{2{scale_q[15]}},scale_q}),    // 18-bit multiplier input
119       .C(clk),    // Clock input
120       .CE(1),  // Clock enable input
121       .R(rst)     // Synchronous reset input
122       );
123    
124    always @(posedge clk)
125      dac_a <= prod_i[28:13];
126    
127    always @(posedge clk)
128      dac_b <= prod_q[28:13];
129
130    assign      debug = {strobe_cic, strobe_hb1, strobe_hb2,run};
131
132 endmodule // dsp_core