900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 用verilog HDL实现数字基带信号的2FSK调制

用verilog HDL实现数字基带信号的2FSK调制

时间:2019-10-26 19:33:46

相关推荐

用verilog HDL实现数字基带信号的2FSK调制

2FSK的介绍可以参考:/qq_39148922/article/details/84337730

下面介绍verilog HDL的源代码

module FSK(input clk,//时钟信号output reg [7:0]sigOut,//输出已调信号output reg [7:0]carryWave1,//1对应的载波幅度output reg [7:0]carryWave0,//0对应的载波幅度output wire codeSource,//数字基带信号output reg codeClk=0,//用来控制数字基带信号的时钟output reg stClk=0//用来控制载波的时钟,数字基带时钟周期应为载波时钟的n倍);//分频器部分reg [7:0]codeClkCount=0;//时钟计数器reg [3:0]carryClkCount=0;//载波时钟计数器always @(posedge clk)begin//codeClkif(codeClkCount==127)begincodeClk=~codeClk;codeClkCount=0;endelsebegincodeClkCount=codeClkCount+1;end//carryClkif(carryClkCount==1)beginstClk=~stClk;carryClkCount=0;endelsebegincarryClkCount=carryClkCount+1;endend//数字基带信号,m序列发生器reg [5:0]outReg=6'b010101;//序列寄存器初始化reg mAdded;//m序列移位的辅助变量assign codeSource=outReg[5];//输出变量为寄存器序列的最高位always @(negedge codeClk)begin//手动异或if(outReg[0]==outReg[5])beginmAdded=0;endelsebeginmAdded=1;endoutReg=outReg<<1;//对寄存器左移outReg=outReg+mAdded;end//载波的产生reg [7:0]waveCount=0;//载波幅度查询变量always @(posedge stClk)beginif(waveCount==63)beginwaveCount=0;endelsebeginwaveCount=waveCount+1;end//根据查询变量进行载波幅度查询case(waveCount)0:begin carryWave0<=0;carryWave1<=0; end1:begin carryWave0<=12;carryWave1<=25; end2:begin carryWave0<=25;carryWave1<=49; end3:begin carryWave0<=37;carryWave1<=71; end4:begin carryWave0<=49;carryWave1<=90; end5:begin carryWave0<=60;carryWave1<=106; end6:begin carryWave0<=71;carryWave1<=117; end7:begin carryWave0<=81;carryWave1<=125; end8:begin carryWave0<=90;carryWave1<=127; end9:begin carryWave0<=98;carryWave1<=125; end10:begin carryWave0<=106;carryWave1<=117; end11:begin carryWave0<=112;carryWave1<=106; end12:begin carryWave0<=117;carryWave1<=90; end13:begin carryWave0<=122;carryWave1<=71; end14:begin carryWave0<=125;carryWave1<=49; end15:begin carryWave0<=126;carryWave1<=25; end16:begin carryWave0<=127;carryWave1<=0; end17:begin carryWave0<=126;carryWave1<=-25; end18:begin carryWave0<=125;carryWave1<=-49; end19:begin carryWave0<=122;carryWave1<=-71; end20:begin carryWave0<=117;carryWave1<=-90; end21:begin carryWave0<=112;carryWave1<=-106; end22:begin carryWave0<=106;carryWave1<=-117; end23:begin carryWave0<=98;carryWave1<=-125; end24:begin carryWave0<=90;carryWave1<=-127; end25:begin carryWave0<=81;carryWave1<=-125; end26:begin carryWave0<=71;carryWave1<=-117; end27:begin carryWave0<=60;carryWave1<=-106; end28:begin carryWave0<=49;carryWave1<=-90; end29:begin carryWave0<=37;carryWave1<=-71; end30:begin carryWave0<=25;carryWave1<=-49; end31:begin carryWave0<=12;carryWave1<=-25; end32:begin carryWave0<=0;carryWave1<=0; end33:begin carryWave0<=-12;carryWave1<=25; end34:begin carryWave0<=-25;carryWave1<=49; end35:begin carryWave0<=-37;carryWave1<=71; end36:begin carryWave0<=-49;carryWave1<=90; end37:begin carryWave0<=-60;carryWave1<=106; end38:begin carryWave0<=-71;carryWave1<=117; end39:begin carryWave0<=-81;carryWave1<=125; end40:begin carryWave0<=-90;carryWave1<=127; end41:begin carryWave0<=-98;carryWave1<=125; end42:begin carryWave0<=-106;carryWave1<=117; end43:begin carryWave0<=-112;carryWave1<=106; end44:begin carryWave0<=-117;carryWave1<=90; end45:begin carryWave0<=-122;carryWave1<=71; end46:begin carryWave0<=-125;carryWave1<=49; end47:begin carryWave0<=-126;carryWave1<=25; end48:begin carryWave0<=-127;carryWave1<=0; end49:begin carryWave0<=-126;carryWave1<=-25; end50:begin carryWave0<=-125;carryWave1<=-49; end51:begin carryWave0<=-122;carryWave1<=-71; end52:begin carryWave0<=-117;carryWave1<=-90; end53:begin carryWave0<=-112;carryWave1<=-106; end54:begin carryWave0<=-106;carryWave1<=-117; end55:begin carryWave0<=-98;carryWave1<=-125; end56:begin carryWave0<=-90;carryWave1<=-127; end57:begin carryWave0<=-81;carryWave1<=-125; end58:begin carryWave0<=-71;carryWave1<=-117; end59:begin carryWave0<=-60;carryWave1<=-106; end60:begin carryWave0<=-49;carryWave1<=-90; end61:begin carryWave0<=-37;carryWave1<=-71; end62:begin carryWave0<=-25;carryWave1<=-49; end63:begin carryWave0<=-12;carryWave1<=-25; endendcaseend//调制部分always @(posedge stClk)beginif(codeSource)beginsigOut=carryWave1;endelsebeginsigOut=carryWave0;endendendmodule

方法相对粗糙一些,毕竟是第一次用verilog实现调制的过程,就是按照调制的原理分步完成,考虑到的可优化的地方较少。

下面逐个对每个模块进行介绍。

分频器

//分频器部分reg [7:0]codeClkCount=0;//时钟计数器reg [3:0]carryClkCount=0;//载波时钟计数器always @(posedge clk)begin//codeClkif(codeClkCount==127)begincodeClk=~codeClk;codeClkCount=0;endelsebegincodeClkCount=codeClkCount+1;end//carryClkif(carryClkCount==1)beginstClk=~stClk;carryClkCount=0;endelsebegincarryClkCount=carryClkCount+1;endend

对于分频器,写过verilog的同学应该都比较熟悉。就是让程序去数数嘛,看着时钟滴答滴答的走:1、2、3、4……127!然后将时钟取反一次,再次重新计数。这叫做256分频。计数置位的时刻应该是分频数的一半。

需要特别说明的是,在这里之所以需要两个时钟,主要还是为了下面的系统处理进行服务的。分频数应该适应于要处理的问题。我们希望看到数字信号的每个码元对应正弦波的一个周期,或者两个周期,总之要有一个容易判断的对应关系。不然如果一串数字信号是00001111,这样的信号调制过后,谁能知道一个正弦波中有几个0几个1呢。

至于分频后时钟比例的确定,到后面载波的部分再进一步确定。

数字基带信号的产生

//数字基带信号,m序列发生器reg [5:0]outReg=6'b010101;//序列寄存器初始化reg mAdded;//m序列移位的辅助变量assign codeSource=outReg[5];//输出变量为寄存器序列的最高位always @(negedge codeClk)begin//手动异或if(outReg[0]==outReg[5])beginmAdded=0;endelsebeginmAdded=1;endoutReg=outReg<<1;//对寄存器左移outReg=outReg+mAdded;end

数字基带信号通过m序列产生。m序列通过控制寄存器移位来产生“不太有规律”的信号,这样的信号通常用来当作一个系统的检测序列。不必太纠结于m序列的产生原理,只要是可以测试系统的二进制序列都可以。完全可以随心所欲地写一串二进制码让它循环输出,也可以达到测试系统的效果。

载波的产生

//载波的产生reg [7:0]waveCount=0;//载波幅度查询变量always @(posedge stClk)beginif(waveCount==63)beginwaveCount=0;endelsebeginwaveCount=waveCount+1;end//根据查询变量进行载波幅度查询case(waveCount)0:begin carryWave0<=0;carryWave1<=0; end1:begin carryWave0<=12;carryWave1<=25; end2:begin carryWave0<=25;carryWave1<=49; end3:begin carryWave0<=37;carryWave1<=71; end4:begin carryWave0<=49;carryWave1<=90; end5:begin carryWave0<=60;carryWave1<=106; end6:begin carryWave0<=71;carryWave1<=117; end7:begin carryWave0<=81;carryWave1<=125; end8:begin carryWave0<=90;carryWave1<=127; end9:begin carryWave0<=98;carryWave1<=125; end10:begin carryWave0<=106;carryWave1<=117; end11:begin carryWave0<=112;carryWave1<=106; end12:begin carryWave0<=117;carryWave1<=90; end13:begin carryWave0<=122;carryWave1<=71; end14:begin carryWave0<=125;carryWave1<=49; end15:begin carryWave0<=126;carryWave1<=25; end16:begin carryWave0<=127;carryWave1<=0; end17:begin carryWave0<=126;carryWave1<=-25; end18:begin carryWave0<=125;carryWave1<=-49; end19:begin carryWave0<=122;carryWave1<=-71; end20:begin carryWave0<=117;carryWave1<=-90; end21:begin carryWave0<=112;carryWave1<=-106; end22:begin carryWave0<=106;carryWave1<=-117; end23:begin carryWave0<=98;carryWave1<=-125; end24:begin carryWave0<=90;carryWave1<=-127; end25:begin carryWave0<=81;carryWave1<=-125; end26:begin carryWave0<=71;carryWave1<=-117; end27:begin carryWave0<=60;carryWave1<=-106; end28:begin carryWave0<=49;carryWave1<=-90; end29:begin carryWave0<=37;carryWave1<=-71; end30:begin carryWave0<=25;carryWave1<=-49; end31:begin carryWave0<=12;carryWave1<=-25; end32:begin carryWave0<=0;carryWave1<=0; end33:begin carryWave0<=-12;carryWave1<=25; end34:begin carryWave0<=-25;carryWave1<=49; end35:begin carryWave0<=-37;carryWave1<=71; end36:begin carryWave0<=-49;carryWave1<=90; end37:begin carryWave0<=-60;carryWave1<=106; end38:begin carryWave0<=-71;carryWave1<=117; end39:begin carryWave0<=-81;carryWave1<=125; end40:begin carryWave0<=-90;carryWave1<=127; end41:begin carryWave0<=-98;carryWave1<=125; end42:begin carryWave0<=-106;carryWave1<=117; end43:begin carryWave0<=-112;carryWave1<=106; end44:begin carryWave0<=-117;carryWave1<=90; end45:begin carryWave0<=-122;carryWave1<=71; end46:begin carryWave0<=-125;carryWave1<=49; end47:begin carryWave0<=-126;carryWave1<=25; end48:begin carryWave0<=-127;carryWave1<=0; end49:begin carryWave0<=-126;carryWave1<=-25; end50:begin carryWave0<=-125;carryWave1<=-49; end51:begin carryWave0<=-122;carryWave1<=-71; end52:begin carryWave0<=-117;carryWave1<=-90; end53:begin carryWave0<=-112;carryWave1<=-106; end54:begin carryWave0<=-106;carryWave1<=-117; end55:begin carryWave0<=-98;carryWave1<=-125; end56:begin carryWave0<=-90;carryWave1<=-127; end57:begin carryWave0<=-81;carryWave1<=-125; end58:begin carryWave0<=-71;carryWave1<=-117; end59:begin carryWave0<=-60;carryWave1<=-106; end60:begin carryWave0<=-49;carryWave1<=-90; end61:begin carryWave0<=-37;carryWave1<=-71; end62:begin carryWave0<=-25;carryWave1<=-49; end63:begin carryWave0<=-12;carryWave1<=-25; endendcaseend

用来进行频率调制的是两种正弦波,而正弦波是连续的模拟信号,在数字系统中只能通过采样对它进行近似化处理。预先设定好64个数值,并且对时钟滴答进行计数。计数到不同的时刻的时候,就按照时刻对应的数值查询预先存储好的正弦波的幅度值。比如现在时钟计数变量waveCount=48;那面就根据case语句找到对应的carryWave0=127,carryWave1=0。

如何获得这些正弦波的数值呢?用计算器么?你有耐心的话可以尝试一下。下面介绍一些如何用matlab生成这些代码,matlab真可谓大学生写作业的偷懒神器(不过有一套答案的话更是美滋滋)。

matlab偷懒代码

t=0:63;y0=round(127*sin(2*pi*t/64));y1=round(127*sin(4*pi*t/64));fid=fopen('dataSave.txt','wt');for i=0:63fprintf(fid,'%d:begin carryWave0<=%d;carryWave1<=%d; end\n',i,y0(i+1),y1(i+1));endfclose(fid);

用matlab对正弦波取样,计算,存储到记事本中,而且,在生成的时候直接将语句中的begin end和一些必要的逻辑符号都包括了。毕竟只是个偷懒的手段,重在解决问题,脑补matlab大佬笑笑不说话的样子……

计算正弦波的时候,之所以将幅度取为127,是载波幅度寄存器的限制。8位的寄存器共可以表达256个数字,考虑到正负两边,因此绝对值最大127了。这个要根据调制的时候分配的寄存器大小来考虑。

调制部分

//调制部分always @(posedge stClk)beginif(codeSource)beginsigOut=carryWave1;endelsebeginsigOut=carryWave0;endend

2FSK调制的核心思想就是0和1两种不同的状态对应两种不同的频率,到信号接收端的时候通过判断信号的频率从而确定数字信号原本的状态。因此通过一个if的判断语句即可完成。

testbench代码如下

`timescale 10ns/10psmodule test_sim;reg clk;wire [7:0]sigOut;wire [7:0]carryWave0;wire [7:0]carryWave1;wire codeSource;wire codeClk;wire stClk;FSK FSK(.clk (clk),.sigOut (sigOut),.carryWave0 (carryWave0),.carryWave1 (carryWave1),.codeSource (codeSource),.codeClk (codeClk),.stClk (stClk));parameter clkper=100;initial beginclk = 1'b0;endalwaysbegin#(clkper / 2) clk=~clk;endendmodule

通过modelsim得到的仿真结果如下图

这里需要注意一个细节,我在最后仿真的时候才看到的一个问题

控制数字基带信号的时钟,codeClk,它的第一个上升沿并不是发生在codeClk的一个周期之后,而是半个周期。因此通过时钟上升沿来改变m序列的变化的话,就会产生调制后的信号发生相位突变。

所以在设置时钟的时候应该特别考虑时钟的起始位置,以及两个时钟的配合方式。这里通过把触发方式改为时钟下降沿来解决。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。