Attention
This documentation is a work in progress. Expect to see errors and unfinished things.
mon_2chiq Source File
1`timescale 1ns / 1ns
2
3module mon_2chiq #(
4 parameter dwi=16, // data width
5 parameter rwi=28, // result width
6 // Difference between above two widths should be N*log2 of the maximum number
7 // of samples per CIC sample, where N=2 is the order of the CIC filter.
8 parameter davr=3, // how many guard bits to keep in output of multiplier
9 parameter dwlo=18 // Local Oscillator data width
10) (
11 input clk, // timespec 8.4 ns
12 input signed [dwi-1:0] iqd, // two-way interleaved data
13 input signed [17:0] scale, // e.g., 18'd61624 = floor((32/33)^2*2^16)
14 // Note that scale is typically positive; full-scale negative is not allowed
15 input iqs, // sync high when iq_data holds I, low when iq_data holds Q
16 input samp,
17 input signed [rwi-1:0] s_in,
18 output signed [rwi-1:0] s_out,
19 input g_in,
20 output g_out,
21 input reset
22);
23
24
25// Maybe wasteful, but use a multiplier so we can get full-scale to match between
26// input and output when using a non-binary CIC interval
27reg signed [18+dwi-1:0] product_iq=0, product_iq2=0;
28always @(posedge clk) begin
29 product_iq <= iqd * scale;
30 product_iq2 <= product_iq;
31end
32wire signed [dwi+davr-1:0] scaled_iq = product_iq2[18+dwi-2:18-davr-1];
33
34reg [1:0] iq_sync_sr=0;
35wire iq_syncx = iq_sync_sr[1];
36reg [dwi+davr-1:0] i_data0=0, i_data=0, q_data=0;
37always @(posedge clk) begin
38 iq_sync_sr <= {iq_sync_sr[0:0],iqs};
39 if ( iq_syncx) i_data0 <= scaled_iq;
40 if (~iq_syncx) q_data <= scaled_iq;
41 i_data <= i_data0; // Time-align the common case where I and Q are paired
42end
43
44reg [1:0] reset_r=0;
45always @(posedge clk) reset_r <= {reset_r[0],reset};
46
47wire signed [rwi-1:0] s_reg1, s_reg2;
48wire g_reg1, g_reg2;
49
50wire signed [rwi-1:0] i1out;
51double_inte #(.dwi(dwi+davr),.dwo(rwi)) i1(.clk(clk), .in(i_data), .out(i1out), .reset(reset_r[1]));
52serialize #(.dwi(rwi)) s1(.clk(clk), .samp(samp), .data_in(i1out),
53 .stream_in(s_reg2), .stream_out(s_reg1), .gate_in(g_reg2), .gate_out(g_reg1));
54
55wire signed [rwi-1:0] i2out;
56double_inte #(.dwi(dwi+davr),.dwo(rwi)) i2(.clk(clk), .in(q_data), .out(i2out), .reset(reset_r[1]));
57serialize #(.dwi(rwi)) s2(.clk(clk), .samp(samp), .data_in(i2out),
58 .stream_in(s_in), .stream_out(s_reg2), .gate_in(g_in), .gate_out(g_reg2));
59
60assign s_out = s_reg1;
61assign g_out = g_reg1;
62
63endmodule