EDA设计:序列信号发生器


前言

  本次主要介绍一下关于EDA的实验:序列信号发生器,包括两种考虑分频和不考虑分频的模12计数器型序列信号发生器、以及长度为N的序列信号发生器。


一、设计内容及原理

1.1 设计内容

  (1)基础任务:不考虑分频,设计一个计数器型序列信号发生器(12位序列信号),首先设计一个模为12的计数器,然后设计组合逻辑电路序列输出。输出是发光二极管显示输出,看看发生什么现象,为什么?
   (2)提高任务:设计一个计数器型序列信号发生器(12位序列信号),首先设计一个模为12的计数器(时钟要分频,计数器的频率),然后设计组合逻辑电路序列输出。输入是系统时钟100MHZ时钟频率(需 要分频),输出是发光二极管显示输出。
  (3)扩展任务:设计一个长度为N的序列信号发生器。首先设计模为N的计数器(时钟要分频,计数器的频率),然后设计组合逻辑电路序列输出。输入是系统时钟 100MHZ 时钟频率(需要分频),输出是发光二极管显示输出。N 由拨码开关外部给入。

1.2 设计原理

  (1)基础、提高任务:基础、提高任务均为设计一个计数器型的12位序列信号发生器,只是提高任务要求进行分频。首先设计一个模为12的计数器,位数是4位,然后将计数过程四位中的第一位和第三位进行同或运算,输出到对应的结果z中,最后硬件仿真时,对应的流水灯会根据计数过程依次循环显示对应位是否亮起,进而表示序列信号的发生。具体情况下面表格。
  (2)拓展任务:我程序中,N设置的可取2到15,硬件仿真时首先由拨码开关确定N的值,然后进行N进制的计数,将计数过程四位中的第一位和第三位进行异或运算,输出到对应的结果z中,对应的流水灯会根据计数过程依次循环显示对应位是否亮起,进而表示序列信号的发生。具体情况下面表格。

计数过程基础、提高任务:输出z扩展任务:输出z
000010
000101
001010
001101
010001
010110
011001
011110
100010
100101
101010
101101
11001
11010
11110

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

2.1 基础任务

(1)源程序:

module mod12xulie(rst,clk,z);    //声明模块名,端口信号
        input clk;       //时钟  
        input rst;     //清零端
        output reg [11:0] z; //12位的序列信号
        always@(posedge rst or posedge clk) //模12计数器   
        begin       
           if(!rst)
               led<=0;
           else if(led==11)
           begin               
               led<=0;
               z<=0;
           end   
           else begin
              led<=led+1;
              z[led]<=led[2]~^led[0];  //同或运算
           end
        end   
endmodule


(2)仿真程序:

