用Verilog实现60秒倒计时时钟

文章目录

  • 设计思路
  • 程序设计框图
  • 具体代码实现
    • 1000分频器
    • 60计数器(60Counter)
    • 二进制转BCD码转换器(HEX2BCD)
    • Controller
    • segment_decoder(数码管7段码解码器)
    • 模块整合

设计思路

因为使用nexys 4板自带的时钟信号,频率约为100000000hz,若想实现每秒计时一次,首先利用分频器将时钟频率分频成1hz的信号,每当这个1hz的输入信号改变时计时器自增1,计时器最大值为59,计时器输出的2进制信号再转换成分别表示十位和个位的BCD码再传送给控制模块,控制模块负责接受BCD码和控制两个LED轮流显示数据

程序设计框图

用Verilog实现60秒倒计时时钟_第1张图片

具体代码实现

1000分频器

module fre_div_1000(
    input clk,
    input rst,
output reg cout
);
 reg [8:0]count;//1000DIVIDER
 always@(posedge clk,posedge rst)
 if(rst==1) begin
 count<=0;
 cout<=0;
 end
 else
 if(count==499) begin
 cout<=~cout;
 count<=0;
 end
 else
 count<=count+1;
endmodule

想改变分频系数只需要改变count系数;
这里只适用于偶数分频

60计数器(60Counter)

module Counter_sixty(
input clk,
input rst,
input up,//技术模式转换
output reg [5:0]cnt
 );
 
 //variation declaration
// reg state,state_next;//1 represents up
// reg c,c_next;//show wherther up?
 
 //state logic
 always@(posedge clk,posedge rst)
 if(rst)
 cnt<=0;
 else
 if(up)//高电平上升计数
 if(cnt==60)
 cnt<=0;
 else
 cnt<=cnt+1;
 else//下降计数
 if(cnt==0)
 cnt<=60;
 else
 cnt<=cnt-1;

endmodule

二进制转BCD码转换器(HEX2BCD)

