1.Count15(16进制同步复位计数器)
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'b1;
end
endmodule
2.Decade counter(十进制计数器)
module top_module (
input clk,
input reset, // 同步 active-high reset
output [3:0] q);
always @ (posedge clk) begin
if(reset)
q <= 0;
else if(q < 4'd9)
q <= q + 1'b1;
else
q <= 0;
end
endmodule
3.Decade counter again
module top_module (
input clk,
input reset,
output [3:0] q);
always @ (posedge clk) begin
if(reset)
q <= 1;
else if(q < 4'd10)
q <= q + 1'b1;
else
q <= 1;
end
endmodule
4.slow decade counter
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
reg [3:0] cnt;
always @ (posedge clk) begin
if(reset)
cnt <= 0;
else if(slowena) begin
if(cnt == 4'd9)
cnt <= 0; //从0-9计数,周期为10,则9过后应该为0
else
cnt <= cnt + 1'b1;
end
end
assign q = cnt;
endmodule
5.counter 1-12
提供了模块count4,可以直接例化,但是本题主要考虑对于四位计数器的理解,时钟和使能信号都很好理解,但是对于load信号,其代表的是重新加载,即回到初始值,那么就存在两种情况,一是有效置位reset==1’b1,二是计数循环结束并可以开始下一循环,即Q值达到4’d12并且使能信号enable为1’b1,两种情况为或关系;对于d信号而言,其在load信号有效时值为4‘d1,其余情况为任意值即可。来源博客
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_enable=enable;
assign c_load=(reset|(Q==4'd12&enable))?1'b1:1'b0;
assign c_d=c_load?4'b1:Q;
count4 instance1(clk,c_enable,c_load,c_d,Q);
endmodule
6.counter1000(分频)
从 1000 Hz 时钟中,导出一个1 Hz 信号,称为 OneHertz,可用于驱动一组小时/分钟/秒计数器的使能信号以创建数字挂钟。由于我们希望时钟每秒计数一次,因此必须每秒正好对OneHertz信号进行一个周期的置位。使用模10(BCD)计数器和尽可能少的其他门构建分频器。同时从您使用的每个 BCD 计数器输出使能信号(最快的计数器c_enable[0],最慢的计数器c_enable[2])
题目使用3个0-9的计数器来实现时钟分频功能。若仅使用一个bcdcount分频,每计数10次,OneHertz输出为高,那么可以实现10分频,即100Hz。如果counter0每计数10次,counter1计数1次,那么counter1计数10次时OneHertz为高,则可以实现100分频,即10Hz。同理,三个bcdcount可以实现1000分频,即1Hz。
采用组合逻辑电路使能三个bcdcount,容易理解,reset不为1时,counter0始终在计数,c_enable[0]=1’b1;
仅当counter0计数10次(q0=4’d9)时,counter1计数1次,也就是counter0计数10个时钟周期后,下一时钟周期counter1计数,c_enable[1]=1’b1;
当counter1计数10次时(q1=4’d9),counter1会保存q1=4’d9十个时钟周期才会变回0,即需要counter0=4’d9才会再次变化。所以counter2有效的时钟周期为counter1=4’d9的情况下,counted0=4’d9的下一时钟周期。所以q1=4’d9 && q0=4’d9时c_enable[2]=1’b1。
根据最终得到的波形图可以看到,要求的OneHertz输出并不是频率为1Hz、占空比为50%的时钟,而是频率为1Hz、宽度为一个clk时钟周期的的脉冲。所以,OneHertz为高的条件为q2=4’d9 && q1=4’d9 && q0=4’d9。原文分析链接
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
);
reg [3:0] q0,q1,q2;
always @(*) begin
if(reset) begin
c_enable <= 3'b000;
end
else begin
c_enable[0] = 1'b1;
if(q0==4'd9)
c_enable[1] = 1'b1;
else
c_enable[1] = 1'b0;
if(q1==4'd9 && q0==4'd9)
c_enable[2] = 1'b1;
else
c_enable[2] = 1'b0;
end
end
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
7.4-digit decimal counter(多位bcd十进制计数器)
16个bit的变量分为四段,从低到高每段分别计数,其中对于每段信号的状态而言,有三个可能,一是无进位信号保持计数值不变,二是有进位信号且计数值小于4’h9,因此计数值+1’b1,三是有进位信号但计数值达到4’h9,循环结束回到初始值4’h0;对于进位信号ena而言,需要注意两点,一是进位信号的判断值在循环结束的前一个状态即4’h8、8’h98和12’h998,因为这样才能在时钟触发的时候正常计数,二是进位需要在无效置位情况下发生,因此每一项都要与上~reset。
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
always @ (posedge clk) begin
ena<={~reset&q[11:0]==12'h998,~reset&q[7:0]==8'h98,~reset&q[3:0]==4'h8};
if(reset) begin
q<=16'd0;
end
else begin
q[3:0]<=(q[3:0]<4'h9)?q[3:0]+1'b1:4'h0;
q[7:4]<=(!ena[1])?q[7:4]:(q[7:4]<4'h9)?q[7:4]+1'b1:4'h0;
q[11:8]<=(!ena[2])?q[11:8]:(q[11:8]<4'h9)?q[11:8]+1'b1:4'h0;
q[15:12]<=(!ena[3])?q[15:12]:(q[15:12]<4'h9)?q[15:12]+1'b1:4'h0;
end
end
endmodule
8.12 hours clock
总共需要用到6个BCD counter,表示时、分、秒各两个,时从01计到12,分从00计到59,秒从00计到59;复位时显示AM 12:00:00;复位的优先级高于enable,也就是说,即使enable为0,只要复位,也要显示AM 12:00:00。
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
reg [3:0] ss0,ss1,mm0,mm1,hh1,hh0;
reg [3:0] state;
always @ (posedge clk) begin
if(reset)
ss0 <= 4'd0;
else if(ena) begin
if(ss0 == 4'd9)
ss0 <= 4'd0;
else
ss0 <= ss0 + 4'd1;
end
else
ss0 <= ss0;
end
always @ (posedge clk) begin
if(reset)
ss1 <= 4'd0;
else if(ss1 == 4'd5) begin
if(ss0 == 4'd9 && ena)
ss1 <= 4'd0;
else
ss1 <= ss1;
end
else begin
if(ss0 == 4'd9 && ena)
ss1 <= ss1 + 4'd1;
else
ss1 <= ss1;
end
end
always @ (posedge clk) begin
if(reset)
mm0 <= 4'd0;
else if(mm0 == 4'd9) begin
if(ss1 == 4'd5 && ss0 == 4'd9)
mm0 <= 4'd0;
else
mm0 <= mm0;
end
else begin
if(ss1 == 4'd5 && ss0 == 4'd9)
mm0 <= mm0 + 4'd1;
else
mm0 <= mm0;
end
end
always @ (posedge clk) begin
if(reset)
mm1 <= 4'd0;
else if(mm1 == 4'd5) begin
if(mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd9)
mm1 <= 4'd0;
else
mm1 <= mm1;
end
else begin
if(mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd9)
mm1 <= mm1 + 4'd1;
else
mm1 <= mm1;
end
end
always @ (posedge clk) begin
if(reset) begin
state <= 4'd0;
hh1 <= 4'd1;
hh0 <= 4'd2;
end
else begin
case(state)
4'd0:begin
hh1 <= 4'd1;
hh0 <= 4'd2;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd1;
end
4'd1:begin
hh1 <= 4'd0;
hh0 <= 4'd1;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd2;
end
4'd2:begin
hh1 <= 4'd0;
hh0 <= 4'd2;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd3;
end
4'd3:begin
hh1 <= 4'd0;
hh0 <= 4'd3;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd4;
end
4'd4:begin
hh1 <= 4'd0;
hh0 <= 4'd4;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd5;
end
4'd5:begin
hh1 <= 4'd0;
hh0 <= 4'd5;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd6;
end
4'd6:begin
hh1 <= 4'd0;
hh0 <= 4'd6;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd7;
end
4'd7:begin
hh1 <= 4'd0;
hh0 <= 4'd7;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd8;
end
4'd8:begin
hh1 <= 4'd0;
hh0 <= 4'd8;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd9;
end
4'd9:begin
hh1 <= 4'd0;
hh0 <= 4'd9;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd10;
end
4'd10:begin
hh1 <= 4'd1;
hh0 <= 4'd0;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd11;
end
4'd11:begin
hh1 <= 4'd1;
hh0 <= 4'd1;
if(mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd8)
state <= 4'd0;
end
default:begin
state <= 4'd0;
hh1 <= 4'd1;
hh0 <= 4'd2;
end
endcase
end
end
assign hh = {hh1,hh0};
assign mm = {mm1,mm0};
assign ss = {ss1,ss0};
always @ (posedge clk) begin
if(reset)
pm <= 1'b0;
else if(hh1 == 4'd1 && hh0 == 4'd1 && mm1 == 4'd5 && mm0 == 4'd9 && ss1 == 4'd5 && ss0 == 4'd9)
pm <= ~pm;
else
pm <= pm;
end
endmodule