基于AD9361的BPSK调制解调器探索:位同步与误码率测试

基于AD9361的BPSK调制解调器、位同步、误码率测试demo。 零中频架构,适用于AD9361等软件无线电平台,带AD9361纯逻辑FPGA驱动,verilog代码,Vivado 2019.1工程。 本产品为代码

最近在捣鼓软件无线电相关的项目,基于AD9361开发了一个超有意思的BPSK调制解调器,还实现了位同步以及误码率测试的demo,今天就来和大家分享分享。

零中频架构与AD9361平台

这次选用的零中频架构,特别适合像AD9361这样的软件无线电平台。零中频架构简单来说,就是把射频信号直接下变频到基带,这样能减少很多复杂的变频级,降低成本和复杂度,对于我们搞开发来说简直不要太友好。

AD9361更是软件无线电领域的明星芯片,它集成了很多功能,为我们开发调制解调器提供了强大的硬件支持。

AD9361纯逻辑FPGA驱动Verilog代码

下面就来看看AD9361的FPGA驱动Verilog代码片段(这里只展示关键部分):

verilog 复制代码
module ad9361_driver (
    input wire clk,
    input wire rst,
    // 其他控制信号输入
    output reg [15:0] ad9361_data_out,
    // 其他输出信号
);

always @(posedge clk or posedge rst) begin
    if (rst) begin
        ad9361_data_out <= 16'b0;
        // 初始化其他信号
    end else begin
        // 根据具体逻辑处理数据
        ad9361_data_out <= some_processed_data;
    end
end

// 其他功能模块逻辑

endmodule

这段代码定义了一个ad9361driver**模块,它的输入信号包括时钟clk和复位信号rst。在复位信号有效的时候,会对输出数据ad9361 dataout**进行清零操作,同时也会初始化其他一些信号。而在正常时钟驱动下,会按照特定的逻辑处理数据,并将处理后的数据赋给ad9361 data_out。当然,实际代码里还有很多其他功能模块逻辑,这里省略了,不过核心就是围绕对AD9361的控制和数据交互。

BPSK调制解调器实现

BPSK调制解调器可是这个项目的核心部分。BPSK,也就是二进制相移键控,它通过改变载波的相位来传输二进制数据,0对应一种相位,1对应另一种相位。

在FPGA里实现BPSK调制的代码逻辑大概是这样(简化示意):

verilog 复制代码
module bpsk_modulator (
    input wire clk,
    input wire [7:0] data_in,
    output reg [15:0] modulated_signal
);

always @(posedge clk) begin
    for (int i = 0; i < 8; i = i + 1) begin
        if (data_in[i]) begin
            // 1对应一种相位,这里假设相位为180度
            modulated_signal <= {16{1'b1}}; 
        end else {
            // 0对应另一种相位,假设相位为0度
            modulated_signal <= {16{1'b0}}; 
        }
    end
end

endmodule

这段代码的bpskmodulator**模块接收8位的输入数据data in,在时钟上升沿,对每一位数据进行处理。如果数据位是1,就设置调制信号modulated_signal为对应180度相位的数字表示;如果是0,就设置为0度相位的数字表示。实际实现中还会涉及到更多细节,比如载波频率的设置、信号幅度调整等等,但基本思路就是这样。

位同步实现

位同步是确保接收端能够准确识别每一位数据的关键。实现位同步的方法有很多,这里采用了一种简单的基于时钟同步的方法。代码实现如下:

verilog 复制代码
module bit_sync (
    input wire clk,
    input wire rx_signal,
    output reg synced_signal
);

reg [3:0] counter;

always @(posedge clk or negedge rx_signal) begin
    if (!rx_signal) begin
        counter <= 4'b0;
    end else begin
        if (counter == 4'd15) begin
            synced_signal <= rx_signal;
            counter <= 4'b0;
        end else begin
            counter <= counter + 1;
        end
    end
end

endmodule

在这个bitsync**模块里,使用了一个4位的计数器counter。当接收到的信号rx signal下降沿到来时,计数器清零。在时钟上升沿,计数器开始递增,当计数器达到15时,就认为当前接收到的rxsignal**是经过同步的信号,赋给synced signal,同时计数器再次清零,准备下一次同步。

误码率测试

误码率测试能让我们知道这个调制解调器在不同环境下的性能表现。基本思路就是在发送端发送已知的数据,在接收端对比接收到的数据和原始数据,统计错误的位数,进而计算误码率。

verilog 复制代码
module ber_test (
    input wire clk,
    input wire [7:0] tx_data,
    input wire [7:0] rx_data,
    output reg [31:0] error_count,
    output reg [31:0] total_count
);

always @(posedge clk) begin
    total_count <= total_count + 1;
    for (int i = 0; i < 8; i = i + 1) begin
        if (tx_data[i]!= rx_data[i]) begin
            error_count <= error_count + 1;
        end
    end
end

endmodule

bertest**模块中,每次时钟上升沿,total count就增加1,表示又处理了一组数据。然后对比发送数据txdata**和接收数据rx data的每一位,如果发现不同,error_count就加1。通过这两个计数器,就能很方便地计算出误码率了。

这个基于AD9361的BPSK调制解调器项目涵盖了从硬件驱动到核心调制解调算法,再到位同步和误码率测试的完整流程,对于深入理解软件无线电和数字通信非常有帮助。希望这篇分享能给同样在这个领域探索的朋友们一些启发。

相关推荐
Lian_Ge_Blog1 天前
Embedding 模型word2vec/glove/fasttext/elmo/doc2vec/infersent学习总结
embedding·word2vec
_codemonster2 天前
AI大模型入门到实战系列(三)词元(token)和嵌入(embedding)
人工智能·机器学习·embedding
GokuCode3 天前
【GO高级编程】05.类的扩展与复用
golang·embedding·xcode
大千AI助手3 天前
Text-Embedding-Ada-002:技术原理、性能评估与应用实践综述
人工智能·机器学习·openai·embedding·ada-002·文本嵌入·大千ai助手
_codemonster4 天前
AI大模型入门到实战系列(五)上下文嵌入向量(contextualized embedding)
人工智能·深度学习·embedding
Blossom.1185 天前
基于Embedding+图神经网络的开源软件供应链漏洞检测:从SBOM到自动修复的完整实践
人工智能·分布式·深度学习·神经网络·copilot·开源软件·embedding
Yeliang Wu6 天前
基于 ms-swift 框架微调 Embedding 模型(Ubuntu22.04):从原理到实践
微调·embedding·训练·ms-swift
点云SLAM11 天前
Embedding 英文单词学习
人工智能·学习·嵌入式·embedding·安装·英文单词学习·雅思备考
陈鋆11 天前
Langchain-Chatchat[三、PG向量库embedding存储]
langchain·embedding