日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人工智能 > 循环神经网络 >内容正文

循环神经网络

matlab与quartus的联合数据交换(NCO与文件数据的混频处理)

發(fā)布時間:2025/4/5 循环神经网络 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 matlab与quartus的联合数据交换(NCO与文件数据的混频处理) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 背景
  • 再次認(rèn)識關(guān)于DDS的來源
  • 實際案例
    • 官方資料閱讀(NCO IP core)
      • 參數(shù)原理
      • 通常的步驟
    • 工程實例
      • MATLAB生成波形txt文件
      • IP配置
      • 文件命令語法(官方提示)
      • modelsim仿真
      • 工程福利連接

背景

由于modelsm只能觀察時域波形,無法顯示數(shù)據(jù)的頻譜特性,并且對數(shù)據(jù)進(jìn)行分析、處理不夠方便,特別是在FPGA中設(shè)計數(shù)字濾波器時,無法直接觀察濾波器的頻域響應(yīng)。另外書寫激勵文件的時候,很難產(chǎn)生用戶所需要的具有任意信噪比的輸入信號。特別聲明,不要轉(zhuǎn)載本博主的所有blog,侵權(quán)必究,否則博主將關(guān)閉自己的所有blog。

再次認(rèn)識關(guān)于DDS的來源

實際案例

官方資料閱讀(NCO IP core)

參數(shù)原理

通常你可以使用IP工具接口來實施NCO的架構(gòu),包括基于ROM,CORDIC算法、和乘法器。另外IP工具會在你設(shè)置參數(shù)的時候提供可視化的時域和頻域圖像。設(shè)計者通常可以用NCO在通信領(lǐng)域,產(chǎn)生正交的IQ生成器。


輸出的兩個信號,用補(bǔ)碼的形式給出。
正如上圖所示,上圖是官方給出的NCO的架構(gòu),其實可以看到,是不用于我們所認(rèn)知的DDS的,所以有很多人通常用DDS來認(rèn)知NCO,這個是不對的,對于IP核,我們只有從官方手冊中學(xué)習(xí),才能正確認(rèn)識到官方想表達(dá)的意思。
另外,我們需要注意的是實線部分是必須的,而虛線部分是可選的輸入?yún)?shù)。NCO的IP核函數(shù)允許你生成一種NCO架構(gòu),你可以創(chuàng)建你自定義的NCO,實施的效果你可以在NCO的圖形界面中看到。

正如上圖公式所示,你可以看到這個波形生成是由上述公式生成的,其中我們要注意的正是這些參數(shù)。


從生成的黑盒子模塊,我們可以看到,輸入接口phi_inc_i正是公式中的fO,也就是NCO架構(gòu)中左邊的第一個必須輸入的參數(shù)。

而例化中的 [15:0] freq_mod_i ,這個指的正是上圖中的Frequency Modulation中,這個是個可選項。
所以輸出波形的頻率正由[15:0] phi_inc_i;和[15:0] freq_mod_i一起累加構(gòu)成頻率。


上圖中的兩個公式,雖然官方介紹的是f0(phi_inc)是相位增量,而fFM是頻率,其實根據(jù)公式,我們可以看出,沒啥區(qū)別,都是作為頻率,既然官方這么叫,那也行吧。另外還有一個精度是角度精度,這個沒啥用,和相位精度保持一致即可,這里官方解釋的是:角度精度是將坐標(biāo)轉(zhuǎn)換為笛卡爾的極化坐標(biāo)轉(zhuǎn)換前的角度精度,那么我們就把它與相位精度保持一致即可。


正如上圖所示,我們還可以看到相位調(diào)制器參數(shù),這個也是個可選項,它影響我們的初始相位,所以在黑盒子,我們可以看到
input [15:0] phase_mod_i;
正是代表的這個參數(shù)。
此外還有一個參數(shù)就是抖動,啥叫相位抖動,也就是說會有某個相位這個參數(shù)的值是不確定的,會有左右漂移,從而導(dǎo)致幅度的不確定性。


在IP核的這里面可以設(shè)置,也就是說我們可以設(shè)置相位噪聲。


