180 lines
6.1 KiB
Verilog
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
|