313 lines
10 KiB
Verilog
313 lines
10 KiB
Verilog
// * Engineer:
|
|
// * *************************************************** *
|
|
// * ███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗ *
|
|
// * ╚══███╔╝██╔═══██╗██╔══██╗██╔═══██╗██╔════╝ ██║ ██║ *
|
|
// * ███╔╝ ██║ ██║██████╔╝██║ ██║██║ ███╗███████║ *
|
|
// * ███╔╝ ██║ ██║██╔══██╗██║ ██║██║ ██║██╔══██║ *
|
|
// * ███████╗╚██████╔╝██║ ██║╚██████╔╝╚██████╔╝██║ ██║ *
|
|
// * ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ *
|
|
// * *************************************************** *
|
|
// * Update Date: 2024/7/16
|
|
// * NOTE : this file use the sign bit number to estimate the
|
|
// * NOTE : signal power, the drawback of this module is that
|
|
// * NOTE : little amplitude over the threhold will be treated
|
|
// * NOTE : as overflow, thus indicating a flag_too_high pulse
|
|
// * NOTE :
|
|
// * NOTE : as improvemnt, we can use a number as the threshold
|
|
// * NOTE : such as 1800 ( under the 12bit input ).
|
|
// * NOTE :
|
|
|
|
module power_measure (
|
|
input clk,
|
|
input rst,
|
|
input start,
|
|
// data input
|
|
input wire [11:0] data_i,
|
|
input wire [11:0] data_q,
|
|
output reg flag_too_high,
|
|
output reg flag_too_low,
|
|
output reg power_measure_done_pulse
|
|
);
|
|
|
|
localparam CNT_WAIT_9361_MAX = 80; //* 等待周期数
|
|
localparam CNT_MEASURING_MAX = 256; // * 观察64个周期
|
|
localparam CNT_ADJUST_TIMES_MAX = 25;
|
|
localparam CNT_AMP_TOO_HIGH_THRESHOLD = 6;
|
|
// ******** Wire & Reg ********
|
|
|
|
// * NOTE: during measuring, the sign bit numbers changes .
|
|
// * NOTE: as the signal amplitude(power) changes.
|
|
// * NOTE: thus, measuring the sign bit numbers can indicate
|
|
// * NOTE: the power of the signal.
|
|
// * NOTE:
|
|
// * NOTE: the sign bit number min, represents the minimum of
|
|
// * NOTE: the sign bit number, meaning the highest signal power.
|
|
// * NOTE: if sign_bit_num_min_* is too small (1 or 2), we should
|
|
// * NOTE: decrease the input signal power.
|
|
// * NOTE:
|
|
// * NOTE: reversely, the sign_bit_num_max_* means the maximum of
|
|
// * NOTE: the amplitude, if signal power is too small, it will be
|
|
// * NOTE: small, indicating increasing the input signal power.
|
|
// * NOTE:
|
|
// * NOTE: for a modulated signal, the power can not be indicated by
|
|
// * NOTE: max sign bit number, so we should only control the min sign
|
|
// * NOTE: bit numer.
|
|
|
|
reg [ 3:0] sign_bit_num_i;
|
|
reg [ 3:0] sign_bit_num_min_i;
|
|
reg [ 3:0] sign_bit_num_q;
|
|
reg [ 3:0] sign_bit_num_min_q;
|
|
|
|
// startup
|
|
reg [ 7:0] cnt_startup; // set rx gain to max each time start posedge comes
|
|
reg [ 3:0] cnt_amp_too_high; // for short cuirt
|
|
|
|
// abs
|
|
reg [11:0] data_i_abs;
|
|
reg [11:0] data_q_abs;
|
|
|
|
// measuring the signal power
|
|
reg [15:0] cnt_measuring;
|
|
// for waiting ad9361 adjust done
|
|
reg [15:0] cnt_wait_9361;
|
|
// the times fsm have adjust already
|
|
reg [ 7:0] cnt_adjust_times;
|
|
|
|
// fsm var
|
|
localparam S_MEASURE_IDLE = 0;
|
|
localparam S_MEASURE_ING = 1;
|
|
localparam S_MEASURE_DONE = 2;
|
|
localparam S_MEASURE_ADJ = 3;
|
|
localparam S_MEASURE_STARTUP = 4;
|
|
|
|
reg [2:0] cs = S_MEASURE_IDLE;
|
|
reg [2:0] ns = S_MEASURE_IDLE;
|
|
|
|
|
|
// ******** Assingment ********
|
|
|
|
|
|
// ******** Logic Block ********
|
|
|
|
always @(posedge clk) begin
|
|
if (rst || start) begin
|
|
cnt_startup <= 0;
|
|
end
|
|
else if (cs == S_MEASURE_STARTUP && cnt_startup < 255) begin
|
|
cnt_startup <= cnt_startup + 1;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
cs <= S_MEASURE_IDLE;
|
|
end
|
|
else begin
|
|
cs <= ns;
|
|
end
|
|
end
|
|
|
|
// fsm
|
|
always @(*) begin
|
|
case (cs)
|
|
|
|
S_MEASURE_IDLE: begin
|
|
if (start) begin
|
|
ns = S_MEASURE_STARTUP;
|
|
end
|
|
else begin
|
|
ns = S_MEASURE_IDLE;
|
|
end
|
|
end
|
|
|
|
S_MEASURE_STARTUP: begin
|
|
if (cnt_startup == 255) begin
|
|
ns = S_MEASURE_ING;
|
|
end
|
|
else begin
|
|
ns = S_MEASURE_STARTUP;
|
|
end
|
|
end
|
|
|
|
S_MEASURE_ING: begin
|
|
if (cnt_measuring == CNT_MEASURING_MAX - 1 || cnt_amp_too_high == CNT_AMP_TOO_HIGH_THRESHOLD - 1) begin
|
|
ns = S_MEASURE_DONE;
|
|
end
|
|
else begin
|
|
ns = S_MEASURE_ING;
|
|
end
|
|
end
|
|
|
|
S_MEASURE_DONE: begin
|
|
ns = S_MEASURE_ADJ;
|
|
end
|
|
|
|
S_MEASURE_ADJ: begin
|
|
// mgc adjust done
|
|
if (cnt_adjust_times == CNT_ADJUST_TIMES_MAX - 1) begin
|
|
ns = S_MEASURE_IDLE;
|
|
end
|
|
// wait ad9361 feedback
|
|
else if (cnt_wait_9361 == CNT_WAIT_9361_MAX - 1) begin
|
|
ns = S_MEASURE_ING;
|
|
end
|
|
else begin
|
|
ns = S_MEASURE_ADJ;
|
|
end
|
|
end
|
|
|
|
default: begin
|
|
ns = S_MEASURE_IDLE;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (cs == S_MEASURE_ING) begin
|
|
cnt_measuring <= cnt_measuring + 1;
|
|
end
|
|
else begin
|
|
cnt_measuring <= 0;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (cs == S_MEASURE_ADJ) begin
|
|
cnt_wait_9361 <= cnt_wait_9361 + 1;
|
|
end
|
|
else begin
|
|
cnt_wait_9361 <= 0;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (cs == S_MEASURE_DONE) begin
|
|
cnt_adjust_times <= cnt_adjust_times + 1;
|
|
end
|
|
else if (cs == S_MEASURE_IDLE) begin
|
|
cnt_adjust_times <= 0;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (cs == S_MEASURE_ING && (sign_bit_num_i == 1 || sign_bit_num_q == 1)) begin
|
|
cnt_amp_too_high <= cnt_amp_too_high + 1;
|
|
end
|
|
else if (cs == S_MEASURE_ADJ || cs == S_MEASURE_IDLE) begin
|
|
cnt_amp_too_high <= 0;
|
|
end
|
|
else begin
|
|
cnt_amp_too_high <= cnt_amp_too_high;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (cs == S_MEASURE_ADJ && ns == S_MEASURE_IDLE) begin
|
|
power_measure_done_pulse <= 1;
|
|
end
|
|
else begin
|
|
power_measure_done_pulse <= 0;
|
|
end
|
|
end
|
|
|
|
|
|
// get the abs value
|
|
always @(posedge clk) begin
|
|
// i
|
|
if (data_i[11]) begin
|
|
data_i_abs <= -data_i;
|
|
end
|
|
else begin
|
|
data_i_abs <= data_i;
|
|
end
|
|
// q
|
|
if (data_q[11]) begin
|
|
data_q_abs <= -data_q;
|
|
end
|
|
else begin
|
|
data_q_abs <= data_q;
|
|
end
|
|
end
|
|
|
|
// get the sign number bit number of the temporary 12 bit number
|
|
always @(*) begin
|
|
casez (data_i_abs)
|
|
12'b1000_0000_0000: sign_bit_num_i <= 8'd1;
|
|
12'b01??_????_????: sign_bit_num_i <= 8'd1;
|
|
12'b001?_????_????: sign_bit_num_i <= 8'd2;
|
|
12'b0001_????_????: sign_bit_num_i <= 8'd3;
|
|
12'b0000_1???_????: sign_bit_num_i <= 8'd4;
|
|
12'b0000_01??_????: sign_bit_num_i <= 8'd5;
|
|
12'b0000_001?_????: sign_bit_num_i <= 8'd6;
|
|
12'b0000_0001_????: sign_bit_num_i <= 8'd7;
|
|
12'b0000_0000_1???: sign_bit_num_i <= 8'd8;
|
|
12'b0000_0000_01??: sign_bit_num_i <= 8'd9;
|
|
12'b0000_0000_001?: sign_bit_num_i <= 8'd10;
|
|
12'b0000_0000_0001: sign_bit_num_i <= 8'd11;
|
|
default: begin
|
|
sign_bit_num_i <= 8'd12;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
// get the sign number bit number of the temporary 12 bit number
|
|
always @(*) begin
|
|
casez (data_q_abs)
|
|
12'b1000_0000_0000: sign_bit_num_q <= 8'd1;
|
|
12'b01??_????_????: sign_bit_num_q <= 8'd1;
|
|
12'b001?_????_????: sign_bit_num_q <= 8'd2;
|
|
12'b0001_????_????: sign_bit_num_q <= 8'd3;
|
|
12'b0000_1???_????: sign_bit_num_q <= 8'd4;
|
|
12'b0000_01??_????: sign_bit_num_q <= 8'd5;
|
|
12'b0000_001?_????: sign_bit_num_q <= 8'd6;
|
|
12'b0000_0001_????: sign_bit_num_q <= 8'd7;
|
|
12'b0000_0000_1???: sign_bit_num_q <= 8'd8;
|
|
12'b0000_0000_01??: sign_bit_num_q <= 8'd9;
|
|
12'b0000_0000_001?: sign_bit_num_q <= 8'd10;
|
|
12'b0000_0000_0001: sign_bit_num_q <= 8'd11;
|
|
default: begin
|
|
sign_bit_num_q <= 8'd12;
|
|
end
|
|
endcase
|
|
end
|
|
|
|
|
|
always @(posedge clk) begin
|
|
if (cs == S_MEASURE_IDLE || cs == S_MEASURE_ADJ) begin
|
|
sign_bit_num_min_i <= 8'd11;
|
|
sign_bit_num_min_q <= 8'd11;
|
|
end
|
|
else if (cs == S_MEASURE_ING) begin
|
|
if (sign_bit_num_min_i > sign_bit_num_i) begin
|
|
sign_bit_num_min_i <= sign_bit_num_i;
|
|
end
|
|
if (sign_bit_num_min_q > sign_bit_num_q) begin
|
|
sign_bit_num_min_q <= sign_bit_num_q;
|
|
end
|
|
end
|
|
end
|
|
|
|
// * flag_too_* generate logic, the core of the module
|
|
always @(posedge clk) begin
|
|
if (cnt_startup[2:0] == 3'b101 && cnt_startup <= 200) begin
|
|
flag_too_high <= 0;
|
|
flag_too_low <= 1;
|
|
end
|
|
else if (cs == S_MEASURE_DONE) begin
|
|
// * 若符号位太多,则信号太小,需要增加信号功率
|
|
if (sign_bit_num_min_i >= 3 || sign_bit_num_min_q >= 3) begin
|
|
flag_too_low <= 1;
|
|
end
|
|
// * 若符号位太少,则信号太大,需要降低信号功率
|
|
else if (sign_bit_num_min_i <= 1 || sign_bit_num_min_q <= 1 || cnt_amp_too_high >= CNT_AMP_TOO_HIGH_THRESHOLD - 1) begin
|
|
flag_too_high <= 1;
|
|
end
|
|
end
|
|
else begin
|
|
flag_too_high <= 0;
|
|
flag_too_low <= 0;
|
|
end
|
|
end
|
|
|
|
endmodule
|