首先了解一下2FSK的百度百科:(2ASK請直接看結尾)
我們需要怎麼做
首先是頂層文件(實踐中就是原理草圖,大概的實現原理)
從左到右分別是時鐘接口->分頻器->正弦波發生器/M序列發生器->開關選通(實驗中時鐘爲20M),下面是各個模塊代碼:
分頻器:(N代表分頻數,爲了讓結果清晰,所以M序列的分頻數很高,因爲要讓一個上升沿有好幾個週期才行)
module fenpin(clk_out,clk_in);
output clk_out;
input clk_in;
reg[13:0] cnt;
reg clk_out;
parameter N=1024;
always@(posedge clk_in)
begin
begin
if(cnt==N/2-1)
begin clk_out<=!clk_out;
cnt<=0;
end else
cnt<=cnt+1;
end
end
endmodule
仿真結果:
M序列發生器:
module MXL(clk ,out);
input clk;
output out;
reg[3:0] tmp=4'b0;
reg out;
always @(posedge clk )
begin
if(tmp > 4'd15)
tmp=4'd0;
else tmp=tmp+1'b1;
case(tmp)
4'd0:out<=0;
4'd1:out<=1;
4'd2:out<=0;
4'd3:out<=0;
4'd4:out<=1;
4'd5:out<=1;
4'd6:out<=0;
4'd7:out<=1;
4'd8:out<=1;
4'd9:out<=0;
4'd10:out<=1;
4'd11:out<=0;
4'd12:out<=0;
4'd13:out<=0;
4'd14:out<=0;
4'd15:out<=0;
endcase
end
endmodule
仿真結果:
重點,正弦波發生器:(這是這個實驗難點,需要使用IP,所謂正弦波發生器,就是計數器+ram核,將正弦波抽樣128個點,然後隨着計數器計數逐個輸出,ps,並口),調用IP核流程和mif文件的參數設置參考TOP文件,就是頂層文件圖。mif文件導入在ram核的創建中。下面也帶上C語言產生mif文件(也就是正弦波的序列)
內部結構圖:
C語言mif文件代碼(用VC或者devc++運行即可,摘自:點擊打開鏈接)這個代碼淺顯易懂,讀懂爲好。
#include <stdio.h>
#include <math.h>
#define PI 3.141592
#define DEPTH 128 /*數據深度,即存儲單元的個數*/
#define WIDTH 8 /*存儲單元的寬度*/
int main(void)
{
int i,temp;
float s;
FILE *fp;
fp = fopen("TestMif.mif","w"); /*文件名隨意,但擴展名必須爲.mif*/
if(NULL==fp)
printf("Can not creat file!\r\n");
else
{
printf("File created successfully!\n");
/*
* 生成文件頭:注意不要忘了“;”
*/
fprintf(fp,"DEPTH = %d;\n",DEPTH);
fprintf(fp,"WIDTH = %d;\n",WIDTH);
fprintf(fp,"ADDRESS_RADIX = HEX;\n");
fprintf(fp,"DATA_RADIX = HEX;\n");
fprintf(fp,"CONTENT\n");
fprintf(fp,"BEGIN\n");
/*
* 以十六進制輸出地址和數據
*/
for(i=0;i<DEPTH;i++)
{
/*週期爲128個點的正弦波*/
s = sin(PI*i/64);
/*將-1~1之間的正弦波的值擴展到0-255之間*/
temp = (int)((s+1)*255/2);
/*以十六進制輸出地址和數據*/
fprintf(fp,"%x\t:\t%x;\n",i,temp);
}//end for
fprintf(fp,"END;\n");
fclose(fp);
}
}
仿真結果:
選通開關代碼:
module KAIGUAN(din0,dout,din1,sel);
parameter N=12;
input[N-1:0] din0;
output[N-1:0] dout;
input[N-1:0] din1;
input sel;
wire[N-1:0] MW_din0l;
wire[N-1:0] MW_din1l;
reg[N-1:0] MW_dtempl;
always@(MW_din0l or MW_din1l or sel)
begin
case(sel)
1'd0:MW_dtempl=MW_din0l;
default:MW_dtempl=MW_din1l;
endcase
end
assign dout=MW_dtempl;
assign MW_din0l=din0;
assign MW_din1l=din1;
endmodule
整體系統的仿真結果:
仿真成功!
下載到FPGA中接上示波器:(FFT中有兩個高峯,實驗成功,具體速率大家可以自己算哦)
2ASK比較簡單,至於要信號發生器的分頻器分頻數目一致,然後改任意一個波形發生器的mif文件(中心範圍縮小,可改代碼得,記得有個直流偏置),其他不用變。
過程寫的比較簡單粗暴,有問題可留言或者私信,我都會看的!