Attention

This documentation is a work in progress. Expect to see errors and unfinished things.

ll_prop Source File

 1`timescale 1ns / 1ns
 2
 3// Keep the interface to this module simple:
 4//  all IQ inputs and outputs are co-phased,
 5//  i.e., I values when iq is high, Q values when iq is low.
 6module ll_prop(
 7     input clk,
 8     input iq,
 9     input signed [17:0] in_iq,
10     output signed [17:0] out_iq,
11     input [1:0] coarse_scale,  // max gain 8, 64, 512, 4096
12     // slowly varying control inputs, also IQ multiplexed
13     input signed [17:0] set_iq,
14     input signed [17:0] gain_iq,
15     input signed [17:0] drive_iq
16);
17
18`define SAT(x,old,new) ((~|x[old:new] | &x[old:new]) ? x[new:0] : {x[old],{new{~x[old]}}})
19
20reg signed [18:0] err_iq=0;
21reg signed [22:0] err_iq_s=0;
22reg signed [17:0] err_iq_lim=0;
23always @(posedge clk) begin
24     err_iq <= in_iq - set_iq;
25     err_iq_s <= coarse_scale[0] ? (err_iq <<< 4) : (err_iq <<< 1);
26     err_iq_lim <= `SAT(err_iq_s,22,17);
27end
28
29wire signed [17:0] prod_iq;
30complex_mul mul(.clk(clk), .gate_in(1'b1), .iq(iq),
31     .x(err_iq_lim), .y(gain_iq), .z(prod_iq));
32
33reg signed [25:0] prod_iq_s=0;
34reg signed [14:0] prod_iq_lim=0;  // max contribution 1/8 of full scale
35// add circular and/or configurable limit?
36// add peak/rms error monitoring?
37reg signed [18:0] sum_iq=0;
38reg signed [17:0] sum_iq_s=0;
39always @(posedge clk) begin
40     prod_iq_s <= coarse_scale[1] ? (prod_iq <<< 8) : (prod_iq <<< 2);
41     prod_iq_lim <= `SAT(prod_iq_s,25,14);
42     sum_iq <= prod_iq_lim + drive_iq;
43     sum_iq_s <= `SAT(sum_iq,18,17);
44end
45`undef SAT
46
47assign out_iq=sum_iq_s;
48
49endmodule