EDA设计:计数器


前言

  本次主要介绍一下关于EDA的实验:计数器,包括模4计数器、模10计数器、模n计数器。


一、设计内容及原理

  (1)基础任务:设计一个4位二进制计数器,由发光二极管显示输出。
  (2)拓展任务:设计一个模10的计数器,输出结果由数码管显示.。
  (3)提高任务:设计一个模 N 的计数器,N 值可自己通过外部设定(通过外部设定N值,可以改变模值,模值由拨码开关设定,数码管显示), 模值和输出结果都由数码管显示。

二、设计过程(及设计步骤)

2.1 基础任务

(1)源程序:

module mod(rst,clk,led);    //声明模块名,端口信号
        input clk;       //时钟
        input rst;       //清零端
        output reg [2:0] led; 
        reg [31:0]  sum;
        reg clk1;
        always@(posedge rst or posedge clk)  //时钟分频  
        begin            
           if(!rst)
           begin
              sum<=0;
              clk1<=0;
           end         
           else if(sum==50000000)   //分频50M次
           begin
              clk1<=~clk1;  //时钟翻转
              sum<=0;     //sum清零
           end
           else
               sum<=sum+1'b1; //sum累加直至50M
        end  
        always@(posedge rst or posedge clk1) //模4计数器   
        begin       
          if(!rst)
                led<=0;
           else if(led==3)     //当led为3时,立即清零
                 led<=0;
           else 
                 led<=led+1;  //led累加计数,表示0到3
        end             
endmodule

(2)仿真程序:

module sim_mod;
       reg rst;
       reg clk;
       wire[2:0] led;
       mod u0(           //实例化模4计数器
       .rst(rst),
       .led(led),
       .clk(clk)
       );
        parameter PERIOD = 10;   //参数声明,并赋值为10
        always 
        begin            //每隔5,时钟翻转一次
          clk = 1'b0;
           #(PERIOD/2) clk = 1'b1;
           #(PERIOD/2);
        end
        initial 
        begin         //对clk,rst进行赋值
            clk = 1'b0; 
            rst = 1'b0;    
            #100;
            rst = 1'b1;
         end       
 endmodule

(3)约束程序:

set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports clk ]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports rst ]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {led[2]}]

2.2 提高任务

(1)源程序:

module mod(rst,clk,wei,b);   //声明模块名,端口信号
        input clk;        //时钟
        input rst;       //清零端
        output reg  wei=1'b1;  //位选
        output reg [7:0] b;   //段选
        reg [3:0] led; 
        reg [31:0] sum=0;
        reg clk1=0;
        always@(posedge rst or posedge clk)    //时钟分频
        begin        
           if(!rst)
           begin
              sum<=0;
              clk1<=0;
           end         
           else if(sum==50000000) //分频50M次
           begin
              clk1<=~clk1;  //时钟翻转
              sum<=0;   //sum清零
           end
           else
               sum<=sum+1'b1; //sum累加直至50M
        end  
        always@(posedge rst or posedge clk1)    //模10的计数器
        begin       
          if(!rst)
                led<=0;
           else if(led==9)  //当led为9时,立即清零
                 led<=0;
           else 
                 led<=led+1;  //led累加计数,表示0到9
        end 
        always@(led)    
        begin
            case(led)   //led输入不同的值时,对应数码管的输出
               0:b=8'b11111100;
               1:b=8'b01100000;
               2:b=8'b11011010;
               3:b=8'b11110010;
               4:b=8'b01100110;
               5:b=8'b10110110;
               6:b=8'b10111110;
               7:b=8'b11100000;
               8:b=8'b11111110;
               9:b=8'b11110110;
            endcase
        end          
endmodule

(2)仿真程序:

module sim_mod;
       reg rst;
       reg clk;     
       wire[7:0] b;
       modn u0(     //实例化模10计数器
       .rst(rst),   
       .b(b),
       .clk(clk)
       );
        parameter PERIOD = 10;   //参数声明,并赋值为10
        always 
        begin            //每隔5,时钟翻转一次
          clk = 1'b0;
           #(PERIOD/2) clk = 1'b1;
           #(PERIOD/2);
        end
        initial 
        begin        //对clk,rst进行赋值
            clk = 1'b0;
            rst = 1'b0;
            #100;
            rst = 1'b1;
         end        
endmodule

(3)约束程序:

set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports clk ]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports rst ]
set_property -dict {PACKAGE_PIN C1 IOSTANDARD LVCMOS33} [get_ports wei]  
set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {b[7]}]  
set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {b[6]}]  
set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {b[5]}]
set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports {b[4]}]
set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports {b[3]}]
set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {b[2]}]
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {b[1]}]
set_property -dict {PACKAGE_PIN D5 IOSTANDARD LVCMOS33} [get_ports {b[0]}]

