本系列内容来自于知乎专栏,链接如下:https://zhuanlan.zhihu.com/c_1131528588117385216 本系列文章将和读者一起巡礼数字逻辑在线学习网站 HDLBits 的教程与习题,并附上解答和一些作者个人的理解,相信无论是想 7 分钟精通 Verilog,还是对 Verilog 和数电知识查漏补缺的同学,都能从中有所收获。
有趣的表情包,与大家共享!
Problem 100 Decade counter again
牛刀小试
本题和Problem 99 类似,还是1~10的计数器,唯一不同是同步复位为1.
解答与解析
代码语言:javascript复制module top_module (
input clk,
input reset,
output [3:0] q);
always @ (posedge clk)
begin
if(reset)
q <= 4'b0001;
else if(q <= 4'b1001)
q <= q 1'b1;
else
q <= 4'b0001;
end
endmodule
Problem 101 Slow decade counter
牛刀小试
设计一个0~9的计数器,共10个周期。该计数器采用同步复位且复位为0。但是本题是希望该计数器并不是随着clk的变化而递增,而是随着一个slowena使能信号来控制增加。时序图如下图所示
解答与解析
本题相比于之前的计数器,不同点在于多了一个enable信号来控制计数器的增加。
代码语言:javascript复制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 <= 4'b0;
else if(slowena == 1'b1)
//slowena 为高,计数器才能正常运行
begin
if(cnt == 4'd9)
cnt <= 4'b0;
//因为题目要求周期为10,所以0~9之后下一个为0;
else
cnt <= cnt 4'd1;
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计数器
- 有enable信号,带复位和置位的计数器,将该计数器例化至我们的代码中。
- 再用一些其他的逻辑门来完成本题
//题目提供的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.
就是上图所示的样子。
代码语言:javascript复制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 == 4'd12 & enable == 1'b1);
assign c_d = 4'b1;
// 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的时钟。
代码语言:javascript复制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了。
代码语言:javascript复制module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //
wire [3:0] q0, q1, q2;
assign c_enable = {q1 == 4'd9 && q0 == 4'd9, q0 == 4'd9, 1'b1};
assign OneHertz = {q2 == 4'd9 && q1 == 4'd9 && q0 == 4'd9};
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],该信号用来表示个位、十位和百位的进位。时序图如下图所示:
解答与解析
代码语言:javascript复制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(1'b1),
.q(q[3:0])
);
//ten
count Inst2_count
(
.clk(clk),
.reset(reset),
.ena(q[3:0] == 4'd9),
.q(q[7:4])
);
//hundred
count Inst3_count
(
.clk(clk),
.reset(reset),
.ena(q[7:4] == 4'd9 && q[3:0] == 4'd9),
.q(q[11:8])
);
//thousand
count Inst4_count
(
.clk(clk),
.reset(reset),
.ena(q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9),
.q(q[15:12])
);
//用来表示进位
assign ena = {q[11:8] == 4'd9 && q[7:4] == 4'd9 && q[3:0] == 4'd9, q[7:4] == 4'd9 && q[3:0] == 4'd9, q[3:0] == 4'd9};
endmodule
module count
(
input clk,
input reset,
input ena,
output reg[3:0] q
);
always @ (posedge clk)
begin
if(reset)
q <= 4'b0;
else if (ena)
begin
if(q == 4'd9)
q <= 4'd0;
else
q <= q 1'b1;
end
end
endmodule