
dsd1-10 / dsd-07=Verilog / timer-progs
.doc1. button control
module button_control(in_100, B_in, B_out);
input in_100, B_in;
output B_out;
reg [2:0] count;
wire B_out;
always @(posedge in_100)
if(~B_in) count = 3'd0; else
if(count < 3'd5) count = 3'd1 + count;
assign B_out = (count > 3'd4)? 1 : 0;
initial count = 3'd0;
endmodule
2. display
module display(CLK_100, R);
input CLK_100;
output [4:0] R;
reg [4:0] R;
wire [4:0] nR;
assign nR = ~R;
always @(posedge CLK_100)
if(~R[4]) #3.5 R = 5'b11110; else
#3.5 R = {R[3:0],R[4]};
initial R = 5'b11110;
endmodule
3. control
module control(B1, B2, in_100, Y, en, CLK_other, blink, p, zero, en_count);
input B1, B2, in_100, en;
input [1:0] zero;
output [3:0] Y;
output [1:0] blink, p, en_count;
output CLK_other;
reg [2:0] mode;
wire B1_f, B2_f, CLK_other;
wire [3:0] Y;
reg [1:0] blink, p, en_count;
wire [1:0] zero_in;
button_control one(in_100, B1, B1_f);
button_control two(in_100, B2, B2_f);
assign zero_in = (zero == 2'b11)?1 : 0;
always @(negedge B1_f or posedge zero_in)
if(zero_in & (mode == 3'd0)) mode = 3'd2; else //stop
if(~B1_f & (mode == 3'd1)) mode = 3'd3; else
if(~B1_f & (mode == 3'd5)) mode = 3'd0; else
if(~B1_f) mode = mode + 3'd1; else //start -> stop -> blink -> set_sec -> set_min -> blink
mode = mode;
//--- blink
always @(mode)
case(mode)
3'd0: blink = 2'b00;
3'd1: blink = 2'b00;
3'd2: blink = 2'b11;
3'd3: blink = 2'b01;
3'd4: blink = 2'b10;
3'd5: blink = 2'b11;
endcase
//--- p & en_count
always @(mode)
case(mode)
3'd0: begin p = 2'b00; en_count = 2'b11; end // start
3'd1: begin p = 2'b00; en_count = 2'b00; end // stop
3'd2: begin p = 2'b00; en_count = 2'b00; end // blink
3'd3: begin p = 2'b01; en_count = 2'b01; end // set sec
3'd4: begin p = 2'b10; en_count = 2'b10; end // set min
3'd5: begin p = 2'b00; en_count = 2'b00; end // blink
endcase
//--- Y
assign Y = (~en)? 4'hF : 4'bzzzz;
assign CLK_other = B2_f;
initial
begin
mode = 3'd1;
blink = 2'b00;
p = 2'b00;
en_count = 2'b00;
end
endmodule
4. counter_60
module counter_60(in_1, CLK_other, reset, en_count, out, p, en, blink, y, zero);
input in_1, CLK_other, reset, blink, en_count, p, out;
input [1:0] en;
output [3:0] y;
output zero;
wire L1, L0;
wire out0, out1, zero, z0, z1, in, nil, out;
wire [3:0] y;
divider_10 one(in, en_count, p, reset, out0, y, L0, z0);
divider_6 two(in, out0, p, reset, out, y, L1, z1);
assign zero = z0 & z1;
assign nil = (blink & in_1)? 1: 0;
assign L0 = (~en[0] & ~nil)? 0: 1;
assign L1 = (~en[1] & ~nil)? 0: 1;
assign y = (nil)? 4'hA : 4'bzzzz;
assign in = (p)? CLK_other : in_1;
assign out = (p)? out1: 0;
endmodule
5. desh
`timescale 1ns/10ps
module desh(A, Y);
input [3:0] A;
output [6:0] Y;
reg [6:0] Y;
always @(A)
case (A)
4'h0: Y = 7'b0111_111;
4'h1: Y = 7'b0001_100;
4'h2: Y = 7'b1011_011;
4'h3: Y = 7'b1101_111;
4'h4: Y = 7'b1100_110;
4'h5: Y = 7'b1101_101;
4'h6: Y = 7'b1111_101;
4'h7: Y = 7'b0000_111;
4'h8: Y = 7'b1111_111;
4'h9: Y = 7'b1101_111;
4'hF: Y = 7'b1000_000;
4'hA: Y = 7'b0000_000;
endcase
endmodule
6. divider
`timescale 1ns/10ps
module divider(CLK, out_100, out_1);
input CLK;
output out_100, out_1;
reg f_2, f_4, f_8, f_16, f_32, f_64, f_400k, f_800k, f_40kk, f_80kk;
wire f_320, f_1600, f_8k, f_40k, f_200k, out_100, f_4kk, f_20kk;
always @(posedge CLK) #3.5 f_2 = ~f_2;
always @(posedge f_2) #3.5 f_4 = ~f_4;
always @(posedge f_4) #3.5 f_8 = ~f_8;
always @(posedge f_8) #3.5 f_16 = ~f_16;
always @(posedge f_16) #3.5 f_32 = ~f_32;
always @(posedge f_32) #3.5 f_64 = ~f_64; // 0.625 Mhz
divider_5 one(f_64, f_320);
divider_5 two(f_320, f_1600);
divider_5 three(f_1600, f_8k);
divider_5 fore(f_8k, f_40k);
divider_5 five(f_40k, f_200k);
always @(posedge f_200k) #3.5 f_400k = ~f_400k;
always @(posedge f_400k) #3.5 f_800k = ~f_800k;
assign out_100 = f_800k;
divider_5 seven(f_800k, f_4kk);
divider_5 six(f_4kk, f_20kk);
always @(posedge f_20kk) #3.5 f_40kk = ~f_40kk;
always @(posedge f_40kk) #3.5 f_80kk = ~f_80kk;
assign out_1 = f_80kk;
initial
begin
f_2 = 0;
f_4 = 0;
f_8 = 0;
f_16 = 0;
f_32 = 0;
f_64 = 0;
f_400k = 0;
f_800k = 0;
f_40kk = 0;
f_80kk = 0;
end
endmodule
7. divider_5
`timescale 1ns/10ps
module divider_5(CLK, out);
input CLK;
output out;
reg f_2, f_4, f_8;
wire res, out;
reg reset;
always @(negedge CLK or posedge reset)
if(reset) #3.5 f_2 = 0; else
#3.5 f_2 = ~f_2;
always @(negedge f_2 or posedge reset)
if(reset) #3.5 f_4 = 0; else
#3.5 f_4 = ~f_4;
always @(negedge f_4 or posedge reset)
if(reset) #3.5 f_8 = 0; else
#3.5 f_8 = ~f_8;
assign #2 res = (~f_2 & ~f_4 & f_8);
always @(posedge CLK)
if(res) reset = 1; else
reset = 0;
assign out = reset;
initial
begin
reset = 0;
f_2 = 0;
f_4 = 0;
f_8 = 0;
end
endmodule
8. divider_6
`timescale 1ns/10ps
module divider_6(CLK, en_count, p, reset_counter, out, y, en, z);
input CLK, reset_counter, en, en_count, p;
output out, z;
output [3:0] y;
reg [3:0] Q;
wire out;
wire reset, f;
assign f = en_count & CLK;
always @(negedge f)
if(reset & p) Q = 4'd0; else
if(reset & ~p)Q = 4'd5; else
if(p) Q = Q + 4'd1; else
Q = Q - 4'd1;
assign #2 reset = ((Q == 4'd5) && p) || ((Q == 4'd0) && ~p) || reset_counter;
assign y = (~en)? Q: 4'bzzzz;
assign out = reset;
assign z = (Q == 4'd0);
initial
begin
Q = 4'd0;
end
endmodule
9. divider_10
`timescale 1ns/10ps
module divider_10(CLK, en_count, p, reset_counter, out, y, en, z);
input CLK, reset_counter, en, en_count, p;
output out, z;
output [3:0] y;
reg [3:0] Q;
wire out;
wire reset, f;
assign f = en_count & CLK;
always @(negedge f)
if(reset & p) Q = 4'd0; else
if(reset & ~p)Q = 4'd9; else
if(p) Q = Q + 4'd1; else
Q = Q - 4'd1;
assign #2 reset = ((Q == 4'd9) && p) || ((Q == 4'd0) && ~p) || reset_counter;
assign y = (~en)? Q: 4'bzzzz;
assign out = reset;
assign z = (Q == 4'd0);
initial
begin
Q = 4'd0;
end
endmodule
10. test
`timescale 1ms/10us
module test;
reg CLK_100, B1, B2, f_40kk, f_80kk;
wire [4:0] R;
wire [6:0] D;
wire f_4kk, f_20kk, CLK_1;
top one(CLK_100, CLK_1, B1, B2, R, D);
initial
begin
CLK_100 =0;
B1 = 0;
B2 = 0;
f_40kk = 0;
f_80kk = 0;
end
always #5 CLK_100 = ~CLK_100;
divider_5 seven(CLK_100, f_4kk);
divider_5 six(f_4kk, f_20kk);
always @(posedge f_20kk) f_40kk = ~f_40kk;
always @(posedge f_40kk) f_80kk = ~f_80kk;
assign CLK_1 = f_80kk;
initial #100000 $finish;
initial begin #103 B1 = 1; #40 B1 = 0;end
initial begin #303 B1 = 1; #40 B1 = 0;end
always #157 B2 = ~B2;
initial
begin
#1003 B1 = 1;
#105 B1 = 0;
#1003 B1 = 1;
#105 B1 = 0;
#1003 B1 = 1;
#105 B1 = 0;
#1003 B1 = 1;
#105 B1 = 0;
#1003 B1 = 1;
#105 B1 = 0;
#1003 B1 = 1;
#105 B1 = 0;
#1003 B1 = 1;
#105 B1 = 0;
end
endmodule
11. top
`timescale 1ms/10us
module top(CLK_100, CLK_1, B1, B2, R, D);
input CLK_100, CLK_1, B1, B2;
output [4:0] R;
output [6:0] D;
wire f_100, f_1, f__100, f__1, sec_p, min_p, z_s, z_m;
reg reset;
wire [3:0] y;
wire CLK_other, min_en;
wire [1:0] blink, p, en_count, zero;
wire [4:0] R;
assign f_1 = CLK_1;
assign f_100 = CLK_100;
assign zero = z_s & z_m;
assign min_en = en_count[1] & sec_p;
divider one(CLK_100, f__100, f__1);
display two(f_100, R);
desh three(y, D);
control fore(B1, B2, f_100, y, R[2], CLK_other, blink, p, zero, en_count);
counter_60 five(f_1, CLK_other, reset, en_count[0], sec_p, p[0], R[1:0], blink[0], y, z_s);
counter_60 six(f_1, CLK_other, reset, min_en, min_p, p[1], R[4:3], blink[1], y, z_m);
initial begin reset = 0; #20 reset = 1; #20 reset = 0; end
endmodule