题目
地址:HDLBits - Exams/ece241 2014 q7b
详细:
From a 1000 Hz clock, derive a 1 Hz signal, called OneHertz, that could be used to drive an Enable signal for a set of hour/minute/second counters to create a digital wall clock. Since we want the clock to count once per second, the OneHertz signal must be asserted for exactly one cycle each second. Build the frequency divider using modulo-10 (BCD) counters and as few other gates as possible. Also output the enable signals from each of the BCD counters you use (c_enable[0] for the fastest counter, c_enable[2] for the slowest).
The following BCD counter is provided for you. Enable must be high for the counter to run. Reset is synchronous and set high to force the counter to zero. All counters in your circuit must directly use the same 1000 Hz signal.
module bcdcount (
input clk,
input reset,
input enable,
output reg [3:0] Q
);
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
);
分析
题目使用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