你的阳光 学习频道

FPGA应用实验

使用4个LED数码管显示秒计数

实验时间:2008-10-07

⒈实验设计要求

设计一个计数器,使用四个数码管显示秒计数,每秒加一。

  1. 十进制计数,从右边的数码管开始,没有前导零
  2. 到达最大值9999后,重新开始计数

⒉实验原理

⒊实验平台

FPGA的开发环境为Xilinx公司的Foundation ISE 8.1i,使用DP-FPGA实验仪,目标FPGA芯片为XC2S100-PQ208。

⒋模块设计框图

电路图

⒌Verilog模块设计

顶层 b.v


module b(SL, CLK);
    output [12:1] SL;
    input CLK;
    wire CLK_1Hz;
    wire [15:0] numbers;
    wire [3:0] blanks;
    div_1Hz u1(CLK_1Hz,CLK);
    digits u2(SL,numbers,blanks,4'b0000,CLK);
    counter10_inc u3(numbers[3:0],CLK_1Hz);
    counter10_inc u4(numbers[7:4],(numbers[3:0]==4'd0));
    counter10_inc u5(numbers[11:8],(numbers[7:4]==4'd0));
    counter10_inc u6(numbers[15:12],(numbers[11:8]==4'd0));
    assign blanks[3]=numbers[15:12]==4'd0;
    assign blanks[2]=numbers[11:8]==4'd0 && blanks[3];
    assign blanks[1]=numbers[7:4]==4'd0 && blanks[2];
    assign blanks[0]=1'b0;
endmodule

上升沿触发的十进制正向计数器 counter10_inc.v


module counter10_inc(N, CLK);
    output reg [3:0] N = 4'd0;
    input CLK;
    always @(posedge CLK) begin
        if (N==4'd9) N<=4'd0;
        else N<=N+4'd1;
    end
endmodule

32MHz到1Hz分频器 div_1Hz.v


module div_1Hz(CLK_1Hz, CLK_32M);
    output CLK_1Hz;
    input CLK_32M;
    reg [24:0] counter;
    always @(posedge CLK_32M)
        if (counter < 25'd32000000) counter <= counter+1;
        else counter <= 25'b0;
    //assign CLK_1Hz = counter < 25'd16000000;
    assign CLK_1Hz = counter[24];
endmodule

四位数码管显示 digits.v


module digits(SL, numbers, blanks, dots, CLK_32M);
    output [12:1] SL;//{SLA,SLB,SLC,SLD,SLE,SLF,SLG,SLH,SL1,SL2,SL3,SL4}
    input [15:0] numbers;
    input [3:0] blanks;
    input [3:0] dots;
    input CLK_32M;
    // ######## select digit
    reg [7:0] counter=8'b0;
    always @(posedge CLK_32M) counter <= counter+8'b1;
    wire [1:0] pos;
    assign pos=counter[7:6];
    wire [3:0] this_number;
    assign this_number=
        (pos==2'h0) ? numbers[15:12] : (
        (pos==2'h1) ? numbers[11:8] : (
        (pos==2'h2) ? numbers[7:4] : (
        numbers[3:0] )));
    wire this_blank;
    assign this_blank=
        (pos==2'h0) ? blanks[3] : (
        (pos==2'h1) ? blanks[2] : (
        (pos==2'h2) ? blanks[1] : (
        blanks[0] )));
    wire this_dot;
    assign this_dot=
        (pos==2'h0) ? dots[3] : (
        (pos==2'h1) ? dots[2] : (
        (pos==2'h2) ? dots[1] : (
        dots[0] )));
    // ######## show dot
    wire dot_seg;
    assign dot_seg=~this_dot;
    // ######## show digit
    wire [6:0] digit_seg;
    assign digit_seg=
        (this_number==4'h0) ? 7'b0000001 : (
        (this_number==4'h1) ? 7'b1001111 : (
        (this_number==4'h2) ? 7'b0010010 : (
        (this_number==4'h3) ? 7'b0000110 : (
        (this_number==4'h4) ? 7'b1001100 : (
        (this_number==4'h5) ? 7'b0100100 : (
        (this_number==4'h6) ? 7'b0100000 : (
        (this_number==4'h7) ? 7'b0001111 : (
        (this_number==4'h8) ? 7'b0000000 : (
        (this_number==4'h9) ? 7'b0000100 : (
        (this_number==4'ha) ? 7'b0001000 : (
        (this_number==4'hb) ? 7'b1100000 : (
        (this_number==4'hc) ? 7'b0110001 : (
        (this_number==4'hd) ? 7'b1000010 : (
        (this_number==4'he) ? 7'b0110000 : (
        (this_number==4'hf) ? 7'b0111000 : (
        7'b1111111 ))))))))))))))));
    // ######## refresh
    wire digit_refresh;
    assign digit_refresh=(counter[5]==counter[4]);
    assign SL[12:6]=((digit_refresh|this_blank) ? 7'b1111111 : digit_seg);
    assign SL[5]=(digit_refresh ? 1'b1 : dot_seg);
    assign SL[4:1]=(digit_refresh ? 4'b1111 :
        (pos==2'h0) ? 4'b0111 : (
        (pos==2'h1) ? 4'b1011 : (
        (pos==2'h2) ? 4'b1101 : (
        4'b1110 ))) );
endmodule

⒍实验结果分析

照片 照片

digits.v(u2)模块的RTL分析

RTL分析