module Hex2BCD(
    input [5:0]HEX,
    output  [3:0]BCDH,
    output  [3:0]BCDL
);
 //variation declaration
 wire [7:0] A;
 wire [3:0] c1,c2,c3,c4,c5,c6,c7;
 wire [3:0] d1,d2,d3,d4,d5,d6,d7;
 
 assign A={2'b00,HEX};//standardize HEX
 assign d1={1'b0,A[7:5]};
 assign d2={c1[2:0],A[4]};
 assign d3={c2[2:0],A[3]};
 assign d4={c3[2:0],A[2]};
 assign d5={c4[2:0],A[1]};
 assign d6={1'b0,c1[3],c2[3],c3[3]};
 assign d7={c6[2:0],c4[3]};
 Converter m1(d1,c1);
 Converter m2(d2,c2);
 Converter m3(d3,c3);
 Converter m4(d4,c4);
 Converter m5(d5,c5);
 Converter m6(d6,c6);
 Converter m7(d7,c7);
 //output
 assign BCDL={c5[2:0],A[0]};
 assign BCDH={c7[2:0],c5[3]};
 
endmodule

这里包含了一个内部的转换函数converter

module Converter(
input [3:0]in,
output reg [3:0]out
    );
	 always@(in)
	 case(in)
	 4'b0000:out<=4'b0000;
	 4'b0001:out<=4'b0001;
	 4'b0010:out<=4'b0010;
	 4'b0011:out<=4'b0011;
	 4'b0100:out<=4'b0100;
	 4'b0101:out<=4'b1000;
	 4'b0110:out<=4'b1001;
	 4'b0111:out<=4'b1010;
	 4'b1000:out<=4'b1011;
	 4'b1001:out<=4'b1100;
	 default: out<=4'b0000;
	 endcase
endmodule

Controller

module Controller(
    input clk,
    input rst,
    input [3:0]H,
    input [3:0]L,
    output reg [3:0]Q,
    output reg [7:0]AN
    );
    //variation declaration
    reg state;
    reg state_next;//state reg 0 or 1;o represent low,1 represent high
    reg [3:0]Q_next;
    reg [7:0]AN_next;
    
    //FSMD state
    always@(posedge clk,posedge rst)
    if(rst==1) begin
    state<=0;
    Q<=8'H00;
    AN<=8'Hff;//全1测试
    end
    else begin
    state<=state_next;
    AN<=AN_next;
    Q<=Q_next;
    end
    
    //next state logic & output logic
    always@*
    begin
    state_next<=state;
    case(state)
    0: begin
    Q_next<=L;//output equals low 
    AN_next<=8'b11111110;//turn on the 8th led//高电平选中数码管位数
    state_next<=1;//next stage is high
    end
    1: begin
    Q_next<=H;//output equals HIGH 
    AN_next<=8'b11111101;//turn on the 7th led
    state_next<=0;//next stage is LOW
    end
    default:begin
     Q_next<=L;//output equals low 
     AN_next<=8'b11111110;//turn on the 8th led
     state_next<=1;//next stage is high
     end
     endcase
     end
     
endmodule

利用有限状态机实现,十位数和个位数分别对应0,1两个状态
这里用的是共阳极数码管

segment_decoder(数码管7段码解码器)

module Controller(
    input clk,
    input rst,
    input [3:0]H,
    input [3:0]L,
    output reg [3:0]Q,
    output reg [7:0]AN
    );
    //variation declaration
    reg state;
    reg state_next;//state reg 0 or 1;o represent low,1 represent high
    reg [3:0]Q_next;
    reg [7:0]AN_next;
    
    //FSMD state
    always@(posedge clk,posedge rst)
    if(rst==1) begin
    state<=0;
    Q<=8'H00;
    AN<=8'Hff;//全1测试
    end
    else begin
    state<=state_next;
    AN<=AN_next;
    Q<=Q_next;
    end
    
    //next state logic & output logic
    always@*
    begin
    state_next<=state;
    case(state)
    0: begin
    Q_next<=L;//output equals low 
    AN_next<=8'b11111110;//turn on the 8th led//高电平选中数码管位数
    state_next<=1;//next stage is high
    end
    1: begin
    Q_next<=H;//output equals HIGH 
    AN_next<=8'b11111101;//turn on the 7th led
    state_next<=0;//next stage is LOW
    end
    default:begin
     Q_next<=L;//output equals low 
     AN_next<=8'b11111110;//turn on the 8th led
     state_next<=1;//next stage is high
     end
     endcase
     end
     
endmodule

模块整合

module Conjugate(
    input clk,
    input rst,
    input up,
    output  [7:0] SEG,
    output  [7:0] AN
    );
    
    //varuation declaration
    wire clk1,clk2,clk3;
    wire [5:0]HEX;
    wire [3:0]BCDH;
    wire [3:0]BCDL;
    wire [3:0]BCD;
    wire [7:0]AN0;
//    wire [7:0]SEG0;
    
    //module declaration
    fre_div_1000 fre_div1(
    .clk(clk),
    .rst(rst),
    .cout(clk1)
    );//frequency divider 1
    fre_div_1000 fre_div2(
    .clk(clk1),
    .rst(rst),
    .cout(clk2)
    );//100hz
    fre_div_100 fre_div3(
    .clk(clk2),
    .rst(rst),
    .cout(clk3)
    );//1HZ
    
    Counter_sixty Counter(
    .clk(clk3),
    .rst(rst),
    .up(up), //up signal
    .cnt(HEX)
    );//60Counter
    
    Hex2BCD hex2bcd(
    .HEX(HEX),
    .BCDH(BCDH),
    .BCDL(BCDL)
    );//transform HEX to BCD
    
    Controller controller(
    .clk(clk2),
    .rst(rst),
    .H(BCDH),
    .L(BCDL),
    .Q(BCD),//check the signal
    .AN(AN)
    );//control module
    
    
    Decoder decoder(
    .BCD(BCD),
    .SEG(SEG)//output SEG
    );
    
    //output logic
 
    
endmodule

至于最后NEXYS 4板的约束文件就需要自己去添加了

你可能感兴趣的:(VIVADO)