module sim_mod12xulie;
       reg rst;
       reg clk;     
       wire[11:0] z;
       mod12xulie  u0(     //实例化序列信号发生器
       .rst(rst),   
       .clk(clk),
       .z(z)
       );
        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 J5 IOSTANDARD LVCMOS33} [get_ports {z[11]}]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {z[10]}]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {z[9]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {z[8]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {z[7]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {z[6]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {z[5]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {z[4]}]
set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {z[3]}]
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {z[2]}]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {z[1]}]
set_property -dict {PACKAGE_PIN F6 IOSTANDARD LVCMOS33} [get_ports {z[0]}]


2.2 提高任务

(1)源程序:

module mod12xulie(rst,clk,z);    //声明模块名,端口信号
        input clk;       //时钟  
        input rst;     //清零端
        output reg [11:0] z; //12位的序列信号
        reg [3: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) //模12计数器   
        begin       
           if(!rst)
               led<=0;
           else if(led==11)
           begin               
               led<=0;
               z<=0;
           end   
           else begin
              led<=led+1;
              z[led]<=led[2]~^led[0];  //同或运算
           end
        end   
endmodule


(2)仿真程序:

module sim_mod12xulie;
       reg rst;
       reg clk;     
       wire[11:0] z;
       mod12xulie  u0(     //实例化序列信号发生器
       .rst(rst),   
       .clk(clk),
       .z(z)
       );
        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 J5 IOSTANDARD LVCMOS33} [get_ports {z[11]}]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {z[10]}]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {z[9]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {z[8]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {z[7]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {z[6]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {z[5]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {z[4]}]
set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {z[3]}]
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {z[2]}]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {z[1]}]
set_property -dict {PACKAGE_PIN F6 IOSTANDARD LVCMOS33} [get_ports {z[0]}]

2.3 拓展任务

(1)源程序:

module mod(rst,clk,n,wei,b,z);  //声明模块名,端口信号
        input clk;     //时钟    
        input rst;   //清零端
        input [3:0] n; //模的取值
        output reg [14:0] z; //12位的序列信号
        output reg [7:0] b; //段选
        reg [3:0] led; 
        output reg  wei=1'b1; //位选
        reg [31:0]  sum=0;
        reg clk1=0;
        always@(*)    
        begin
            case(n)         //不同模的取值,对应数码管的显示   
               0:b=8'b00000000; 
               1:b=8'b00000000;                              
               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(n<2)
           begin               
               led<=0;
                z<=0;
           end              
           else if(led==(n-1))  //当led为n-1时,立即清零
           begin               
               led<=0;
               z<=0;
           end   
           else begin
              led<=led+1; 
              z[led]<=led[2]^led[0];  //异或运算
           end
        end
endmodule


(2)仿真程序:

module sim_mod12xulie;
       reg rst;
       reg clk;
       reg [3:0] n;
       wire[7:0] b;
       wire[14:0] z;       
       mod12xulie u0(        //实例化模n序列信号发生器
       .rst(rst),
       .clk(clk),
       .n(n),
       .z(z),
       .b(b)
       );
        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;
            #200;
            n=4'b0111;  // 模7序列信号发生器
            clk = 1'b0;
            rst = 1'b0;
            #100;
            rst = 1'b1;
            #200;          
            n=4'b1001;   // 模9序列信号发生器
            clk = 1'b0;
            rst = 1'b0;
            #100;
            rst = 1'b1;   
            #200;
            n=4'b1011;  // 模11序列信号发生器
            clk = 1'b0;
            rst = 1'b0;
            #100;
            rst = 1'b1;
            #200;            
            n=4'b1111;   // 模15计数器序列信号发生器
            clk = 1'b0;
            rst = 1'b0;
            #200;
            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 M1 IOSTANDARD LVCMOS33} [get_ports {z[14]}]
set_property -dict {PACKAGE_PIN L1 IOSTANDARD LVCMOS33} [get_ports {z[13]}]
set_property -dict {PACKAGE_PIN K6 IOSTANDARD LVCMOS33} [get_ports {z[12]}]
set_property -dict {PACKAGE_PIN J5 IOSTANDARD LVCMOS33} [get_ports {z[11]}]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {z[10]}]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {z[9]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {z[8]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {z[7]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {z[6]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {z[5]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {z[4]}]
set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {z[3]}]
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {z[2]}]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {z[1]}]
set_property -dict {PACKAGE_PIN F6 IOSTANDARD LVCMOS33} [get_ports {z[0]}] 
set_property -dict {PACKAGE_PIN H1 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]}]

三、仿真结果

3.1  基础任务

在这里插入图片描述

  结果分析:z对应显示的序列,每隔一定时间,[11:0]z从最低位依次显示最高位。如图所示,红框中是一个周期,只需看该周期的最后一列表示的高低电平,即可看出信号的发生序列,本图中可以看出是101001011010。

3.2 提高任务

在这里插入图片描述

  结果分析:与基础任务近似,只是添加了时钟分频,显示的序列和基础任务一致,为101001011010。

3.3  拓展任务

在这里插入图片描述

  结果分析:N对应不同序列的长度, N可取[2:15], z对应显示的序列。如图所示,仿真时,这里我N分别取的是3,7,9,11,15。从上面红色框中可以看出信号的发生序列。n=3时,产生的序列信号为010; n=7时,产生的序列信号为0101101; n=9时,产生的序列信号为010110100; n=11时,产生的序列信号为01011010010; n=15时,产生的序列信号为010110100101100。

四、 硬件验证

4.1 基础任务

在这里插入图片描述

  结果分析:硬件仿真时,有试验现象,流水灯显示的序列为101001011010,但是没有按照预期的进行循环显示。是因为没有进行时钟分频,时钟的频率太高,为100Mhz,led进行循环一次的时间太短,加上人眼的分辨能力有限,故无法识别,看上去是流水灯一直亮。

4.2 提高任务

在这里插入图片描述

  结果分析:硬件仿真时,流水灯显示的序列为101001011010。

4.3 拓展任务

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

  结果分析:上图是N取不同值的两个过程:第一幅图:N取9时,流水灯显示的序列为010110100;第二幅图:N取15时,流水灯显示的序列为010110100101100。

