zoukankan      html  css  js  c++  java
  • 【原创】DE2实验练习解答—lab5 Clocks and Timers 【Verilog】【Digital Logic】

    本练习的主要目的是如何实现和使用一个实时时钟。

    Part I 3位BCD计数器

        设计一个3位的BCD计数器。其值按秒递增,输出显示在HEX2~0上,用KEY0复位。计数器的控制信号由50MHz的时钟提供。

    分析:

    1. 按秒递增计数,所以要把50MHz的时钟分频得到1Hz的脉冲。
    2. 3位BCD计数器,可用1位BCD计数器组合,其计数范围000~999。

    Part I 代码如下:

    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :counter10.v
    6 *Description:3-digit BCD counter
    7 *Release :06/20/2010 1.0
    8 */
    9
    10 module bcd_counter(CLOCK_50,KEY,HEX2,HEX1,HEX0);
    11 output [6:0]HEX2,HEX1,HEX0; //输出显示
    12 input CLOCK_50; //50MHz时钟
    13 input [0:0]KEY; //复位
    14
    15 wire clk_1hz; //1hz时钟信号
    16 wire [11:0]cnt; //计数器输出
    17 wire e2,e3;
    18 supply1 vdd;
    19
    20 assign e2=cnt[3]&cnt[0];
    21 assign e3=e2&(cnt[7]&cnt[4]);
    22
    23 //分频产生1hz的脉冲
    24 div u0(.o_clk(clk_1hz),
    25 .i_clk(CLOCK_50),
    26 .rst_n(KEY)
    27 );
    28
    29 //3-digit BCD计数器
    30 counter10 u1(.en(vdd),.clk(clk_1hz),.rst_n(KEY),
    31 .q(cnt[3:0])
    32 );
    33 counter10 u2(.en(e2),.clk(clk_1hz),.rst_n(KEY),
    34 .q(cnt[7:4])
    35 );
    36 counter10 u3(.en(e3),.clk(clk_1hz),.rst_n(KEY),
    37 .q(cnt[11:8])
    38 );
    39
    40 //译码显示
    41 seg7_lut h0(.oseg(HEX0),
    42 .idig(cnt[3:0])
    43 );
    44 seg7_lut h1(.oseg(HEX1),
    45 .idig(cnt[7:4])
    46 );
    47 seg7_lut h2(.oseg(HEX2),
    48 .idig(cnt[11:8])
    49 );
    50 endmodule
    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :counter10.v
    6 *Description:1-digit BCD counter
    7 *Release :06/20/2010 1.0
    8 */
    9
    10 module counter10(en,clk,rst_n,q);
    11 output reg [3:0]q;
    12 input en,clk,rst_n;
    13
    14 always@(posedge clk or negedge rst_n)
    15 begin
    16 if(!rst_n)
    17 q<=4'b0;
    18 else if(!en)
    19 q<=q;
    20 else if(q==4'b1001)
    21 q<=4'b0;
    22 else
    23 q<=q+1'b1;
    24 end
    25 endmodule
    seg7_lut.v 和 div.v 略

    Part II 时钟

        在DE2上实现一个时钟,要求用HEX7~6显示小时(0~23),用HEX5~4显示分钟(0~59),用HEX3~2显示秒钟(0~59),用SW15~0设定时间。

    分析:

    1. 基本的时钟功能,时,分,秒分别对应模24和60的计数器。
    2. 由50MHz的时钟分频得到1Hz的脉冲驱动时钟。
    3. 要能设定时间,计数器必须要加载置数的功能。

    Part II 代码如下:

    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :digitclock.v
    6 *Description:Top_level file
    7 *Release :06/20/2010 1.0
    8 */
    9
    10 module digiclock(
    11 CLOCK_50, //50MHz时钟
    12 SW,
    13 KEY,
    14 HEX2,
    15 HEX3,
    16 HEX4,
    17 HEX5,
    18 HEX6,
    19 HEX7
    20 );
    21 input CLOCK_50;
    22 input [17:0]SW;
    23 input [1:0]KEY;
    24 output [6:0]HEX2,HEX3,HEX4,HEX5,HEX6,HEX7;
    25
    26 wire clk_1hz; //1hz时钟信号
    27 wire [3:0]w_sq0;
    28 wire [3:0]w_sq1;
    29 wire [3:0]w_mq0;
    30 wire [3:0]w_mq1;
    31 wire [3:0]w_hq0;
    32 wire [3:0]w_hq1;
    33
    34 div u0(
    35 .o_clk(clk_1hz),
    36 .rst_n(KEY[0]),
    37 .i_clk(CLOCK_50)
    38 );
    39
    40 clock u1(
    41 .clk(clk_1hz),
    42 .rst_n(KEY[1]), //复位
    43 .en(SW[17]), //计数使能
    44 .load(SW[16]), //置数使能
    45 .sd0(4'b0),
    46 .sd1(4'b0),
    47 .md0(SW[3:0]), //分的个位置数
    48 .md1(SW[7:4]), //分的十位置数
    49 .hd0(SW[11:8]),//时的个位置数
    50 .hd1(SW[15:12]),//时的十位置数
    51 .sq0(w_sq0),
    52 .sq1(w_sq1),
    53 .mq0(w_mq0),
    54 .mq1(w_mq1),
    55 .hq0(w_hq0),
    56 .hq1(w_hq1)
    57 );
    58
    59 seg7_lut h2(
    60 .idig(w_sq0),
    61 .oseg(HEX2)
    62 );
    63 seg7_lut h3(
    64 .idig(w_sq1),
    65 .oseg(HEX3)
    66 );
    67 seg7_lut h4(
    68 .idig(w_mq0),
    69 .oseg(HEX4)
    70 );
    71 seg7_lut h5(
    72 .idig(w_mq1),
    73 .oseg(HEX5)
    74 );
    75 seg7_lut h6(
    76 .idig(w_hq0),
    77 .oseg(HEX6)
    78 );
    79 seg7_lut h7(
    80 .idig(w_hq1),
    81 .oseg(HEX7)
    82 );
    83
    84 endmodule
    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :clock.v
    6 *Description:A clock circuit
    7 *Release :06/20/2010 1.0
    8 */
    9 module clock(
    10 clk,
    11 rst_n,
    12 en,
    13 load,
    14 sd0, //秒的个位预置数
    15 sd1, //秒的十位预置数
    16 md0, //分的个位预置数
    17 md1, //分的十位预置数
    18 hd0, //时的个位预置数
    19 hd1, //时的十位预置数
    20 sq0, //秒的个位输出0-9
    21 sq1, //秒的十位输出0-5
    22 mq0, //分的个位输出0-9
    23 mq1, //分的十位输出0-5
    24 hq0, //时的个位输出0-9
    25 hq1, //时的十位输出0-2
    26 co //整体进位23:59:59
    27 );
    28 input clk,rst_n,en,load;
    29 input [3:0]sd0,sd1,md0,md1,hd0,hd1;
    30 output [3:0]sq0,sq1,mq0,mq1,hq0,hq1;
    31 output co;
    32
    33 wire w_clr;
    34 wire [3:0]w_md0;
    35 wire [3:0]w_md1;
    36 reg [3:0]w_hd0;
    37 reg [3:0]w_hd1;
    38 wire w_sco;
    39 wire w_mco;
    40 wire w_hco;
    41
    42 counter60 sec(
    43 .clk(clk),
    44 .rst_n(w_clr),
    45 .load(load),
    46 .en(en),
    47 .d0(sd0),
    48 .d1(sd1),
    49 .q0(sq0),
    50 .q1(sq1),
    51 .co(w_sco)
    52 );
    53 counter60 min(
    54 .clk(clk),
    55 .rst_n(w_clr),
    56 .load(load),
    57 .en(en&w_sco),
    58 .d0(w_md0),
    59 .d1(w_md1),
    60 .q0(mq0),
    61 .q1(mq1),
    62 .co(w_mco)
    63 );
    64 counter24 hour(
    65 .clk(clk),
    66 .rst_n(w_clr),
    67 .load(load),
    68 .en(en&w_sco&w_mco),
    69 .d0(w_hd0),
    70 .d1(w_hd1),
    71 .q0(hq0),
    72 .q1(hq1),
    73 .co(w_hco)
    74 );
    75
    76 assign w_clr=rst_n|co; //复位
    77 assign co=w_sco&w_mco&w_hco;
    78 assign w_md0=(!load)?0:(md0<10)?md0:9; //置数处理
    79 assign w_md1=(!load)?0:(md1<6)?md1:5;
    80
    81 always @(load or hd0 or hd1) //置数处理
    82 begin
    83 if(!load) begin
    84 w_hd0=4'b0;
    85 w_hd1=4'b0;
    86 end
    87 else begin
    88 if(hd1<=1) begin
    89 w_hd1=hd1;
    90 if(hd0<10)
    91 w_hd0=hd0;
    92 else
    93 w_hd0=4'b1001;
    94 end
    95 else begin
    96 w_hd1=4'b0010;
    97 if(hd0<4)
    98 w_hd0=hd0;
    99 else
    100 w_hd0=4'b0011;
    101 end
    102 end
    103 end
    104
    105 endmodule
    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :counter24.v
    6 *Description:A 8-bit counter (00~23)
    7 *Release :06/20/2010 1.0
    8 */
    9
    10 module counter24(
    11 clk,
    12 rst_n,
    13 load,
    14 en,
    15 d0,
    16 d1,
    17 q0,
    18 q1,
    19 co
    20 );
    21 input clk,rst_n,load,en;
    22 input [3:0]d0,d1;
    23 output reg [3:0]q1,q0;
    24 output co;
    25
    26 assign co=q1[1]&q0[1]&q0[0]; //0010_0011
    27
    28 always @(posedge clk )
    29 begin
    30 if(!rst_n)
    31 {q1,q0}<=8'h00;
    32 else if(load)
    33 begin
    34 q1<=d1;
    35 q0<=d0;
    36 end
    37 else if(en)
    38 begin
    39 if(q0==4'b1001)
    40 begin
    41 q0<=4'b0;
    42 q1<=q1+1'b1;
    43 end
    44 else if((q1==4'b0010)&&(q0==4'b0011))
    45 begin
    46 q1<=4'b0;
    47 q0<=4'b0;
    48 end
    49 else
    50 q0<=q0+1'b1;
    51 end
    52 else
    53 begin
    54 q1<=q1;
    55 q0<=q0;
    56 end
    57 end
    58
    59 endmodule
    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :counter60.v
    6 *Description:A 8-bit counter (00~59)
    7 *Release :06/20/2010 1.0
    8 */
    9
    10 module counter60(
    11 clk,
    12 rst_n,
    13 load, //置数使能
    14 en, //计数使能
    15 d0, //数据输入低4位(BCD:0-9)
    16 d1, //数据输入高4位(BCD:0-5)
    17 q0, //计数输出低4位(BCD:0-9)
    18 q1, //计数输出高4位(BCD:0-5)
    19 co //进位脉冲(bcd:59)
    20 );
    21
    22 input clk,rst_n,load,en;
    23 input [3:0]d0,d1;
    24 output reg [3:0]q0,q1;
    25 output co;
    26
    27 assign co=q1[2]&q1[0]&q0[3]&q0[0]; //0101_1001
    28
    29 always @(posedge clk )
    30 begin
    31 if(!rst_n) //复位
    32 {q1,q0}<=8'h00;
    33 else if(load) //置数
    34 begin
    35 q0<=d0;
    36 q1<=d1;
    37 end
    38 else if(en) //计数
    39 begin
    40 if(q0==4'b1001)
    41 begin
    42 q0<=4'b0;
    43 if(q1==4'b0101)
    44 q1<=4'b0;
    45 else
    46 q1<=q1+1'b1;
    47 end
    48 else
    49 q0<=q0+1'b1;
    50 end
    51 else
    52 begin
    53 q1<=q1;
    54 q0<=q0;
    55 end
    56 end
    57
    58 endmodule

    seg7_lut.v 和 div.v 略

    Part III 反应时间按测试电路

    要求:

    1. 按KEY0复位测试电路。
    2. 复位一段时间后,LEDR0亮,4位BCD计数器开始以ms为单位计数。从复位到LEDR0亮之间的时间用

       SW7~0以秒为单位设置。

     3.被测试的人看到LEDR0亮时,立即按下KEY3,LEDR0熄灭,4位BCD计数器停止计数,显示值为反应时间,在HEX3~0上。

    分析:

    1. 可将要求分为2块,一是4位BCD计数器,计数脉冲为1KHz。一是8-bit计数器,计数脉冲为1Hz。
    2. LEDR0为测试开始的信号,也是BCD计数器计数的起始,可将其与BCD计数器的计数使能连接。8-bit的计数器计数结果不用显示,只需要其计数值等于SW7~0的预置值时,计数停止。同时输出一判断是否相等的信号eq。
    3. KEY3作为测试键,也就是控制bcd计数器的计数停止与否,所以其应与eq相与,控制BCD的计数使能。

    Part III代码如下:

    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :reflex_timer.v
    6 *Description:A ciucuit for test reflex time
    7 *Release :06/20/2010 1.0
    8 */
    9
    10 //=====================top-level-file===========//
    11 module reflex_timer(
    12 CLOCK_50, //50MHz输入时钟
    13 KEY0, //2个计数器的复位
    14 KEY3, //反应时间测试键
    15 KEY1, //分频器的复位
    16 SW, //设置反应前的随机时间0-9999s
    17 HEX3,HEX2,HEX1,HEX0,//输出显示
    18 LEDR0 //测试起始的信号灯
    19 );
    20
    21 input CLOCK_50;
    22 input KEY0,KEY3,KEY1;
    23 input [7:0] SW;
    24 output [6:0]HEX3,HEX2,HEX1,HEX0;
    25 output LEDR0;
    26
    27 wire eq,en,clk_1,clk_1k;
    28 wire [3:0] q3,q2,q1,q0;
    29 //-----------------------insitiate modules------//
    30 counter_8b u0( //8-bit counter
    31 .clk(clk_1),
    32 .rst_n(KEY0),
    33 .d(SW),
    34 .eq(eq)
    35 );
    36
    37 counter_4_bcd u1( //4-digit BCD counter
    38 .en(en),
    39 .rst_n(KEY0),
    40 .clk(clk_1k),
    41 .q3(q3),
    42 .q2(q2),
    43 .q1(q1),
    44 .q0(q0)
    45 );
    46 //---------------------Decoding and disply-------//
    47 seg7_lut h0(.oseg(HEX0),
    48 .idig(q0)
    49 );
    50 seg7_lut h1(.oseg(HEX1),
    51 .idig(q1)
    52 );
    53 seg7_lut h2(.oseg(HEX2),
    54 .idig(q2)
    55 );
    56 seg7_lut h3(.oseg(HEX3),
    57 .idig(q3)
    58 );
    59 //---------------------Freguency divide---------//
    60 div #(.N(50_000_000),.M(24_999_999)) //1-Hz
    61 c0(
    62 .o_clk(clk_1),
    63 .rst_n(KEY1),
    64 .i_clk(CLOCK_50)
    65 );
    66 div #(.N(50_000),.M(24_999)) //1K-Hz
    67 c1(
    68 .o_clk(clk_1k),
    69 .rst_n(KEY1),
    70 .i_clk(CLOCK_50)
    71 );
    72
    73 assign en=(eq&KEY3); //反应时间计数器的计数使能
    74 assign LEDR0=en;
    75
    76 endmodule
    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :counter_4_bcd.v
    6 *Description:A 4-digit BCD counter
    7 *Release :06/20/2010 1.0
    8 */
    9
    10 //===============4-digit-BCD-counter============//
    11 module counter_4_bcd(
    12 en, //计数使能
    13 rst_n, //复位
    14 clk, //计数的时钟脉冲
    15 q3, //计数输出
    16 q2,
    17 q1,
    18 q0
    19 );
    20
    21 input en,rst_n,clk;
    22 output [3:0] q3,q2,q1,q0;
    23
    24 wire co0,co1,co2;
    25
    26 counter_1_bcd c0(.en(en),
    27 .rst_n(rst_n),
    28 .clk(clk),
    29 .q(q0)
    30 );
    31 counter_1_bcd c1(.en(co0),
    32 .rst_n(rst_n),
    33 .clk(clk),
    34 .q(q1)
    35 );
    36 counter_1_bcd c2(.en(co1),
    37 .rst_n(rst_n),
    38 .clk(clk),
    39 .q(q2)
    40 );
    41 counter_1_bcd c3(.en(co2),
    42 .rst_n(rst_n),
    43 .clk(clk),
    44 .q(q3)
    45 );
    46
    47 assign co0=(q0[0]&q0[3]); //q0=4'd9
    48 assign co1=(co0&(q1[0]&q1[3])); //{q1,q0}=8'd99
    49 assign co2=(co0&co1&(q2[0]&q2[3])); //{q2,q1,q0}=12'd999
    50
    51 endmodule
    52 //===============================================//
    53
    54 //===================1-digit-BCD-counter=========//
    55 module counter_1_bcd(
    56 en,
    57 rst_n,
    58 clk,
    59 q
    60 );
    61
    62 input en,rst_n,clk;
    63 output reg [3:0]q;
    64
    65 always @(posedge clk)
    66 begin
    67 if(!rst_n)
    68 q<=4'b0;
    69 else if(en) begin
    70 if(q>=4'd9)
    71 q<=4'b0;
    72 else
    73 q<=q+1'b1;
    74 end
    75 else
    76 q<=q;
    77 end
    78 endmodule
    79 //=============================================//
    80
    1 /*
    2 *(C) yf.x 2010 http://halflife.cnblogs.com
    3 *
    4 *Complier :Quartus II 9.1
    5 *Filename :counter_8b.v
    6 *Description:A 8-bit counter
    7 *Release :06/20/2010 1.0
    8 */
    9
    10 module counter_8b(clk,
    11 rst_n,
    12 d,
    13 eq
    14 );
    15
    16 input clk,rst_n;
    17 input [7:0]d;
    18 output reg eq;
    19 reg [7:0]q;
    20
    21 always @(posedge clk)
    22 begin
    23 if(!rst_n)
    24 q<=8'b0;
    25 else if(q==d)
    26 q<=q;
    27 else
    28 q<=q+1'b1;
    29 end
    30
    31 always @(q or d)
    32 begin
    33 if(q==d)
    34 eq=1;
    35 else
    36 eq=0;
    37 end
    38
    39
    40 endmodule
    1 //divider
    2 module div(
    3 output reg o_clk,
    4 input rst_n,
    5 input i_clk
    6 );
    7
    8 parameter N=50_000_000;
    9 parameter M=24_999_999;
    10
    11 reg [25:0]cnt;
    12
    13 always @(posedge i_clk or negedge rst_n)
    14 begin
    15 if(!rst_n)
    16 cnt<=26'b0;
    17 else
    18 begin
    19 if(cnt==N-1)
    20 cnt<=26'b0;
    21 else
    22 cnt<=cnt+1'b1;
    23 end
    24 end
    25 always @(posedge i_clk or negedge rst_n)
    26 begin
    27 if(!rst_n)
    28 o_clk<=0;
    29 else
    30 begin
    31 if(cnt<=M)
    32 o_clk<=1;
    33 else
    34 o_clk<=0;
    35 end
    36 end
    37
    38 endmodule

    001 

     图1 4-digit BCD计数器仿真结果

  • 相关阅读:
    linux内存的使用与page buffer (转)
    基于linux2.6.38.8内核的SDIO/wifi驱动分析(转)
    RamDisk块设备驱动实例开发讲解一
    Linux加密框架设计与实现(转)
    v4l2子系统学习心得
    一句memset引发的疑案
    linux 信号量之SIGNAL 0(转)
    可重入函数
    从ARM VIVT看linux的cache 处理
    内核抢占与preempt_count
  • 原文地址:https://www.cnblogs.com/halflife/p/1761459.html
Copyright © 2011-2022 走看看