Files
MM7020/hdl/ad9361_mgc_pin_ctrl.v
T

180 lines
6.1 KiB
Verilog

// * 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 wire flag_mgc_done_pulse, // active high pulse signal
output reg flag_mgc_done = 0 // active high level signal
);
// * 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;
assign flag_mgc_done_pulse = power_measure_done_pulse;
// ******** 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
else begin
ns = S_IDLE;
end
end
S_DEC: begin
if (cnt_pulse_width == 0) begin
ns = S_DONE;
end
else begin
ns = S_IDLE;
end
end
S_DONE: begin
ns = S_IDLE;
end
default: 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