// * Engineer: // * *************************************************** * // * ███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗ * // * ╚══███╔╝██╔═══██╗██╔══██╗██╔═══██╗██╔════╝ ██║ ██║ * // * ███╔╝ ██║ ██║██████╔╝██║ ██║██║ ███╗███████║ * // * ███╔╝ ██║ ██║██╔══██╗██║ ██║██║ ██║██╔══██║ * // * ███████╗╚██████╔╝██║ ██║╚██████╔╝╚██████╔╝██║ ██║ * // * ╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ * // * *************************************************** * // * Update Date: 2024年7月12日 // * NOTE : after test , the pin control pulse effect take palce // * NOTE : after about 50 clocks. so re-measuring the energy // * NOTE : after more than 50 clocks is ok. Here I choose 100 clocks(25 syms) module ad9361_mgc_pin_ctrl ( input clk, input rst, input start, input [11:0] rx_data_i, input [11:0] rx_data_q, // this port is from zynq to ad9361 output wire [ 3:0] ad9361_ctrl_in, output reg flag_mgc_done ); // * CTRL_IN0 causes the gain index to increase for Rx1 // * CTRL_IN1 causes the gain index to decrease for Rx1 localparam PULSE_PERIOD = 5; // ******** Wire & Reg ******** reg start_d1; wire start_posedge; wire inc_pulse; wire dec_pulse; wire flag_too_high; // high amplitude wire flag_too_low; // low amplitude wire flag_adjust; reg [3:0] cnt_pulse_width; // indicating the mgc done ready wire power_measure_done_pulse; // adjust fsm localparam S_IDLE = 0; localparam S_INC = 1; localparam S_DEC = 2; localparam S_DONE = 3; reg [2:0] cs; reg [2:0] ns; // ******** Assingment ******** assign ad9361_ctrl_in[0] = inc_pulse; assign ad9361_ctrl_in[1] = dec_pulse; assign flag_adjust = flag_too_high | flag_too_low; assign inc_pulse = (cs == S_INC); assign dec_pulse = (cs == S_DEC); assign start_posedge = start & ~start_d1; // ******** Logic Block ******** // self decrese cnt always @(posedge clk) begin if (flag_adjust) begin cnt_pulse_width = PULSE_PERIOD; end else if (cnt_pulse_width > 0) begin cnt_pulse_width <= cnt_pulse_width - 1; end end always @(posedge clk) begin start_d1 <= start; end // single pulse to level signal always @(posedge clk) begin if (rst) begin flag_mgc_done <= 0; end else if (power_measure_done_pulse) begin flag_mgc_done <= 1; end end // FSM always @(posedge clk) begin if (rst) begin cs <= S_IDLE; end else begin cs <= ns; end end // fsm for dec and inc always @(*) begin case (cs) S_IDLE: begin if (flag_too_high) begin ns = S_DEC; end else if (flag_too_low) begin ns = S_INC; end else begin ns = S_IDLE; end end S_INC: begin if (cnt_pulse_width == 0) begin ns = S_DONE; end end S_DEC: begin if (cnt_pulse_width == 0) begin ns = S_DONE; end end S_DONE: begin ns = S_IDLE; end endcase end // ******** Inst ******** // measuring the signal power // two cases, amplitute too high or amplitude too low power_measure u_power_measure ( .clk (clk), .rst (rst), .start (start_posedge), .data_i (rx_data_i), .data_q (rx_data_q), .flag_too_high (flag_too_high), .flag_too_low (flag_too_low), .power_measure_done_pulse(power_measure_done_pulse) ); // ******** Debug ******** // vio_mgc_control_in u_vio_mgc_control_in ( // .clk (clk), // input wire clk // .probe_out0(start) // output wire [0 : 0] probe_out0 // ); ila_ad9361_mgc u_ila_ad9361_mgc ( .clk (clk), // input wire clk .probe0(start_posedge), // input wire [0:0] probe0 .probe1(rx_data_i), // input wire [11:0] probe1 .probe2(u_power_measure.cs), // input wire [2:0] probe2 .probe3(u_power_measure.sign_bit_num_i), // input wire [3:0] probe3 .probe4(u_power_measure.sign_bit_num_min_i), // input wire [3:0] probe4 .probe5(flag_too_high), // input wire [0:0] probe5 .probe6(flag_too_low), // input wire [0:0] probe6 .probe7(u_power_measure.cnt_amp_too_high), // input wire [0:0] probe6 .probe8(u_power_measure.cnt_startup) // input wire [11:0] probe6 ); endmodule