概述
3.2.2 Counters
3.2.2.1 Count15
创建一个计数器,当同步复位信号reset
置1
时,清零
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always @ (posedge clk) begin
if(reset) begin
q <= 4'd0;
end
else begin
if(q == 4'd15) begin
q <= 4'd0;
end
else begin
q <= q + 1'b1;
end
end
end
endmodule
3.2.2.2 Decade counter
模10计数器
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always @ (posedge clk) begin
if(reset) begin
q <= 4'd0;
end
else begin
if(q == 4'd9) begin
q <= 4'd0;
end
else begin
q <= q + 1;
end
end
end
endmodule
3.2.2.3 Decade counter again
从1-10计数
module top_module (
input clk,
input reset,
output [3:0] q);
always @ (posedge clk) begin
if(reset) begin
q <= 4'd1;
end
else begin
if(q == 4'd10) begin
q <= 4'd1;
end
else begin
q <= q + 1;
end
end
end
endmodule
3.2.2.3 Slow decade counter
带使能端和复位端的模10计数器
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always @ (posedge clk) begin
if(reset) begin
q <= 4'd0;
end
else begin
if(slowena) begin
if(q == 4'd9) begin
q <= 4'd0;
end
else begin
q <= q + 1;
end
end
else begin
q <= q;
end
end
end
endmodule
3.2.2.4 Counter1-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信号,带复位和置位的计数器,将该计数器例化至我们的代码中。
再用一些其他的逻辑门来完成本题
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);
assign c_d = c_load ? 4'd1 : 4'd0;
count4 the_counter (.clk(clk), .enable(c_enable), .load(c_load), .d(c_d), .Q(Q)/*, ... */ );
endmodule
这个我没看懂,从网上找的代码
3.2.2.5 Counter1000
用4bit的BCD码实现个、十、百的计数,当计数1000次后,OneHertz输出为1
通过例化如下module
实现该功能
当个位计数10次,十位计数1次
当十位计数10次,百位计数1次
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //
wire [3:0]one,ten,hundred;
assign c_enable = {one == 4'd9 && ten == 4'd9, one == 4'd9, 1'd1};
assign OneHertz = (hundred == 4'd9 && ten == 4'd9 && one == 4'd9);
bcdcount counter0 (clk, reset, c_enable[0], one/*, ... */);
bcdcount counter1 (clk, reset, c_enable[1], ten/*, ... */);
bcdcount counter2 (clk, reset, c_enable[2], hundred);
endmodule
3.2.2.6 4-digital decimal counter
同步复位信号
ena[3:0]
代表进位输出信号
q
为16-bit
数据输出,用BCD的形式表示
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
reg [3:0] one, ten, hundred, thousand;
always @ (posedge clk) begin //one
if(reset) begin
one <= 4'd0;
end
else if(one == 4'd9) begin //one couter to 9, set one to 0
one <= 4'd0;
end
else begin
one <= one + 1'b1;
end
end
always @ (posedge clk) begin //ten
if(reset) begin
ten <= 4'd0;
end
else if(ten == 4'd9 && one == 4'd9) begin //one counter to 99, set ten to 0
ten <= 4'd0;
end
else if(one == 4'd9) begin //one counter to 9, ten count one time
ten <= ten + 1'b1;
end
end
always @ (posedge clk) begin //hundred
if(reset) begin
hundred <= 4'd0;
end
else if(hundred == 4'd9 && ten == 4'd9 && one == 4'd9) begin //one counter to 999, set hundred to 0
hundred <= 4'd0;
end
else if(ten == 4'd9 && one == 4'd9) begin//one counter to 99, hundred counter one time
hundred <= hundred + 1'b1;
end
end
always @ (posedge clk) begin //thousand
if(reset) begin
thousand <= 4'd0;
end
else if(thousand == 4'd9 && hundred == 4'd9 && ten == 4'd9 && one == 4'd9) begin
thousand <= 4'd0; //one counter to 9999, set thousand to 0
end
else if(hundred == 4'd9 && ten == 4'd9 && one == 4'd9) begin
thousand <= thousand + 1'b1; // one counter to 999, thousand counter one time
end
end
assign q = {thousand, hundred, ten, one};
assign ena = {(hundred == 4'd9 && ten == 4'd9 && one == 4'd9), (ten == 4'd9 && one == 4'd9), (one == 4'd9)};
endmodule
总的来说,就是设计一个从0能计数到9999的计数器,从代码中可以看出,我用来4个always
块来计数,分别代表个位、十位、百位和千位,在one
的always
块中,当one
计数到9
,就将one
清零,在ten
的 always
块中,当one
和ten
都计数到9
时,将其清零;在one
计数到9
时,ten
才计数一次,同理,hundred
和thousand
都是如此计数的,最后,将千位、百位、十位和个位,用连续赋值语句assign
传递给q
,对于进位输出信号ena
,我也用连续赋值语句assign
进行赋值,当one
为9
的时候,ena[1]
条件为真,输出为1
,同理,ena[2]
和ena[3]
处理方法类似
3.2.2.7 12-hour clock
创建一个带PM和AM的12小时制的时钟,要求
reset
时,时间为12:00:00 AMena
有效时候,开始计时pm=0
是AM,pm=1
是PM- 若
11:59:59
是AM
,下一时刻12: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);
reg [3:0] hh_one;
reg [3:0] hh_ten;
reg [3:0] mm_one;
reg [3:0] mm_ten;
reg [3:0] ss_one;
reg [3:0] ss_ten;
reg pm_tmp;
wire en_ss_one;
wire end_ss_one;
wire en_ss_ten;
wire end_ss_ten;
wire en_mm_one;
wire end_mm_one;
wire en_mm_ten;
wire end_mm_ten;
wire en_hh_one;
wire end_hh_one_0;
wire end_hh_one_1;
wire en_hh_ten;
wire end_hh_ten_0;
wire end_hh_ten_1;
wire pm_tmp_ping;
/* 秒针的个位,计数到9,清零 */
assign en_ss_one = ena;
assign end_ss_one = en_ss_one && (ss_one == 4'd9);
always @ (posedge clk) begin
if(reset) begin
ss_one <= 4'd0;
end
else begin
if(end_ss_one) begin
ss_one <= 4'd0;
end
else if(en_ss_one) begin
ss_one <= ss_one + 4'd1;
end
end
end
/* 秒针的十位,个位计数到9,十位计数一次,秒针计数到59,清零 */
assign en_ss_ten = end_ss_one; //--:--:-9
assign end_ss_ten = en_ss_ten && (ss_ten == 4'd5);
always @ (posedge clk) begin
if(reset) begin
ss_ten <= 4'd0;
end
else begin
if(end_ss_ten) begin
ss_ten <= 4'd0;
end
else if(en_ss_ten) begin
ss_ten <= ss_ten + 4'd1;
end
end
end
/* 分针的个位,当秒针计数到59,分针个位计数一次 */
assign en_mm_one = end_ss_ten; //--:--:59
assign end_mm_one = en_mm_one && (mm_one == 4'd9);
always @ (posedge clk) begin
if(reset) begin
mm_one <= 4'd0;
end
else begin
if(end_mm_one) begin
mm_one <= 4'd0;
end
else if(en_mm_one) begin
mm_one <= mm_one + 4'd1;
end
end
end
/* 分针的十位,当秒针计数到59,分针计数到59,清零 */
assign en_mm_ten = end_mm_one; //--:-9:59
assign end_mm_ten = en_mm_ten && (mm_ten == 4'd5);
always @ (posedge clk) begin
if(reset) begin
mm_ten <= 4'd0;
end
else begin
if(end_mm_ten) begin
mm_ten <= 4'd0;
end
else if(en_mm_ten) begin
mm_ten <= mm_ten + 4'd1;
end
end
end
/* 时针的个位,分两种情况,当时针的十位为0,可计数到9 */
/* 当时针的十位为1时,个位只能计数到2 */
assign en_hh_one = end_mm_ten; // --:59:59
assign end_hh_one_0 = en_hh_one && (hh_one == 4'd9); //十位为0 -9:59:59
assign end_hh_one_1 = en_hh_one && (hh_one == 4'd2 && hh_ten == 4'd1); //十位为1 -2:59:59
always @ (posedge clk) begin
if(reset) begin
hh_one <= 4'd2;
end
else begin
if(end_hh_one_0) begin
hh_one <= 4'd0;
end
else if(end_hh_one_1) begin
hh_one <= 4'd1;
end
else if(en_hh_one) begin
hh_one <= hh_one + 4'd1;
end
end
end
/* 时针的十位 */
assign en_hh_ten = end_mm_ten;
assign end_hh_ten_0 = end_mm_ten && (hh_one == 4'd9); //09:59:59
assign end_hh_ten_1 = end_mm_ten && (hh_one == 4'd2) && (hh_ten == 4'd1); //12:59:59
always @ (posedge clk) begin
if(reset) begin
hh_ten <= 4'd1;
end
else if(en_hh_ten) begin
if(end_hh_ten_0) begin
hh_ten <= hh_ten + 4'd1;
end
else if(end_hh_ten_1) begin
hh_ten <= 4'd0;
end
end
end
/* PM 当11:59:59时,pm_tmp发生翻转 */
assign pm_tmp_ping = (hh_ten == 4'd1) && (hh_one == 4'd1) && end_mm_ten;
always @ (posedge clk) begin
if(reset) begin
pm_tmp <= 1'b0;
end
else if(pm_tmp_ping) begin
pm_tmp <= ~pm_tmp;
end
end
assign ss = {ss_ten,ss_one};
assign mm = {mm_ten,mm_one};
assign hh = {hh_ten,hh_one};
assign pm = pm_tmp;
endmodule
最后
以上就是耍酷宝马为你收集整理的HDLbits 刷题答案 3.2.2 Counters的全部内容,希望文章能够帮你解决HDLbits 刷题答案 3.2.2 Counters所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复