基于FPGA的BPSK、QPSK以及OQPSK实现

这篇具有很好参考价值的文章主要介绍了基于FPGA的BPSK、QPSK以及OQPSK实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

大家第一次接触PSK是什么时候呢?我第一次是在通信原理里面的数字带通传输系统里面接触到了数字调制原理。然后由于自己现在在学FPGA,所以就想着看能不能用FPGA实现一下书本里面所学的BPSK、QPSK以及OQPSK。

首先介绍一下几种调制原理:

一、二进制相移键控(BPSK)

相移键控是利用载波的相位变化来传递信息,而振幅和频率保持不变。在BPSK中,通常用初始相位0和π分别表示二进制“1”和“0”。因此,BPSK信号的时域表达式为  

fpga实现bpsk调制,小白学FPGA,fpga开发

    

其中φn表示第n个符号的绝对相位,即    

fpga实现bpsk调制,小白学FPGA,fpga开发

                    

因此,BPSK信号的表达式也可写为

fpga实现bpsk调制,小白学FPGA,fpga开发

BPSK信号的调制有两种方法,一种是模拟调制方法,如图1(a)所示,另一种则是键控法,如图1(b)所示,即通过开关电路来输出相应相位的载波。我们在这里采用键控法来产生BPSK信号。

fpga实现bpsk调制,小白学FPGA,fpga开发(a)模拟调制方法

fpga实现bpsk调制,小白学FPGA,fpga开发(b)键控法

图1BPSK信号调制原理框图

fpga实现bpsk调制,小白学FPGA,fpga开发

fpga实现bpsk调制,小白学FPGA,fpga开发

 二、正交相移键控(QPSK) 

QPSK即正交相移键控又被称为四相移键控。它具有4种相位状态对应四组数据,即00,01,10,11。

QPSK信号的产生有两种方法,第一种是正交调相,其原理如图2(a)所示。输入的基带信号(单极性归零码元)经过串并转换电路变成两路二进制不归零双极性码元a和b。并行码元a和b的持续时间均是输入码元的2倍。a路码元与载波相乘得到I路信号,b路码元与载波相乘得到Q路信号,再经过相乘电路将I、Q两路信号进行叠加得到QPSK信号。

第二种是相位选择法,其原理如图2(a)所示。这时输入的基带信号经过串并转换后用于控制一个相位选择电路,按照当时输入的双比特ab,决定选择哪一个相位的载波输出。

fpga实现bpsk调制,小白学FPGA,fpga开发(a)正交调相法产生QPSK信号

fpga实现bpsk调制,小白学FPGA,fpga开发(b)相位选择法产生QPSK信号

图2QPSK信号调制原理框图

fpga实现bpsk调制,小白学FPGA,fpga开发

fpga实现bpsk调制,小白学FPGA,fpga开发

fpga实现bpsk调制,小白学FPGA,fpga开发

三、偏置正交相移键控(OQPSK)

OQPSK称为偏置正交相移键控,它与QPSK的唯一区别在于两个正交分量的两个比特a和b在时间上错开了半个码元周期。在QPSK体制中,它的相邻码元最大相位差达到了180°,由于这样的相位突变在频带受限的系统中会引起信号包络的很大起伏,这是不希望的,所以为了减少此相位突变,将两个正交的分量比特a和b在时间上错开半个码元,使之不能同时改变。 

fpga实现bpsk调制,小白学FPGA,fpga开发

fpga实现bpsk调制,小白学FPGA,fpga开发

fpga实现bpsk调制,小白学FPGA,fpga开发

 下面就进入程序设计及仿真部分:

整个程序设计主要包括伪随机序列产生模块、载波产生模块、调制模块。

一、随机序列产生模块

module m_data(
    input sys_clk,
    input rst_n,
    output m_data1,
    output reg [1:0] m_data2,
    output reg [1:0] om_data2
    );
