G F S K

FPGA Implementation of DBPSK Modulator and Demodulator

前言

本设计使用开发工具为Quartus prime 18.1和Matlab 2018B
工程连接:

一、方案设计

1、系统介绍

GFSK介绍:
GFSK(Gaussian Frequency-Shift Keying)是一种数字调制技术,用于在无线通信中传输数字信息。它是一种频率移键控(FSK)调制方式,通过在调制信号的频率上引入高斯滚降滤波来实现平滑频率切换,从而在频谱上产生光滑的频率转移。

2、系统流程图

在这里插入图片描述

3、模块分析

3.1 信源差分编码

差分编码原理:

B(n) = A(n) ^ B(n-1)

相对码 = 绝对码 异或 相对码前一马元

3.2 FSK调制

请添加图片描述

3.3 FSK解调

请添加图片描述

3.4 信宿差分解码

差分译码原理:

A(n) = B(n) ^ B(n-1)

绝对码 = 相对码 异或 相对码前一码元

二、matlab实现

1、 信源差分编码

%% 产生二进制序列
s=randi([0 1],max,1); %产生介于0-1之间的长度为max的1列随机序列  输入序列码元
Sinput=[]; %输入序列波形
for n=1:length(s)
    if s(n)==0
        A=zeros(1,Code_Len);    %码元宽度为2000
    else
        s(n)=1;
        A=ones(1,Code_Len);
    end
    Sinput=[Sinput A];
end 

%% 差分编码
Sbianma=encode(s,15,11,'hamming'); %汉明码编码后序列,一行15列的二进制数字
a1=[];%差分编码序列波形
b1=[];%解调载波
for n=1:length(Sbianma) %差分编码
    if Sbianma(n)==0
        B=zeros(1,Code_Len);  %每个值2000个点
    else
        Sbianma(n)=1;
        B=ones(1,Code_Len);
    end
    a1=[a1 B];  %s(t),码元宽度2000
    c=cos(2*pi*f*t);  %载波信号 0相位
    b1=[b1 c];  %与s(t)等长的载波信号,变为矩阵形式
end 

在这里插入图片描述

2、 GFSK调制

%% GFSK调制
a2=[];%FSK调制信号波形
ca2=[];%调制载波

for n=1:length(Sbianma)%调制载波2
    if Sbianma(n)==0
        C=ones(1,Code_Len);  %每个码元采样2000点
        d=cos(2*pi*f1*t);  %载波1
    else
        Sbianma(n)=1;
        C=ones(1,Code_Len);
        d=cos(2*pi*f2*t);  %载波2
    end
    a2=[a2 C];  %s(t),码元宽度2000
    ca2=[ca2 d];  %与s(t)等长的载波信号 
end
tiaoz=a2.*ca2;  %FSK调制

在这里插入图片描述

3、加入高斯滤波器

% 定义高斯滤波器参数
sigma = 2; % 高斯函数的标准差
filter_size = 9; % 滤波器尺寸
% 使用filter函数设计一维高斯滤波器
gaussian_filter = fspecial('gaussian', [1, filter_size], sigma);

% 使用filter函数对输入信号进行滤波
GF_singal = filter(gaussian_filter, 1, tz);

高斯滤波器系数
在这里插入图片描述

4、带通滤波器

Filter_1 = BPF10M_70_1800Kto2200K;%带通滤波器1 (采样频率10M,100阶,通频带1.8M~2.2M,保留信号频率2M)
Carrier_1 = filter(Filter_1,tz);

Filte_2 = LPF10M_50_15Kto25K;%带通通滤波器2 (采样频率10M,10阶,截止频率10K~500K,保留信号频率30K)
Carrier_2 = filter(Filte_2,tz);

在这里插入图片描述

带通滤波器1
在这里插入图片描述

带通滤波器2
在这里插入图片描述

5、 相干解调

demodulation_1 = 2*b1.*Carrier_1;%经过带通滤波器后的载波1,乘以2M信号相干解调

