数码管的计数器

要求:
在数码管上显示类似秒表的计数器。
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
上一篇:网络编程Socket之RST详解


下一篇:Verilog上升沿检测