本次學(xué)習(xí)的內(nèi)容來自B站:Verilog零基礎(chǔ)入門?
其他相關(guān)引用以貼上原鏈接
時(shí)序邏輯電路
一、計(jì)數(shù)器
1.原理及代碼實(shí)現(xiàn)
2.Modelsim仿真
二、四級(jí)偽隨機(jī)碼發(fā)生器
1.原理及代碼實(shí)現(xiàn)
2.Moselsim仿真
總結(jié)
時(shí)序邏輯電路
?時(shí)序邏輯電路是數(shù)字邏輯電路的重要組成部分,時(shí)序邏輯電路又稱,主要由存儲(chǔ)電路和組合邏輯電路兩部分組成。它和我們熟悉的其他電路不同,其在任何一個(gè)時(shí)刻的輸出狀態(tài)由當(dāng)時(shí)的輸入信號(hào)和電路原來的狀態(tài)共同決定,而它的狀態(tài)主要是由存儲(chǔ)電路來記憶和表示的。同時(shí)時(shí)序邏輯電路在結(jié)構(gòu)以及功能上的特殊性,相較其他種類的數(shù)字邏輯電路而言,往往具有難度大、電路復(fù)雜并且應(yīng)用范圍廣的特點(diǎn)??。
在數(shù)字電路通常分為組合邏輯電路和時(shí)序邏輯電路兩大類,組合邏輯電路的特點(diǎn)是輸入的變化直接反映了輸出的變化,其輸出的狀態(tài)僅取決于輸入的當(dāng)前的狀態(tài),與輸入、輸出的原始狀態(tài)無關(guān),而時(shí)序電路是一種輸出不僅與當(dāng)前的輸入有關(guān),而且與其輸出狀態(tài)的原始狀態(tài)有關(guān),其相當(dāng)于在組合邏輯的輸入端加上了一個(gè)反饋輸入,在其電路中有一個(gè)存儲(chǔ)電路,其可以將輸出的狀態(tài)保持住,我們可以用下圖的框圖來描述時(shí)序電路的構(gòu)成。(Verilog零基礎(chǔ)入門)
一、計(jì)數(shù)器
1.原理及代碼實(shí)現(xiàn)
計(jì)數(shù)器是一種典型的時(shí)序邏輯電路,其電路圖如下:?
左邊的加法器為組合邏輯電路,用于對(duì)輸出的結(jié)果加一計(jì)數(shù),右邊為一個(gè)D觸發(fā)器,在時(shí)鐘的上升沿到來時(shí)觸發(fā),輸出結(jié)果(因?yàn)槲姨脹]學(xué)數(shù)電了,很多知識(shí)都遺忘了,所以這里只是用我目前的知識(shí)進(jìn)行復(fù)述,不一定對(duì)),從而實(shí)現(xiàn)計(jì)數(shù)操作。下面我們一起來編寫代碼吧!
//2023.4.12 Bread
//計(jì)數(shù)器
`timescale 1ns/1ps
module counter(
clk,
rst,
y
);
input clk;
input rst;
output[7:0] y;
reg[7:0] y;
wire[7:0] sum;//+1運(yùn)算的結(jié)果
assign sum = y+1;//組合邏輯部分
always@(posedge clk or negedge rst)
if(~rst)begin
y<=0;
end
else begin
y<=sum;
end
endmodule
這里的`timescale 1ns/1ps表示以1ns為時(shí)間單位,精度為1ps,可以根據(jù)自己的喜好設(shè)置,這是testbench需要用到的。
在代碼中,clk為時(shí)鐘信號(hào),rst為復(fù)位信號(hào),y為輸出。always@里的內(nèi)容為敏感變量,表示在時(shí)鐘的上升沿或者復(fù)位信號(hào)的下降沿觸發(fā)。在復(fù)位信號(hào)為0的時(shí)候,我們將輸出值復(fù)位,置為0(這里也可以按照自己的喜歡,將復(fù)位信號(hào)的0或1用于復(fù)位,但是為了嚴(yán)謹(jǐn)還是使用D觸發(fā)器原本的復(fù)位模式,因?yàn)槲易约阂膊惶宄允褂玫氖歉鶕?jù)老師的代碼)。在這里我們就是實(shí)現(xiàn)了對(duì)計(jì)數(shù)器代碼的編寫,接下來我們來編寫他的test_bench:
//----testbench----
module counter_tb;
reg clk,rst;
wire[7:0] y;
counter counter(
.clk(clk),
.rst(rst),
.y(y)
);
initial begin
clk<=0;rst<=0;
#17 rst<=1;
#6000 $stop;
end
always #5 clk<=~clk;
endmodule
testbench主要用于仿真波形,這里我們采用異名例化。編寫完代碼后,我們就一起使用Modelsimj進(jìn)行仿真吧~?
2.Modelsim仿真
1.打開Modelsim,找到首頁(yè)的work目錄,點(diǎn)擊右上角的編譯
?選擇我們剛才編寫好的.v文件,點(diǎn)擊Complie進(jìn)行編譯
?在這里我們也可以選擇更改我們的工作路徑:File->Change Directory... 將工作路徑放到我們自己想要的文件夾下,但是建議使用默認(rèn)的路徑,因?yàn)槊看未蜷_Modelsim后都會(huì)停留在默認(rèn)路徑下,需要每次手動(dòng)更改路徑,更改路徑后選擇編譯會(huì)出現(xiàn)沒有‘work’的情況,選擇yes即可。
?之后在work目錄下就會(huì)出現(xiàn)counter和counter_tb兩個(gè)文件了,我們選擇tb文件,右鍵,點(diǎn)擊Simulate,就會(huì)進(jìn)入我們的仿真頁(yè)面了。
?
?第一次進(jìn)入這里可能沒有波形圖的頁(yè)面,我們選擇View->wave就可以打開波形圖界面啦
然后我們將想觀察的信號(hào)導(dǎo)入波形圖中:右擊信號(hào)->Add to->Wave->Signals in Region,就可以將該頁(yè)面的信號(hào)一起導(dǎo)入進(jìn)去了
?
導(dǎo)入進(jìn)來發(fā)現(xiàn)沒有波形?最后我們點(diǎn)擊右上角的Restart和Runall,我們的波形就展示出來了。?
?現(xiàn)在的波形看著很亂是吧?我們點(diǎn)擊以下三個(gè)按鈕可以實(shí)現(xiàn)對(duì)波形的觀察了。
?首先點(diǎn)擊第三個(gè) Zoom Full按鈕,可以將波形全局展示,之后再通過放大和縮小觀察我們想要的波形了,我們的計(jì)數(shù)器的波形如下:
可以看到,在每一個(gè)時(shí)鐘的上升沿到來的時(shí)候,輸出的值就會(huì)加一,但是當(dāng)加到255后又置零了,這是因?yàn)槲覀儾捎玫陌宋挥?jì)數(shù)器,可以顯示的范圍只有00000000——11111111。并且在這里我們使用的是無符號(hào)位表示,如果使用十進(jìn)制表示,默認(rèn)是有符號(hào)的,到127后就會(huì)開始變成負(fù)數(shù)了!更改表示進(jìn)制可以右擊信號(hào)->Radix中選擇我們想要觀察的進(jìn)制數(shù)了(如二進(jìn)制,八進(jìn)制,十六進(jìn)制等)。?
?以上就是計(jì)數(shù)器和Modelsim仿真觀察波形圖的內(nèi)容了。
二、四級(jí)偽隨機(jī)碼發(fā)生器
1.原理及代碼實(shí)現(xiàn)
????????偽隨機(jī)序列又稱為偽隨機(jī)碼,是一種人工生成的周期序列,可以作為數(shù)字通信中的一個(gè)信號(hào)源,用于檢測(cè)數(shù)字通信系統(tǒng)錯(cuò)碼的概率,即誤碼率。
????????產(chǎn)生偽隨機(jī)碼的方式有很多,通常使用線性反饋移位寄存器(LFSR)來產(chǎn)生。所謂線性反饋,是指反饋函數(shù)中僅包含模 2 加運(yùn)算(也就是邏輯異或),而不含非線性運(yùn)算。由線性反饋寄存器產(chǎn)生的周期最長(zhǎng)的二進(jìn)制序列稱為最大長(zhǎng)度線線性反饋寄存器序列,簡(jiǎn)稱m序列。如果移位寄存器長(zhǎng)度為n,則m序列的周期是(2^n -1),沒有全0的狀態(tài)。
????????偽隨機(jī)碼發(fā)生器的初始狀態(tài)由微處理器通過SEED寄存器發(fā)出。seed不能為全0的狀態(tài) ,因?yàn)?^0=0,會(huì)陷入0的死循環(huán) 。(http://t.csdn.cn/dmROL)
四級(jí)偽隨機(jī)碼發(fā)生器的電路圖如下所示:
?通過4個(gè)D觸發(fā)器以及一個(gè)模2加單元實(shí)行不斷的移位與模二加,就可以得到除去0000的0001-1111即1-15的隨機(jī)數(shù)了。代碼如下:
//2023.4.12 Bread
//四級(jí)偽隨機(jī)碼發(fā)生器;
`timescale 1ns/1ps
module m_gen(
clk,
rst,
y
);
input clk;
input rst;
output y;
reg[3:0] d;
assign y=d[0];
always@(posedge clk or negedge rst) begin
if(~rst) begin
d<=4'b1111;
end
else begin
d[2:0]<=d[3:1];//右移一位
d[3]<=d[3]+d[0];//模二加
end
end
endmodule
在這里我們使用d[2:0]<=d[3:1]的方式進(jìn)行右移,將高三位的值賦給低三位。(其實(shí)verilog里面還可以用>>的方式進(jìn)行移位,但是老師說盡量不要那樣寫,猜測(cè)可能跟位右移和邏輯右移有關(guān)?一些位溢出的問題?)
相應(yīng)的testbench如下:
//----testbench----
module m_gen_tb;
reg clk,rst;
wire y;
m_gen m_gen(
.clk(clk),
.rst(rst),
.y(y)
);
initial begin
clk<=0;rst<=0;
#10 rst<=1;
#600 $stop;
end
always #5 clk<=~clk;
endmodule
這里的testbench和上面計(jì)數(shù)器的類似,就不過多敘述。接下來我們進(jìn)行仿真吧。?
2.Modelsim仿真
其他的方式都和上面一樣,但是要注意的是,這里的d我們并沒有在testbench中注明,所以我們需要單獨(dú)將其添加到波形圖中:
(注意:因?yàn)槲覀冎疤砑恿薱lk,rst,y等信號(hào),所以這里我們僅選擇Selected Signals,不然會(huì)重復(fù)添加)
最后仿真的波形如下:
?可以看到,這里的y輸出值僅僅只是最后一個(gè)D觸發(fā)器的輸出值,我們的偽隨機(jī)碼是d[3:0]構(gòu)成的數(shù)字,實(shí)際上,輸出d更符合偽隨機(jī)碼的特性(1-15的隨機(jī)數(shù)),但是這里的隨機(jī)碼是跟輸入的時(shí)鐘信號(hào)有關(guān),在時(shí)間上呈現(xiàn)一定的周期性,并非是完全隨機(jī)的。
?文章來源:http://www.zghlxwxcb.cn/news/detail-768476.html
總結(jié)
以上就是本文的全部?jī)?nèi)容了。本人只是一個(gè)剛?cè)腴T自學(xué)的萌新,有很多不對(duì)的地方,發(fā)布這篇文章也只是記錄自己的學(xué)習(xí)過程,因?yàn)樽约旱膶W(xué)習(xí)習(xí)慣很不好,從來不愛動(dòng)筆只喜歡看,很快就忘記了,所以想通過這樣的方式來記錄。同時(shí)也提醒自己在編寫代碼的時(shí)候要保持良好的習(xí)慣,以及編寫邊檢查。我在寫四位偽隨機(jī)碼放發(fā)生器的時(shí)候因?yàn)椴恍⌒膶?rst(rst)寫成了.rst(clk)導(dǎo)致波形圖一直無法更新,輸出的y值一直為1,在排查了很久后也沒有發(fā)現(xiàn)問題,編譯器也沒有報(bào)錯(cuò)。導(dǎo)致浪費(fèi)了一個(gè)小時(shí)的時(shí)間在這里,還一直在always語(yǔ)句里面找問題,最后才發(fā)現(xiàn)!這種問題一定要注意呀,有時(shí)候參數(shù)寫錯(cuò)了并不會(huì)報(bào)錯(cuò)但是結(jié)果會(huì)有很大的問題!希望能夠堅(jiān)持下去。文章來源地址http://www.zghlxwxcb.cn/news/detail-768476.html
到了這里,關(guān)于Verilog學(xué)習(xí)記錄(一):時(shí)序邏輯代碼設(shè)計(jì)和仿真的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!