demodulation_2 = 2*b11.*Carrier_2;%经过带通滤波器后的载波2,乘以30K信号相干解调

在这里插入图片描述

6、 低通滤波

LPF1 = LPF10M_100_10K;%FIR低通滤波,采样频率10M,100阶,截止频率10K
LPres_1 = filter(LPF1,demodulation_1);%fir滤波

LPF2 = LPF10M_100_10K;%FIR低通滤波,采样频率10M,500阶,截止频率10K
LPres_2 = filter(LPF2,demodulation_2);%fir滤波

在这里插入图片描述

低通FIR滤波器设计
在这里插入图片描述

7、 抽样判决

%% 抽样判决
for m=1:Code_Len*length(Sbianma)
    if jt(m)<0
        jt(m)=1;
    else jt(m)>0
        jt(m)=0;
    end
end

在这里插入图片描述

8、 信宿差分解码

%% 差分解码
n=1:Code_Len:Code_Len*length(Sbianma);
a5=[];
a5=[a5 jt(n)];
s1=decode(a5,15,11,'hamming'); %汉明译码
a6=[];
for n=1:length(s1)
    if s1(n)==0
        G=zeros(1,Code_Len);
    else
        s1(n)=1;
        G=ones(1,Code_Len);
    end
    a6=[a6 G];
end

输入信号和输出信号对比
在这里插入图片描述

三、FPGA实现

顶层RTL

在这里插入图片描述

1、随机序列生成

/*
m:x^8+x^4+x^3+x^2+1
*/

module msequence8#(
   parameter seed= 8'b1111_1111
)(
   input clk,
   input rst_n,
   input en,
   output reg [31:0]num,
   output mse8, //m sequence
   output reg [7:0]rand8
);

assign mse8 = rand8[0];

always @ (posedge clk or negedge rst_n)begin
   if(!rst_n) begin
      rand8 <= seed;
      num <= 32'd1;
   end
   else if(en) begin
      rand8[0] <= rand8[1];
      rand8[1] <= rand8[2];
      rand8[2] <= rand8[3];
      rand8[3] <= rand8[4];
      rand8[4] <= rand8[5];
      rand8[5] <= rand8[6];
      rand8[6] <= rand8[7];
      rand8[7] <= rand8[0] ^ rand8[4] ^ rand8[5] ^ rand8[6];
      num <= num + 1'b1;
   end
   else
      rand8 <= rand8;
end

endmodule

RTL视图:
在这里插入图片描述

2、 信源差分编码

module encode(
	input Clk,
	input Rst_n,
	input an,//绝对码
	
	output reg bn//相对码
);

reg bn_latter;//相对码前一码元

always@(posedge Clk or negedge Rst_n)begin
	if(!Rst_n)
		bn_latter <= 0;
	else
		bn_latter <= bn;
end

always@(posedge Clk or negedge Rst_n)begin
	if(!Rst_n)
		bn <= 0;
	else
		bn <=  an ^ bn_latter;
end

endmodule

差分编码仿真波形
在这里插入图片描述
RTL:

在这里插入图片描述

3、 GFSK调制

module FSK_modulation(
    input Clk_10M,
    input Rst_n,
//	input [31:0]data_in,//串行差分编码信号输入
	input encode_data,//输入数据
    
	output reg Signal_CLK,//码元同步时钟
	output reg [7:0]num,
	output [8:0]address_m,
    output signed [7:0]modulation_data//调制信号输出
);

reg [10:0]cnt;
reg Clear;//单码元结束表示

