Attention
This documentation is a work in progress. Expect to see errors and unfinished things.
upconv Source File
1`timescale 1ns / 1ns
2
3module upconv(
4 input clk,
5 input signed [15:0] in_d, // baseband, interleaved I and Q
6 input in_strobe, // Set at I time, Q follows
7 input signed [15:0] cos, // LO input
8 input signed [15:0] sin, // LO input
9 output signed [15:0] cos_interp, // interpolated output immediately before upconversion
10 output signed [15:0] sin_interp,
11 output signed [15:0] out_d // at IF
12);
13
14reg in_strobe1=0;
15always @(posedge clk) in_strobe1 <= in_strobe;
16
17wire signed [17:0] d2out;
18wire d2strobe0;
19doublediff #(.dw(18), .dsr_len(2)) d2dt2(.clk(clk),
20 .d_in({{2{in_d[15]}},in_d}), .g_in(in_strobe|in_strobe1),
21 .d_out(d2out), .g_out(d2strobe0)
22);
23
24reg signed [17:0] d2out_d=0, d2i=0, d2q=0;
25reg d2strobe1=0, d2strobe2=0;
26always @(posedge clk) begin
27 d2out_d <= d2out;
28 d2strobe1 <= d2strobe0;
29 d2strobe2 <= d2strobe1;
30 if (d2strobe1&~d2strobe2) d2i <= d2out_d;
31 if (d2strobe1&~d2strobe2) d2q <= d2out;
32
33end
34
35wire signed [15:0] i2i, i2q;
36interp1 inti(.clk(clk), .x(d2i), .y(i2i));
37interp1 intq(.clk(clk), .x(d2q), .y(i2q));
38
39`define SAT(x,old,new) ((~|x[old:new] | &x[old:new]) ? x[new:0] : {x[old],{new{~x[old]}}})
40reg signed [31:0] cosp=0, sinp=0;
41wire signed [17:0] cosp_msb = cosp[30:13];
42wire signed [17:0] sinp_msb = sinp[30:13];
43reg signed [18:0] sum=0;
44reg signed [16:0] sum2=0;
45always @(posedge clk) begin
46 cosp <= i2i*cos;
47 sinp <= i2q*sin;
48 sum <= cosp_msb + sinp_msb + 1;
49 sum2 <= `SAT(sum,18,16);
50end
51assign out_d = sum2[16:1];
52
53assign cos_interp = i2i;
54assign sin_interp = i2q;
55`undef SAT
56
57endmodule