SPI_Test/rtl/awg/awg_ctrl.v

281 lines
13 KiB
Coq
Raw Normal View History

2024-06-25 16:41:01 +08:00
//+FHDR--------------------------------------------------------------------------------------------------------
// Company:
//-----------------------------------------------------------------------------------------------------------------
// File Name : awg_ctrl.v
// Department :
// Author : PWY
// Author's Tel :
//-----------------------------------------------------------------------------------------------------------------
// Relese History
// Version Date Author Description
// 0.1 2024-03-13 PWY Envelope readout, modulation NCO control, and interpolator selection
//-----------------------------------------------------------------------------------------------------------------
// Keywords :
//
//-----------------------------------------------------------------------------------------------------------------
// Parameter
//
//-----------------------------------------------------------------------------------------------------------------
// Purpose :
//
//-----------------------------------------------------------------------------------------------------------------
// Target Device:
// Tool versions:
//-----------------------------------------------------------------------------------------------------------------
// Reuse Issues
// Reset Strategy:
// Clock Domains:
// Critical Timing:
// Asynchronous I/F:
// Synthesizable (y/n):
// Other:
//-FHDR--------------------------------------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////////////////////////////
//Key timing diagram
///////////////////////////////////////////////////////////////////////////////////////////////////////
// -------------------------------------
// | |
//wave_hold_i - -----------------------
// -------------------------------------
// | |
//wave_hold --------- ---------------
// -------------------------------------
// | |
//wave_hold_r1 -------------- -----------
// -------------------------------------
// | |
//wave_hold_2 ------------------ --------
// ---- ----
// | | | |
//ilde2read ---- -------------------------------- ---------------
// ----
// | |
//read2idle --------------------------------- ---------------------
// ---------------------------------------------------------------
//state_c | idle | read | idle | read
// ---------------------------------------------------------------
// ---------------------------------------------------------------
//state_n | idle | read | idle | read
// ---------------------------------------------------------------
// ---------------------------------------------------------------
//enve_rddata_i | invalid | valid | idle | valid
// ---------------------------------------------------------------
// ----
// | |
//end_cnt_r ------------------------------------ ---------------------
// ---------------------------------------------------------------
//last_rddata | invalid | enve_rddata_i
// ---------------------------------------------------------------
// ---------------------------------------------------------------
//enve_data_w | invalid | enve_rddata_i | last_rddata |
// ---------------------------------------------------------------
// ------------------------- ----------
// | | |
//enve_vld_w ---------------- -----------
// ------------------------------------------
// |
//enve_vld_o ----------------
//After two cycles of a valid signal(enve_index_vld_i), output the envelope data(enve_idata_o & enve_qdata_o & enve_vld_o)
module awg_ctrl (
//system port
input clk // System Main Clock
,input rst_n // Spi Reset active low
//Envelope index Information
,input enve_index_vld_i
,input [15 :0] enve_start_addr_i
,input [15 :0] enve_len_i
,input wave_hold_i
//Envelope memory read signals
,output enve_rden_o
,output [15 :0] enve_rdaddr_o
,input [31 :0] enve_rddata_i
//Envelope outpiut
,output [15 :0] enve_idata_o
,output [15 :0] enve_qdata_o
,output [0 :0] enve_vld_o
//Envelope read fsm status
,output [0 :0] enve_read_fsm_st_o
//Process conflict
,output proc_cft_o
//modulation NCO control signals
//Data from the lookup table
,input [31:0] muc_mod_nco_fcw_i
,input [15:0] muc_mod_nco_pha_i
,input [15:0] muc_mod_nco_rz_pha_i
,input muc_mod_pha_clr_i
//Modulating nCO control signal output
,output [31:0] mod_nco_fcw_o
,output [15:0] mod_nco_pha_o
,output mod_pha_clr_o
//Other parameters register
,input [15:0] muc_mod_amp_i
,input [15:0] muc_z_bais_i
,output [15:0] mod_amp_o
,output [15:0] z_bais_o
);
localparam IDLE = 1'b0,
READ = 1'b1;
wire [0:0] state_c;
wire [0:0] state_n;
wire ilde2read;
wire read2idle;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Envelope readout
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ------------------------------------------------------
// -- read envelope memory count
// ------------------------------------------------------
wire [15:0] enve_len;
wire [15:0] cnt_c;
wire add_cnt = (state_c == READ );
wire end_cnt = add_cnt & (cnt_c == enve_len-1);
wire [15:0] cnt_n = end_cnt ? 32'h0 :
add_cnt ? cnt_c + 1'b1 :
cnt_c ;
sirv_gnrl_dffr #(16) cnt_c_dffr (cnt_n, cnt_c, clk, rst_n);
//The first section of the state machine
//state_c
sirv_gnrl_dffr #(1) state_c_dffr (state_n, state_c, clk, rst_n);
//////////////////////////////////////////////////////////////
//fsm
//////////////////////////////////////////////////////////////
//state_n
assign state_n = ((state_c == IDLE ) && ilde2read ) ? READ :
((state_c == READ ) && read2idle ) ? IDLE :
state_c ;
//Generating jump conditions for state machines
assign ilde2read = (state_c == IDLE ) && enve_index_vld_i;
assign read2idle = (state_c == READ ) && end_cnt && ~enve_index_vld_i;
/////////////////////////////////////////////////////////////////////
//Signal Latching
/////////////////////////////////////////////////////////////////////
//enve_start_addr
wire [15:0] enve_start_addr;
//sirv_gnrl_dfflr #(16) enve_start_addr_dfflr (ilde2read, enve_start_addr_i, enve_start_addr, clk, rst_n);
sirv_gnrl_dfflr #(16) enve_start_addr_dfflr (enve_index_vld_i, enve_start_addr_i, enve_start_addr, clk, rst_n);
//enve_len
//sirv_gnrl_dfflr #(16) enve_len_dfflr (ilde2read, enve_len_i, enve_len, clk, rst_n);
sirv_gnrl_dfflr #(16) enve_len_dfflr (enve_index_vld_i, enve_len_i, enve_len, clk, rst_n);
//wave_hold
wire wave_hold;
//sirv_gnrl_dfflr #(1) wave_hold_dfflr (ilde2read, wave_hold_i, wave_hold, clk, rst_n);
sirv_gnrl_dfflr #(1) wave_hold_dfflr (enve_index_vld_i, wave_hold_i, wave_hold, clk, rst_n);
wire wave_hold_r1;
sirv_gnrl_dffr #(1) wave_hold_r1_dffr (wave_hold, wave_hold_r1, clk, rst_n);
wire wave_hold_r2;
sirv_gnrl_dffr #(1) wave_hold_r2_dffr (wave_hold_r1, wave_hold_r2, clk, rst_n);
// ------------------------------------------------------
// -- Generate Read Envelope Storage Signal
// ------------------------------------------------------
assign enve_rden_o = (state_c == READ );
assign enve_rdaddr_o = enve_start_addr + (cnt_c << 2);
// ------------------------------------------------------
// -- Receive envelope data
// ------------------------------------------------------
//Lock and store the last piece of data
wire end_cnt_r;
sirv_gnrl_dffr #(1) end_cnt_r_dffr (end_cnt, end_cnt_r, clk, rst_n);
wire [31:0] last_rddata;
sirv_gnrl_dfflr #(32) last_rddata_dfflr (end_cnt_r, enve_rddata_i[31 :0], last_rddata, clk, rst_n);
//enve_vld_w
wire enve_vld_w = enve_rden_o | wave_hold_r1;
wire [1:0] enve_vld_r;
//wire [31:0] enve_data_w = {32{enve_vld_r[0]}} & enve_rddata_i
// | {32{wave_hold_r2 }} & last_rddata ;
//M--20240516
wire [31:0] enve_data_w = enve_vld_r[0] ? enve_rddata_i :
wave_hold_r2 ? last_rddata :
32'h0;
sirv_gnrl_dffr #(2) enve_vld_r_dffr ({enve_vld_r[0],enve_vld_w}, enve_vld_r, clk, rst_n);
//enve_vld_o
assign enve_vld_o = enve_vld_r[1];
//enve_idata_o
sirv_gnrl_dffr #(16) enve_idata_o_dffr (enve_data_w[31:16], enve_idata_o, clk, rst_n);
//enve_qdata_o
sirv_gnrl_dffr #(16) enve_qdata_o_dffr (enve_data_w[15 :0], enve_qdata_o, clk, rst_n);
//Process conflict
wire proc_cft_w = (state_c == READ ) & enve_index_vld_i & ~end_cnt;
sirv_gnrl_dffr #(1) proc_cft_dffr (proc_cft_w, proc_cft_o, clk, rst_n);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//NCO control
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------------------------
//To ensure the stability of the NCO control signals throughout the entire readout process,
//the state machine locks the NCO control signals upon entering the readout state.
//---------------------------------------------------------------------------------------------
wire [1:0] ilde2read_r;
sirv_gnrl_dffr #(2) ilde2read_r_dffr ({ilde2read_r[0],enve_index_vld_i}, ilde2read_r, clk, rst_n);
//----------------------------------------------------------
//Modulation NCO frequency-controlled word processing
//----------------------------------------------------------
//Align the frequency-controlled word with the envelope output signal in timing
sirv_gnrl_dfflr #(32) mod_nco_fcw_o_dfflr (enve_index_vld_i, muc_mod_nco_fcw_i, mod_nco_fcw_o, clk, rst_n);
//----------------------------------------------------------
//Modulation NCO phase control word processing
//----------------------------------------------------------
//Align the phase control word with the envelope output signal in timing
sirv_gnrl_dfflr #(16) mod_nco_pha_r_dfflr (enve_index_vld_i, muc_mod_nco_pha_i + muc_mod_nco_rz_pha_i, mod_nco_pha_o, clk, rst_n);
//----------------------------------------------------------
//Modulating NCO phase clean signal processing
//----------------------------------------------------------
assign mod_pha_clr_o = muc_mod_pha_clr_i;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//mod_amp_o & z_bais_o
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Align the mod_amp_o with the envelope output signal in timing
sirv_gnrl_dfflr #(16) mod_amp_o_dfflr (ilde2read_r[1], muc_mod_amp_i, mod_amp_o, clk, rst_n);
//Align the z_bais_o with the envelope output signal in timing
sirv_gnrl_dfflr #(16) z_bais_o_dfflr (ilde2read_r[1], muc_z_bais_i, z_bais_o, clk, rst_n);
//enve_read_fsm_st_o
assign enve_read_fsm_st_o = state_c;
endmodule