基于FPGA通原学习第二天(2)

发布时间:2026/9/28 21:04:34

基于FPGA通原学习第二天(2)
1. 引言BPSK二进制相移键控是数字通信中最基本的调制方式之一它用载波的两种相位0° 和 180°表示二进制信息具有抗噪声能力强、实现简单的优点。在 FPGA 中我们可以利用直接数字频率合成DDS技术生成高精度的正弦载波并结合简单的逻辑运算完成调制与解调整个过程均可在数字域内实现非常适合在低成本 FPGA 上部署。本文将分享一个完整的 BPSK 调制解调系统包含以下模块bpsk_modulatorBPSK 调制器根据输入比特翻转 DDS 载波的符号。bpsk_demodulatorBPSK 解调器使用相干解调恢复数据。bpsk_top顶层模块将调制器和解调器级联构成自环测试系统。所有代码均用 Verilog 编写并在 ModelSim 下完成功能仿真。2. 系统总体架构下图展示了系统的连接关系实际为自环测试拓扑--------------- ----------------- data_in -| bpsk_modulator|---------| bpsk_demodulator|-- data_out --------------- ----------------- ^ ^ | | fcw,clk,rst_n fcw,clk,rst_n发送端和接收端使用完全相同的fcw频率控制字和时钟因此本地载波与接收信号的载波同频同相实现了理想的相干解调条件。这种结构主要用于功能验证在真实无线通信中还需要增加载波同步和位同步电路。3. BPSK 调制器设计3.1 DDS 载波发生器调制器的核心是一个基于相位累加器的 DDS其框图如下fcw - [32位相位累加器] - 高8位作为地址 - [256×8bit正弦LUT] - sin_out相位累加器每个时钟周期累加fcw溢出自动循环相当于模 2^32 的计数器。取累加器高 8 位phase_acc[31:24]作为查找表地址对应相位分辨率 360°/256 1.40625°。正弦查找表sin_lut中预存一个完整周期的正弦波采样值有符号 8 位范围 -128~127。输出正弦波的频率由下式决定fcarrierfcw232×fclkfcarrier​232fcw​×fclk​例如系统时钟 100 MHz、fcw 429496730 时载波频率约为 10 MHz。3.2 BPSK 调制实现调制逻辑非常简单根据输入data_in选择输出sin_out或-sin_out对应相位 0° 和 180°。always (posedge clk or negedge rst_n) begin if(!rst_n) bpsk_out 8sd0; else if(data_in) bpsk_out -sin_out; // 比特1 → 载波反相 else bpsk_out sin_out; // 比特0 → 载波同相 end这样当data_in在符号速率下变化时bpsk_out便是一个相位连续或仅在比特边界跳变的 BPSK 已调信号。完整调制器代码bpsk_modulator.vmodule bpsk_modulator( input wire clk, input wire rst_n, input wire data_in, input wire [31:0] fcw, output reg signed [7:0] bpsk_out ); reg [31:0] phase_acc; always (posedge clk or negedge rst_n) begin if (!rst_n) phase_acc 32d0; else phase_acc phase_acc fcw; end wire [7:0] addr phase_acc[31:24]; reg signed [7:0] sin_lut [0:255]; initial begin $readmemh(sin_lut_one.hex, sin_lut); end wire signed [7:0] sin_out; assign sin_out sin_lut[addr]; always (posedge clk or negedge rst_n) begin if(!rst_n) bpsk_out 8sd0; else if(data_in) bpsk_out -sin_out; else bpsk_out sin_out; end endmodule4. BPSK 解调器设计解调器采用相干解调结构包含本地载波产生、乘法混频、低通滤波和判决四个部分。4.1 本地载波与混频解调器内部复用了与调制器完全相同的 DDS产生同频同相的本地正弦信号local_sin。接收信号bpsk_in与local_sin相乘若发送比特为 0bpsk_in sin(ωt)相乘后得sin²(ωt) 0.5 - 0.5cos(2ωt)。若发送比特为 1bpsk_in -sin(ωt)相乘后得-sin²(ωt) -0.5 0.5cos(2ωt)。因此乘积中包含一个直流分量±0.5和一个高频分量2倍载波频率。通过低通滤波器滤除高频后即可根据直流分量的极性恢复原始数据。wire signed [7:0] local_sin; assign local_sin sin_lut[phase_acc[31:24]]; // 相位累加器与调制端相同 reg signed [15:0] mixed_signal; always (posedge clk or negedge rst_n) begin if (!rst_n) mixed_signal 16sd0; else mixed_signal bpsk_in * local_sin; // 有符号乘法位宽扩展 end4.2 低通滤波器设计1. 数学原理从公式到代码一阶 IIR 低通滤波器的标准差分方程如下其中是当前的滤波输出对应代码中的 lpf_out 的新值。是上一拍的滤波输出对应代码中等号右边的 lpf_out。是当前的输入信号对应代码中的 mixed_signal。是滤波系数介于 $0$ 到 $1$ 之间决定了滤波的强度。我们对这个公式进行简单的代数变换代码中用移位操作实现除以 16 的运算避免了乘法器reg signed [15:0] lpf_out; always (posedge clk or negedge rst_n) begin if (!rst_n) lpf_out 16sd0; else lpf_out lpf_out (mixed_signal 4) - (lpf_out 4); end仔细观察最后这个公式你会发现它和我们的 Verilog 代码结构完全一致注意有符号数的算术右移会保留符号位确保了滤波器的正确性。4.3 判决输出当lpf_out 0时输出比特1否则输出0。这正好与调制器映射规则对应。always (posedge clk or negedge rst_n) begin if (!rst_n) data_out 1b0; else begin if (lpf_out 16sd0) data_out 1b1; else data_out 1b0; end end完整解调器代码bpsk_demodulator.vmodule bpsk_demodulator( input wire clk, input wire rst_n, input wire signed [7:0] bpsk_in, input wire [31:0] fcw, output reg data_out ); reg [31:0] phase_acc; always (posedge clk or negedge rst_n) begin if (!rst_n) phase_acc 32d0; else phase_acc phase_acc fcw; end reg signed [7:0] sin_lut [0:255]; initial begin $readmemh(sin_lut_one.hex, sin_lut); end wire signed [7:0] local_sin; assign local_sin sin_lut[phase_acc[31:24]]; reg signed [15:0] mixed_signal; always (posedge clk or negedge rst_n) begin if (!rst_n) mixed_signal 16sd0; else mixed_signal bpsk_in * local_sin; end reg signed [15:0] lpf_out; always (posedge clk or negedge rst_n) begin if (!rst_n) lpf_out 16sd0; else lpf_out lpf_out (mixed_signal 4) - (lpf_out 4); end always (posedge clk or negedge rst_n) begin if (!rst_n) data_out 1b0; else begin if (lpf_out 16sd0) data_out 1b1; else data_out 1b0; end end endmodule5. 顶层模块与自环测试顶层模块bpsk_top将调制器和解调器直接连接形成自环测试通路。这里需要特别注意fcw的位宽声明为[31:0]避免默认 1 位导致的不匹配。module bpsk_top( input wire clk, input wire rst_n, input wire data_in, input wire [31:0] fcw, output wire data_out ); wire [7:0] bpsk_data; bpsk_modulator u_bpsk_modulator( .clk (clk), .rst_n (rst_n), .data_in (data_in), .fcw (fcw), .bpsk_out (bpsk_data) ); bpsk_demodulator u_bpsk_demodulator( .clk (clk), .rst_n (rst_n), .bpsk_in (bpsk_data), .fcw (fcw), .data_out (data_out) ); endmodule测试仿真BPSK调制部分基本正常解调输出data_out正确恢复。

