【FPGA】基于vivado的AM调制与解调(verilog)(二、程序设计篇)

设计程序

`timescale 1ns / 1ps

……………………………………………………………………………
module exm(
    input sysclk,//输入100MHz时钟
    input wire [15:0] carrier_int,//输入载波信号频率控制字,16位
    input wire [23:0] modulate_int,//输入调制信号频率控制字,24位
    input wire [3:0] depth,//输入调制深度
    
    output wire [7:0] modulate_signal,//定义调制信号,8位
    output wire [7:0] carrier_signal,//定义载波信号,8位
    output wire [17:0] modulated_signal,//定义已调信号,18位
    output wire [7:0] demodulated_final//定义解调信号,8位
    );
……………………………………………………………………………

//    wire [15:0] carrier_int=2620;//定义载波信号频率控制字,16位
//    wire [23:0] modulate_int=1677;//定义调制信号频率控制字,24位
//    wire [3:0] depth= 9;//定义调制深度
//    wire [7:0] modulate_signal;//定义调制信号,8位
//    wire [7:0] carrier_signal;//定义载波信号,8位
//    wire [17:0] modulated_signal;//定义已调信号,24位
//    wire [7:0] demodulated_final;//定义解调信号
……………………………………………………………………………

    reg signed[8:0] depth_int;  //定义调制深度控制字
    reg  [7:0] A = 127; //定义直流分量
    wire signed[16:0] modulate_depth;//调制信号×调制深度
    wire signed[8:0] modulate_depth_out;//右移八位
    reg [9:0] modulate_A;//叠加直流
    wire [23:0] modulated_final;//定义位扩展后的信号
    reg [23:0] modulated_signal_abs;//定义全波整流后的信号
    wire [39:0] demodulated_signal;//定义滤波后的信号
……………………………………………………………………………

    //调用dds:generate_modulate_signal,产生调制信号,注意:左面的名字dds_compiler_0是调用的时候确定的,右面的名字generate_modulate_signal可以自定义,但不要和前面的变量名重复。
    dds_compiler_0 generate_modulate_signal (
      .aclk(sysclk),  // 输入系统时钟
      .s_axis_config_tvalid(1),  // 使能设置为1
      .s_axis_config_tdata(modulate_int), // input wire [23 : 0] s_axis_config_tdata,输入24位频率控制字
      .m_axis_data_tvalid(),  // output wire m_axis_data_tvalid
      .m_axis_data_tdata(modulate_signal) // output wire [7 : 0] m_axis_data_tdata,输出调制信号
    );
    //调用dds:generate_carrier_signal,产生载波信号
    dds_compiler_1 generate_carrier_signal (
      .aclk(sysclk),   // input wire aclk
      .s_axis_config_tvalid(1),  // input wire s_axis_config_tvalid
      .s_axis_config_tdata(carrier_int), // input wire [15 : 0] s_axis_config_tdata
      .m_axis_data_tvalid(),   // output wire m_axis_data_tvalid
      .m_axis_data_tdata(carrier_signal)  // output wire [7 : 0] m_axis_data_tdata
    );
……………………………………………………………………………

    //设置调制深度
    always@(posedge sysclk)     //设置不同调制深度
    begin
       case (depth)
            0:  depth_int <= 0 ;
            1:  depth_int <= 26;//0.1*256,取整
            2:  depth_int <= 51;
            3:  depth_int <= 77;
            4:  depth_int <= 102;
            5:  depth_int <= 128;
            6:  depth_int <= 154;
            7:  depth_int <= 179;
            8:  depth_int <= 205;
            9:  depth_int <= 230;
            10: depth_int <= 255;
       endcase
    end
……………………………………………………………………………

    //调用乘法器,计算调制信号 × 调制深度控制字
    mult_gen_0 out_depth (               
          .CLK(sysclk),  // input wire CLK
          .A(modulate_signal),      // input wire [7 : 0] A
          .B(depth_int),      // input wire [8 : 0] B
          .P(modulate_depth)      // output wire [16 : 0] P
        );
    assign modulate_depth_out = modulate_depth>>8;//右移8位

    always@(posedge sysclk)
    begin
        modulate_A <=  modulate_depth_out + 127;//叠加直流分量
    end
    //调用乘法器,计算 modulate_A × 载波信号
    mult_gen_1 out_mdl (
      .CLK(sysclk),  // input wire CLK
      .A(modulate_A),      // input wire [9 : 0] A
      .B(carrier_signal),      // input wire [7 : 0] B
      .P(modulated_signal)      // output wire [17 : 0] P
    );
assign modulated_final={
    
    {
    
    6{
    
    modulated_signal[17]}},modulated_signal}; //位扩展
……………………………………………………………………………

    //全波整流
        always @(posedge sysclk ) begin
            if(modulated_final[23] == 1)  begin  //全波整流
                modulated_signal_abs <= -{
    
    modulated_final}; 
                //如果符号位是1,对数据取反
            end
            else begin
                modulated_signal_abs <= modulated_final;
                //如果符号位是0,数据不变
            end
        end
……………………………………………………………………………

    //低通滤波
    fir_compiler_0 Lfilter (
      .aclk(sysclk),   // input wire aclk
      .s_axis_data_tvalid(1),  // input wire s_axis_data_tvalid
      .s_axis_data_tready(s_axis_data_tready),  // output wire s_axis_data_tready
      .s_axis_data_tdata(modulated_signal_abs),    // input wire [23 : 0] s_axis_data_tdata
      .m_axis_data_tvalid(),  // output wire m_axis_data_tvalid
      .m_axis_data_tdata(demodulated_signal)    // output wire [39 : 0] m_axis_data_tdata
    );
    assign demodulated_final[7:0] = demodulated_signal[34:27];  //截位(注意根据仿真文件中demodulated_signal选取截位位置)

仿真程序

`timescale 1ns / 1ps
……………………………………………………………………………

