HDLBits:在線學習 Verilog (二十一 · Problem 100 - 104)

首先附上傳送門:

Count1to10 - HDLBits?

hdlbits.01xz.net

Problem 100 Decade counter again

牛刀小試

本題和Problem 99 類似,還是1~10的計數器,唯一不同是同步複位為1.

解答與解析

module top_module (
input clk,
input reset,
output [3:0] q);

always @ (posedge clk)
begin
if(reset)
q <= 4b0001;
else if(q <= 4b1001)
q <= q + 1b1;
else
q <= 4b0001;

end

endmodule

Problem 101 Slow decade counter

牛刀小試

設計一個0~9的計數器,共10個周期。該計數器採用同步複位且複位為0。但是本題是希望該計數器並不是隨著clk的變化而遞增,而是隨著一個slowena使能信號來控制增加。時序圖如下圖所示

解答與解析

本題相比於之前的計數器,不同點在於多了一個enable信號來控制計數器的增加。

module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);

reg [3:0] cnt;
//period is 10
//What is supposed to happen when the counter is 9 and not enabled?
always @ (posedge clk)
begin
if(reset)
cnt <= 4b0;
else if(slowena == 1b1)
//slowena 為高,計數器才能正常運行
begin
if(cnt == 4d9)
cnt <= 4b0;
//因為題目要求周期為10,所以0~9之後下一個為0;
else
cnt <= cnt + 4d1;
end
end

assign q = cnt;

endmodule

Problem 102 Counter 1-12

牛刀小試

根據以下輸入輸出信號設計一個計算1~12的計數器

Reset:同步複位信號,高複位,將計數器複位為1.

Enable:使能信號高有效

Clk:時鐘上升沿觸發計數器工作

Q[3:0]:計數器輸出

c_enable, c_load, c_d[3:0]:題目中給我們提供了一個4-bit的計數器,這三個信號是用於該4-bit計數器的控制信號。

題目提供給我們4-bit計數器

  1. 有enable信號,帶複位和置位的計數器,將該計數器例化至我們的代碼中。
  2. 再用一些其他的邏輯門來完成本題

//題目提供的4-bit計數器代碼
module count4(
input clk,
input enable,
input load,
input [3:0] d,
output reg [3:0] Q
);

解答與解析

本題相當於用c_enale、c_load和c_d[3:0]三個控制信號來控制題目中給我們提供的4-bit計數器,使得該計數器的技術範圍改變為1~12.

就是上圖所示的樣子。

module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output c_enable,
output c_load,
output [3:0] c_d
); //

reg [3:0] temp;

//4-bit計數器的控制信號
assign c_enable = enable;
//帶複位和置位,
assign c_load = reset | (Q == 4d12 & enable == 1b1);
assign c_d = 4b1;

// count4 the_counter (clk, c_enable, c_load, c_d, Q );
count4 Inst_count4
(
.clk(clk),
.enable(c_enable),
.load(c_load),
.d(c_d),
.Q(Q)
);

endmodule

Problem 103 Counter 1000

牛刀小試

從1000Hz中分離出1Hz的信號,叫做OneHertz。這個主要用作與數字時鐘中。利用一個模10的BCD計數器和盡量少的邏輯門來建立一個時鐘分頻器。同時輸出每個BCD計算器的使能信號(c_enable[0]為高位,c_enable[2]為低位)。

題目已經給我們提供了BCD計數器。Enable信號高有效。Reset信號高有效且複位為0。我們設計的電路中均要採用1000Hz的時鐘。

module bcdcount (
input clk,
input reset,
input enable,
output reg [3:0] Q
);

解答與解析

本題可以這樣考慮,假設三個定時器a,b,c都是模10的計數器,a的輸入時鐘是1000Hz,每當a計到10的時候,給b一個使能,相當於a計10次,b才計1次,b是a的十分之一,故b的時鐘是100Hz。同理c是a的百分之1為10Hz。所以到999是輸出就為1Hz了。

module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //

wire [3:0] q0, q1, q2;

assign c_enable = {q1 == 4d9 && q0 == 4d9, q0 == 4d9, 1b1};
assign OneHertz = {q2 == 4d9 && q1 == 4d9 && q0 == 4d9};

bcdcount counter0 (clk, reset, c_enable[0], q0);
bcdcount counter1 (clk, reset, c_enable[1], q1);
bcdcount counter2 (clk, reset, c_enable[2], q2);

endmodule

Problem 104 4-digit decimal counter

牛刀小試

設計一個4位BCD(二進位編碼十進位)計數器。每個十進位數字使用4-bit來表示:q[3:0]是個位,q[7:4]是十位等。對於ena[3:1],該信號用來表示個位、十位和百位的進位。時序圖如下圖所示:

解答與解析

module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);

//one
count Inst1_count
(
.clk(clk),
.reset(reset),
.ena(1b1),
.q(q[3:0])
);

//ten
count Inst2_count
(
.clk(clk),
.reset(reset),
.ena(q[3:0] == 4d9),
.q(q[7:4])
);

//hundred
count Inst3_count
(
.clk(clk),
.reset(reset),
.ena(q[7:4] == 4d9 && q[3:0] == 4d9),
.q(q[11:8])
);

//thousand
count Inst4_count
(
.clk(clk),
.reset(reset),
.ena(q[11:8] == 4d9 && q[7:4] == 4d9 && q[3:0] == 4d9),
.q(q[15:12])
);

//用來表示進位
assign ena = {q[11:8] == 4d9 && q[7:4] == 4d9 && q[3:0] == 4d9, q[7:4] == 4d9 && q[3:0] == 4d9, q[3:0] == 4d9};

endmodule

module count
(
input clk,
input reset,
input ena,
output reg[3:0] q
);

always @ (posedge clk)
begin
if(reset)
q <= 4b0;
else if (ena)
begin
if(q == 4d9)
q <= 4d0;
else
q <= q + 1b1;
end
end

endmodule

推薦閱讀:

FPGA遠程更新設計的需求分析
曾被微軟放言取代馮氏結構的FPGA,被阿里雲玩「活」了
關於Xilinx FPGA載入中兩個問題的不嚴肅討論
PCIE板卡DDR3調試——DDR3跑不到1600M原因
FPGA入門淺談

TAG:現場可編輯邏輯門陣列(FPGA) | Verilog | veriloghdl |