// * 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