module exm_tb(
    );
    //定义变量
    reg sysclk;
    wire [15:0] carrier_int=5243;//定义载波信号频率控制字,16位
    wire [23:0] modulate_int=1342;//定义调制信号频率控制字,24位
    wire [3:0] depth= 9;//定义调制深度
    
    wire [7:0] modulate_signal;//定义调制信号,8位
    wire [7:0] carrier_signal;//定义载波信号,8位
    wire [17:0] modulated_signal;//定义已调信号,24位    
    wire [7:0] demodulated_final;//最终解调输出
    reg [17:0] modulated_out;//输出到文件
    reg [7:0] demodulated_out;//输出到文件          
……………………………………………………………………………

    //产生100MHz时钟,计算周期为10ns
    initial
    begin
        sysclk <= 0;
    end 
    always
    #5 sysclk = ~sysclk;//这样一个周期就是10ns
 ……………………………………………………………………………
 
    //调用设计文件(注意:exm,是设计文件的名字,不要直接复制本程序,instance_AM是自定义的名字)
    exm instance_AM(
        .sysclk(sysclk),
        .carrier_int(carrier_int),
        .modulate_int(modulate_int),
        .depth(depth),
        .modulate_signal(modulate_signal),
        .carrier_signal(carrier_signal),
        .modulated_signal(modulated_signal),
        .demodulated_final(demodulated_final)   
    );
……………………………………………………………………………
//将仿真数据存入文本文件
    always@(posedge sysclk) 
    begin
    modulated_out <= modulated_signal;
    demodulated_out <= demodulated_final;
    end
    integer modulated_file, demodulated_file; 
    initial modulated_file = $fopen("G:/FPGA/modulated_out.txt", "w");//打开文件,写模式
    initial demodulated_file = $fopen("G:/FPGA/demodulated_out.txt", "w");
    always@(posedge sysclk) 
    begin
	$fwrite(modulated_file, "%d\n", $signed(modulated_out));//注意:modulated_out是有符号数,%d\n是以十进制形式写入并换行的意思,也可以用自动换行的语句。
    $fwrite(demodulated_file, "%d\n", demodulated_out);
    end
    
endmodule

猜你喜欢

转载自blog.csdn.net/dovings/article/details/106889148
今日推荐