module top_module (
input clk,
input slowena,
input reset,
output [3:0] q);
always @(posedge clk) if (reset || (q == 9 && slowena)) q <= 0; else if (slowena) q <= q + 1;
endmodule
enable이 있는 카운터의 경우, 오버플로우 초기화 조건에 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
); //
// When using always @(pos clk) to set c_load, it very slow and fail
assign c_d = 4'b1;
assign c_enable = enable;
assign c_load = reset || (enable && Q == 4'd12);
count4 the_counter (clk, c_enable, c_load, c_d, Q);
endmodule
주어진 4비트 카운터를 사용해 1부터 12까지 세는 회로다. 12일 때 load 신호를 줘 1을 로드하는 방식이다.
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;
count4 the_counter (clk, c_enable, c_load, c_d, Q);
always @(posedge clk) begin
if (reset || (enable && (Q == 4'd12))) c_load <= 1'b1;
else
c_load <= 1'b0;
end
endmodule
c_load가 reg가 되어버리면 다음 클럭에서 변하는 문제 때문에 안 되는 것 같다.
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //
wire [3:0] q0;
wire [3:0] q1;
wire [3:0] q2;
assign c_enable[0] = 1'b1;
assign c_enable[1] = q0 == 4'b1001;
assign c_enable[2] = q1 == 4'b1001 && q0 == 4'b1001;
bcdcount counter0 (clk, reset, c_enable[0], q0);
bcdcount counter1 (clk, reset, c_enable[1], q1);
bcdcount counter2 (clk, reset, c_enable[2], q2);
always @(posedge clk) begin
if (q0 == 8 && q1 == 9 && q2 == 9) OneHertz <= 1;
else if (q0 == 9 && q1 == 9 && q2 == 9) OneHertz <= 0;
end
endmodule
3개의 bcd 카운터를 이용해 1000까지 세면서 마지막 10% 듀티에 출력을 활성화하는 분주 회로이다. 899->900, 999->0에서 출력을 변화시킨다.
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
cnt ss_lower (
.clk, .reset,
.ena,
.lowval(4'h0),
.highval(4'h9),
.q(ss[3:0])
);
cnt ss_upper (
.clk, .reset,
.ena(ena && ss[3:0] == 4'h9),
.lowval(4'h0),
.highval(4'h5),
.q(ss[7:4])
);
cnt mm_lower (
.clk, .reset,
.ena(ena && ss == 8'h59),
.lowval(4'h0),
.highval(4'h9),
.q(mm[3:0])
);
cnt mm_upper (
.clk, .reset,
.ena(ena && ss == 8'h59 && mm[3:0] == 4'h9),
.lowval(4'h0),
.highval(4'h5),
.q(mm[7:4])
);
hhm hh_module (
.clk, .reset,
.ena(ena && ss == 8'h59 && mm == 8'h59),
.q(hh)
);
ampm pm_module (
.clk, .reset,
.ena(ena && ss == 8'h59 && mm == 8'h59 && hh == 8'h11),
.q(pm)
);
endmodule
module cnt (
input clk, reset, ena,
input [3:0] lowval,
input [3:0] highval,
output [3:0] q
);
always @(posedge clk) begin
if (reset || ena && q == highval) q <= lowval;
else if (ena) q <= q + 1;
end
endmodule
module hhm (
input clk, reset, ena,
output [7:0] q
);
reg [3:0] state; // 0(12) to 11(11)
always @(posedge clk) begin
if (reset || ena && state == 4'd11) state <= 4'b0;
else if (ena) state <= state + 1;
end
always @(*) begin
case (state)
4'd0: q <= 8'h12;
4'd1: q <= 8'h1;
4'd2: q <= 8'h2;
4'd3: q <= 8'h3;
4'd4: q <= 8'h4;
4'd5: q <= 8'h5;
4'd6: q <= 8'h6;
4'd7: q <= 8'h7;
4'd8: q <= 8'h8;
4'd9: q <= 8'h9;
4'd10: q <= 8'h10;
4'd11: q <= 8'h11;
endcase
end
endmodule
module ampm (
input clk, reset, ena,
output q
);
always @(posedge clk)
if (reset) q <= 1'b0;
else if (ena) q <= ~q;
endmodule
왜 이딴 문제에 솔루션을 안 주는지 모르겠다.
115959pm 다음이 120000am, 125959am 다음이 010000am이라는 잔혹한 현실이 괴로워 시간의 경우 FSM 형태로 구현하였다.