要求:
在数码管上显示类似秒表的计数器。
1按键:key1控制开始,key2控制结束。
2将数码管分为三个部分,百微秒,毫秒,秒。
想法:
分为6个模块:
第一个模块:按键(按键里面注意的就是按键消抖)
第二个模块:状态机(分为三个状态,IDLE,work,stop),从状态机引出一个control(控制信号)。
第三个模块:分频(将50M的频率分成0.01M的频率,百微秒的分频)其它的不用分,它是随着百微秒变化而变化。
第四个模块:计数,有6个计数器,每一个计数器在work状态中都工作,且每一个计数器都受到分频之后的clk控制。且后一个计数随着前一个计数变化。
第五个模块:译码模块:数码管的译码。
第六个模块:顶层模块,将各个子模块实列化。
------------------------------------------------------------------------------------------------------------------------代码:
module pro(
input clk,
input rst,
input key1,
input key2,
output key1_o,
output key2_o
);
reg key1_o5;
reg key1_o4;
reg key1_o1;
always@(posedge clk or negedge rst)
begin
if(~rst)
key1_o1<=0;
else
key1_o1<=key1;
end
reg key1_o3;
reg key1_o2;
always@(posedge clk or negedge rst)
begin
if(~rst)
key1_o2<=0;
else
key1_o2<=key1_o1;
end
always@(posedge clk or negedge rst)
begin
if(~rst)
key1_o3<=0;
else
key1_o3<=key1_o2;
end
wire pos;
always@(posedge clk or negedge rst)
begin
if(~rst)
key1_o4<=0;
else
key1_o4<=key1_o3;
end
assign pos=key1_o3&(~key1_o4);
always@(posedge clk or negedge rst)
begin
if(~rst)
key1_o5<=0;
else if(pos==1)
key1_o5<=1;
else
key1_o5<=0;
end
reg key2_o1;
reg key2_o4;
reg key2_o5;
always@(posedge clk or negedge rst)
begin
if(~rst)
key2_o1<=0;
else
key2_o1<=key2;
end
reg key2_o2;
always@(posedge clk or negedge rst)
begin
if(~rst)
key2_o2<=0;
else
key2_o2<=key2_o1;
end
reg key2_o3;
always@(posedge clk or negedge rst)
begin
if(~rst)
key2_o3<=0;
else
key2_o3<=key2_o2;
end
wire neg;
always@(posedge clk or negedge rst)
begin
if(~rst)
key2_o4<=0;
else
key2_o4<=key2_o3;
end
assign neg=(~key2_o3)&key2_o4;
always@(posedge clk or negedge rst)
begin
if(~rst)
key2_o5<=0;
else if(neg==1)
key2_o5<=1;
else
key2_o5<=0;
end
assign key1_o=key1_o5;
assign key2_o=key2_o5;
endmodule
//状态机
module snain_st(
input clk,
input rst,
input key1_o,
input key2_o,
output control
);
reg control1;
parameter IDLE=3'b001,
work=3'b010,
stop=3'b100;
reg [2:0]c_state,n_state;
always@(posedge clk or negedge rst)
begin
if(~rst)
c_state<=IDLE;
else
c_state<=n_state;
end
always@(*)
begin
n_state=IDLE;
case(c_state)
IDLE:
if(key1_o==1)
n_state=work;
else
n_state=IDLE;
work:
if(key2_o==1)
n_state=stop;
else// if(key1_o==1)
n_state=work;
stop:
if(key1_o==1)
n_state=work;
else
n_state=stop;
default: n_state=IDLE;
endcase
end
always@(posedge clk or negedge rst)
begin
if(~rst)
control1<=0;
else
case(n_state)
IDLE:control1<=0;
work:control1<=1;
stop:control1<=0;
default:;
endcase
end
assign control=control1;
endmodule
//分频
module div(
input clk,
input rst,
input control,
output [3:0]cnt1,
output [15:0]count1
);
reg [3:0]cnt1_0;
parameter N=25'd50000;
reg [15:0]count1_o;
always@(posedge clk or negedge rst)
begin
if(~rst)
count1_o<=0;
else if(count1_o==N-1'b1)
count1_o<=0;
else
count1_o<=count1_o+1;
end
always@(posedge clk )
begin
if(~rst)
cnt1_0<=0;
else if(count1==N-1'b1)
begin
if(control==1)
begin
if(cnt1_0==9)
cnt1_0<=0;
else
cnt1_0<=cnt1_0+1'b1;
end
end
end
assign cnt1=cnt1_0;
assign count1=count1_o;
endmodule
//译码
module yima(
input clk,
input rst,
input [3:0]number,
output [6:0]light
);
reg [6:0]light_o;
always@(posedge clk)
begin
if(~rst)
light_o=7'b100_0000;
else
case(number)
4'b0000:light_o=7'b100_0000;
4'b0001:light_o=7'b111_1001;
4'b0010:light_o=7'b010_0100;
4'b0011:light_o=7'b011_0000;
4'b0100:light_o=7'b001_1001;
4'b0101:light_o=7'b001_0010;
4'b0110:light_o=7'b000_0010;
4'b0111:light_o=7'b111_1000;
4'b1000:light_o=7'b000_0000;
4'b1001:light_o=7'b001_0000;
default:light_o=7'b100_0000;
endcase
end
assign light=light_o;
endmodule
//顶层
module clock_o(
input clk,
input rst,
input key1,
input key2,
output [6:0]LG,
output [6:0]LG1,
output [6:0]LG2,
output [6:0]LG3,
output [6:0]LG4,
output [6:0]LG5
);
wire control;
wire [3:0]cnt1;
wire [15:0]count1;
wire [3:0]c2,c3,c4,c5,c6;
wire key1_o,key2_o;
pro pro_inst(
.clk(clk),
.rst(rst),
.key1_o(key1_o),
.key2_o(key2_o),
.key1(key1),
.key2(key2)
);
snain_st snain_inst(
.clk(clk),
.rst(rst),
.key1_o(key1_o),
.key2_o(key2_o),
.control(control)
);
decode decode_inist(
.clk(clk),
.rst(rst),
.cnt1(cnt1),
.control(control),
.count1(count1),
.c2(c2),
.c3(c3),
.c4(c4),
.c5(c5),
.c6(c6)
);
div div_inist(
.clk(clk),
.rst(rst),
.control(control),
.count1(count1),
.cnt1(cnt1)
);
yima yima1(
.clk(clk),
.rst(rst),
.number(cnt1),
.light(LG)
);
yima yima2(
.clk(clk),
.rst(rst),
.number(c2),
.light(LG1)
);
yima yima3(
.clk(clk),
.rst(rst),
.number(c3),
.light(LG2)
);
yima yima4(
.clk(clk),
.rst(rst),
.number(c4),
.light(LG3)
);
yima yima5(
.clk(clk),
.rst(rst),
.number(c5),
.light(LG4)
);
yima yima6(
.clk(clk),
.rst(rst),
.number(c6),
.light(LG5)
);
endmodule
//激励
`timescale 1ns/1ns
module clock_o_tb();
reg clk;
reg rst;
reg key1;
reg key2;
initial
begin
rst=0;
#100 rst=1;
#100000 $stop;
end
initial
begin
clk=0;
end
initial
begin
key1=0;
# 1000 key1=1;
# 1001 key1=0;
end
initial
begin
key2=0;
#20000 key2=1;
#20001 key2=0;
end
always #10 clk<=~clk;
clock_o clock_o_out(
.clk(clk),
.rst(rst),
.key1(key1),
.key2(key2),
.LG(),
.LG1(),
.LG2(),
.LG3(),
.LG4(),
.LG5()
);
endmodule