從今天開始新的一章-時序電路,包括觸發器、計數器、移位寄存器、狀態機等。
今天更新計數器,這也是FPGA部分非常重要的設計技巧。
Problem 98-Count15
題目說明
構建一個4位二進制計數器,計數范圍從0到15(包括0和15),計數周期為16。同步復位輸入時,將計數器重置為0。
圖片來自HDLBits
模塊端口聲明
moduletop_module( inputclk, inputreset,//Synchronousactive-highreset output[3:0]q);
題目解析
這是一個基本計數器。同步復位情況下,復位不放在敏感列表里。
moduletop_module( inputlogicclk, inputlogicreset,//Synchronousactive-highreset outputlogic[3:0]q); always_ff@(posedgeclk)begin if(reset)q<=?'0?; ????????else?if(q?==?4'd15)?q?<=?'0?; ????????else??q?<=?q?+?1?; ????end ???????????? endmodule
點擊Submit,等待一會就能看到下圖結果:
注意圖中的Ref是參考波形,Yours是你的代碼生成的波形,網站會對比這兩個波形,一旦這兩者不匹配,仿真結果會變紅。
這一題就結束了。
Problem 99-Count10
題目說明
構建一個十進制計數器,從0到9(包括0和9)計數,計數周期為10。同步復位輸入時,將計數器重置為0。
圖片來自HDLBits
模塊端口聲明
moduletop_module( inputclk, inputreset,//Synchronousactive-highreset output[3:0]q);
題目解析
和上一題類似。
moduletop_module( inputlogicclk, inputlogicreset,//Synchronousactive-highreset outputlogic[3:0]q); always_ff@(posedgeclk)begin if(reset)q<=?'0?; ????????else?if(q?==?4'd9)??q?<=?'0?; ????????else????????????????q?<=?q?+?1; ????end ? endmodule
點擊Submit,等待一會就能看到下圖結果:
注意圖中的Ref是參考波形,Yours是你的代碼生成的波形,網站會對比這兩個波形,一旦這兩者不匹配,仿真結果會變紅。
這一題就結束了。
Problem 100-Count1to10
題目說明
做一個十進制計數器,從1到10(包括1和10)計數,計數周期為10。同步復位輸入時,將計數器重置為1。
圖片來自HDLBits
模塊端口聲明
moduletop_module( inputclk, inputreset, output[3:0]q);
題目解析
和上一節一樣,上一節是從0到9,這題從1到10,計數結束條件和重置條件不一樣,其他一樣。
moduletop_module( inputlogicclk, inputlogicreset, outputlogic[3:0]q); always_ff@(posedgeclk)begin if(reset)q<=?4'd1; ????????else?if(q?==?4'd10)?q?<=?4'd1; ????????else????????????????q?<=?q?+?1; ????end endmodule
點擊Submit,等待一會就能看到下圖結果:
注意圖中的Ref是參考波形,Yours是你的代碼生成的波形,網站會對比這兩個波形,一旦這兩者不匹配,仿真結果會變紅。
這一題就結束了。
Problem 101-Countslow
題目說明
構建一個十進制計數器,從0到9(包括0和9)計數,計數周期為10。同步復位輸入時,將計數器重置為0。但是本題是希望該計數器并不是隨著clk的變化而遞增,而是隨著一個slowena使能信號來控制增加。時序圖如下圖所示:
圖片來自HDLBits
模塊端口聲明
moduletop_module( inputclk, inputslowena, inputreset, output[3:0]q);
題目解析
本題相比于之前的計數器,不同點在于多了一個enable信號來控制計數器的增加(這應該叫使能同步計數器(戰術后仰))。
moduletop_module( inputlogicclk, inputlogicslowena, inputlogicreset, outputlogic[3:0]q); always_ff@(posedgeclk)begin if(reset)q<=?'0?; ????????else?if(slowena?&?q==4'd9)?q?<=?'0?; ????????else?if(slowena?&?q!=4'd9)?q?<=?q?+?1?; ????????else???????????????????????q?<=?q??; ????end endmodule
點擊Submit,等待一會就能看到下圖結果:
注意圖中的Ref是參考波形,Yours是你的代碼生成的波形,網站會對比這兩個波形,一旦這兩者不匹配,仿真結果會變紅。
這一題就結束了。
Problem 102-ece241_2014_q7a
題目說明
根據以下輸入輸出信號設計一個計算1~12的計數器
Reset:同步復位信號,高復位,將計數器復位為1.
Enable:使能信號高有效
Clk:時鐘上升沿觸發計數器工作
Q[3:0]:計數器輸出
c_enable, c_load, c_d[3:0]:題目中給我們提供了一個4-bit的計數器,這三個信號是用于該4-bit計數器的控制信號。
題目提供給我們4-bit計數器
有enable信號,帶復位和置位的計數器,將該計數器例化至我們的代碼中。
再用一些其他的邏輯門來完成本題
//題目提供的4-bit計數器代碼 modulecount4( inputclk, inputenable, inputload, input[3:0]d, outputreg[3:0]Q );
模塊端口聲明
moduletop_module( inputclk, inputreset, inputenable, output[3:0]Q, outputc_enable, outputc_load, output[3:0]c_d );
題目解析
本題相當于用c_enale、c_load和c_d[3:0]三個控制信號來控制題目中給我們提供的4-bit計數器,使得該計數器的技術范圍改變為1~12.
moduletop_module( inputlogicclk, inputlogicreset, inputlogicenable, outputlogic[3:0]Q, outputlogicc_enable, outputlogicc_load, outputlogic[3:0]c_d );// count4u1_count4(clk,c_enable,c_load,c_d,Q); assignc_enable=enable; assignc_load=reset|((Q==4'd12)&&enable); assignc_d=c_load?4'd1:4'd0; endmodule
點擊Submit,等待一會就能看到下圖結果:
注意圖中的Ref是參考波形,Yours是你的代碼生成的波形,網站會對比這兩個波形,一旦這兩者不匹配,仿真結果會變紅。
這一題就結束了。
Problem 103-ece241_2014_q7b
題目說明
從1000Hz中分離出1Hz的信號,叫做OneHertz。這個主要用作與數字時鐘中。利用一個模10的BCD計數器和盡量少的邏輯門來建立一個時鐘分頻器。同時輸出每個BCD計算器的使能信號(c_enable[0]為高位,c_enable[2]為低位)。
題目已經給我們提供了BCD計數器。Enable信號高有效。Reset信號高有效且復位為0。我們設計的電路中均要采用1000Hz的時鐘。
modulebcdcount( inputclk, inputreset, inputenable, outputreg[3:0]Q );
模塊端口聲明
moduletop_module( inputclk, inputreset, outputOneHertz, output[2:0]c_enable );
題目解析
題目已經提供了一個模塊,但是是個模10的BCD計數器,1000Hz提取1Hz,那么需要3個上面的計數器(1000/10/10/10=1).
moduletop_module( inputlogicclk, inputlogicreset, outputlogicOneHertz, outputlogic[2:0]c_enable );// wirelogic[3:0]unit,ten,hundred; assignc_enable={unit==4'd9&&ten==4'd9,unit==4'd9,1'b1}; assignOneHertz=(unit==4'd9&&ten==4'd9&&hundred==4'd9); bcdcountcounter0(clk,reset,c_enable[0],unit); bcdcountcounter1(clk,reset,c_enable[1],ten); bcdcountcounter2(clk,reset,c_enable[2],hundred); endmodule
點擊Submit,等待一會就能看到下圖結果:
注意圖中的Ref是參考波形,Yours是你的代碼生成的波形,網站會對比這兩個波形,一旦這兩者不匹配,仿真結果會變紅。
這一題就結束了。
Problem 104-Countbcd
題目說明
構建一個4位BCD(二進制編碼十進制)計數器。每個十進制數字使用4位進行編碼:q[3:0]是一位數字,q[7:4]是十位數字,等等。對于ena[3:1],該信號用來表示個位、十位和百位的進位。時序圖如下圖所示:
圖片來自HDLBits
模塊端口聲明
moduletop_module( inputclk, inputreset,//Synchronousactive-highreset output[3:1]ena, output[15:0]q);
題目解析
這是一個數字時鐘的一部分。
moduletop_module( inputlogicclk, inputlogicreset,//Synchronousactive-highreset outputlogic[3:1]ena, outputlogic[15:0]q); reg[3:0]ones; reg[3:0]tens; reg[3:0]hundreds; reg[3:0]thousands; always@(posedgeclk)begin if(reset)ones<=?4'd0; ????????else?if(ones?==?4'd9)???ones?<=?4'd0; ????????else????????????????????ones?<=?ones?+?4'd1?; ????end ???? ????always@(posedge?clk)begin ????????if(reset)???????????????tens?<=?4'd0; ???????????? ????????else?if(tens?==?4'd9?&&?ones?==?4'd9)?? ????????????????????????????????tens?<=?4'd0; ????????else?if(ones?==?4'd9)???tens?<=?tens?+?4'd1; ????end ???? ????always@(posedge?clk)begin ????????if(reset)???????????????hundreds?<=?4'd0; ???????????? ????????else?if(hundreds?==?4'd9?&&?tens?==?4'd9?&&?ones?==?4'd9) ????????????????????????????????hundreds?<=?4'd0; ????????else?if(tens?==?4'd9?&&?ones?==?4'd9)? ????????????????????????????????hundreds?<=?hundreds?+?4'd1; ????end ???? ????always@(posedge?clk)begin ????????if(reset)???????????????thousands?<=?4'd0; ????????else?if(thousands?==?4'd9?&&?hundreds?==?4'd9?&&?tens?==?4'd9?&&?ones?==?4'd9) ????????????????????????????????thousands?<=?4'd0; ????????else?if(hundreds?==?4'd9?&&?tens?==?4'd9?&&?ones?==?4'd9)? ????????????????????????????????thousands?<=?thousands?+?4'd1; ????end ???? ????assign?q?=?{thousands,?hundreds,?tens,?ones}; ????assign?ena[1]?=?(ones?==?4'd9)???1'b1?:?1'b0; ????assign?ena[2]?=?(tens?==?4'd9?&&?ones?==?4'd9)???1'b1?:?1'b0; ????assign?ena[3]?=?(hundreds?==?4'd9?&&?tens?==?4'd9?&&?ones?==?4'd9)???1'b1?:?1'b0; ? endmodule
點擊Submit,等待一會就能看到下圖結果:
注意圖中的Ref是參考波形,Yours是你的代碼生成的波形,網站會對比這兩個波形,一旦這兩者不匹配,仿真結果會變紅。
這一題就結束了。
Problem 105-Count_clock
題目說明
用計數器設計一個帶am/pm的12小時時鐘。該計數器通過一個CLK進行計時,用ena使能信號來驅動時鐘的遞增。
reset信號將時鐘復位為12:00 AM。 信號pm為0代表AM,為1代表PM。hh、mm和ss由兩個BCD計數器構成hours(01~12), minutes(00~59) , second(00~59)。Reset信號比enable信號有更高的優先級,即使沒有enable信號也可以進行復位操作。
下圖所示的時序圖給出了從1159 AM 到12 :00 : 00 PM的變化。
圖片來自HDLBits
模塊端口聲明
moduletop_module( inputclk, inputreset, inputena, outputpm, output[7:0]hh, output[7:0]mm, output[7:0]ss);
題目解析
moduletop_module( inputlogicclk, inputlogicreset, inputlogicena, outputlogicpm, outputlogic[7:0]hh, outputlogic[7:0]mm, outputlogic[7:0]ss); //ssvar varlogic[3:0]ss_one,ss_ten; varlogicena_ss_one,ena_ss_ten; varlogicrst_ss_one,rst_ss_ten; //mmvar varlogic[3:0]mm_one,mm_ten; varlogicena_mm_one,ena_mm_ten; varlogicrst_mm_one,rst_mm_ten; //hhvar varlogic[3:0]hh_one,hh_ten; varlogicena_hh_one,ena_hh_ten; varlogicrst_hh_one_0,rst_hh_one_1,rst_hh_ten_0,rst_hh_ten_1; //pmvar varlogicrev_pm; //sscoutpart assignena_ss_one=ena; assignrst_ss_one=ena_ss_one&&(ss_one==4'd9); always_ff@(posedgeclk)begin if(reset)ss_one<=?'0?; ????????else?if(ena_ss_one)?begin ????????????if(rst_ss_one)??ss_one?<=?'0?; ????????????else????????????ss_one?<=?ss_one?+?4'd1?; ????????end ????end ???? ????assign?ena_ss_ten?=?rst_ss_one?; ????assign?rst_ss_ten?=?ena_ss_ten?&&?(ss_ten?==?4'd5)?; ???? ????always_ff@(posedge?clk)?begin ????????if(reset)???????????ss_ten?<=?'0?; ????????else?if(ena_ss_ten)?begin ????????????if(rst_ss_ten)??ss_ten?<=?'0?; ????????????else????????????ss_ten?<=?ss_ten?+?4'd1?; ????????end ????end ??? ???? ????//mm?cout?part ???? ????assign?ena_mm_one?=?rst_ss_ten?; ????assign?rst_mm_one?=?ena_mm_one?&&?(mm_one?==?4'd9)?; ??????? ????always_ff@(posedge?clk)?begin ????????if(reset)???????????mm_one?<=?'0?; ????????else?if(ena_mm_one)?begin ????????????if(rst_mm_one)??mm_one?<=?'0?; ????????????else????????????mm_one?<=?mm_one?+?4'd1?; ????????end ????end? ???? ???? ????assign?ena_mm_ten?=?rst_mm_one?; ????assign?rst_mm_ten?=?ena_mm_ten?&&?(mm_ten?==?4'd5)?; ???? ????always_ff@(posedge?clk)?begin ????????if(reset)???????????mm_ten?<=?'0?; ????????else?if(ena_mm_ten)?begin ????????????if(rst_mm_ten)??mm_ten?<=?'0?; ????????????else????????????mm_ten?<=?mm_ten?+?4'd1?; ????????end ????end ???? ????//hh?cout?part ???? ????assign?ena_hh_one?=?rst_mm_ten?; ????assign?rst_hh_one_0?=?ena_hh_one?&&?(hh_one?==?4'd9)?; ????assign?rst_hh_one_1?=?ena_hh_one?&&?(hh_one?==?4'd2?&&?hh_ten?==?4'd1)?; ???? ????always_ff@(posedge?clk)?begin ????????if(reset)?????????????hh_one?<=?4'd2?; ????????else?if(ena_hh_one)?begin ????????????if(rst_hh_one_0)??hh_one?<=?4'd0?; ????????????else?if(rst_hh_one_1)??????????? ??????????????????????????????hh_one?<=?4'd1?; ????????????else??????????????hh_one?<=?hh_one?+?4'd1?; ????????end ????end? ???? ???? ????assign?ena_hh_ten?=?ena_hh_one?; ????assign?rst_hh_ten_0?=?ena_hh_ten?&&?(hh_one?==?4'd2?&&?hh_ten?==?4'd1)?; ????assign?rst_hh_ten_1?=?ena_hh_ten?&&?(hh_one?==?4'd9)?; ???? ????always_ff@(posedge?clk)?begin ????????if(reset)?????????????hh_ten?<=?4'd1?; ????????else?if(ena_hh_ten)?begin ????????????if(rst_hh_ten_0)??hh_ten?<=?4'd0?; ????????????else?if(rst_hh_ten_1)???????????? ??????????????????????????????hh_ten?<=?4'd1?; ????????end ????end ???? ???? ????//pm?display?part ???? ????assign?rev_pm?=?(hh_ten?==?4'd1)?&&?(hh_one?==?4'd1)?&&?ena_hh_one?; ???? ????always_ff@(posedge?clk)?begin ????????if(reset)???????pm?<=?'0??; ????????else?if(rev_pm)?pm?<=?~pm?; ????end ???? ????//assign?time?output ???? ????assign?ss?=?{ss_ten,ss_one}?; ????assign?mm?=?{mm_ten,mm_one}?; ????assign?hh?=?{hh_ten,hh_one}?; endmodule
點擊Submit,等待一會就能看到下圖結果:
注意圖中的Ref是參考波形,Yours是你的代碼生成的波形,網站會對比這兩個波形,一旦這兩者不匹配,仿真結果會變紅。
這一題就結束了。
總結
今天的幾道題就結束了,對于計數器的設計真的需要掌握,不僅是時序電路的基礎,同時在后續FPGA設計也是一個重要的設計技巧。
最后我這邊做題的代碼也是個人理解使用,有錯誤歡迎大家批評指正,祝大家學習愉快~
審核編輯:劉清
-
二進制
+關注
關注
2文章
794瀏覽量
41602 -
計數器
+關注
關注
32文章
2254瀏覽量
94371 -
時序電路
+關注
關注
1文章
114瀏覽量
21682 -
CLK
+關注
關注
0文章
127瀏覽量
17129 -
Verilog語言
+關注
關注
0文章
113瀏覽量
8219
原文標題:HDLBits: 在線學習 SystemVerilog(十六)-Problem 98-105(計數器)
文章出處:【微信號:Open_FPGA,微信公眾號:OpenFPGA】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論