數電基礎
關于時序邏輯設計的部分依然強烈推薦mooc上華科的數字電路與邏輯設計。
計數器可以分為同步和異步計數器,2進制、10進制和任意進制計數器,加法和減法計數器。同步和異步是指觸發器是否都由同一個時鐘信號控制。一個觸發器能存儲1位二進制數,所以由N個觸發器構成N位寄存器。例如3個JK觸發器可以存儲000-111種狀態。在數電的原理方面,mooc上講解的很清晰,可以自行學習同步或異步的二進制寄存器、使用復位清零和反饋置數將M進制構成N進制(N
設計規劃
本例將采用一個外部時鐘信號,一個復位鍵和一個LED燈來實現1s內LED閃爍(亮0.5s滅0.5s)。這種計時的功能在FPGA中是通過計數器完成的: 經歷一個時鐘周期,計數器+1 ,我們只需要計算出計數截止的值,就可以完成計時。由于采用的50MHz時鐘頻率,也就是1s產生510e7個時鐘。那么亮滅0.5s就是需要計2.510e7個數。計數器從0-24999999,2^24<24999999<2^25,因此需要25個觸發器,即25位寄存器。這個計數過程是:復位鍵生效時計數器歸零,釋放后的第一個時鐘上升沿開始計數,從0計到2499999時LED燈改變狀態,計數器歸零重新開始計數,到2499999時LED燈改變狀態...
編寫代碼
module counter
#(
parameter CNT_MAX = 25'd24_999_999
)
(
input wire sys_clk , //系統時鐘50MHz
input wire sys_rst_n , //全局復位
output reg led_out
);
reg [24:0] cnt; //經計算得需要25位寬的寄存器才夠500ms
//cnt:計數器計數,當計數到CNT_MAX的值時清零
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt <= 25'b0;
else if(cnt == CNT_MAX)
cnt <= 25'b0;
else
cnt <= cnt + 1'b1;
//led_out:輸出控制一個LED燈,每當計數滿標志信號有效時取反
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
led_out <= 1'b0;
else if(cnt == CNT_MAX)
led_out <= ~led_out;
endmodule
代碼注釋:與#define 標識符 常量類似,這里使用參數的方式定義常量。在RTL代碼中實例化該模塊時,如果需要兩個不同計數值的計數器,只需要修改常數值。使用testbench仿真時也需要實例化,0.5s才能看到led_out的變化,仿真時間過長。如果我們直接修改參數縮短時間就能看到效果。parameter定義的是局部參數,只在本模塊中有效,不會影響實際值。
我們觀察cnt和led_out的變化條件:計數器發生改變的條件有兩個,一個是時鐘上升沿,一個是復位有效(復位下降沿)。計數器發生的改變有兩個,要么+1要么清零。清零條件有兩個:復位和溢出。因此第一個always塊中有三個判斷條件:復位和溢出時清零,其他的時候+1。
led_out的變化條件:時鐘上升沿和復位有效(復位下降沿)。LED燈狀態的變化有兩個,當復位時LED燈為低電平,溢出時取反。
編寫testbench
`timescale 1ns/1ns
module tb_counter();
//reg define
reg sys_clk;
reg sys_rst_n;
//wire define
wire led_out;
//初始化輸入信號
initial begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
//sys_clk:每10ns電平翻轉一次,產生一個50MHz的時鐘信號
always #10 sys_clk = ~sys_clk;
//---------------------flip_flop_inst----------------------
counter
#(
.CNT_MAX (25'd24 )
)
counter_inst(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n ),
.led_out (led_out )
);
endmodule
初始化:時鐘高電平,復位低電平,20s延遲后復位高電平。
實例化:此處的參數只對該模塊有效,想要改變這個模塊里的參數數值,只需要在這里改變即可。這里設置成24是為了方便觀察,節省時間。
對比波形
24個時鐘脈沖輸出就會取反,同理trl文件中24999999個脈沖(0.5s)之后LED燈會改變狀態,實現1s內閃爍。
分配管腳
全編譯后上板驗證
LED燈在1s內閃爍,且S1一直按LED燈會一直亮(S1按下去為低電平,復位有效,led_out=0,LED燈亮,和預期一致。
-
FPGA
+關注
關注
1626文章
21671瀏覽量
601900 -
計數器
+關注
關注
32文章
2254瀏覽量
94360 -
數字電路
+關注
關注
193文章
1600瀏覽量
80502 -
觸發器
+關注
關注
14文章
1996瀏覽量
61053 -
時鐘信號
+關注
關注
4文章
445瀏覽量
28511
發布評論請先 登錄
相關推薦
評論