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