)
在数字通信、软件无线电SDR中BPSK二进制相移键控是最基础、最经典的数字调制方式。它用 0° 和 180° 两个相位的正弦载波分别表示二进制 0 和 1抗噪性能强、实现简单。本文就基于一段可直接综合、可仿真运行的 Verilog 代码从零讲透数字 BPSK 到底怎么实现代码每一行在干什么背后原理是什么一、BPSK 概念一句话用载波相位表示数字信息发送0→ 输出正常正弦波相位 0°发送1→ 输出反转正弦波相位 180°数学上0 对应\(s_0(t) \sin(\omega t)\)1 对应\(s_1(t) -\sin(\omega t) \sin(\omega t\pi)\)在数字电路里我们不用复杂的相位计算直接对正弦波采样值取反就完成了 180° 相移 —— 这也是这份代码最巧妙的地方。二、DDS 载波 BPSK 调制这份代码只有一个模块完成两件核心事DDS直接数字频率合成生成稳定的正弦载波BPSK 调制根据输入比特输出原波 / 反相波整体信号流输入比特 data_in→相位判断0/1→DDS 生成正弦→原波/取反→输出调制波形 bpsk_out三、逐行拆解 Verilog 代码1. 模块端口定义verilogmodule bpsk_modulator( input wire clk, // 系统时钟 input wire rst_n, // 低电平复位 input wire data_in, // 基带比特流0/1 input wire [31:0] fcw, // 频率控制字控制载波频率 output reg signed [7:0] bpsk_out // BPSK调制输出8位有符号 );fcw频率控制字决定载波频率改它就能改频bpsk_out8 位有符号数直接送给 DAC 就能出模拟波形2. DDS 核心相位累加器verilogreg [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每来一个时钟相位就 fcw32 位寄存器不断累加相当于数字角度旋转器频率公式越大载波频率越高。3. 正弦波查找表LUTverilogwire [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 assign sin_out sin_lut[phase_acc[31:24]];相位高 8 位作为地址0~255刚好对应一个完整正弦周期从 ROM 里读出预存的正弦采样值不用乘法器纯查表速度快、省资源4. BPSK 调制最关键一行逻辑verilogalways (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 → 原相 enddata_in 0直接输出正弦data_in 1正弦值取反 180° 相移这就是数字 BPSK 的最简实现仿真代码和结果timescale 1ns/1ps module tb_bpsk_modulator(); reg clk ; reg rst_n ; reg data_in ; reg [31:0] fcw ; wire [7:0] bpsk_out ; bpsk_modulator u_bps_modulator( .clk (clk ), .rst_n (rst_n ), .fcw (fcw ), .data_in (data_in ), .bpsk_out (bpsk_out) ); initial begin clk 0 ; forever begin #5 clk ~clk; end end initial begin rst_n 0; fcw 32d429496730; #100 rst_n 1; data_in 0; #100 data_in 1; #100 data_in 1; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 rst_n 1; data_in 0; #100 data_in 1; #100 data_in 1; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 rst_n 1; data_in 0; #100 data_in 1; #100 data_in 1; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 rst_n 1; data_in 0; #100 data_in 1; #100 data_in 1; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 rst_n 1; data_in 0; #100 data_in 1; #100 data_in 1; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 rst_n 1; data_in 0; #100 data_in 1; #100 data_in 1; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 1; #100 data_in 0; #100 data_in 0; #100 data_in 0; #100 data_in 1; #5000 $finish; end endmodule设定系统时钟 100MHz、频率控制字 FCW429496730 完成波形仿真对比可见输入基带比特 0、1 对应的两路载波相位区分清晰调制波形规整理想。