從上面兩張圖中,我僅僅改變了抖動大小,可以看到抖動越大,信噪比越低,這一點特別是在輸出頻率比較高的情況下尤其明顯。注意,參數(shù)只是樣圖,請不要按照上面的參數(shù)設(shè)置。

至此,我已經(jīng)對主要的輸入?yún)?shù)進(jìn)行了徹底的講解了。

通常的步驟

首先配置參數(shù)

然后建立仿真,勾選仿真模型,并設(shè)置仿真用的語言,verilog。注意,如果不勾選仿真,那么在后續(xù)的仿真中,仿真是無法運(yùn)行的。

最后是生成IP

如上圖,會生成如上圖所示的這些文件。從上面,我們可以知道.v文件需要Quartus II綜合,它會添加到你的Quartus II工程中。另外qiq文件,也是需要添加入工程中的。另外_bb.v文件,是IP的黑盒子,當(dāng)使用第三方仿真工具的時候可以使用這個文件,來例化。cos_c.hex和cos_f.hex文件sin_c.hex和sin_f.hex文件,這四個文件是存儲初始化數(shù)據(jù)文件,以十六進(jìn)制。

  • setting parameters

    首先,對于算法的具體實現(xiàn)細(xì)節(jié),我就不展開講了,因為很多論文都有寫過(抄過)。



好的,至此理論部分,我們已經(jīng)講解完畢,至于具體算法實現(xiàn)的細(xì)節(jié),比如CORDIC算法的原理,這些我就不講解了,很多論文已經(jīng)反反復(fù)復(fù)的抄過。

工程實例

MATLAB生成波形txt文件

%采用matlab進(jìn)行電路仿真,用于驗證整個FPGA電路的工作過程及輸出結(jié)果是否滿足要求 %同時產(chǎn)生FPGA程序中需要使用到的正弦波采樣數(shù)據(jù),50M采樣率產(chǎn)生625KHZ的隨機(jī)相位的正弦信號。也就是說一個周期可以采樣80個點,已經(jīng)能夠非常好的顯示出正弦波形了。 %采用matlab進(jìn)行電路仿真,用于驗證整個FPGA電路的工作過程及輸出結(jié)果是否滿足要求 %同時產(chǎn)生FPGA程序中需要使用到的正弦波采樣數(shù)據(jù) clc; clear; fi=625000; %輸入信號的頻率 fc=625000; %本振信號的頻率Fs=50000000; %采樣頻率 L=1024; %數(shù)據(jù)長度 N=10; %量化位數(shù)% 產(chǎn)生輸入信號 t=0:1/Fs:(1/Fs)*(L-1); %產(chǎn)生采樣頻率的時間序列 theta=rand()*2*pi; %產(chǎn)生一個隨機(jī)相位角度 si=sin(2*pi*fi*t+theta); %生成具隨機(jī)起始相位的正弦波輸入信號si=round(si*(2^(N-1)-1)); %10bit量化%產(chǎn)生本振信號 sc=sin(2*pi*fc*t); %生成本振信號 sc=round(sc*(2^(N-1)-1)); %10bit量化%仿真混頻輸出并畫圖 so=si.*sc; %混頻器輸出 sof=so-mean(so); %混頻器濾出直流分量后輸出 fso=abs(fft(so,L)); %求FFT變換的幅度值 %歸一化處理 sc=sc/max(abs(sc)); %本振信號的歸一化處理 si=si/max(abs(si)); %輸入信號的歸一化處理 so=so/max(abs(so)); %輸出信號的歸一化處理 sof=sof/max(abs(sof)); %混頻器輸出信號濾出直流分量后歸一化處理 fso=fso/max(fso); %FFT的幅度值歸一化處理 %轉(zhuǎn)換成相對于原點對稱的信號 fso=[fso(L/2+1:L),fso(1:L/2)]; %畫圖 m=[-L/2:1:(L/2-1)]*Fs/L*(10^(-6)); %生成頻率坐標(biāo)軸,單位為MHz t=t*(10^6) ; %生成時間坐標(biāo)軸,單位為us subplot(221);plot(t(1:L),si(1:L)); title('10bit量化后的輸入信號si','fontsize',8); subplot(222);plot(t(1:L),so(1:L)); title('20bit量化后的混頻輸出信號so','fontsize',8); subplot(223);plot(t(1:L),sof(1:L)); title('20bit濾出直流分量后的混頻輸出sof','fontsize',8); subplot(224);plot(m,fso); title('混頻輸出信號的幅頻響應(yīng)','fontsize',8);%將生成的輸入正弦信號的數(shù)據(jù),寫入外部文本文件(sinin.txt)中 f_s=si/max(abs(si)); %歸一化處理 Q_s=round(f_s*(2^(N-1)-1)); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %新建文本文件前,必須建好文件存放的目錄文件夾,否則出現(xiàn)提示信息: %??? Error using ==> fprintf %Invalid file identifier fid=fopen('D:\quartus_Project\Liruifeng_tem\DO_Pro\CP2\CP_2_4_matlab_alt_mixNCO\sin.txt','w'); for k=1:length(Q_s)B_s=dec2bin(Q_s(k)+(Q_s(k)<0)*2^N,N); %Q_s小于0就為1,大于0就為0%k;for j=1:Nif B_s(j)=='1'tb=1;elsetb=0;endfprintf(fid,'%d',tb); endfprintf(fid,'\r\n'); end fprintf(fid,';'); fclose(fid);


關(guān)于以上部分代碼的解釋:
B_s=dec2bin(Q_s(k)+(Q_s(k)<0)*2^N,N); %Q_s小于0就為1,大于0就為0
由于dec2bin只能夠?qū)⒄麛?shù)轉(zhuǎn)換成二進(jìn)制,所以必須要判斷一下是否有負(fù)數(shù),如果有負(fù)數(shù),(Q_s(k)<0)的返回值就是1,如果是正數(shù),返回值就是0,也就是說,如果是負(fù)數(shù),那么就將原來的值加2^N ,就是其負(fù)數(shù)的補(bǔ)碼的二進(jìn)制。這一點,我之前已經(jīng)寫過。https://blog.csdn.net/ciscomonkey/article/details/87104636

頂層文件設(shè)計

module mix_top (rst,clk,din,s_oc,dout) ; input rst; //復(fù)位信號,高電平有效 input clk; //數(shù)據(jù)采樣時鐘/FPGA系統(tǒng)時鐘,頻率為5MHz input [9:0] din; //輸入的625KHz單頻信號 output [9:0] s_oc; //本地OC輸出的625KHz單頻信號 output [19:0] dout; //輸出混頻濾波后的的1.25MHz單頻信號//實例化NCO IP核 wire reset_n,out_valid,clken; wire [15:0] phi_inc_i; //本地信號的相位 wire [15:0] phase_mod_i; wire [15:0] freq_mod_i; wire [9:0] oc_sin; //本地信號的輸出,默認(rèn)無符號assign reset_n = rst; //NCO的復(fù)位信號低電平有效assign phi_inc_i = 16'd0; //設(shè)置相位為0 assign phase_mod_i=16'd0; //設(shè)置相位為0 assign freq_mod_i=16'd819; //大約為624KHZ,當(dāng)然,有小數(shù)的話也只能舍棄。值本來應(yīng)該是819.2,其實我們可以從IP核里面的提示看出,叫我們相位增量設(shè)置為819,這里,我把頻率增量設(shè)置為819,相位增量設(shè)置為0,也一樣。assign clken = 1'b1; //設(shè)置時鐘允許信號始終有效assign s_oc = oc_sin; //將本振輸出信號送至模塊輸出nco nco_inst(.phi_inc_i(phi_inc_i),.freq_mod_i(freq_mod_i),.phase_mod_i(phase_mod_i),.clk(clk),.reset_n(reset_n),.clken(clken),.fsin_o(oc_sin),.out_valid(out_valid)); //乘法運(yùn)算實現(xiàn)混頻輸出 reg signed [19:0] mult=0; //有符號的混頻運(yùn)算結(jié)果 wire signed [9:0] s_din; //有符號的輸入數(shù)字信號 wire signed [9:0] s_oc_sin; //有符號的本地輸出625KHzassign s_din = din; //將乘數(shù)轉(zhuǎn)換成有符號數(shù)運(yùn)算 assign s_oc_sin = oc_sin; //將乘數(shù)轉(zhuǎn)換成有符號數(shù)運(yùn)算always @(posedge clk or negedge rst)if (!rst)mult <= 20'd0;elsemult <= s_din * s_oc_sin; //轉(zhuǎn)換為有符號后,進(jìn)行乘法運(yùn)算//求均值 reg signed [19:0] m1,m2,m3,m4,m5,m6,m7; always @(posedge clk or negedge rst)if (!rst)beginm1 <= 20'd0;m2 <= 20'd0;m3 <= 20'd0;m4 <= 20'd0;m5 <= 20'd0;m6 <= 20'd0;m7 <= 20'd0;endelsebeginm1 <= mult;m2 <= m1;m3 <= m2;m4 <= m3;m5 <= m4;m6 <= m5; m7 <= m6;end wire signed [22:0] madd; wire signed [19:0] mean,mt; assign madd = mult+m1+m2+m3+m4+m5+m6+m7; //代表將8個有符號數(shù)據(jù)加起來,其實這里我要補(bǔ)充一點了,原書上寫的是給輸入時鐘是5M,輸出625KHZ,所以剛好是8倍關(guān)系,那么也就是一個周期8個點。但是,這里我們的時鐘是50MHz,我們本來應(yīng)該是去平均值80個點,寄存80個,才能求出平均值。這里我就不管那么多啦,大家明白即可。畢竟要寫80個點平均值,有點懶得寫。 assign mean = madd[22:3]; //代表將8加起來的數(shù)據(jù)左移3位,相當(dāng)于除以8//濾出直流分量(均值) assign mt = mult -mean; //濾出去直流分量 assign dout = mt; endmodule

這里為什么要減去直流分量呢,當(dāng)然是因為混頻后626KHZ-625KHZ=0KHZ,那么就會產(chǎn)生直流分量,所以必須要減去直流分量。此外,還要注意的是,你試圖計算一下頻率增量,如果要在16位,50M時鐘的情況下產(chǎn)生NCO,那么根本沒法算出一個625KHZ的正弦,算出來,頻率增量,我們應(yīng)該取819.4,這里我就取819吧,這樣產(chǎn)生的就是一個624點幾KHZ的正弦。也差不多吧,本來也有噪聲的,也會導(dǎo)致難免差一點點。這些東西差一點點,也影響不大。

仿真文件:

// Copyright (C) 1991-2013 Altera Corporation // Your use of Altera Corporation's design tools, logic functions // and other software and tools, and its AMPP partner logic // functions, and any output files from any of the foregoing // (including device programming or simulation files), and any // associated documentation or information are expressly subject // to the terms and conditions of the Altera Program License // Subscription Agreement, Altera MegaCore Function License // Agreement, or other applicable license agreement, including, // without limitation, that your use is for the sole purpose of // programming logic devices manufactured by Altera and sold by // Altera or its authorized distributors. Please refer to the // applicable agreement for further details.// ***************************************************************************** // This file contains a Verilog test bench template that is freely editable to // suit user's needs .Comments are provided in each section to help the user // fill out necessary details. // ***************************************************************************** // Generated on "05/30/2019 16:24:44"// Verilog Test Bench template for design : mix_top // // Simulation tool : ModelSim (Verilog) // `timescale 1 ns/ 1 ns module mix_top_vlg_tst(); reg clk; reg [9:0] din; reg rst; // wires wire [19:0] dout; wire [9:0] s_oc;parameter clk_period=20; //20ns parameter data_num=800; //仿真數(shù)據(jù)長度 parameter time_sim=data_num*clk_period; //仿真時間// assign statements (if any) mix_top i1 ( // port map - connection between master ports and signals/registers .clk(clk), //時鐘.din(din), //從文件讀取輸入的625KHz單頻信號.dout(dout), // 輸出混頻濾波后的的1.25MHz單頻信號 .rst(rst), //復(fù)位.s_oc(s_oc) //本地NCO產(chǎn)生輸出的625KHz單頻信號 ); initial begin clk=0; rst=0; din=10'd10;//設(shè)置從文本中讀取輸入的625KHz單頻信號的初值 #50 rst=1;//設(shè)置仿真時間 #time_sim $stop;end //產(chǎn)生時鐘信號 always #(clk_period/2) clk=~clk; //從外部TXT文件中讀入數(shù)據(jù)作為測試激勵 reg [9:0] stimulus[1:data_num]; //用于存儲從文本中讀取的數(shù)據(jù),全部存放于數(shù)組stimulus中 integer address=0; initial begin $readmemb("sin.txt",stimulus);//文件必須放到simulation\modelsim的文件夾中repeat(data_num) beginaddress=address+1;din=stimulus[address];#clk_period;end end //將混頻濾波后的的1.25MHz單頻信號dout寫入外部TXT文件中(out.txt)integer file_out; initial begin file_out=$fopen("out.txt");//文件必須放到simulation\modelsim的文件夾中if(!file_out)begin$display("could not open file!");$finish;end endwire clk_write; wire signed[19:0] dout_s; //將混頻后的數(shù)據(jù),轉(zhuǎn)換為有符號數(shù) assign dout_s=dout; assign clk_write=clk&(rst); //產(chǎn)生寫入的時鐘信號,復(fù)位狀態(tài)時候不寫入數(shù)據(jù)always @ (posedge clk_write)$fdisplay(file_out,"%d",dout_s); //將混頻后輸出的有符號的數(shù)據(jù),寫入file_out代表的out.txt文件中//將NCO產(chǎn)生的數(shù)據(jù)寫入NCO.txt文件中 integer file_nco; initial begin//文件必須放到simulation\modelsim的文件夾中 file_nco = $fopen("nco.txt");if(!file_nco)begin$display("could not open file!");$finish;end end wire signed [9:0] nco_s; assign nco_s = s_oc;//將NCO產(chǎn)生的數(shù)據(jù)轉(zhuǎn)變?yōu)橛蟹枖?shù)據(jù) always @(posedge clk_write)$fdisplay(file_nco,"%d",nco_s); endmodule

IP配置

調(diào)用NCO的IP核





然后點擊geinirate即可

最后生成成功。
最后,方可得出NCO成功生成并添加其IP。

仿真的過程主要包括了行為仿真和時序仿真,無論何種仿真均需要設(shè)計測試激勵文件,采用HDL代碼文件書寫激勵,且需要在激勵文件中將部分仿真結(jié)果數(shù)據(jù)寫入外部的文本中,以方便matlab讀取數(shù)據(jù)做進(jìn)一步的仿真。
testbench中導(dǎo)入文本數(shù)據(jù)文件

文件命令語法(官方提示)



modelsim仿真


如上圖所示,可以看到混頻后輸出的波形差不多是1.24MHz的樣子,大差不差,存在誤差也正常,畢竟我們的NCO本來就是產(chǎn)生的近似625KHZ的信號。

下面,我們來仔細(xì)看看從modelsim中,我們還能獲取哪些知識。

首先,我們可以看到din,導(dǎo)入的數(shù)據(jù)是與文件中的數(shù)據(jù)完全一致的,
此外,我們可以看到,NCO產(chǎn)生的數(shù)據(jù),剛開始需要一定的時鐘后,然后才能產(chǎn)生穩(wěn)定的波形。

此外,我們可以看到,寫入數(shù)據(jù)文本與波形中的數(shù)據(jù)完全一致

我們看到noc_s的波形數(shù)據(jù)與文本上面的一致。
mult <= s_din * s_oc_sin; //轉(zhuǎn)換為有符號后,進(jìn)行乘法運(yùn)算
下面,我們再來看一下轉(zhuǎn)換為有符號后,進(jìn)行乘法運(yùn)算,乘法運(yùn)算所消耗的時鐘。

可以看到一個時鐘就可以完成乘法運(yùn)算。
另外采用8級流水線,求平均值,然后減去平均值

可以看到移位操作在本時鐘周期以內(nèi)就可以完成,所以,這就是說移位操作符是非常的強(qiáng)大。
另外,我們再來看看減法操作,減法操作也是在本時鐘周期以內(nèi)就可以完成。

工程福利連接

聯(lián)系QQ:1183699227 并附帶加友目的。

總結(jié)

以上是生活随笔為你收集整理的matlab与quartus的联合数据交换(NCO与文件数据的混频处理)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。