verilog qpsk调制解调
qpsk調制解調
qpsk調制解調原理
-
qpsk調制主要有兩種調制方式,一種是基于0,π/2,π,3π/2四種相位的調制,一種是基于π/4,3π/4,5π/4,7π/4的調制。我采用的是第二種調制方法。
-
第二種方法我采用如下系統來實現。其實就是兩路2psk調制后再相加。
-
有關解調,在不考慮載波提取和位同步信號提取的前提下,只需要將qpsk信號經過相乘器和兩個同相、正交兩個正弦信號相乘再低通濾波,即可得出基帶波形。最后再抽樣判決,恢復出原本的數字基帶信號。
-
我的代碼主要由以下幾個部分組成
-
數字序列生成器
always@(*) begin case(state) 3'd0: code <= 2'b00; 3'd1: code <= 2'b01; 3'd2: code <= 2'b10; 3'd3: code <= 2'b11; 3'd4: code <= 2'b11; 3'd5: code <= 2'b10; 3'd6: code <= 2'b01; 3'd7: code <= 2'b00; default code <= 2'b00; endcase end
生成如上二進制序列
00 代表 45°
01 代表 315°
10 代表 135°
11 代表 225° -
qpsk調制部分
-
先生成一個0相載波和一個90°初相位載波,這里我用二進制序列的高位控制0相載波,低位控制90°載波,可以當成是兩個獨立的2psk調制進行處理。然后再將這兩個信號相加得到qpsk信號。將來解調的時候依然是按此規則,解調得到二進制序列的高低位。
-
always@(posedge clk) begin if(dq == 1) sin_q <= sin_0; else sin_q <= -sin_0; if(di == 1) sin_i <= sin_90; else sin_i <= -sin_90; end assign qpsk = sin_q + sin_i ;
仿真結果如下
-
qpsk解調部分
如上面提到的,這里采用相干解調,暫時先直接用本地生成的0相載波和90°載波來解調(過幾天學習如何使用克斯塔斯環來從已調信號中提取)。如調制的順序,乘以0相載波的對應二進制序列高位,乘以90°載波的對應二進制序列低位。
reg signed [16:0]mult_sin_q; reg signed [16:0]mult_sin_i; always@(*) begin mult_sin_q <= qpsk * sin_0; mult_sin_i <= qpsk * sin_90; end
兩路信號分別通過低通濾波器,濾除2倍載波分量(這里載波頻率為2Mhz,基帶信號的第一零點帶寬為100khz),這里取濾波器截止頻率為1Mhz,濾波器用matlab軟件生成。
filter02 filter02_inst1( .clk(clk), .clk_enable(1), .reset(0), .filter_in(mult_sin_q[16:1]), .filter_out(filter_out_q) );
filter02 filter02_inst2( .clk(clk), .clk_enable(1), .reset(0), .filter_in(mult_sin_i[16:1]), .filter_out(filter_out_i) );
可見濾波后波形基本上關于0對稱,因此可以以0為判決門限進行抽樣判決。
最后抽樣判決得到數字基帶信號。
always@(posedge syc_clk) begin if(filter_out_q >= 0) demod_out[1] <= 0; else demod_out[1] <= 1; if(filter_out_i >= 0 ) demod_out[0] <= 0; else demod_out[0] <= 1; end
這里的syc_clk作為位同步信號,我直接用的是本地生成二進制基帶信號時的控制時鐘,沒有進行位同步信號提取。
可見譯碼基本正確。注意到抽樣判決輸出的信號比原本的二進制碼元滯后一個位同步時鐘,根據分析,可能是因為濾波器的輸入到輸出需要多個系統時鐘周期來處理,因此在輸入碼元跳變的時候它不會立馬跳變,因此導致了判決時鐘來了的時候濾波器輸出的基帶波形仍然保持上一個狀態的值。導致滯后一個時鐘。
完整項目獲取:
如果想要獲得完整項目,請掃碼贊助該項目。
獲取方式:掃碼贊助19.9,留言郵箱地址。
總結
以上是生活随笔為你收集整理的verilog qpsk调制解调的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql的告警日志_MySQL Abo
- 下一篇: mysql多表查询语句_mysql查询语