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