*使用Quartus编译器参考杜勇先生的数字调制解调技术MATLAB与FPGA实现 Altera Verilog版本(我已经上传到我的资源)
利用DDS内部IP核的2ASK信号调制:如何配置DDS请看我上一篇文章:IP核中NCO核(DDS的配置)https://blog.csdn.net/weixin_50966238/article/details/125723232?csdn_share_tail={"type":"blog","rType":"article","rId":"125723232","source":"weixin_50966238"}&ctrtid=a3zAj
ASK即范围键控制,使用0或1的基带矩形波控制连续载波,即基带矩形波直接乘以载波。当数字信息为1时,载波直接通过,当数字信息为0时,载波不通过。该机制产生的信号为2ASK信号,2代表二进制。
以下是主代码模块:
module ASKMod ( rst,clk,din, dout); input rst; //复位信号,高电平有效 input clk; //FPGA系统时钟:8MHz input [1:0] din; //基带输入数据 output signed [13:0] dout; //ASK输出数据 //实例化NCO/DDS核 wire reset_n,out_valid,clken; wire signed [31:0] carrier; wire signed [13:0]sine ; assign reset_n = !rst; assign clken = 1'b1; assign carrier=32'd1073741824;//2MHz dds u0 ( .phi_inc_i (carrier), .clk (clk), .reset_n (reset_n), .clken (clken), .fsin_o (sine), .out_valid (out_valid)); reg [13:0] ask; always @(*) case(din) 2'd0: ask <= 14'd0; 2'd1: //0.3281=1/4 1/16 1/32 ask <= {
{2{sine[13]}},sine[13:2]} {
{4{sine[13]}},sine[13:4]} {
{5{sine[13]}},sine[13:5]}; 2'd2: //0.6563=1/2 1/8 1/16 ask <= {
{
{sine[13]}},sine[13:1]} {
{3{sine[13]}},sine[13:3]} {
{4{sine[13]}},sine[13:4]}; 3'd3: ask <= sine; endcase assign dout = ask; endmodule
测试代码testBench代码如下:
`timescale 1 ns/ 1 ns module ASKMod_vlg_tst(); // constants // general purpose registers //reg eachvec; // test vector input registers reg clk; reg [1:0] din; reg rst; // wires wire [13:0] dout; // assign statements (if any) ASKMod i1 ( // port map - connection between master ports and signals/registers .clk(clk), .din(din), .dout(dout), .rst(rst) ); parameter clk_period=20; ///设置时钟信号周期(频率)MHz parameter data_clk_period=clk_period*4; ////设置数据时钟周期 parameter clk_half_period=clk_period/2; parameter data_half_period=data_clk_period/2; parameter data_num=2000; ///模拟数据长度 parameter time_sim=data_num*clk_period; //仿真时间 initial begin ///设置输入信号的初始值 din=2'd0; ////设置时钟信号的初始值 clk=1; //clk_data=1; //设置复位信号 rst=1; #110 rst=0; //设置模拟时间 #time_sim $finish; end //产生时钟信号 always #clk_half_period clk=~clk; //always // #data_half_period clk_data=~clk_data; reg [4:0] count; always @(posedge clk or posedge rst) if (rst) begin count <= 5'd0; end else begin count <= count 5'd1; //din <= count[4:3];/4ASK din <= {count[3],count[3]}//2ASK end endmodule
ModelSim仿真图如下: