今天給大俠帶來(lái)基于FPGA的擴(kuò)頻系統(tǒng)設(shè)計(jì),由于篇幅較長(zhǎng),分三篇。今天帶來(lái)第一篇,下篇。話不多說(shuō),上貨。
在無(wú)線通信系統(tǒng)中,普遍使用擴(kuò)頻通信技術(shù),因此擴(kuò)頻技術(shù)對(duì)通信系統(tǒng)具有重要的現(xiàn)實(shí)意義。直接序列擴(kuò)頻技術(shù)是應(yīng)用最廣的一種擴(kuò)頻技術(shù),F(xiàn)PGA具備高速度的并行性特點(diǎn)在無(wú)線通信系統(tǒng)中的優(yōu)勢(shì)日益增強(qiáng),利用FPGA實(shí)現(xiàn)直接序列擴(kuò)頻技術(shù),可增大傳輸速率,可以使擴(kuò)頻技術(shù)有更好的發(fā)展與應(yīng)用。
本篇利用本原多項(xiàng)式產(chǎn)生偽隨機(jī)序列用作擴(kuò)頻,通過(guò)同步模塊對(duì)擴(kuò)頻后的信號(hào)進(jìn)行捕獲,通過(guò)直接序列解擴(kuò)模塊進(jìn)行解擴(kuò)。本篇給出了編解碼、擴(kuò)頻解擴(kuò)、同步的整體方案,使用Quartus實(shí)現(xiàn)功能,并結(jié)合Matlab和ModelSim對(duì)模塊進(jìn)行調(diào)試和測(cè)試,實(shí)現(xiàn)擴(kuò)頻通信模塊的搭建仿真,驗(yàn)證其設(shè)計(jì)的正確性。首先概述了方案設(shè)計(jì)與論證、整體方案的設(shè)計(jì)、各個(gè)模塊的設(shè)計(jì)、個(gè)別模塊的調(diào)試與各個(gè)模塊的仿真驗(yàn)證。本篇主要實(shí)現(xiàn)的模塊有:漢明編碼模塊、直接序列擴(kuò)頻模塊、量化器模塊、同步模塊、直接序列解擴(kuò)模塊和漢明譯碼模塊。各位大俠可依據(jù)自己的需要進(jìn)行閱讀,參考學(xué)習(xí)。
第三篇內(nèi)容摘要:本篇會(huì)介紹分析調(diào)試,包括漢明碼解碼模塊調(diào)試、直接序列擴(kuò)頻模塊調(diào)試、同步模塊調(diào)試、整體設(shè)計(jì)資源占用率、整體設(shè)計(jì)RTL設(shè)計(jì)圖,還會(huì)介紹系統(tǒng)測(cè)試,包括漢明編碼模塊測(cè)試、直接序列擴(kuò)頻模塊測(cè)試、量化器模塊測(cè)試、同步模塊測(cè)試、直接序列解擴(kuò)模塊測(cè)試、漢明譯碼模塊測(cè)試、系統(tǒng)整體測(cè)試等相關(guān)內(nèi)容。
四、分析調(diào)試
4.1 漢明編解碼模塊調(diào)試
首先利用Matlab該模塊進(jìn)行調(diào)試,利用隨機(jī)函數(shù)生成10個(gè)隨機(jī)數(shù),通過(guò)74漢明碼編碼函數(shù)對(duì)10個(gè)隨機(jī)函數(shù)進(jìn)行編碼,隨機(jī)數(shù)分別為4’h0、4’hb、4’h6、4’h1、4’h3、4’h9、4’h7、4’h9、4’h7和4’hd,編碼后分別為7’h00、7’h4b、7’h46、7’h51、7’h23、7’h39、7’h17、7’h39、7’h17和7’h0d。具體如圖4.1所示,對(duì)應(yīng)Matlab代碼詳見附錄A。
圖4.1 漢明碼編碼Matlab仿真圖
利用Matlab的隨機(jī)函數(shù)生成10個(gè)隨機(jī)數(shù),通過(guò)74漢明碼編碼函數(shù)對(duì)10個(gè)隨機(jī)函數(shù)進(jìn)行編碼,編碼后引入噪聲如圖4.2所示:
圖4.2 編碼后與加入噪聲后對(duì)比圖
通過(guò)譯碼函數(shù)進(jìn)行譯碼,如下圖4.3所示:
圖4.3 編碼前與譯碼后對(duì)比圖
根據(jù)圖4.3可知,當(dāng)發(fā)生一位碼值錯(cuò)誤時(shí),漢明譯碼模塊可以正確糾錯(cuò);當(dāng)發(fā)生一位以上碼值錯(cuò)誤時(shí),漢明譯碼模塊不能正確糾錯(cuò),導(dǎo)致譯碼錯(cuò)誤。利用Matlab可知漢明譯碼模塊具有譯碼能力和一位碼值的糾錯(cuò)能力。
利用Verilog對(duì)漢明碼編碼模塊和漢明譯碼模塊進(jìn)行編寫,然后一同進(jìn)行調(diào)試,在兩個(gè)模塊中間加一噪聲模塊,保證編碼后數(shù)據(jù)任意一位發(fā)生錯(cuò)誤,通過(guò)譯碼模塊后,判斷是否能夠進(jìn)行正確糾錯(cuò),編碼前數(shù)據(jù)與編碼后的數(shù)據(jù)是否一致,判斷兩個(gè)模塊的正確性,調(diào)試模型如圖4.4所示:
圖4.4 斷言調(diào)試模型
ModelSim仿真波形截圖如圖4.5所示:
圖4.5 漢明編解碼模塊仿真波形圖
利用斷言的仿真方式打印報(bào)告如圖4.6所示,通過(guò)確認(rèn)編解碼前后數(shù)據(jù)一致,也證明漢明編碼模塊和漢明譯碼模塊正確性。
圖4.6 打印結(jié)果圖
4.2 直接序列擴(kuò)頻模塊調(diào)試
利用Matlab對(duì)該模塊進(jìn)行調(diào)試,利用Matlab偽隨機(jī)函數(shù)生成偽隨機(jī)數(shù),通過(guò)設(shè)置初始值來(lái)與3.4.2節(jié)表3.2的結(jié)果進(jìn)行對(duì)比,通過(guò)對(duì)比可以確定生成偽隨機(jī)序列滿足要求,為采用Verilog設(shè)計(jì)打好堅(jiān)實(shí)的基礎(chǔ)。如圖4.7為Matlab生成的偽隨機(jī)數(shù),對(duì)應(yīng)Matlab代碼詳見附錄A。
圖4.7 Matlab生成偽隨機(jī)數(shù)圖
4.3 同步模塊調(diào)試
在進(jìn)行同步調(diào)試時(shí)出現(xiàn)對(duì)不齊同步頭的問(wèn)題,例如計(jì)算所延時(shí)時(shí)間應(yīng)為29個(gè)系統(tǒng)時(shí)鐘周期,即計(jì)數(shù)器僅需要延時(shí)29個(gè)時(shí)鐘周期,因?yàn)橛?jì)數(shù)器是從“0”開始進(jìn)行計(jì)數(shù),當(dāng)計(jì)數(shù)值等于延時(shí)時(shí)間-1時(shí),模塊可以進(jìn)行同步頭解擴(kuò)處理,由于沒有對(duì)齊同步頭,導(dǎo)致利用最小二乘法計(jì)算結(jié)果均大于預(yù)設(shè)閾值,系統(tǒng)無(wú)法進(jìn)行下去。仿真波形截圖如圖4.8所示:
圖4.8 同步錯(cuò)誤情況仿真波形圖
根據(jù)仿真波形結(jié)合設(shè)計(jì)代碼最終找到原因,由于同步模塊對(duì)延時(shí)時(shí)間信號(hào)進(jìn)行捕獲也需要一個(gè)系統(tǒng)時(shí)鐘周期,所以計(jì)數(shù)器的計(jì)數(shù)值應(yīng)該等于延時(shí)時(shí)間-2,模塊才可以進(jìn)行同步頭解擴(kuò)處理,仿真波形截圖如圖4.9所示:
圖4.9 同步修改正確仿真波形圖
4.4 整體設(shè)計(jì)資源占用率
在設(shè)計(jì)完成后,在如圖4.10所示,該整體設(shè)計(jì)共使用3735個(gè)組合邏輯,占5%;使用1782個(gè)寄存器,占3%;使用39個(gè)I/O引腳,占6%;使用5888個(gè)存儲(chǔ)器,約占1%;使用2個(gè)9bit嵌入式硬件乘法器,約占1%。
圖4.10 FPGA資源占用率
4.5 整體設(shè)計(jì)RTL視圖
由于例化的原因?qū)е屡c整體設(shè)計(jì)框圖不一致,因?yàn)槔瘜?duì)其整體設(shè)計(jì)功能無(wú)影響。所以設(shè)計(jì)整體RTL視圖如圖4.11所示:
圖4.11 設(shè)計(jì)整體RTL圖
五、系統(tǒng)測(cè)試
對(duì)整體系統(tǒng)設(shè)計(jì)進(jìn)行測(cè)試,通過(guò)發(fā)送端到接收端的各個(gè)模塊逐級(jí)進(jìn)行測(cè)試,確保每個(gè)環(huán)節(jié)的正確性。
5.1 漢明編碼模塊模塊測(cè)試
利用Verilog進(jìn)行漢明碼編碼模塊進(jìn)行編寫。在testbench測(cè)試文件總輸入數(shù)據(jù)初始化為8’h55,通過(guò)時(shí)鐘上升沿到來(lái)進(jìn)行取反,所以數(shù)據(jù)依次為8’h55、8’haa、8’h55…8’haa等,接口采用同步fifo進(jìn)行數(shù)據(jù)緩沖,如圖5.1所示,在測(cè)試文件中通過(guò)判斷t_full信號(hào)高有效來(lái)判斷fifo是否為滿狀態(tài),若不是滿狀態(tài),則置寫操作的使能信號(hào)t_wrreq高電平有效,對(duì)fifo進(jìn)行寫操作,否則不進(jìn)行寫操作。漢明碼編碼模塊通過(guò)判斷h_empty信號(hào)來(lái)判斷fifo是否為空狀態(tài),若不為空,則置讀操作使能信號(hào)h_rdreq高電平有效對(duì)fifo進(jìn)行讀操作,否則不進(jìn)行讀操作。
圖5.1 fifo接口圖
通過(guò)漢明碼編碼模塊對(duì)數(shù)據(jù)進(jìn)行漢明碼編碼,如圖5.2所示,信號(hào)ha_data為對(duì)應(yīng)編碼結(jié)果。4’h5編碼為7’h2d,4’ha編碼為7’h52,如圖5.2表明,漢明編碼模塊能夠正確編碼。
圖5.2 漢明碼編碼模塊ModelSim仿真波形圖
5.2 直接序列擴(kuò)頻模塊測(cè)試
利用Verilog進(jìn)行偽隨機(jī)數(shù)模塊編寫,初始值為5’b00001,生成序列為如圖5.3所示。信號(hào)m_bit為偽隨機(jī)數(shù),在進(jìn)行編碼數(shù)據(jù)信號(hào)進(jìn)行擴(kuò)頻之前,應(yīng)將數(shù)據(jù)信息加上幀頭14’b11111111111110,信號(hào)m_data為漢明編碼模塊編碼后的7bits數(shù)據(jù)信息,信號(hào)s_bit為幀頭或編碼數(shù)據(jù)信息并串轉(zhuǎn)換后的信號(hào),信號(hào)bc控制信號(hào)s_bit哪個(gè)數(shù)據(jù)位于信號(hào)m_bit相異或,得到的結(jié)果為輸出信號(hào)q_data,從而實(shí)現(xiàn)直接序列擴(kuò)頻的功能。如圖5.3表明,直接序列擴(kuò)頻模塊能夠正確完成擴(kuò)頻。
圖5.3 直接序列擴(kuò)頻模塊ModelSim仿真波形圖
5.3 量化器模塊測(cè)試
量化器模塊將單比特的信號(hào)變?yōu)?bits有符號(hào)數(shù),仿真波形截圖如圖5.4所示,可以確定量化器模塊能夠正確進(jìn)行對(duì)信號(hào)量化。
圖5.4 量化器模塊ModelSim仿真波形圖
5.4 同步模塊測(cè)試
為了模擬實(shí)際傳輸過(guò)程,擴(kuò)頻信號(hào)再進(jìn)入同步模塊前引入±46的噪聲,實(shí)際輸入值信號(hào)line如圖5.5所示:
圖5.5 加入噪聲后ModelSim仿真波形圖
利用最小二乘法對(duì)輸入信號(hào)與31個(gè)模板進(jìn)行計(jì)算,得到小于閾值的唯一的延時(shí)數(shù)據(jù)信號(hào)xx如圖5.6所示,模板2滿足要求,信號(hào)xx計(jì)算值為29,因此要進(jìn)行29拍解擴(kuò)時(shí)鐘周期的延時(shí),來(lái)對(duì)齊同步頭。
圖5.6 計(jì)算延時(shí)ModelSim仿真波形圖
通過(guò)延時(shí)達(dá)到對(duì)齊同步頭的目的,對(duì)齊使能信號(hào)en_m為高電平,說(shuō)明已對(duì)齊。如圖5.7所示:
圖5.7 同步頭對(duì)齊ModelSim仿真波形圖
對(duì)齊后將數(shù)據(jù)信號(hào)每31bits與模板“0”模板“1”進(jìn)行最小二乘法計(jì)算,如圖5.8所示:
圖5.8 同步頭解擴(kuò)ModelSim仿真波形圖
信號(hào)data_tm為判斷出的信號(hào)數(shù)據(jù),當(dāng)檢測(cè)到同步頭最后一位的“0”數(shù)據(jù)信息后,說(shuō)明同步頭已結(jié)束,同步功能已實(shí)現(xiàn)。如圖5.9所示,同步模塊能夠正確實(shí)現(xiàn)同步。
圖5.9 同步頭識(shí)別ModelSim仿真波形圖
5.5 直接序列解擴(kuò)模塊測(cè)試
當(dāng)檢測(cè)到最后一位為“0”后,進(jìn)入數(shù)據(jù)信號(hào)解擴(kuò)過(guò)程,與同步頭解擴(kuò)相類似,只是把解擴(kuò)后的數(shù)據(jù)利用計(jì)數(shù)器的計(jì)數(shù)值,寫到寄存器對(duì)應(yīng)的位置,同時(shí)進(jìn)行串并轉(zhuǎn)換功能,信號(hào)bc為計(jì)數(shù)器,信號(hào)hdata_reg1為串并轉(zhuǎn)換后存儲(chǔ)數(shù)據(jù)的寄存器。如圖5.10所示,直接序列解擴(kuò)模塊能夠正確實(shí)現(xiàn)解擴(kuò)。
圖5.10 數(shù)據(jù)信息解擴(kuò)ModelSim仿真波形圖
5.6 漢明譯碼模塊測(cè)試
利用Verilog對(duì)漢明譯碼模塊進(jìn)行編寫。通過(guò)直接序列解擴(kuò)模塊后的數(shù)據(jù)經(jīng)過(guò)漢明譯碼模塊后,如圖5.11所示:
圖5.11 漢明譯碼ModelSim仿真波形圖
信號(hào)data_reg被譯碼正確后通過(guò)對(duì)fifo的滿標(biāo)志信號(hào)H_full高電平進(jìn)行判斷,若為高電平則不進(jìn)行寫操作,若為低電平則將fifo的寫使能信號(hào)置高進(jìn)行寫操作,將譯碼后的數(shù)據(jù)寫入fifo中。如圖5.12所示,漢明譯碼模塊能夠?qū)?shù)據(jù)進(jìn)行正確譯碼。
圖5.12 數(shù)據(jù)輸出端口仿真截圖
5.7 系統(tǒng)整體測(cè)試
通過(guò)打印信息確認(rèn),原始數(shù)據(jù)與譯碼后的數(shù)據(jù)一致,能夠確認(rèn)系統(tǒng)整體設(shè)計(jì)正確,如圖5.13所示:
圖5.13 打印結(jié)果截圖
引用2.1節(jié)設(shè)計(jì)要求,總結(jié)系統(tǒng)整體設(shè)計(jì)完成對(duì)應(yīng)功能情況,如表5.1所示:
表5.1 系統(tǒng)功能測(cè)試表
結(jié) 論
直接序列擴(kuò)頻是主流的擴(kuò)頻通信之一,有著許多重要特點(diǎn)與優(yōu)點(diǎn),本篇利用FPGA的處理速度和并行運(yùn)行等特點(diǎn),設(shè)計(jì)完成了一個(gè)基于FPGA擴(kuò)頻模塊設(shè)計(jì)。在利用Quartus II、Matlab和ModelSim對(duì)直接序列擴(kuò)頻模塊進(jìn)行了仿真分析。利用偽隨機(jī)序列進(jìn)行擴(kuò)頻,是擴(kuò)頻模塊獲得高抗噪聲性能和抗干擾性能的關(guān)鍵。
本文首先對(duì)直接序列擴(kuò)頻模塊一般原理進(jìn)行介紹,然后重點(diǎn)分析直接序列擴(kuò)頻解擴(kuò),合理分配功能模塊、準(zhǔn)確掌握各個(gè)模塊之間的控制和被控制的關(guān)系,以及整體時(shí)序關(guān)系。通過(guò)從接口fifo讀取數(shù)據(jù)后,采用漢明編碼模塊,完成了對(duì)數(shù)據(jù)的編碼,在完成編碼后加入同步頭,為同步做準(zhǔn)備。利用本原多項(xiàng)式產(chǎn)生偽隨機(jī)數(shù),偽隨機(jī)數(shù)與編碼后的數(shù)據(jù)進(jìn)行異或處理,已達(dá)到擴(kuò)頻的目的,擴(kuò)頻后的數(shù)據(jù)進(jìn)行量化且引入噪聲送入同步模塊。同步模塊利用31個(gè)偽隨機(jī)數(shù)的模板,采用最小二乘法對(duì)數(shù)據(jù)進(jìn)行計(jì)算,計(jì)算值小于預(yù)定閾值,則該數(shù)據(jù)對(duì)應(yīng)的信息為接收端需要進(jìn)行延拍的個(gè)數(shù),對(duì)齊后利用2個(gè)偽隨機(jī)數(shù)的模板對(duì)數(shù)據(jù)進(jìn)行“0”和“1”的判斷,當(dāng)同步頭數(shù)據(jù)值出現(xiàn)“0”后,代表下一位開始為數(shù)據(jù)信息,直接序列解擴(kuò)模塊開始進(jìn)行解擴(kuò)處理,和同步模塊同理,將數(shù)據(jù)與2個(gè)偽隨機(jī)進(jìn)行最小二乘法的計(jì)算,從而達(dá)到解擴(kuò)的目的。解擴(kuò)后的數(shù)據(jù)通過(guò)漢明譯碼模塊進(jìn)行譯碼后寫入接口fifo,再通過(guò)fifo輸出。經(jīng)過(guò)驗(yàn)證該整體模塊達(dá)到擴(kuò)頻的目的,提高了抗噪聲的能力,各個(gè)模塊能夠正確完成對(duì)應(yīng)功能。
附錄部分源代碼
偽隨機(jī)數(shù)Matlab代碼:
polynomial=[1 0 0 1 0 1];
reg=[0 0 0 0 1];
grade=length(polynomial)-1;
PN_Length=(2^grade-1);
pn=zeros(1,PN_Length);
n=0; c=zeros(1,grade);
for i=grade:-1:1
if polynomial(i)==1
n=n+1;
c(n)=grade+1-i;
end
end
q=0;
for i=1:PN_Length
p(i)=reg(1)
m=reg(grade+1-c(1));
for q=2:grade
if (c(q)>0) & (reg(grade+1-c(q))==1)
m=~m;
end
end
for q=1:(grade-1)
reg(q)=reg(q+1);
end
reg(5)=m;
end
漢明碼編碼譯碼Matlab代碼:
k=4;
n=7;
msg=randint(10,4,2)
code=encode(msg,n,k)
code_noise=rem(code+rand(10,7)>0.95,2)
rcv=decode(code_noise,n,k)
disp(['Error rate in the received code:' num2str(symerr(code,code_noise)/length(code))])
disp(['Error rate after decode:' num2str(symerr(msg,rcv)/length(msg))])
漢明碼編碼Verilog代碼:
module hamming74(clk_10, rst_n, hi_data, ha_data, hm_sel);
input clk_10;
input rst_n;
input [7:0] hi_data;
output reg [6:0] ha_data;
input hm_sel;
wire [3:0] hm_data;
wire q0,q1,q2;
assign hm_data = hm_sel ? hi_data[7:4] : hi_data[3:0];
always @ (posedge clk_10)
begin
if(!rst_n)
begin
ha_data <= 0;
end
else
begin
ha_data[6] <= hm_data[3];
ha_data[5] <= hm_data[2];
ha_data[4] <= hm_data[1];
ha_data[3] <= q2;
ha_data[2] <= hm_data[0];
ha_data[1] <= q1;
ha_data[0] <= q0;
end
end
assign q0 = hm_data[0] ^ hm_data[1] ^ hm_data[3];
assign q1 = hm_data[0] ^ hm_data[2] ^ hm_data[3];
assign q2 = hm_data[1] ^ hm_data[2] ^ hm_data[3];
endmodule
偽隨機(jī)數(shù)產(chǎn)生Verilog代碼:
module m_generator(clk_10, rst_n, m_bit);
input clk_10;
input rst_n;
output m_bit;
reg [4:0] q;
parameter KEY = 5'b00001;
always @ (posedge clk_10)
begin
if(!rst_n)
begin
q <= KEY;
// q <= 0;
end
else begin
q[0] <= q[1];
q[1] <= q[2];
q[2] <= q[3];
q[3] <= q[4];
q[4] <= q[3] ^ q[0];
end
end
assign m_bit = q[0];
endmodule
偽隨機(jī)序列與數(shù)據(jù)信息異或處理Verilog代碼:
module me_xor(clk, rst_n, s_bit, m_bit, q_data);
input clk, rst_n;
input s_bit, m_bit;
output reg q_data;
always @ (posedge clk)
begin
if (!rst_n)
q_data <= 0;
else
q_data <= s_bit ^ m_bit;
end
endmodule
量化器模塊Verilog代碼:
module quantizer(clk, rst_n, qdata, line_out);
input clk, rst_n;
input qdata;
output reg signed [7:0] line_out;
always @ (posedge clk)
begin
if (!rst_n)
line_out <= 0;
else
if (qdata)
line_out <= 63;
else
line_out <= -64;
end
endmodule
最小二乘法Verilog代碼:
module m_leastsquare(clk_10, rst_n, line, distance);
input clk_10, rst_n;
input signed [7:0] line;
output reg signed [21:0] distance;
parameter KEY = 5'b00001;
wire m;
reg [4:0] count;
reg signed [21:0] int_distance;
always @ (posedge clk_10)
begin
if (!rst_n || count >= 5'd30)
count <= 0;
else
count <= count + 5'd1;
end
m_generator #(.KEY(KEY)) u_mg(.clk_10(clk_10), .rst_n(rst_n), .m_bit(m));
always @ (posedge clk_10)
begin
if (!rst_n)
begin
int_distance <= 0;
distance <= 0;
end
else
if (count < 5'd30)
if (!m)
int_distance <= int_distance + (line - 63) * (line - 63);
else
int_distance <= int_distance + (line + 64) * (line + 64);
else
begin
int_distance <= 0;
if (!m)
distance <= int_distance + (line - 63) * (line - 63);
else
distance <= int_distance + (line + 64) * (line + 64);
end
end
endmodule
同步模塊Verilog部分代碼:
module test_mdecoder_ls(clk_10, rst_n, line, xx);
input clk_10, rst_n;
input signed [7:0] line;
output reg [5:0] xx;
wire signed [21:0] distance [30:0];
wire [30:0] xx_reg;
integer i;
m_leastsquare #(.KEY(5'h01)) u0(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[0]));
m_leastsquare #(.KEY(5'h10)) u1(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[1]));
m_leastsquare #(.KEY(5'h08)) u2(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[2]));
m_leastsquare #(.KEY(5'h14)) u3(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[3]));
m_leastsquare #(.KEY(5'h0A)) u4(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[4]));
m_leastsquare #(.KEY(5'h15)) u5(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[5]));
m_leastsquare #(.KEY(5'h1A)) u6(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[6]));
m_leastsquare #(.KEY(5'h1D)) u7(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[7]));
m_leastsquare #(.KEY(5'h0E)) u8(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[8]));
m_leastsquare #(.KEY(5'h17)) u9(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[9]));
m_leastsquare #(.KEY(5'h1B)) u10(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[10]));
m_leastsquare #(.KEY(5'h0D)) u11(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[11]));
m_leastsquare #(.KEY(5'h06)) u12(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[12]));
m_leastsquare #(.KEY(5'h03)) u13(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[13]));
m_leastsquare #(.KEY(5'h11)) u14(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[14]));
m_leastsquare #(.KEY(5'h18)) u15(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[15]));
m_leastsquare #(.KEY(5'h1C)) u16(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[16]));
m_leastsquare #(.KEY(5'h1E)) u17(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[17]));
m_leastsquare #(.KEY(5'h1F)) u18(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[18]));
m_leastsquare #(.KEY(5'h0F)) u19(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[19]));
m_leastsquare #(.KEY(5'h07)) u20(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[20]));
m_leastsquare #(.KEY(5'h13)) u21(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[21]));
m_leastsquare #(.KEY(5'h19)) u22(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[22]));
m_leastsquare #(.KEY(5'h0C)) u23(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[23]));
m_leastsquare #(.KEY(5'h16)) u24(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[24]));
m_leastsquare #(.KEY(5'h0B)) u25(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[25]));
m_leastsquare #(.KEY(5'h05)) u26(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[26]));
m_leastsquare #(.KEY(5'h12)) u27(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[27]));
m_leastsquare #(.KEY(5'h09)) u28(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[28]));
m_leastsquare #(.KEY(5'h04)) u29(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[29]));
m_leastsquare #(.KEY(5'h02)) u30(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[30]));
assign xx_reg[0] = (distance[0]>0 && distance[0]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[1] = (distance[1]>0 && distance[1]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[2] = (distance[2]>0 && distance[2]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[3] = (distance[3]>0 && distance[3]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[4] = (distance[4]>0 && distance[4]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[5] = (distance[5]>0 && distance[5]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[6] = (distance[6]>0 && distance[6]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[7] = (distance[7]>0 && distance[7]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[8] = (distance[8]>0 && distance[8]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[9] = (distance[9]>0 && distance[9]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[10] = (distance[10]>0 && distance[10]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[11] = (distance[11]>0 && distance[11]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[12] = (distance[12]>0 && distance[12]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[13] = (distance[13]>0 && distance[13]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[14] = (distance[14]>0 && distance[14]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[15] = (distance[15]>0 && distance[15]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[16] = (distance[16]>0 && distance[16]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[17] = (distance[17]>0 && distance[17]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[18] = (distance[18]>0 && distance[18]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[19] = (distance[19]>0 && distance[19]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[20] = (distance[20]>0 && distance[20]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[21] = (distance[21]>0 && distance[21]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[22] = (distance[22]>0 && distance[22]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[23] = (distance[23]>0 && distance[23]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[24] = (distance[24]>0 && distance[24]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[25] = (distance[25]>0 && distance[25]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[26] = (distance[26]>0 && distance[26]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[27] = (distance[27]>0 && distance[27]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[28] = (distance[28]>0 && distance[28]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[29] = (distance[29]>0 && distance[29]< 19'd50000)? 1'b1:1'b0;
assign xx_reg[30] = (distance[30]>0 && distance[30]< 19'd50000)? 1'b1:1'b0;
always @ (*)
begin
if(!rst_n)
begin
xx <= 6'd32;
end
else
begin
for(i=0;i<30;i=i+1)
if(xx_reg[i]==1)
xx <= 31-i;
end
end
endmodule
直接序列解擴(kuò)模塊部分Verilog代碼:
module test_mdecoder_2s(clk_10, rst_n, line, data_tm, en_m); //測(cè)試,最小二乘法
input clk_10, rst_n;
input signed [7:0] line;
output data_tm;
input en_m;
wire signed [30:0] distance [1:0];
wire [30:0] reg1 , reg0 ;
m_leastsquare_nl #(.KEY(5'h01)) u32(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[0]), .en_m(en_m));//0
m_leastsquare_no #(.KEY(5'h01)) u33(.clk_10(clk_10), .rst_n(rst_n), .line(line), .distance(distance[1]), .en_m(en_m));//1
assign data_tm = ( distance[1]>distance[0])? 1'b0:1'b1;//比較倆數(shù)據(jù)大小
endmodule
漢明碼譯碼Verilog代碼:
module deserialzer(clk_10, rst_n, data_tm, en_m, hdata, h_full, h_wrreq);
/* 串轉(zhuǎn)并模塊加漢明譯碼模塊 */
input clk_10;
input rst_n;
input data_tm;
input en_m;
output reg [7:0] hdata;
input h_full;
output reg h_wrreq;
reg [5:0] count;
reg [2:0] bc;
reg [6:0] hdata_reg1;
reg start;
wire c0,c1,c2;
reg lh;
reg [3:0] data_reg;
/* 用來(lái)計(jì)算數(shù)據(jù)位 */
always @ (posedge clk_10)
begin
if(!rst_n)
begin
count <= 0;
bc <= 0;
end
else if(en_m && count < 30)
count <= count + 6'd1;
else
begin
if(count == 6'd30 && bc < 3'd6)
bc <= bc + 3'd1;
else
bc <= 0;
count <= 0;
end
end
/* 用來(lái)緩沖數(shù)據(jù) */
always @ (posedge clk_10)
begin
hdata_reg1[bc] <= data_tm;
end
/* 用來(lái)控制數(shù)據(jù)寫在高低位,同時(shí)控制發(fā)送寫使能 */
always @ (posedge clk_10)
begin
if(!rst_n)
begin
h_wrreq <= 0;
lh <= 1;
end
else if(!h_full && bc == 3'd6 && count == 6'd30)
begin
lh <= ~lh;
if(lh)
h_wrreq <= 0;
else
h_wrreq <= 1;
end
else
h_wrreq <= 0;
end
/* 用來(lái)控制譯碼的使能 */
always @ (posedge clk_10)
begin
if(!rst_n)
begin
start <= 0;
end
else if(!h_full && bc == 3'd6 && count == 6'd29)
begin
start <= 1;
end
else
start <= 0;
end
assign c0 = hdata_reg1[0] ^ hdata_reg1[2] ^ hdata_reg1[4] ^ hdata_reg1[6];
assign c1 = hdata_reg1[1] ^ hdata_reg1[2] ^ hdata_reg1[5] ^ hdata_reg1[6];
assign c2 = hdata_reg1[3] ^ hdata_reg1[4] ^ hdata_reg1[5] ^ hdata_reg1[6];
/* 用來(lái)高低位數(shù)據(jù)賦值 */
always @ (*)
begin
if(lh)
hdata[7:4] <= data_reg;
else
hdata[3:0] <= data_reg;
end
always @ (posedge clk_10)
begin
if(!rst_n)
begin
data_reg <= 0;
end
else if (start)
case({c2,c1,c0})
3'b000:begin//沒錯(cuò)誤
data_reg[3] <= hdata_reg1[6];
data_reg[2] <= hdata_reg1[5];
data_reg[1] <= hdata_reg1[4];
data_reg[0] <= hdata_reg1[2];
end
3'b001:begin//校驗(yàn)位hc_in[0]有錯(cuò)誤
data_reg[3] <= hdata_reg1[6];
data_reg[2] <= hdata_reg1[5];
data_reg[1] <= hdata_reg1[4];
data_reg[0] <= hdata_reg1[2];
end
3'b010:begin//校驗(yàn)位hc_in[1]有錯(cuò)誤
data_reg[3] <= hdata_reg1[6];
data_reg[2] <= hdata_reg1[5];
data_reg[1] <= hdata_reg1[4];
data_reg[0] <= hdata_reg1[2];
end
3'b011:begin//校驗(yàn)位hc_in[0]、hc_in[1]有錯(cuò)誤
data_reg[3] <= hdata_reg1[6];
data_reg[2] <= hdata_reg1[5];
data_reg[1] <= hdata_reg1[4];
data_reg[0] <= ~hdata_reg1[2];
end
3'b100:begin//校驗(yàn)位hc_in[2]有錯(cuò)誤
data_reg[3] <= hdata_reg1[6];
data_reg[2] <= hdata_reg1[5];
data_reg[1] <= hdata_reg1[4];
data_reg[0] <= hdata_reg1[2];
end
3'b101:begin//校驗(yàn)位hc_in[0]、hc_in[2]有錯(cuò)誤
data_reg[3] <= hdata_reg1[6];
data_reg[2] <= hdata_reg1[5];
data_reg[1] <= ~hdata_reg1[4];
data_reg[0] <= hdata_reg1[2];
end
3'b110:begin//校驗(yàn)位hc_in[1]、hc_in[2]有錯(cuò)誤
data_reg[3] <= hdata_reg1[6];
data_reg[2] <= ~hdata_reg1[5];
data_reg[1] <= hdata_reg1[4];
data_reg[0] <= hdata_reg1[2];
end
3'b111:begin//校驗(yàn)位hc_in[1]、hc_in[2]、hc_in[0]有錯(cuò)誤
data_reg[3] <= ~hdata_reg1[6];
data_reg[2] <= hdata_reg1[5];
data_reg[1] <= hdata_reg1[4];
data_reg[0] <= hdata_reg1[2];
end
endcase
end
endmodule