2.3 拓展任务

(1)源程序:

module mod(rst,clk,n,wei,wei1,led,b,a);  //声明模块名,端口信号
        input clk;     //时钟    
        input rst;   //清零端
        input [3:0] n; //模的取值
        output reg  wei=1'b1; //位选
        output reg  wei1=1'b1; //位选
        output reg [7:0] b;   //段选,显示模
        output reg [7:0] a;   //段选,显示计数过程
        output reg [3:0] led; 
        reg [31:0]  sum=0;
        reg clk1=0;
        always@(*)    
        begin
            case(n)         //不同模的取值,对应数码管的显示                                    
               2:b=8'b11011010;
               3:b=8'b11110010;
               4:b=8'b01100110;
               5:b=8'b10110110;
               6:b=8'b10111110;
               7:b=8'b11100000;
               8:b=8'b11111110;
               9:b=8'b11110110;
               10:b=8'b11101110;
               11:b=8'b00111110;
               12:b=8'b10011100;
               13:b=8'b01111010;
               14:b=8'b10011110;
               15:b=8'b10001110;
             endcase
          end    
        always@(posedge rst or posedge clk)    //时钟分频
        begin        
           if(!rst)
           begin
              sum<=0;
              clk1<=0;
           end         
           else if(sum==50000000) //分频50M次
           begin
              clk1<=~clk1;  //时钟翻转
              sum<=0;   //sum清零
           end
           else
               sum<=sum+1'b1; //sum累加直至50M
        end 
        always@(posedge rst or posedge clk1)     //模n计数器
        begin       
          if(!rst)
                led<=0;
           else if(led==(n-1))  //当led为n-1时,立即清零
                 led<=0;
           else 
                 led<=led+1;     //led累加计数,表示0到n-1
        end 
        always@(led)    
        begin
            case(led)        //led输入不同的值时,对应数码管的输出
               0:a=8'b11111100;
               1:a=8'b01100000;
               2:a=8'b11011010;
               3:a=8'b11110010;
               4:a=8'b01100110;
               5:a=8'b10110110;
               6:a=8'b10111110;
               7:a=8'b11100000;
               8:a=8'b11111110;
               9:a=8'b11110110;
              10:a=8'b11101110;
              11:a=8'b00111110;
              12:a=8'b10011100;
              13:a=8'b01111010;
              14:a=8'b10011110;
              15:a=8'b10001110;
            endcase
        end          
endmodule

(2)仿真程序:

module sim_mod;
       reg rst;
       reg clk;
       reg [3:0] n;
       wire[3:0] led;
       wire[7:0] b;
       wire[7:0] a;
       mod u0(        //实例化模n计数器
       .rst(rst),
       .clk(clk),
       .n(n),
       .led(led),
       .b(b),
       .a(a)
       );
        parameter PERIOD = 10;   //参数声明,并赋值为10
        always 
        begin            //每隔5,时钟翻转一次
          clk = 1'b0;
           #(PERIOD/2) clk = 1'b1;
           #(PERIOD/2);
        end
        initial 
        begin            //不同n的取值对应的计数器
            n=4'b0011;  // 模3计数器
            clk = 1'b0;   
            rst = 1'b0;
            #100;
            rst = 1'b1;
            #100;
            n=4'b0111;  // 模7计数器
            clk = 1'b0;
            rst = 1'b0;
            #100;
            rst = 1'b1;
            #100;
            n=4'b1001;   // 模9计数器
            clk = 1'b0;
            rst = 1'b0;
            #100;
            rst = 1'b1;   
            #100;
            n=4'b1111;   // 模15计数器
            clk = 1'b0;
            rst = 1'b0;
            #100;
            rst = 1'b1;                                  
         end       
endmodule

(3)约束程序:

set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports clk ]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports rst ]
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports {n[0]}]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports {n[1]}]
set_property -dict {PACKAGE_PIN M4 IOSTANDARD LVCMOS33} [get_ports {n[2]}]
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {n[3]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN H1 IOSTANDARD LVCMOS33} [get_ports wei] 
set_property -dict {PACKAGE_PIN G1 IOSTANDARD LVCMOS33} [get_ports wei1] 
set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {b[7]}]  
set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {b[6]}]  
set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {b[5]}]
set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports {b[4]}]
set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports {b[3]}]
set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {b[2]}]
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {b[1]}]
set_property -dict {PACKAGE_PIN D5 IOSTANDARD LVCMOS33} [get_ports {b[0]}]
set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33} [get_ports {a[7]}]
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports {a[6]}]
set_property -dict {PACKAGE_PIN D3 IOSTANDARD LVCMOS33} [get_ports {a[5]}]
set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33} [get_ports {a[4]}]
set_property -dict {PACKAGE_PIN F3 IOSTANDARD LVCMOS33} [get_ports {a[3]}]
set_property -dict {PACKAGE_PIN E2 IOSTANDARD LVCMOS33} [get_ports {a[2]}]
set_property -dict {PACKAGE_PIN D2 IOSTANDARD LVCMOS33} [get_ports {a[1]}]
set_property -dict {PACKAGE_PIN H2 IOSTANDARD LVCMOS33} [get_ports {a[0]}]