相关新闻

【大数据课程设计/毕业设计】基于大数据可视化的人才职业倾向评估系统的设计与实现 基于智能分析的职业测评与就业招聘可视化系统【附源码、数据库、万字文档】

【大数据课程设计/毕业设计】基于大数据可视化的人才职业倾向评估系统的设计与实现 基于智能分析的职业测评与就业招聘可视化系统【附源码、数据库、万字文档】

2026/9/28 21:04:00

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

企业级AI服务成本与安全解析:从Token计费到数据主权

企业级AI服务成本与安全解析:从Token计费到数据主权

2026/9/6 18:29:45

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 Palantir CEO Alex Karp 最近公开批评 OpenAI 等 AI 公司存在"双重收费"问题,即既向用户收取使用费用&#xff…

【DALL-E 3 vs Midjourney终极对决】:20年AI图像生成实战者亲测的5大关键差异与选型决策指南

【DALL-E 3 vs Midjourney终极对决】:20年AI图像生成实战者亲测的5大关键差异与选型决策指南

2026/9/8 6:38:53

更多请点击: https://kaifayun.com 第一章:DALL-E 3 vs Midjourney终极对决:一场二十年AI图像生成老兵的深度复盘 当DALL-E 3以GPT-4o多模态理解为基座高调入场,Midjourney v6则携其十年迭代沉淀的美学先验强势回应——这场对决早…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/28 4:08:17

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/28 16:01:49

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/28 2:15:29

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/28 3:14:54

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/28 3:58:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/28 3:47:14

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/28 16:01:48

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/28 5:05:21

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/28 16:01:48

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…