当前位置:网站首页>基于 VIVADO 的 AM 调制解调(2)工程实现
基于 VIVADO 的 AM 调制解调(2)工程实现
2022-08-11 08:30:00 【chylinne】
一、概述
本文根据上一篇方案设计,基于 VIVADO 平台实现 AM 调制解调。
二、Verilog 源码
根据下面的原理框图,我们可以直接在 VIVADO 中调用 IP 核来实现这些器件。
对应的 Verilog 源码如下所示:
`timescale 1ns / 1ps
//
// Company: UESTC
// Engineer: chylinne
//
// Create Date: 2022/08/08 21:35:43
// Design Name: am
// Module Name: am
// Project Name: am
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module am (
input clk,
input rst_n,
input wire [15:0] pinc_carrier,
input wire [23:0] pinc_modulate,
input wire [3:0] depth,
output wire [7:0] modulate_signal,
output wire [7:0] carrier_signal,
output wire [17:0] modulated_signal,
output wire [7:0] demodulated_final
);
reg [23:0] cnt_clk;
reg signed [8:0] depth_int;
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 modulated_signal_ready;
wire demodulated_signal_vld;
wire [39:0] demodulated_signal;
dds_compiler_0 generate_modulate_signal (
.aclk(clk),
.s_axis_config_tvalid(1'b1),
.s_axis_config_tdata(pinc_modulate),
.m_axis_data_tvalid(),
.m_axis_data_tdata(modulate_signal)
);
dds_compiler_1 generate_carrier_signal (
.aclk(clk),
.s_axis_config_tvalid(1'b1),
.s_axis_config_tdata(pinc_carrier),
.m_axis_data_tvalid(),
.m_axis_data_tdata(carrier_signal)
);
[email protected](posedge clk)
begin
case (depth)
0: depth_int <= 0 ;
1: depth_int <= 26; // 0.1 * 256
2: depth_int <= 51; // 0.2 * 256
3: depth_int <= 77; // 0.3 * 256
4: depth_int <= 102; // 0.4 * 256
5: depth_int <= 128; // 0.5 * 256
6: depth_int <= 154; // 0.6 * 256
7: depth_int <= 179; // 0.7 * 256
8: depth_int <= 205; // 0.8 * 256
9: depth_int <= 230; // 0.9 * 256
10: depth_int <= 255;
endcase
end
mult_gen_0 cal_mod_depth (
.CLK(clk),
.A(modulate_signal),
.B(depth_int),
.P(modulate_depth)
);
assign modulate_depth_out = modulate_depth >> 8;
[email protected](posedge clk) begin
if(!rst_n)
modulate_A <= 0;
else
modulate_A <= modulate_depth_out + 127;
end
mult_gen_1 cal_mod_signal (
.CLK(clk),
.A(modulate_A),
.B(carrier_signal),
.P(modulated_signal)
);
assign modulated_final={
{6{modulated_signal[17]}},modulated_signal};
always @(posedge clk ) begin
if(!rst_n)
modulated_signal_abs <= 0;
else begin
if(modulated_final[23] == 1)
modulated_signal_abs <= -{modulated_final};
else
modulated_signal_abs <= modulated_final;
end
end
fir_compiler_0 low_pass_filter (
.aclk(clk),
.s_axis_data_tvalid(1'b1),
.s_axis_data_tready(modulated_signal_ready),
.s_axis_data_tdata(modulated_signal_abs[15:0]),
.m_axis_data_tvalid(demodulated_signal_vld),
.m_axis_data_tdata(demodulated_signal)
);
assign demodulated_final[7:0] = demodulated_signal[34:27];
endmodule
三、IP 核配置
(1)调制信号发生器
在 VIVADO 中打开 IP Catalog,搜索 DDS,找到下图所示的 DDS Compiler,双击打开进行配置。
在调制信号的 DDS 配置中,我们设置模式为 Phase Generator and SIN COS LUT,设置系统时钟为 100 MHz。参数模式选择为 Hardware Parameters,这使我们能直接通过代码中的频率控制字来配置该调制信号的频率。最下方将相位累加器位宽设置成 24,输出信号的数据位宽设置为 8。
点击 Next 进入下一页,我们将频率控制字模式(Phase Increment Programmability,相位增量可编程性)设置成可调节模式(Programmability);由于本次设计不用关心相位控制字,因此将相位控制字模式(Phase Offset Programmability,相位偏移量可编程性)设置成关闭模式(None)。然后输出信号我们可以选择正弦波(Sine)。
下一页是 Detailed Implementation,如下所示,保持默认配置即可。
下一页是 Phase Angle Increment Values,由于相位累加器位宽是 24,我们在这里需要将其填写为一个 24 比特的 1,如下所示。
最后是 Summary 页面,直接点击 OK 后 Generate IP 核。
(2)载波信号发生器
载波信号的 DDS IP 核配置过程和上面一模一样,仅有两个地方的参数不同。由于我们设计的载波信号的相位累加器位宽是 16,因此在下图中的 Phase Width 处填写 16。
此外,另一处不同是 Phase Angle Increment Values,由于相位累加器位宽是 16,我们在这里需要将其填写为一个 16 比特的 1,如下所示。
(3)调制深度乘法器
乘法器 IP 核只需配置一下带符号模式以及数据位宽即可,如下图所示。对于调制信号乘上调制深度而言,因调制信号 DDS 输出结果是 8 比特,调制深度(整数)是 9 比特,我们将其设置进 IP 核即可。
(4)载波信号乘法器
同样只需配置一下带符号模式以及数据位宽即可,如下图所示。对于乘上载波信号所需的乘法器而言,因载波信号 DDS 输出结果是 8 比特,之前加上直流分量后的信号是 10 比特,我们将其设置进 IP 核即可。
(5)FIR 低通滤波器
在 VIVADO 中打开 IP Catalog,搜索 FIR,找到下图所示的 FIR Compiler,双击打开进行配置。
我们在如下图示的第一个页面选择 COE File,在下面的 Coefficient File 处导入之前用 MATLAB 生成好的 .coe 文件即可。
后面几页全部保持默认配置,如下所示。
最后,点击 OK 后 Generate IP 核即可。
到此,我们已将 AM 调制解调工程在 VIVADO 平台上搭建完毕。
边栏推荐
- 基础SQL——DDL
- 分门别类输入输出,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang基本数据类型和输入输出EP03
- 万字长文带你了解多态的底层原理,这一篇就够了
- 《剑指offer》题解——week3(持续更新)
- 借问变量何处存,牧童笑称用指针,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang类型指针(Pointer)的使用EP05
- OAuth Client默认配置加载
- 选择收银系统主要看哪些方面?
- Initial use of IDEA
- 迷你图书馆系统(对象+数组)
- Getting Started with Kotlin Algorithms Calculating Prime Factors
猜你喜欢
随机推荐
Find the latest staff salary and the last staff salary changes
gRPC系列(一) 什么是RPC?
进阶-指针
兼容并蓄广纳百川,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang复合容器类型的声明和使用EP04
kali渗透测试环境搭建
【Day_13 0509】▲跳石板
【实战系列】OpenApi设计规范
Linux,Redis中IOException: 远程主机强迫关闭了一个现有的连接。解决方法
框架外的PHP读取.env文件(php5.6、7.3可用版)
Kaldi语音识别工具编译问题记录(踩坑记录)
Kotlin算法入门求自由落体
Rust从入门到精通06-函数
轻量级网络(一):MobileNet V1,V2, V3系列
tensorflow 基础操作1(tensor 基本属性 , 维度变换,数学运算)
囍楽cloud task source code
C语言-结构体
mysql数据查询因为查询的时间跨度过大导致cup爆满应该怎么办
matplotlib
链式编程注解
RestTemplate工具类