基于FPGA的FSK调制
0赞至于FSK调制原理就不多说了,这里做的一个实验是二进制频移键控。发送一组码元,通过响应的键控电路监测是发1还是发0然后选 择频率控制正余弦电路波形。
功能仿真波形如下:
可以看到,codein信号是基带码元,它发送的是1010110001,而在输出端分别用正弦和余弦进行调制。cos_out和sin_out的波形与原始码元基本一致,不同码元衔接处出现较大的跳变是因为 采样的频率不够高造成的。1的调制频率是0的调制频率的两倍。
Verilog程序:
module fsktop(clk,rst,en,cos_out,sin_out,rdy);
input clk;
input rst;
input en;
output[15:0] cos_out;
output[15:0] sin_out;
output rdy;
wire codein;//发送基带码元
wire a_en,b_en;//FSK调制频率选择使能信号
wire ce;//正余弦发生器使能信号
wire[15:0] a_fre,b_fre,fre;
wire clk_40;//主时钟的40分频信号
clkfenpinclkfenpin(clk,rst,clk_40);
codesource codesource(clk_40,rst,en,codein);
coding coding(clk,rst,codein,a_en,b_en,ce,a_fre,b_fre,fre);
a_frequency a_frequency(clk,rst,a_en,a_fre);
b_frequency b_frequency(clk,rst,b_en,b_fre);
cos cos(fre,clk,ce,cos_out,sin_out,rdy);
endmodule
module clkfenpin(clk,rst,clk_40);
input clk;
input rst;
output clk_40;
reg[4:0] num;
reg clk_40;
always @ (posedge clk)
begin
if(rst) begin num <= 5'd0; clk_40 <= 0; end
else
begin
num <= num+1;
if(num==5'd19) begin num <= 5'd0; clk_40 <=~clk_40; end
end
end
endmodule
module codesource(clk_40,rst,en,codein);
input clk_40;
input rst;
input en;
output codein;//发送基带码元
reg codein;
reg[15:0] source;//从高到低连续发送该16bit码元信号
reg[3:0] num;
always @ (posedge clk_40)
begin
if(rst)
begin
source <= 16'b1010110001110010;
codein <= 1'bx;
num <= 4'b1111;
end
else if(en)
begin
codein <= source[num];
num <= num-1;
end
else
begin
source <= 16'b1010110001110010;
codein <= 1'bx;
num <= 4'b1111;
end
end
endmodule
module coding(clk,rst,codein,a_en,b_en,ce,a_fre,b_fre,fre);
input clk;
input rst;
input codein;
input[15:0] a_fre,b_fre;
output[15:0] fre;
output a_en,b_en;
output ce;
reg a_en,b_en;
reg ce;
reg[15:0] fre;
always @ (posedge clk)
begin
if(rst)
begin
a_en <= 0;
b_en <= 0;
ce <= 0;
fre <= 16'd0;
end
else if(!codein) //基带码元为0时,选择a_fre为 输出频率
begin
fre <= a_fre;
a_en <= 1;
b_en <= 0;
ce <= 1;
end
else if(codein) //基带码元为1时,选 择b_fre为输出频率
begin
b_en <= 1;
a_en <= 0;
ce <= 1;
fre <= b_fre;
end
else
begin
a_en <= 0;
b_en <= 0;
ce <= 0;
fre <= 16'd0;
end
end
endmodule
module a_frequency(clk,rst,a_en,fre);
input clk;
input rst;
input a_en;
output[15:0] fre;
reg[15:0] fre;
always @ (posedge clk)
begin
if(rst) begin fre <= 16'h9b82; end //-pi
else if(a_en)
begin
if((fre<16'h8000)&&(fre>16'h6087)) fre <= 16'h9b82;
else fre <= fre+16'h0506;
end
else begin fre <= 16'h9b82; end
end
endmodule
module b_frequency(clk,rst,b_en,fre);
input clk;
input rst;
input b_en;
output[15:0] fre;
reg[15:0] fre;
always @ (posedge clk)
begin
if(rst) begin fre <= 16'h9b82; end //pi
else if(b_en)
begin
if((fre<16'h8000)&&(fre>16'h6087)) fre <= 16'h9b82;
else fre <= fre+16'h0a0c;
end
else begin fre <= 16'h9b82; end
end
endmodule
调用了IP Core中的cos_sin生成函数。