always @(posedge Clk_10M, negedge Rst_n)begin//产生码元同步时钟
	if (!Rst_n) begin
		cnt <= 11'd0;
		num <= 8'd0;
		Clear <= 1;
		Signal_CLK <= 1'b0;
	end
	else if (cnt == 11'd2047)begin//0.0002048s  5K
		cnt <= 11'd0;
		num <= num + 1'b1;
		Clear <= 0;
		Signal_CLK <= 1'b0;
	end
	else if (cnt == 11'd1023)begin
		cnt <= cnt + 1'b1;
		num <= num;
		Clear <= 1;		
		Signal_CLK <= 1'b1;
	end
	else begin
		cnt <= cnt + 1'b1;
		num <= num;
		Clear <= 1;
		Signal_CLK <= 1'b0;
	end
end

//

wire [7:0]modulation_data_310K;
wire [7:0]modulation_data_20K;


//调制载波1 信息0
sin_table_310K sin_table_310K(
	.Clk_10M(Clk_10M),//10M
	.Rst_n(Rst_n),
	.Clear(Clear),
	.Key(1'b1),
	.address(),
	.data_out(modulation_data_310K)//310K
);

//调制载波2 信息1
sin_table_20K sin_table_20K(
	.Clk_10M(Clk_10M),//10M
	.Rst_n(Rst_n),
	.Clear(Clear),
	.Key(1'b1),
	.address(address_m),
	.data_out(modulation_data_20K)//20K
);

assign modulation_data = (encode_data)? modulation_data_20K: modulation_data_310K;


endmodule

GFSK调制仿真波形
在这里插入图片描述
RTL视图:

在这里插入图片描述

4、 带通滤波器

//载波1滤波
wire [22:0]BPF_1_FIR_out;
wire BPF_1_ast_source_valid;
wire [1:0]BPF_1_ast_source_error;
wire [15:0]BPF_1_res16;

BPF_1 BPF_1( //310K
	.clk(Clk_50M),              //                     clk.clk
	.reset_n(Rst_n),          //                     rst.reset_n
	.ast_sink_data(modulation_data),    //   avalon_streaming_sink.data
	.ast_sink_valid(Fs_10M),   //                        .valid
	.ast_sink_error(2'd0),   //                        .error
	.ast_source_data(BPF_1_FIR_out),  // avalon_streaming_source.data
	.ast_source_valid(BPF_1_ast_source_valid), //                        .valid
	.ast_source_error(BPF_1_ast_source_error)  //                        .error
);

assign BPF_1_res16 = BPF_1_FIR_out[22:7];

//载波2滤波
wire [21:0]BPF_2_FIR_out;
wire BPF_2_ast_source_valid;
wire [1:0]BPF_2_ast_source_error;
wire [15:0]BPF_2_res16;

BPF_2 BPF_2( //20K
	.clk(Clk_50M),              //                     clk.clk
	.reset_n(Rst_n),          //                     rst.reset_n
	.ast_sink_data(modulation_data),    //   avalon_streaming_sink.data
	.ast_sink_valid(Fs_10M),   //                        .valid
	.ast_sink_error(2'd0),   //                        .error
	.ast_source_data(BPF_2_FIR_out),  // avalon_streaming_source.data
	.ast_source_valid(BPF_2_ast_source_valid), //                        .valid
	.ast_source_error(BPF_2_ast_source_error)  //                        .error
);

assign BPF_2_res16 = BPF_2_FIR_out[21:6];


调制信号经过带通滤波器后仿真波形
在这里插入图片描述

RTL视图:

在这里插入图片描述
带通滤波器1设计
在这里插入图片描述

带通滤波器2设计
在这里插入图片描述

5、 GFSK相干解调

module FSK_demodulation_310K(
    input Clk_10M,
    input Rst_n,
    input signed [15:0]modulation_data_310K,
    
	output signed [7:0]carrier_wave_310K,
    output [8:0]address_dm_310K,
    output reg signed [23:0]demodulation_data_310K
);

//解调载波1
sin_table_310K sin_table_demodulation_310K(
	.Clk_10M(Clk_10M),//10M
	.Rst_n(Rst_n),
	.Clear(1'b1),
	.Key(1'b1),
	.address(address_dm_310K),
	.data_out(carrier_wave_310K)//310K
);

//载波相乘
always @(posedge Clk_10M, negedge Rst_n)begin
	if (!Rst_n)
		demodulation_data_310K <= 24'd0;
	else
		demodulation_data_310K <= modulation_data_310K * carrier_wave_310K;
end

endmodule

GFSK相干解调后仿真波形
在这里插入图片描述

RTL视图:
在这里插入图片描述

6、 低通滤波

//载波1低通滤波
wire [56:0]LPF_1_FIR_out;
wire LPF_1_ast_source_valid;
wire [1:0]LPF_1_ast_source_error;

LPF LPF_1(
	.clk(Clk_50M),              //   clk
	.reset_n(Rst_n),          //                     rst.reset_n
	.ast_sink_data(demodulation_data_310K),    //   avalon_streaming_sink.data
	.ast_sink_valid(Fs_10M),   // fs
	.ast_sink_error(2'd0),   //                        .error
	.ast_source_data(LPF_1_FIR_out),  // avalon_streaming_source.data
	.ast_source_valid(LPF_1_ast_source_valid), //                        .valid
	.ast_source_error(LPF_1_ast_source_error)  //                        .error
);

wire demd_bitstream_1;
assign demd_bitstream_1 = (LPF_1_FIR_out <= -57'd1110430718497) ? 1'b1: 1'b0;

低通滤波后仿真波形
在这里插入图片描述

FIR IP核调用
在这里插入图片描述

7、 信宿差分解码

module decode(
	input Clk,
	input Rst_n,
	input bn,//相对码
	
	output reg [7:0]num,
	output reg an//绝对码
);

reg bn_latter;//相对码前一码元

always@(posedge Clk or negedge Rst_n)begin
	if(!Rst_n)
		bn_latter <= 0;
	else
		bn_latter <= bn;
end

always@(posedge Clk or negedge Rst_n)begin
	if(!Rst_n)begin
		an <= 0;
		num <= 8'd0;
	end
	else begin
		an <= bn ^ bn_latter;
		num <= num + 1'b1;
	end
end

endmodule

差分解码后仿真波形
在这里插入图片描述

RTL视图:
在这里插入图片描述

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
G-S迭代是一种线性方程组求解的方法,可以用C语言实现。通常需要定义一个数组来存储系数矩阵以及右侧向量,然后按照迭代公式进行迭代计算,直到达到一定的精度要求或者迭代次数限制。下面是一个简单的G-S迭代的C语言实现示例: ```c #include <stdio.h> #include <math.h> #define N 3 // 线性方程组的维度 int main() { double A[N][N] = {{4, 1, 0}, {1, 4, 1}, {0, 1, 4}}; // 系数矩阵 double b[N] = {1, 2, 3}; // 右侧向量 double x[N] = {0, 0, 0}; // 初始解向量 double x_old[N]; // 记录上一次迭代的解向量 double eps = 1e-6; // 精度要求 int max_iter = 100; // 最大迭代次数 for (int k = 0; k < max_iter; k++) { for (int i = 0; i < N; i++) { double sum = 0; for (int j = 0; j < N; j++) { if (j != i) { sum += A[i][j] * x[j]; } } x_old[i] = x[i]; x[i] = (b[i] - sum) / A[i][i]; } double err = 0; for (int i = 0; i < N; i++) { err += pow(x[i] - x_old[i], 2); } err = sqrt(err); if (err < eps) { printf("Converged after %d iterations.\n", k + 1); break; } } printf("Solution: ["); for (int i = 0; i < N; i++) { printf("%f", x[i]); if (i < N - 1) { printf(", "); } } printf("]\n"); return 0; } ``` 这里假设线性方程组的系数矩阵已经存储在一个二维数组`A`中,右侧向量存储在一个一维数组`b`中。初始解向量`x`和上一次迭代的解向量`x_old`都初始化为0。在每一轮迭代中,按照G-S迭代公式计算新的解向量`x`,同时计算误差`err`,如果误差小于精度要求`eps`,则认为已经收敛,退出迭代。如果达到最大迭代次数`max_iter`仍未收敛,则认为迭代失败。最终输出求解结果`x`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值