特权同学

基于FPGA的FSK调制

0
阅读(2492)

至于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生成函数。

Baidu
map