// Relese History // Version Date Author Description // 1.1 2024-04-08 ZYZ //----------------------------------------------------------------------------------------------------------------- // Keywords : 1.add Env_vld // 2.add Mod_vld // 3.change the use of Mod_enable // 4.divide modem into FM and AM // // // // //----------------------------------------------------------------------------------------------------------------- // Parameter // //----------------------------------------------------------------------------------------------------------------- // Purpose : // //----------------------------------------------------------------------------------------------------------------- // Target Device: // Tool versions: //----------------------------------------------------------------------------------------------------------------- // Reuse Issues // Reset Strategy: // Clock Domains: // Critical Timing: // Asynchronous I/F: // Synthesizable (y/n): // Other: //-FHDR-------------------------------------------------------------------------------------------------------- module freqmod ( //System Signal input Dig_Clk //Module Clock ,input Dig_Resetn //Module Reset Signal //Envelope Data ,input signed [15:0] Env_Idata //env_i is signed (two's complement) ,input signed [15:0] Env_Qdata //env_q is signed (two's complement) ,input Env_Vld //env data is vld //Nco data ,input signed [15:0] Nco_Sin //nco_sin is signed (two's complement) ,input signed [15:0] Nco_Cos //nco_cos is signed (two's complement) //Config Signal ,input Mod_Sideband_Sel //1'b0: Mod_data_i = Icoswd+Qsinwd, Mod_data_q = -Isinwd+Qcoswd //1'b1: Mod_data_i = Icoswd-Qsinwd, Mod_data_q = Isinwd+Qcoswd ,input Mod_Enable //1'b0: disable Modem,1'b1:enable modem //Output modem data ,output signed [15:0] Mod_Data_I //Modem output data for I ,output signed [15:0] Mod_Data_Q //Modem output data for Q ,output Mod_Vld //Modem output data vld ); ////////////////////////////////////////////////////////////// // Wire & reg ////////////////////////////////////////////////////////////// //The temporary result Regs of a multiplication operation. wire signed [31:0] mult_isin_tmp; wire signed [31:0] mult_icos_tmp; wire signed [31:0] mult_qsin_tmp; wire signed [31:0] mult_qcos_tmp; //The processing of a multiplication result. wire signed [15:0] mult_isin_w; wire signed [15:0] mult_icos_w; wire signed [15:0] mult_qsin_w; wire signed [15:0] mult_qcos_w; //The multiplier processing result register. reg signed [15:0] mult_isin_r; reg signed [15:0] mult_icos_r; reg signed [15:0] mult_qsin_r; reg signed [15:0] mult_qcos_r; //Temporary storage of IQ data. wire signed [16:0] adder0_icosqsin_tmp; wire signed [16:0] adder1_isinqcos_tmp; //Output of IQ data stored in registers. reg signed [15:0] adder0_icosqsin_r; reg signed [15:0] adder1_isinqcos_r; //Modulation data valid flag Regs. reg [7 :0] freqmod_data_vld_dly; //shifting register,Env_Idata reg signed [15:0] Env_Idata_r1; reg signed [15:0] Env_Idata_r2; reg signed [15:0] Env_Idata_r3; reg signed [15:0] Env_Idata_r4; always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(!Dig_Resetn) begin Env_Idata_r1 <= 16'b0; Env_Idata_r2 <= 16'b0; Env_Idata_r3 <= 16'b0; Env_Idata_r4 <= 16'b0; end else if(~Mod_Enable) begin Env_Idata_r1 <= 16'b0; Env_Idata_r2 <= Env_Idata_r1; Env_Idata_r3 <= Env_Idata_r2; Env_Idata_r4 <= Env_Idata_r3; end else begin Env_Idata_r1 <= Env_Idata; Env_Idata_r2 <= Env_Idata_r1; Env_Idata_r3 <= Env_Idata_r2; Env_Idata_r4 <= Env_Idata_r3; end end //shifting register,Env_Qdata reg signed [15:0] Env_Qdata_r1; reg signed [15:0] Env_Qdata_r2; reg signed [15:0] Env_Qdata_r3; reg signed [15:0] Env_Qdata_r4; always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(!Dig_Resetn) begin Env_Qdata_r1 <= 16'b0; Env_Qdata_r2 <= 16'b0; Env_Qdata_r3 <= 16'b0; Env_Qdata_r4 <= 16'b0; end else if(~Mod_Enable) begin Env_Qdata_r1 <= 16'b0; Env_Qdata_r2 <= Env_Qdata_r1; Env_Qdata_r3 <= Env_Qdata_r2; Env_Qdata_r4 <= Env_Qdata_r3; end else begin Env_Qdata_r1 <= Env_Qdata; Env_Qdata_r2 <= Env_Qdata_r1; Env_Qdata_r3 <= Env_Qdata_r2; Env_Qdata_r4 <= Env_Qdata_r3; end end ////////////////////////////////////////////////////////////// // Orthogonal modulation ////////////////////////////////////////////////////////////// //DW_mult_pipe Instantiation -> Env_Idata * Nco_Sin DW_mult_pipe #( .a_width ( 16 ) ,.b_width ( 16 ) ,.num_stages ( 3 ) ,.stall_mode ( 0 ) ,.rst_mode ( 1 ) ,.op_iso_mode ( 0 ) ) inst_isin_mult ( .clk ( Dig_Clk ) ,.rst_n ( Dig_Resetn ) ,.en ( 1'b1 ) ,.a ( Env_Idata_r4 ) ,.b ( Nco_Sin ) ,.tc ( 1'b1 ) ,.product ( mult_isin_tmp ) ); //DW_mult_pipe Instantiation -> Env_Idata * Nco_Cos DW_mult_pipe #( .a_width ( 16 ) ,.b_width ( 16 ) ,.num_stages ( 3 ) ,.stall_mode ( 0 ) ,.rst_mode ( 1 ) ,.op_iso_mode ( 0 ) ) inst_icos_mult ( .clk ( Dig_Clk ) ,.rst_n ( Dig_Resetn ) ,.en ( 1'b1 ) ,.a ( Env_Idata_r4 ) ,.b ( Nco_Cos ) ,.tc ( 1'b1 ) ,.product ( mult_icos_tmp ) ); //DW_mult_pipe Instantiation -> Env_Qdata * Nco_Sin DW_mult_pipe #( .a_width ( 16 ) ,.b_width ( 16 ) ,.num_stages ( 3 ) ,.stall_mode ( 0 ) ,.rst_mode ( 1 ) ,.op_iso_mode ( 0 ) ) inst_qsin_mult ( .clk ( Dig_Clk ) ,.rst_n ( Dig_Resetn ) ,.en ( 1'b1 ) ,.a ( Env_Qdata_r4 ) ,.b ( Nco_Sin ) ,.tc ( 1'b1 ) ,.product ( mult_qsin_tmp ) ); //DW_mult_pipe Instantiation -> Env_Qdata * Nco_Cos DW_mult_pipe #( .a_width ( 16 ) ,.b_width ( 16 ) ,.num_stages ( 3 ) ,.stall_mode ( 0 ) ,.rst_mode ( 1 ) ,.op_iso_mode ( 0 ) ) inst_qcos_mult ( .clk ( Dig_Clk ) ,.rst_n ( Dig_Resetn ) ,.en ( 1'b1 ) ,.a ( Env_Qdata_r4 ) ,.b ( Nco_Cos ) ,.tc ( 1'b1 ) ,.product ( mult_qcos_tmp ) ); ////////////////////////////////////////////////////////////// // The processing of a multiplication result. ////////////////////////////////////////////////////////////// assign mult_isin_w = {mult_isin_tmp[31],mult_isin_tmp[29:15]} +mult_isin_tmp[14]; assign mult_icos_w = {mult_icos_tmp[31],mult_icos_tmp[29:15]} +mult_icos_tmp[14]; assign mult_qsin_w = {mult_qsin_tmp[31],mult_qsin_tmp[29:15]} +mult_qsin_tmp[14]; assign mult_qcos_w = {mult_qcos_tmp[31],mult_qcos_tmp[29:15]} +mult_qcos_tmp[14]; ////////////////////////////////////////////////////////////// // The multiplier processing result register. ////////////////////////////////////////////////////////////// //mult_isin_r always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(Dig_Resetn == 1'b0) begin mult_isin_r <= 16'd0; end else begin mult_isin_r <= mult_isin_w; end end //mult_icos_r always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(Dig_Resetn == 1'b0) begin mult_icos_r <= 16'd0; end else begin mult_icos_r <= mult_icos_w; end end //mult_qsin_r always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(Dig_Resetn == 1'b0) begin mult_qsin_r <= 16'd0; end else begin mult_qsin_r <= mult_qsin_w; end end //mult_qcos_r always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(Dig_Resetn == 1'b0) begin mult_qcos_r <= 16'd0; end else begin mult_qcos_r <= mult_qcos_w; end end ////////////////////////////////////////////////////////////// // Orthogonal modulation ////////////////////////////////////////////////////////////// assign adder0_icosqsin_tmp = ~Mod_Sideband_Sel ? (mult_icos_r + mult_qsin_r):(mult_icos_r - mult_qsin_r); //1'b0: adder0_icosqsin_tmp = Icoswd+Qsinwd, 1'b1:adder0_icosqsin_tmp = Icoswd-Qsinwd assign adder1_isinqcos_tmp = Mod_Sideband_Sel ? (mult_isin_r + mult_qcos_r):(-mult_isin_r + mult_qcos_r); //1'b0: adder1_isinqcos_tmp = Isinwd+Qcoswd, 1'b1:adder1_isinqcos_tmp = -Isinwd+Qcoswd ////////////////////////////////////////////////////////////// // Output of IQ data stored in registers. ////////////////////////////////////////////////////////////// always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(Dig_Resetn == 1'b0) begin adder0_icosqsin_r <= 16'd0; end else if(adder0_icosqsin_tmp[16:15] == 2'b01)begin adder0_icosqsin_r <= 32767; end else if (adder0_icosqsin_tmp[16:15] == 2'b10)begin adder0_icosqsin_r <= -32768; end else begin adder0_icosqsin_r <= {adder0_icosqsin_tmp[16],adder0_icosqsin_tmp[14:0]}; end end always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(Dig_Resetn == 1'b0) begin adder1_isinqcos_r <= 16'd0; end else if (adder1_isinqcos_tmp[16:15] == 2'b01)begin adder1_isinqcos_r <= 32767; end else if (adder1_isinqcos_tmp[16:15] == 2'b10)begin adder1_isinqcos_r <= -32768; end else begin adder1_isinqcos_r <= {adder1_isinqcos_tmp[16],adder1_isinqcos_tmp[14:0]}; end end assign Mod_Data_I = adder0_icosqsin_r; assign Mod_Data_Q = adder1_isinqcos_r; ////////////////////////////////////////////////////////////// // Generation of Mod_Vld signal. ////////////////////////////////////////////////////////////// //mod_data_vld_dly always @(posedge Dig_Clk or negedge Dig_Resetn) begin if(Dig_Resetn == 1'b0) begin freqmod_data_vld_dly <= 8'b0; end else begin freqmod_data_vld_dly <= {freqmod_data_vld_dly[6:0], Mod_Enable & Env_Vld}; end end assign Mod_Vld = freqmod_data_vld_dly[7]; endmodule