三、仿真结果

3.1  基础任务(模4计数器)

在这里插入图片描述

  结果分析:led对应亮起的灯。如图所示,100ns之前对应的是清零端起作用的情况,led恒为0。100ns之后对应的是模4计数器,有4种情况,000,001,010,011,依次进行循环。

3.2 提高任务(模10计数器)

在这里插入图片描述

  结果分析:8位b对应亮起的数码管的数字。如图所示,100ns之前对应的是清零端起作用的情况,led恒为0。100ns之后对应的是模10计数器,有10种情况,从0到9,数字依次进行循环。

3.3  拓展任务(模n计数器)

在这里插入图片描述
在这里插入图片描述

  结果分析:n对应不同模的取值,模n可取[2:15],b对应模n的显示,a对应计数过程中数字的变化过程。如图所示,仿真时,这里我模n分别取的是3,7,11,15。从上面红色框中可以看出led的变化过程。n=3时,led从0到2,数字依次进行循环; n=7时,led从0到6,数字依次进行循环; n=11时,led从0到10,数字依次进行循环; n=15时,led从0到14,数字依次进行循环。

四、 硬件验证

4.1 基础任务

在这里插入图片描述
在这里插入图片描述
  结果分析:硬件仿真时, led依次显示000,001,010,011,和预期结果相符。上图是其中的两个过程,显示001,011。

4.2 提高任务

在这里插入图片描述
在这里插入图片描述
  结果分析:硬件仿真时,数码管依次显示0到9。上图是其中的两个过程,数码管显示3,8。

4.3 拓展任务

在这里插入图片描述
在这里插入图片描述
  结果分析:硬件仿真时,上图数码管的左边显示模的大小(n可取2到15),由拨码开关确定;上图数码管的右边,显示计数的过程。经过试验,和预期结果相符。上图是其中的两个过程:第一幅图:模取7时,数码管显示计数过程1;第二幅图:模取9时,数码管显示计数过程5。

五、 问题解决

  1.问题:基础任务进行硬件仿真时,没有显示错误,但是没有现象。
  解决办法:需要添加时钟分频,确保每经过一定时间后,计数过程进行一次变化,也就是led变化一次。
  2.问题:编写模n的仿真文件时,添加的n每隔一定时间,n=n+1’b1,但是仿真出来的现象和预期不符。
  解决办法:我选取模n为3,7,9,11的时候,进行仿真计数,同时为了观察方便,我在每一段计数过程前添加了一段清零端作用(led恒为0)的时候。
  3.问题:做提高任务时,仿真结果计数过程循环亮,但是显示模值的数码管没有显示
  解决办法:经检查约束文件,发现是定义两位位选(wei,wei1)时,只连接了wei1,忘记定义wei对应连接的管脚了。

六、 心得体会

  在进行本次实验时,我一开始是按照书上的程序进行编写基础任务的,编写仿真文件时,在#10后的程序总是灰色的,而且仿真出来的结果总是恒定的红线或者蓝线。由于仿真程序中//是注释符,约束程序中的#是注释符,我从这一点发现了端倪,发现是将仿真程序放到了约束文件中,真是太崩溃了。
  后来软件仿真成功后,和预期结果相符,硬件仿真时也没有错误,但是就是没有实验现象。后来查阅资料,发现是时钟的频率太高,为100Mhz,led进行循环时,人眼的分辨能力有限,无法识别,需要进行时钟分频。
  做提高任务时,和基础任务没有什么区别,只是将输出由led变为了数码管,然后将模4计数变成了模10计数。
  最后做扩展任务时,设计源文件时遇到了很大的困难,不知道如何改变模,不知道如何同时显示两位不同数码管的输出等等。经过一番努力,发现n是由拨码开关确定的,用一个case语句,将n对应的模值输出到数码管上。确定n后,开始对应的计数,然后将计数的过程输出到数码管上。这里,表示两位不同数码管的显示时,我用了两组数码管分别表示模的大小以及计数的过程,最后成功做出来了,真是太不容易了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道无方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值