Verilog Circuits-Sequential Logic-Counters
Problem 98:Four-bit binary counter
设计一个 4it 的计数器,从 0-15,共 16 个周期,reset 是同步复位且复位为 0

module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always @(posedge clk)
begin
if(reset)
q<=0;
else
q<=q+1;
end
endmodule
Problem 99 :Decade counter
将上题的 0-15 改为 0-9,同步复位,且复位为 0

module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always @(posedge clk)
begin
if(reset)
q<=0;
else if(q<=4'b1000)
q<=q+1'b1;
else
q<=0;
end
endmodule
- official solution
module top_module(
input clk,
input reset,
output reg [3:0] q);
always @(posedge clk)
if (reset || q == 9) // Count to 10 requires rolling over 9->0 instead of the more natural 15->0
q <= 0;
else
q <= q+1;
endmodule
Problem 100:Decade counter again
1-10 的计数器,不同的是同步复位为 1

module top_module (
input clk,
input reset,
output [3:0] q);
always @(posedge clk)
begin
if(reset)
q<=4'b0001;
else if(q>=4'b1010)
q<=1;
else
q<=q+1;
end
endmodule
Problem 101:Slow decade counter
设计 0-9 的计数器,共 1 0 个周期。该计数器采用同步复位且复位为 0。
我们希望该计数器不是随着 clk 的变化而递增,而是随着一个 slowena 使能信号来控制增加。时序图如图

module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always @(posedge clk)
begin
if(reset)
q<=4'b0;
else if(slowena==1'b1)//当使能端赋值时,计数器才开始工作
begin
if(q<=4'b1000)
q<=q+4'b1;
else
q<=4'b0;
end
end
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
.
module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output c_enable,
output c_load,
output [3:0] c_d
); //
assign c_d=4'b1;
assign c_enable=enable;
assign c_load=reset|(Q==4'd12&enable==1'b1);//读者觉得这里的load应该是置位端
//count4 the_counter (clk, c_enable, c_load, c_d /*, ... */ );
count4 the_count (.clk(clk)
,.enable(c_enable)
,.load(c_load)
,.d(c_d)
,.Q(Q)
);
endmodule
Problem 103:Counter 1000
从 1000Hz 中分离出 1Hz 的信号,叫做 OneHertz。一般用于驱动计数器的使能端去实现数字时钟。
如果我们想让时钟每秒计数一次,那么 OneHertz 信号必须每秒为一个周期
我们可以利用一个模 1 的 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
);
- 假设三个定时器,每个都是模 10 的计数器,a 的输入时钟是 1000Hz,当 a 计到 10,给 b 一个使能,b 是 a 的十分之一,相当于 b 的时钟是 100Hz,同理,c 是 a 的百分之一,所以到 c 之后,也就是 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={q0==4'd9&&q1==4'd9,q0==4'd9,1'b1};
assign OneHertz={q0==4'd9&&q1==4'd9&&q2==4'd9};
//bcdcount counter0 (clk, reset, c_enable[0]/*, ... */);
//bcdcount counter1 (clk, reset, c_enable[1]/*, ... */);
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);
wire [3:0]q0,q1,q2,q3;
assign ena={q2==4'd9&&q1==4'd9&&q0==4'd9,q1==4'd9&&q0==4'd9,q0==4'd9};
count10 add1(clk,reset,1'b1,q0);
count10 add10(clk,reset,ena[1],q1);
count10 add100(clk,reset,ena[2],q2);
count10 add1000(clk,reset,ena[3],q3);
assign q={q3,q2,q1,q0};
endmodule
module count10(input clk,input reset,input enable,output reg[3:0]Q);
always @(posedge clk)
begin
if(reset)
Q<=0;
else if(enable==1)
begin
if(Q<=4'b1000)
Q<=Q+1;
else
Q<=0;
end
end
endmodule
Problem 105:12-hour clock
用计数器设计一个带 am/pm 的 12 小时时钟。该计数器通过一个 CLK 进行计时,用 ena 使能信号来驱动时钟的递增
reset 信号将时钟复位为 12:00AM。信号 pm 为 0 代表 AM,为 1 代表 PM。
hh、mm 和 ss 由两个 BCD 计数器构成 hours(01-12),minutes(00-59),second(00-59)。reset 信号比 enable 信号优先级高。

- 需要注意的是从 11:59:59 PM 到 12:00:00 AM 和从 12:59:59 PM 到 01:00:00 PM 的变化。
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
wire mcin,hcin,pmt;
counter60 seconds(clk,reset,ena,ss,mcin);
counter60 minutes(clk,reset,mcin,mm,hcin);
counter12 hours(clk,reset,hcin&mcin,hh,pmt);
always @(posedge clk)
begin
if(reset)
pm<=1'b0;
else if(pmt)
pm<=~pm;
else
pm<=pm;
end
endmodule
module counter60(input clk,input reset,input ena,output [7:0]tim,output cout);
always @(posedge clk)
begin
if(reset)
tim<=8'd0;
else if(ena)
begin
if(tim==8'b0101_1001)
tim<=8'd0;
else if(tim[3:0]==4'd9)
begin
tim[7:4]<=tim[7:4]+1;
tim[3:0]<=0;
end
else
tim[3:0]<=tim[3:0]+1;
end
end
assign cout=(tim==8'b0101_1001);
endmodule
module counter12(input clk,input reset,input ena,output[7:0]tim,output cout);
always @(posedge clk)
begin
if(reset)
tim<=8'b0001_0010;
else if(ena)
begin
if(tim==8'b0001_0010)
tim<=8'b0000_0001;
else if(tim[3:0]==4'b1001)
begin
tim[3:0]<=0;
tim[7:4]<=tim[7:4]+1'b1;
end
else
tim[3:0]<=tim[3:0]+1'b1;
end
end
assign cout=(tim==8'b0001_0001)&&ena;
endmodule

浙公网安备 33010602011771号