Counters
Four-bit binary counter
重點是用always來計數。
Verilog
module top_module (
input clk,
input reset, // Synchronous active-high reset
output reg[3:0] q);
always@(posedge clk)begin
if(reset) q <= 4'b0000;
else q<= q + 4'b0001;
end
endmodule
Decade counter
重點是用always來計數,只是數到9,多一個條件。
Verilog
module top_module (
input clk,
input reset, // Synchronous active-high reset
output reg[3:0] q);
always@(posedge clk)begin
if(reset) q <= 4'b0000;
else if(q == 4'b1001) q <= 4'b0000;
else q<= q + 4'b0001;
end
endmodule
Decade counter again
重點是用always來計數,只是變成從1數到10。
Verilog
module top_module (
input clk,
input reset,
output reg[3:0] q);
always@(posedge clk)begin
if(reset) q <=4'b0001;
else if(q == 4'b1010) q<=4'b0001;
else q <= q + 4'b0001;
end
endmodule
Slow decade counter
和前一題類似,只是變成用另一個輸入計數。
Verilog
module top_module (
input clk,
input slowena,
input reset,
output reg[3:0] q);
always@(posedge clk)begin
if(reset) q <= 4'b0000;
else if(slowena)begin
if(q == 4'b1001) q<= 4'b0000;
else q <= q + 4'b0001;
end
else q <= q;
end
endmodule
Counter 1-12
原題:Counter 1-12
題目給了完整的計數器,然後要求外接控制reset和數到12。
Verilog
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 | (enable & (Q == 4'b1100));
assign c_d = 4'b0001;
count4 the_counter (clk, c_enable, c_load, c_d ,Q);
endmodule
Counter 1000
原題:Counter 1000
題目給了BCD counter,然後要連續接3個BCD counter數到1000。
Verilog
module top_module (
input clk,
input reset,
output OneHertz,
output [2:0] c_enable
); //
wire [3:0] one, ten, hundred;
wire is_ten, is_hundred;
assign is_ten = (one == 4'b1001);
assign is_hundred = is_ten & (ten == 4'b1001);
assign c_enable = {is_hundred,is_ten,1'b1};
assign OneHertz = is_hundred & (hundred == 4'b1001);
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
4-digit decimal counter
需要自己實作一個BCD,然後要將4個BCD相接,數到9999。
Verilog
module top_module (
input clk,
input reset, // Synchronous active-high reset
output [3:1] ena,
output [15:0] q);
wire is_ten , is_hundred, is_thousand;
assign is_ten = (q[3:0] == 4'b1001);
assign is_hundred = (q[7:4] == 4'b1001) & is_ten;
assign is_thousand = (q[11:8] == 4'b1001) & is_hundred & is_ten;
assign ena = {is_thousand, is_hundred, is_ten};
BCD BCD0(.clk(clk),.reset(reset),.enable( 1'b1 ),.q(q[3:0]));
BCD BCD1(.clk(clk),.reset(reset),.enable(ena[1]),.q(q[7:4]));
BCD BCD2(.clk(clk),.reset(reset),.enable(ena[2]),.q(q[11:8]));
BCD BCD3(.clk(clk),.reset(reset),.enable(ena[3]),.q(q[15:12]));
endmodule
module BCD(
input clk,
input reset,
input enable,
output reg [4:0] q);
always@(posedge clk)begin
if(reset) q <= 4'b0000;
else if(enable)begin
if(q == 4'b1001) q <= 4'b0000;
else q <= q + 4'b0001;
end
else q <= q;
end
endmodule
12-hour clock
實作一個時鐘,算是目前刷題第一次要寫很多程式。
Verilog
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
wire enas2,enam1,enam2,enah1,enah2,enapm,ld;
BCD_zero_to_nine s1( .clk(clk), .reset(reset), .enable(ena), .q(ss[3:0]));
assign enas2 = ena & (ss[3:0] == 4'b1001);
BCD_zero_to_six s2( .clk(clk), .reset(reset), .enable(enas2), .q(ss[7:4]));
assign enam1 = enas2 & (ss[7:4] == 4'b0101);
BCD_zero_to_nine m1( .clk(clk), .reset(reset), .enable(enam1), .q(mm[3:0]));
assign enam2 = enam1 & (mm[3:0] == 4'b1001);
BCD_zero_to_six m2( .clk(clk), .reset(reset), .enable(enam2), .q(mm[7:4]));
assign enah1 = enam2 & (mm[7:4] == 4'b0101);
assign ld = enah1 & (hh == 8'b0001_0010);
BCD_zero_to_nine_wload h1( .clk(clk), .reset(reset), .enable(enah1), .load(ld), .q(hh[3:0]));
assign enah2 = (enah1 & (hh[3:0] == 4'b1001)) | ld;
BCD_zero_to_one_wload h2( .clk(clk), .reset(reset), .enable(enah2), .load(ld), .q(hh[7:4]));
assign enapm = enah1 & (hh == 8'b0001_0001);
PM is_pm( .clk(clk), .reset(reset), .enable(enapm), .pm(pm));
endmodule
module BCD_zero_to_nine(
input clk,
input reset,
input enable,
output reg [3:0]q);
always@(posedge clk)begin
if(reset) q <= 4'b0000;
else if(enable)begin
if(q == 4'b1001) q <= 4'b0000;
else q <= q + 4'b0001;
end
else q <= q;
end
endmodule
module BCD_zero_to_six(
input clk,
input reset,
input enable,
output reg [3:0]q);
always@(posedge clk)begin
if(reset) q <= 4'b0000;
else if(enable)begin
if(q == 4'b0101) q <= 4'b0000;
else q <= q + 4'b0001;
end
else q <= q;
end
endmodule
module BCD_zero_to_nine_wload(
input clk,
input reset,
input enable,
input load,
output reg [3:0]q);
always@(posedge clk)begin
if(reset) q <= 4'b0010;
else if(enable)begin
if(load) q <= 4'b0001;
else if(q == 4'b1001) q <= 4'b0000;
else q <= q + 4'b0001;
end
else q <= q;
end
endmodule
module BCD_zero_to_one_wload(
input clk,
input reset,
input enable,
input load,
output reg [3:0]q);
always@(posedge clk)begin
if(reset) q <= 4'b0001;
else if(enable)begin
if(load) q <= 4'b0000;
else q <= q + 4'b0001;
end
else q <= q;
end
endmodule
module PM(
input clk,
input reset,
input enable,
output reg pm);
always@(posedge clk)begin
if(reset) pm <= 1'b0;
else if(enable) pm <= pm ^ 1'b1;
else pm <= pm;
end
endmodule