五、 问题解决

  1.问题:基础任务添加逻辑关系时,不知道如何添加。
  解决办法:最开始我是另外添加了一个always语句,只要计数过程中led(程序中定义的计数的中间变量)变化,就进行对应的逻辑运算,但是硬件仿真时,流水灯不会循环变化。后来,我直接在计数器中添加了逻辑关系,当led为11时,输出的序列z为0;否则,z[led]<=led[2]~^led[0],第0位和第2位 进行同或运算。
  2.问题:编写序列长度为N的仿真文件时,添加的n每隔一定时间,n=n+1’b1,但是仿真出来的现象和预期不符。
  解决办法:我选取了N为3,7,9,11,15的时候,进行仿真计数,同时为了观察方便,我在每一段计数过程前添加了一段清零端作用的过程,将不同N取值的序列信号隔开。
  3.问题:编写的约束文件总是显示到某一行有错误。
  解决办法:编写的约束文件时我犯过几个错误,主要有三个地方需要注意:(1)约束文件的注释符和源文件不一样,应该用##,而不是//。(2)引脚间要注意有空格。(3)端口信号是一位时,不需要用{}。例如[get_ports {wei}]是错误的,应该写成[get_ports wei]。

六、 心得体会

  在进行本次实验时,我首先从产生序列信号发生器的原理入手,明白了要先实现对应模值的计数器,然后按照一定的组合逻辑序列来显示输出。由于这里并没有对序列进行硬性规定,因此,并不需要推导组合逻辑关系,来输出特定的序列,可以自己规定逻辑关系。
  做基础任务时,编写源代码时,其中:由于序列信号长度为12,故我定义了一个4位的中间寄存器变量reg[3:0]led,来进行计数过程。其中逻辑关系我选取的是z[led]=led[2]~^led[0],led从0到11计数时,z对应位数的结果等于led的第两位和第零位的同或。然后在Vivado中进行软件仿真,顺利地出现了结果,但是硬件仿真时没有按照预期的进行循环显示,只是对应的流水灯常亮。后来发现是因为没有进行时钟分频,时钟的频率太高,为100Mhz,led进行循环一次的时间太短,加上人眼的分辨能力有限,故无法识别,看上去是流水灯一直亮。
  因此做提高任务时,我只在基础任务里添加时钟分频,进而观察EGO1板子上显示z对应的流水灯是否依次亮起,完成一次循环周期的流水灯即是序列信号的产生。
  最后我做扩展任务,设计源文件时遇到了很大的困难,不知道如何改变N,不知道如何控制输出序列的长度等等。经过一番努力,我发现N是由拨码开关确定的,可以用一个case语句,将n对应的模值输出到数码管上。确定N后,开始对应的计数,然后将计数过程的结果进行逻辑运算。后来我巧妙用了z[led],虽然z设定的是15位,但是由于N的取值,我只是选了其中对应的前N-1位,很好的控制了输出序列的长度。

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
EDA多功能信号发生器是一款基于数字信号处理技术的高端测试设备,主要用于广泛的电子设备的研发,生产和维护过程中的测试和分析。对于该设备的系统设计,需要考虑以下几个方面: 1.时基精度设计信号发生器中,时基是非常关键的,它对信号生成的稳定性和精度有着重要的影响。因此,设计时需要采取较高的分辨率ADC和DAC芯片以及高精度时钟模块。同时,为了能够提供更加丰富的信号输出模式,需要将时基板块设计的模块化,方便在需要时进行更换以满足用户不同的信号输出需求。 2.信号处理芯片设计 信号发生器的中心部件是信号处理单元,其主要功能是将用户输入的参数和控制信息转换为数字信号,并通过数字信号处理算法进行计算和处理,进而得到所需的复杂信号输出。因此,需要采用高性能的处理器和FPGA芯片进行设计,支持大量的数字信号处理算法和各种信号处理算法的快速切换,并保证输出信号的高质量和高精度。 3.用户接口设计 可操作的人机界面是信号发生器的一个非常重要的设计环节,设计得合理的人机接口可以极大地方便用户操作设备。因此,系统设计需要考虑采用一些先进的技术,如大屏幕触控显示屏,轻松的图形界面设计,智能识别等技术,从而实现操作的简单化和智能化,加快用户的操作速度和提高工作效率。 总之,EDA多功能信号发生器的系统设计需要高度规范化和先进化的设备资源和技术,以满足各种科研、教学和产业应用场景的需要,进而提高电子设备研发、生产和维护的效率和质量水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

道无方

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

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

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

打赏作者

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

抵扣说明:

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

余额充值