https://hdlbits.01xz.net/wiki/Sequential Logic/Counter 答案
1.Count15
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always@(posedge clk)
begin
if(reset)
q <= 4'b0;
else
q <= q + 4'b1;
end
endmodule
因为q是4位的,所以到了4’hf加一会自动回到0的;
2.Count10
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:0] q);
always@(posedge clk)
begin
if(reset)
q <= 4'b0;
else if(q == 4'd9)
q <= 4'b0;
else
q <= q + 4'b1;
end
endmodule
十进制是不能自己回到0的。
3.Count1to10
module top_module (
input clk,
input reset,
output [3:0] q);
always@(posedge clk)
begin
if(reset)
q <= 4'b1;
else if(q == 4'b1010)
q <= 4'b1;
else
q <= q + 4'b1;
end
endmodule
4.CountSlow
module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always@(posedge clk)
begin
if(reset || (slowena && q == 4'd9))
q <= 4'b0;
else if(slowena)
q <= q + 4'b1;
else
q <= q;
end
endmodule
5.Count1to12
module top_module (
input clk,
input reset,
input enable,
output [3:0] Q,
output c_enable,
output c_load,
output [3:0] c_d
); //count4 the_counter (clk, c_enable, c_load, c_d /*, ... */ );
assign c_enable = enable;
assign c_load = (reset | (enable && Q == 4'b1100))? 1'b1 : 1'b0;
assign c_d = 4'b1;
count4 the_counter(clk, c_enable, c_load, c_d, Q);
endmodule
6.Counter
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //bcdcount counter0 (clk, reset, c_enable[0]/*, ... */);bcdcount counter1 (clk, reset, c_enable[1]/*, ... */);
wire[3:0] out0;
wire[3:0] out1;
wire[3:0] out2;
assign c_enable[0] = 1'b1;
bcdcount conuter0(clk, reset, c_enable[0], out0);
assign c_enable[1] = (out0[0]==1) && (out0[3]==1);
bcdcount conuter1(clk, reset, c_enable[1], out1);
assign c_enable[2] = (out1[0]==1) && (out1[3]==1) && c_enable[1];
bcdcount conuter2(clk, reset, c_enable[2], out2);
assign OneHertz = (out2[0]==1) && (out2[3]==1) && c_enable[1] && c_enable[2];
endmodule
对于第一次分析来说,这个题目是比较难的,必须搞清楚:十位进位是个位为9,百位进位是个位十位均为9,千位则是前三位都为9。
7.countBCD
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
BCD_counter count0(clk, 1, reset, q[3:0]);
assign ena[1] = q[0] && q[3];
BCD_counter count1(clk, ena[1], reset, q[7:4]);
assign ena[2] = ena[1] && (q[7] && q[4]);
BCD_counter count2(clk, ena[2], reset, q[11:8]);
assign ena[3] = ena[1] && ena[2] && (q[11] && q[8]);
BCD_counter count3(clk, ena[3], reset, q[15:12]);
endmodule
module BCD_counter(
input clk,
input enable,
input reset,
output[3:0] q);
always@(posedge clk)
begin
if(reset | (enable && q == 4'b1001))
q <= 4'b0;
else if(enable && q != 4'b1001)
q <= q + 4'b1;
end
endmodule
这一题算是上一题的巩固。
8.
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
wire[3:1] enable;
CLK_counter count1(clk, ena, reset, ss);
assign enable[1] = (ss[6] && ss[4] && ss[3] && ss[0]);
CLK_counter count2(clk, enable[1], reset, mm);
assign enable[2] = (mm[6] && mm[4] && mm[3] && mm[0]) && enable[1];
CLK_conuter_hh count3(clk, enable[2], reset, hh);
assign enable[3] = (hh[4] && hh[0]) && enable[2] && enable[1];
always@(posedge clk or posedge reset)
begin
if(reset)
pm <= 1'b0;
else if(enable[3])
pm <= ~pm;
end
endmodule
module CLK_counter(
input clk,
input enable,
input reset,
output[7:0] q);
always@(posedge clk)
begin
if(reset)
q <= 8'b0;
else if(enable && q[3:0] == 4'b1001)
begin
q[3:0] <= 4'b0;
if(q[7:4] == 4'b0101)
q[7:4] <= 4'b00;
else
q[7:4] <= q[7:4] + 4'b1;
end
else if(enable)
q[3:0] <= q[3:0] + 4'b1;
end
endmodule
module CLK_conuter_hh(
input clk,
input enable,
input reset,
output[7:0] q);
always@(posedge clk)
begin
if(reset)
q <= 8'b00010010;
else if(enable && q[4] && q[1])
q <= 8'b1;
else if(enable && q[3:0] == 4'b1001)
begin
q[3:0] <= 4'b0;
q[7:4] <= 1;
end
else if(enable)
q[3:0] <= q[3:0] + 4'b1;
end
endmodule
这一题很有综合性,也很有难度(主要是某人debug小错误太多了)。
主要的问题在进制分析以及这个时钟的特点上。进制是分和秒是60进制,小时则是13进制,因为小时计数是从1到13,而每到12点就切换pm和am,搞清楚这个逻辑,题目就很清晰了。
如有错误欢迎讨论和指正。
练习网址

浙公网安备 33010602011771号