*使用Quartus编译器,参考杜勇老师《数字调制解调技术的MATLAB与FPGA实现 Altera Verilog版》书(我已上传至我的资源)
利用DDS内部IP核的2ASK信号调制:如何配置DDS核请看我上一篇文章:IP核中NCO核(DDS的配置)https://blog.csdn.net/weixin_50966238/article/details/125723232?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22125723232%22%2C%22source%22%3A%22weixin_50966238%22%7D&ctrtid=a3zAj
ASK调制信号的产生: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; //设置时钟信号周期(频率):50MHz
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仿真图如下: