概述
笔记八是ASK调制解调的仿真实现。
ASK调制解调的实现原理:首先使用MATLAB产生存储基带波形的coe文件,再让ROM读取coe文件输出基带波形,然后DDS产生正弦波信号作为载波信号,接下来使用乘法器将两者相乘产生ASK信号,ASK信号与载波信号相乘之后,再经过FIR低通滤波器解调出基带波形再抽样判决。
1. 打开VIVADO,点击IP Catalog
2. 搜索ROM,点击Block Memory Generator
3. ROM的配置
(1) 选择Single Port ROM
(2) 选择需要加载的coe文件的位宽和深度
(3) 加载coe文件
coe文件的生成
%% 二进制码序列的coe文件生成
clear all ; % 清除变量
clc ; % 清屏
N = 8 ;
L = 512; % 每个码元的采样点数
y = zeros(4096 , 1) ; % 生成4096行1列的全为1的列向量
% 生成4096行1列取值为0,1的二进制码序列向量
% 最大值为1,因此数据位宽为1bit
% code = randi([0,1],1,N); %N为码元个数
code = [1 1 0 1 1 0 0 1];
fz=ones(1,L); %定义复制的次数L,L为每码元的采样点数
x1=code(fz,:); %复制的第1行复制L次,将原来wave的第一行复制L次,称为L*M的矩阵
dnrz=reshape(x1,1,L*N); %产生单极性不归零矩形脉冲波形,将刚得到的L*M矩阵,按列重新排列形成1*(L*M)的矩阵
y = 255*dnrz';
plot(y); % 绘制图像
hold on; % 保留之前的图,实现多图共存
fid = fopen('mayuan_4096_2.coe','wt');% 以写的形式创建文件,文件名为mayuan_4096_1.coe
% 文件格式保存为十进制,以换行隔开
fprintf( fid, 'MEMORY_INITIALIZATION_RADIX = 10;n');
fprintf( fid, 'MEMORY_INITIALIZATION_VECTOR =n');
% 将上面的矩形波值写入文件
for i = 1:1:4096
fprintf(fid,'%d,n',y(i,1));
end
fclose(fid); % 关闭文件
4. 搜索DDS,点击DDS Complier
5. DDS参数配置 依照之前配置DDS IP核
6. 点击IP Catalog,搜索mult,选择Multiplier
7. 参数配置
同样配置另外一个Multiplier
8. 点击IP Catalog,搜索fir,选择FIR Complier
9. 配置参数
(1) 选择coe文件格式,将FIR 的coe文件加载进去,FIR低通滤波器的设计可以参照
(3条消息) FPGA学习笔记(六): FIR IP核的使用_菜yuan~的博客-CSDN博客
低通滤波器的带宽一般设置为第一零点带宽,即基带码元宽度的倒数,采样频率满足奈奎斯特采样定理就行。
(2) 采样频率 50kHz,时钟频率 50MHz
(3) 输入信号位宽为24bit,滤波器抽头系数16个
10. 顶层文件
module ASK_top(
input clk, // 输入clk
input rst_n, // 输入复位
output [7:0] dout, // 输出8位波形,数据宽度,码元输入
output clk2, // 输出clk2
output sig1, // 输出余弦信号,即载波信号
output sig2, // 输出已调信号
output sig3, // 输出已调信号和载波相乘
output code, // 输出判决码元
output fir_out, // fir滤波后的截断信号
output sig4 // 输出fir滤波信号
);
reg ena_reg; // ROM使能信号
reg [24:0] counter; //
reg clk2;
wire [7:0] sig1;
wire [15:0] sig2;
wire [23:0] sig3;
wire [47:0] sig4;
wire [15:0] fir_out;
reg [7:0] code;
// 设计计数器,分频使用,10分频
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
counter <= 1'b0;
else if (counter == 4)
counter <= 1'b0;
else
counter <= counter + 1'b1;
end
// 产生10分频的clk2
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
clk2 <= 1'b0;
else if(counter == 4)
clk2 <= !clk2;
end
// ROM使能信号
always@(posedge clk2 or negedge rst_n)
begin
if(~rst_n)
ena_reg <= 0;
else
ena_reg <= 1;
end
// ROM的地址
reg [11:0] addr_reg;
always@(posedge clk2 or negedge rst_n)
begin
if(~rst_n)
addr_reg <= 12'd0;
else
addr_reg <= addr_reg + 1;
end
// ROM的例化,产生码元方波信号
blk_mem_gen_0 U1 (
.clka(clk2), // input wire clka
.ena(ena_reg), // input wire ena
.addra(addr_reg), // input wire [11 : 0] addra
.douta(dout) // output wire [7 : 0] douta
);
// DDS的例化,产生载波信号
dds_compiler_0 U2 (
.aclk(clk), // input wire aclk
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sig1) // output wire [7 : 0] m_axis_data_tdata
);
// 乘法器的例化,产生已调信号
mult_gen_0 multi0 (
.CLK(clk), // input wire CLK
.A(dout), // input wire [7 : 0] A
.B(sig1), // input wire [7 : 0] B
.P(sig2) // output wire [15 : 0] P
);
// 乘法器的例化,产生已调信号和载波相乘
mult_gen_1 multi1 (
.CLK(clk), // input wire CLK
.A(sig2), // input wire [15 : 0] A
.B(sig1), // input wire [7 : 0] B
.P(sig3) // output wire [23 : 0] P
);
// fir低通滤波器的例化
fir_compiler_0 U3 (
.aclk(clk), // input wire aclk
.s_axis_data_tvalid(1'b1), // input wire s_axis_data_tvalid
.s_axis_data_tready(), // output wire s_axis_data_tready
.s_axis_data_tdata(sig3), // input wire [23 : 0] s_axis_data_tdata
.m_axis_data_tvalid(), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sig4) // output wire [39 : 0] m_axis_data_tdata
);
//fir的截断
assign fir_out = sig4[47:22];
// 判决
always@(posedge clk)
begin
if(!rst_n)
code <= 1'b0;
else if (sig4 == 0)
code <= 8'd0;
else
code <= 8'd255;
end
endmodule
11. 测试文件
module ASK_tb();
reg clk; // 输入clk
reg rst_n; // 输入复位
wire clk2;
wire [7:0] dout; // 输出8bit波形数据
wire [7:0] sig1; // 输出信号1
wire [15:0] sig2; // 输出信号2
wire [23:0] sig3; // 输出信号3
//wire [39:0] sig4; // 输出信号4
wire [15:0] fir_out;
wire [7:0] code;
// 顶层文件的例化
ASK_top u0 (
.clk(clk),
.clk2(clk2),
.rst_n(rst_n),
.dout(dout),
.sig1(sig1),
.sig2(sig2),
.sig3(sig3),
//.sig4(sig4),
.fir_out(fir_out),
.code(code)
);
//reg memdata[0:7] ;
initial // 初始化
begin
clk = 1; // 初始clk为高电平
rst_n = 0; // 复位为低电平
#1 // 延时50ns
rst_n = 1; // 复位为高电平
//$readmemb("F:/shiyan/lab/ASK/data.txt",memdata);
end
always #10 clk = ~clk; // clk周期为20ns
endmodule
12. 结果显示
(1) dout和code的Waveform Style要选择Analog Settings中的hold,这样才能产生方波信号,并且Radix要选择Unsigned Decimal
除fir_outd其余信号的Waveform Style同样操作,Radix选择Signed Dicemal
Fir_out 的Waveform Style选择Analog就可以,Radix选择Unsigned Dicemal
最后
以上就是苗条电话为你收集整理的FPGA学习笔记(八):ASK调制解调的仿真的全部内容,希望文章能够帮你解决FPGA学习笔记(八):ASK调制解调的仿真所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复