parameter N = 32;
parameter counter = 10_000;
reg [8:0] reg1;
reg reg2;
reg [N-1:0] count;
reg count1_flag;
reg count2_flag;
assign m_data1 = reg1[0];
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        count <= 32'd0;
    else if(count == counter - 1'b1)
        count <= 32'd0;
    else
        count <= count + 1'b1;
end
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        reg1 <= 9'b000111101;
    else if(count == counter - 1'b1)
    begin
        reg1[8] <= reg1[0]^reg1[2];
        reg1[7:0] <= reg1[8:1]; 
    end
end

always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
    begin
        om_data2 <= 2'b00;
        reg2 <= 1'b0;
        count1_flag <= 1'b1;
    end
    else if(count == counter - 1'b1)
    begin
        if(count1_flag == 1'b1)
        begin
            om_data2[1] <= m_data1;
            count1_flag <= 1'b0;
        end
        else
        begin 
            om_data2[0] <= m_data1;
            count1_flag <= 1'b1;
        end
    end
end
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
    begin
        m_data2 <= 2'b00;
        reg2 <= 1'b0;
        count2_flag <= 1'b1;
    end
    else if(count == counter - 1'b1)
    begin
        if(count2_flag == 1'b1)
        begin
            reg2 <= m_data1;
            count2_flag <= 1'b0;
        end
        else
        begin 
            m_data2[1] <= reg2;
            m_data2[0] <= m_data1;
            count2_flag <= 1'b1;
        end
    end
end
endmodule

二、载波产生模块

module sine_cosine(
    input sys_clk,
    input rst_n,
    output [7:0] sine,
    output [7:0] cosine
    );
parameter N = 32;
/*
Fout = 50khz    Fclk = 50Mhz    Fout = FEORD*(Fclk / 2**N)
FWORD = (Fout * 2**N) / Fclk = 50_000 * 65536 * 65536 / 50_000_000 = 4294967
*/
parameter FWORD = 4294967;
parameter PWORD = 128;
reg [N-1:0] addr;
wire [8:0] sine_addr;
wire [8:0] cosine_addr;
assign sine_addr = addr[N-1:N-9];
assign cosine_addr = addr[N-1:N-9] + PWORD;
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        addr <= 32'd0;
    else
        addr <= addr + FWORD;  
end
rom_sine rom_sine_inst1 (
  .clka(sys_clk),    // input wire clka
  .addra(sine_addr),  // input wire [8 : 0] addra
  .douta(sine)  // output wire [7 : 0] douta
);
rom_sine rom_sine_inst2 (
  .clka(sys_clk),    // input wire clka
  .addra(cosine_addr),  // input wire [8 : 0] addra
  .douta(cosine)  // output wire [7 : 0] douta
);
endmodule

三、调制模块

(1)BPSK

module bpsk(
    input sys_clk,
    input rst_n,
    input m_data1,
    output [8:0] bpsk
    );
reg [31:0] bpsk_PWORD;
wire [8:0] rom_addr;
wire [7:0] bpsk_reg;
assign bpsk = {1'b0,bpsk_reg};
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        bpsk_PWORD <= 32'd0;
    else if(m_data1)
        bpsk_PWORD <= 32'd0;
    else
        bpsk_PWORD <= 32'd256;
end
rom_addr  rom_addr_inst(
    .sys_clk(sys_clk),
    .rst_n(rst_n),
    .PWORD(bpsk_PWORD),
    .rom_addr(rom_addr)
);
rom_sine rom_sine_inst (
  .clka(sys_clk),    // input wire clka
  .addra(rom_addr),  // input wire [8 : 0] addra
  .douta(bpsk_reg)  // output wire [7 : 0] douta
);
endmodule

(2)QPSK

module qpsk(
    input sys_clk,
    input rst_n,
    input [1:0] m_data2,
    input [7:0] sine,
    input [7:0] cosine,
    output reg  [8:0] qpsk
);
reg [1:0] I_tmp;
reg [1:0] Q_tmp;
reg [7:0] I_cos;
reg [7:0] Q_sin;
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            I_tmp <= 2'b00;
            Q_tmp <= 2'b00;
        end
    else
        begin
             I_tmp <= (m_data2[0]) ? 2'b01 : 2'b11; 
             Q_tmp <= (m_data2[1]) ? 2'b01 : 2'b11;
        end
end
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        Q_sin <= 8'd0;
    else
    begin
        case(Q_tmp)
        2'b01:
            Q_sin <= sine;
        2'b11:
            Q_sin <= -sine;
        endcase
    end
end
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        I_cos <= 8'd0;
    else
    begin
        case(I_tmp)
        2'b01:
            I_cos <= cosine;
        2'b11:
            I_cos <= -cosine;
        endcase
    end
end
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        qpsk <= 9'd0;
    else
        qpsk <= I_cos + Q_sin;
end
endmodule

(3)OQPSK

OQPSK的代码基本上和QPSK保持一致,区别仅在于输入基带信号的不同。

module oqpsk(
    input sys_clk,
    input rst_n,
    input [1:0] m_data2,
    input [7:0] sine,
    input [7:0] cosine,
    output reg [8:0] oqpsk
);
reg [1:0] I_tmp;
reg [1:0] Q_tmp;
reg [7:0] I_cos;
reg [7:0] Q_sin;
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        begin
            I_tmp <= 2'b00;
            Q_tmp <= 2'b00;
        end
    else
        begin
             I_tmp <= (m_data2[0]) ? 2'b01 : 2'b11; 
             Q_tmp <= (m_data2[1]) ? 2'b01 : 2'b11;
        end
end
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        Q_sin <= 8'd0;
    else
    begin
        case(Q_tmp)
        2'b01:
            Q_sin <= sine;
        2'b11:
            Q_sin <= ~sine +1'b1;
        endcase
    end
end
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        I_cos <= 8'd0;
    else
    begin
        case(I_tmp)
        2'b01:
            I_cos <= cosine;
        2'b11:
            I_cos <= ~cosine + 1'b1;
        endcase
    end
end
always@(posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        oqpsk <= 9'd0;
    else
        oqpsk <= I_cos + Q_sin;
end
endmodule

以上都是各子模块的代码,最终我们需要在顶层模块中调用以上模块,然后编写仿真文件才能进行仿真。 

 四、仿真结果分析

通过仿真,我们得到如图所示的结果。m_data1是我们生成的数字基带信号,可以看到,当m_data1为1时,我们的BPSK信号相位为0;m_data1为0时,BPSK信号的相位为180°,达到了设计要求。m_data2是m_data1串并转换之后的信号,可以看出它的码元长度是基带信号的2倍,m_data2[1]和m_data2[0]分别代表I、Q两路信号,当I、Q两路信号为10时,相位为7π/4;为00时,相位为5π/4;为11时,相位为1π/4;为01时,相位为3π/4。m_data3是m_data2的I、Q两路信号错开半个码元周期的信号,此时我们可以看到信号从00变到11经历了00到10再到11即相位从5π/4到7π/4再到1π/4这样一个过程,避免了信号包络起伏大和相位发生突变。

fpga实现bpsk调制,小白学FPGA,fpga开发

到此,本次的设计基本上就结束了。由于水平有限,有些想法和思路还不成熟,存在很大问题。但是我还是想把我的想法分享给大家,希望大家看到之后能有所启发,同时也希望大家在发现错误之后能给我指出来,我会继续对此进行完善。 文章来源地址https://www.toymoban.com/news/detail-752979.html

到了这里,关于基于FPGA的BPSK、QPSK以及OQPSK实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • m基于FPGA的QPSK调制解调通信系统verilog实现,包含testbench,不包含载波同步

    目录 1.算法仿真效果 2.算法涉及理论知识概要 3.Verilog核心程序 4.完整算法代码文件 本系统进行了两个平台的开发,分别是: Vivado2019.2 Quartusii18.0+ModelSim-Altera 6.6d  Starter Edition 其中Vivado2019.2仿真结果如下:  Quartusii18.0+ModelSim-Altera 6.6d  Starter Edition的测试结果如下:        

    2024年02月12日
    浏览(47)
  • 基于FPGA的QPSK调制系统verilog开发

    目录 一、理论基础 二、核心程序 三、测试结果         正交相移键控(Quadrature Phase Shift Keying,QPSK)是一种数字调制方式。它分为绝对相移和相对相移两种。由于绝对相移方式存在相位模糊问题,所以在实际中主要采用相对移相方式DQPSK。QPSK是一种四进制相位调制,具有良

    2024年02月01日
    浏览(47)
  • 基于AD9361的BPSK调制解调器、位同步、误码率测试demo

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

    2024年04月23日
    浏览(52)
  • 【FPGA教程案例34】通信案例4——基于FPGA的QPSK调制信号产生,通过matlab测试其星座图

    FPGA教程目录 MATLAB教程目录 ---------------------------------------------------------------------------------------   目录 1.软件版本 2.QPSK调制原理

    2023年04月12日
    浏览(65)
  • 数字带通调制系统实验-BPSK的调制与解调

    1、实验原理 BPSK的调制原理 在二进制数字调制中,当正弦载波的相位随二进制数字基带信号离散变化 时,则产生二进制移相键控(2PSK)信号。通常用已调信号载波的0度和180 度分别表示二进制数字基带信号的1和0.二进制移相键控信号的时域表达式为 这种以载波的不同相位直接

    2024年02月02日
    浏览(65)
  • 【教程4>第2章>第7节】BPSK解调系统的FPGA开发与matlab对比验证

    欢迎订阅FPGA/MATLAB/Simulink系列教程 《★教程1:matlab入门100例》 《★教程2:fpga入门100例》 《★教程3:simulink入门60例》 《★教程4:FPGA/MATLAB/Simulink联合开发入门与进阶X例》 目录

    2024年04月12日
    浏览(39)
  • FPGA代做-基于FPGA的QPSK实现

    FPGA代做-基于FPGA的QPSK实现 第一章 课题研究意义和发展前景 OQPSK调制技术是一种恒包络调制技术,受系统非线性影响小,具有较高的带宽利用率和功率利用率,在卫星环境、无线环境下得到广泛应用。因此,在通信信号侦收设备所处理的信号中,存在大量的OQPSK信号。在传统

    2024年02月08日
    浏览(81)
  • 通信系统中基于matlab的BPSK信噪比检测算法及实现

    根据是否需要辅助数据,信噪比估计算法可以分为数据辅助类算法(Data aided, DA)和非数据辅助类算法(No Data aided, NDA)。DA估计算法准确性较高,但是需要提供先验信息,需要牺牲信道传输效率。NDA方法在传输数据信息的同时进行信噪比估计,不影响信息传输效率,适用范围较广

    2024年02月04日
    浏览(44)
  • verilog实现bpsk的发送并与matlab的bpsk仿真进行对比

    verilog的设计文件: tb文件: verilog的fir实现的根升余弦滤波器的输出与matlab的根升余弦滤波器输出的代码: 接下来是最终的发送波形的对比 结果如下:

    2024年02月07日
    浏览(49)
  • 基于FPGA的16QAM调制器verilog实现,包括testbench,并通过MATLAB显示FPGA输出信号的星座图

    目录 1.算法仿真效果 2.verilog核心程序 3.算法涉及理论知识概要 4.完整verilog matlab2022a/vivado2019.2仿真结果如下:  将FPGA仿真的数据导出,然后在matlab中将数据通过噪声之后,可以得到如下的星座图效果。 fpga工程版本信息:       16QAM全称正交幅度调制是英文Quadrature Amplitude

    2024年02月07日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包