视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
fir滤波器的fpga实现
2025-09-29 03:08:21 责编:小OO
文档
西南科技大学

课 程 设 计 报 告

课程名称:             

设计名称:    FIR滤波器的FPGA实现        

姓    名:                   

学    号:                     

班    级:                  

指导教师:               

起止日期:  

课 程 设 计 任 务 书

学生班级:      学生姓名:         学号:        

设计名称:                                            

起止日期:           指导教师:          

"

设计要求:

利用MATLAB软件设计一数字频率10MHz的低通滤波器并用FPGA实现它,具体包括:

 1)阐述FIR的基本原理和基本结构;

2)用MATLAB软件设计3dB带宽0.2,阻带抑制≥45dB的FIR滤波器;研究不同滤波器

设计方法滤波器抽头数和滤波器平坦度、带外抑制度、过渡带宽等性能关系;选出符合要求抽头数最少的一种设计;对所设计的FIR系数进行8bit量化,并生成FPGA滤波器系数.coe文件;          

   3)采用QuartusII 或ISE等FPGA集成开发软件,通过调用IPcore设计滤波器,采用10MHz工作时钟和50MHz工作时钟两种方式分别实现2)中的滤波器功能;编写FPGA封装程序和功能测试程序;综合并比较2种设计的资源占用情况。 参考书目:数字信号处理;ISE9.X使用手册;QuartusII7.X 使用手册;软件IPcore自带pdf文档;精通MATLAB7.0

课 程 设 计 学 生 日 志

时间设计内容
11.17-11.22查阅相关资料
11.23-11.25设计系统整体方案,分析功能及指标要求
11.26-11.30完成FIR滤波器系数的设计

12.1-12.4调用Altera MegaCore实现FIR滤波器

12.5-12.7调用Altera DSP Builder实现FIR滤波器

12.8-12.9Simulink下实现FIR滤波器的算法级仿真

12.10-12.14QuartusII下仿真FIR滤波器

12.15-12.17撰写报告
12.21答辩
课 程 设 计 考 勤 表

星期一星期二星期三星期四星期五
课 程 设 计 评 语 表

"

指导教师评语:

   

成绩:                                         指导教师:                 

                                                       年   月   日

FIR滤波器的FPGA实现

一、设计目的和意义

FIR数字滤波器能够满足滤波器对幅度和相位特性的严格要求,避免模拟滤波器的温漂和噪声等问题,具有精确的线性相位、易于硬件实现和系统稳定等优点,可广泛应用于现代电子通信系统。实际信号处理应用往往要求系统兼具实时性和灵活性,而现有设计方案(如DSP)则难以同时达到这两方面要求。而使用具有并行处理特性的FPGA实现FIR滤波器,具有很强的实时性和灵活性,因此为数字信号处理提供一种很好的解决方案。

本设计使用MATLAB软件和Altera公司的FPGA开发软件QuartusⅡ进行FIR滤波器的设计仿真,该设计方案能够直观检验滤波器的设计效果,提高设计效率,缩短设计周期。

通过本次设计的主要目的在于:

1、掌握ENA设计的基本流程及方法

2、熟悉MATLAB工具箱及Simulink的使用

3、熟悉Quartus II开发环境及其使用

4、熟悉verilog HDL的使用

二、设计原理

有限长度滤波器(FIR)是线性滤波器的一种,它因原理及实现结构简单和很容易实现线性相位而在雷达、通信以及信号处理领域得到广泛应用。FPGA具有足够的硬件资源和足够的灵活性,可以几乎无限次修改验证设计和极大缩短研发周期,因而在现代电子系统设计和研发中具有无可替代的作用。

2.1  FIR滤波器的特点

有限长度滤波器(FIR)具有以下特点:

(1)系统的单位冲击响应h(n)在有限个n值处不为零;

(2)系统函数H(z)在|z|>0处只有零点,即有限z平面只有零点,而全部极点都在z=0处(因果系统);

(3)结构上主要是非递归结构,没有输出到输入的反馈;

    FIR滤波器的系统函数为:

              

2.2  FIR滤波器的基本结构

  FIR滤波器主要有:横截型(直接型,卷积型)、级联型、频率抽样型、快速卷积结构、线性相位结构; 

2.2.1 横截型

FIR滤波器的差分方程即卷积和公式,也是x(n)的延时链的横向结构,所以称为卷积型或横截型结构。按H(z)或差分方程直接画出结构图,故也称为直接型结构。横截型结构是FIR滤波器设计中应用最为普遍的一种结构,如图1所示。

图 1  FIR滤波器的横截型结构

2.2.2 级联型

将H (z)分解成实系数二阶因子的乘积形式

                                                                  

图 2  FIR滤波器的级联型结构

其中[N/2]表示取N/2的整数部分。若N为偶数,则N—1为奇数,故系数B2K中有一个为零,这是因为,这时有奇数个根,其中复数根成共轭对必为偶数,必然有奇数个实根;N为奇数时,FIR滤波器的级联结构,其中每一个二阶因子用图1的横型结构。

这种结构的每一节控制一对零点,因而再需要控制传输零点时,可以采用它。但是这种结构所需要的系数(I = 0,1,2,k,= 1,2,...,[N/2])比卷积型的系数h (n)要多,因而所需的乘法次数也比卷积型的要多。

2.2.3 频率抽样型

N个频率抽样H(k)恢复H(z)的内插公式:

图 3  FIR滤波器的频率抽样型结构

在频率抽样型结构中,调整H(k)就可以有效地调整频响特性,若h(n)长度相同,则网络结构完全相同,除了各支路增益H(k),便于标准化、模块化。有限字长效应可能导致零极点不能完全对消,导致系统不稳定,系数多为复数,增加了复数乘法和存储量。

2.2.4 快速卷积结构

只要将两个有限长序列补上一定的零值点,就可以用圆周卷积来代替两序列的线性卷积。由于时域的圆周卷积,等效到频域则为离散傅立叶变换的乘积。因而,如果即将输入x (n)补上L-N1个零值点,将有限长单位冲激响应h (n)补上L-N2个零值点,只要满足L >= N1 + N2-1,则L点的圆周卷积就能代表线性卷积,即用DFT表示,则有Y(k) =X(k)H(k),其中

  Y(k) = DFT[y (n)],L点

  X(k) = DFT[x(n)],L点

  H(k) = DFT[h (n)],L点

这样,我们就可得到快速卷积结构,当N1,N2足够长时,它比直接计算线性卷积要快得多。

2.2.5线性相位结构

FIR滤波器单位抽样响应h(n)为实数,,且满足偶对称或者奇对称,即对称中心在处,则这种FIR滤波器具有严格的线性相位。

N为奇数时,

  (4)

 N为偶数时,

 (5)

三、详细设计步骤

3.1 整体设计思路

首先使用MATLAB进行FIR滤波器的系数设计,然后在simulink中进行算法级仿真,验证设计的正确性,在Quartus II中进行门级仿真,验证硬件的正确性。

3.2 系统算法级设计及指标要求

3.2.1 FIR滤波器设计分析

分析题目要求:设计数字频率10MHz,3dB带宽0.2,阻带抑制≥45dB的FIR滤波器;由3dB带宽0.2,则知需设计通带截止频率为2MHz;由奈奎斯特定律可知阻带起始频率应大于等于1/2被的数字频率,则阻带起始频率设置为3MHz可满足;阻带衰减≥45dB,阻带衰减为65dB的FIR滤波器即可满足要求。

3.2.2 利用“Filter Designer&Analysis”设计FIR滤波器系数并导出到MATLAB工作区间

打开MATLAB软件,打开start—>ToolBoxes—> Filter Designer&Analysis,在Units框内选择“KHz”;在Fs内填写10000,即数字采样频率为10000KHz(10MHz);在Fpass内填写2000,即通带截止频率为2000KHz(2MHz);在Fstop内填写3000,即阻带起始频率为3000KHz(3MHz),Astop填65,即为阻带衰减65dB。如图4:

图 4  FIR滤波器系数设计

在“Filter Designer&Analysis”下,打开File—>Export…出现下图

图 5  导出FIR滤波器系数到MATLAB工作空间

点击“Export” 将系数导出到MATLAB工作区间。在MATLAB命令窗口输入“Num”可显示刚刚设计的浮点数系数如下:

Columns 1 through 11

   -0.0011   -0.0133   -0.0319   -0.0229    0.0248    0.0423   -0.0299   -0.0917    0.0339    0.3133    0.48

  Columns 12 through 21

    0.3133    0.0339   -0.0917   -0.0299    0.0423    0.0248   -0.0229   -0.0319   -0.0133   -0.0011

设计出的FIR滤波器的幅频及相频响应如图6:

图 6  FIR滤波器的幅频、相频响应

冲击响应如图7:

图 7  FIR滤波器的冲击响应

3.2.3 将滤波器系数进行8位量化圆整

在在MATLAB命令窗口输入“num=round(Num*(2^7))”对滤波器系数进行8位量化,量化后的系数如下:

>> num=round(Num*(2^7))

num =

  Columns 1 through 18

     0    -2    -4    -3     3     5    -4   -12     4    40    59    40     4   -12    -4     5     3    -3

  Columns 19 through 21

-4    -2     0

经过8位量化圆整后的系数的幅频相频响应如图:

图 8  FIR滤波器量化圆整后的系数的幅频相频响应

3.2.4 将系数以.coe文件输出

在MATLAB命令窗口输入:

>> freqz(num)

>> fid=fopen('D:\\work\\firdata.coe','wt');

>> fprintf(fid,'%d\\n',num);

>> fclose(fid);

在D盘的“work”文件下生成系数文件。

图 9  利用MATLAB生成.coe文件

3.3 调用DSP Builder设计FIR滤波器

在调用Altera的MegaCore之前,首先要安装Altera公司的DSP Builder工具,同时DSP Builder的版本要和Quartus II的版本一致,并且已装好MATLAB R2007b以上版本。本次课程设计用的工具为Quartus II 9.0、DSP Builder 9.0、MATLAB R2008a。

3.3.1 调用DSP Builder中的MegaCore Functions生成FIR滤波器

装好DSP Builder 9.0后,打开Simulink,就会出现Altera DSP Builder Blockset文件夹。在Altera DSP Builder Blockset文件中找到MegaCore Functions,将“fir_compiler_v9_0”拖入已建好的模型文件中,如下图10:

图 10  Altera MegaCore Functions

双击“fir_compiler_v9_0”将FIR滤波器的系数导入,如图11:

图 11  MegaCore导入FIR滤波器系数

然后生成IP Core,生成后的FIR滤波器如图12:

图 12  利用MegaCore生成的FIR滤波器

其中,reset_n是复位信号输入端口,低电平有效,ast_sink_data(7:0)是8位正弦波数据输入端口,ast_soure_ready是信源准备好信号输入端口,ast_source_data(16:0)是经FIR滤波器后的数据输出端口。加入signle compiler和时钟并连接好电路后如图13:

图 13  MegaCore电路模型图

3.3.2 使用DSP Builder设计FIR滤波器

由FIR滤波器结构可知,FIR滤波器累由乘法器和加法器组成,因此刚刚设计的FIR滤波器可由乘法器和加法器来完成。由于DSP Builder提供的Multiply Add允许输入2、3、4个整形数据,因此,上述设计的21阶FIR滤波器可由7个3输入的Multiply Add来完成。

(1)设计乘加子系统

Multiply Add的设置按照下表进行,其中Constant Values就是滤波器系数。

Table 1  Multiply Add设置参数表

参数名称Multiply AddMultiply Add1Multiply Add2Multiply Add3Multiply Add4Multiply Add5Multiply Add6
Number of Multipliers 3333333
Bus TypeSigned IntegerSigned IntegerSigned IntegerSigned IntegerSigned IntegerSigned IntegerSigned Integer
Input [number of bit].[]16161616161616
Counstant Values[0 -2 -4][-3 3 5][4 -12 4][40 59 40][4 -12 -4][5 3 -3][-4 -2 0]
乘加子系统如图14:

图 14  FIR滤波器的乘加子系统设计

配置完成后,创建乘加子系统如图15:

图 15  设计完成的乘加子系统

(2)加入正弦信号模块和Add模块

在simulink Library Browser下的Source中拖入两个Sine Wave模块,分别设置为10KHz和3.3MHz。

在simulink Library Browser下的Math Operations中找到Add模块并加入文件中。

(3)加入Input、Output、Shift Tap模块

在Altera DSP Builder Blockset中的IO&Bus找到Input、Output模块加入文件中,并设置为16位有符号整型数据。

在在Altera DSP Builder Blockset中的Storage中找到Shift Taps模块并加入文件,设置Number of Taps的参数为21。

(4)加入Bus Conversion模块

      在Altera DSP Builder Blockset中的IO&Bus找到Bus Conversion模块,加入文件中。因为每个Multiply Add的输出为34位,每两个Multiply Add需要扩展一位,因此共输出为40位。因此,Bus Conversion中的Input填40;Output填16,;由于8位量化,输出须截掉8位,因此Input Bit Connected To Output LSB填8。

(5)加入Signl Compiler模块和时钟模块

在Altera DSP Builder Blockset中的AltLab中找到Signl Compiler模块和时钟模块,加入文件中,并将时钟模块设置为100ns。

(6)加入示波器Scope模块并连接各模块

在simulink Library Browser下的sinks中找到Scope并加入文件中,将Scope设置为4通道。连接各个模块,如图16:

图 16  采用DSP Builder设计的FIR滤波器模型

3.3 Simulink下进行算法级仿真

3.3.1 Simulink下进行算法级仿真

在simulation—>Configuration Parameters设置如下图17:

图 17  simulation仿真设置

按下Ctrl+T进行仿真。

3.3.2 建立可进行硬件仿真的FIR滤波器

上述中的FIR滤波器只能在simulink下进行,如果要在硬件中运行,需要采用查表的方法输入正弦波数据,因此需要加入Increment Decrement模块和LUT模块并将电路改为下图18:

图 18  应用于硬件的FIR滤波器模型

3.4 QuartusⅡ仿真

3.4.1 生成Quartus II工程

双击signle compiler,弹出如下图19界面:

图 19  Signl Compiler

点击“compile”生成.qpf工程。

3.4.2 在QuartusII下仿真

首先打开上述生成的QuartusII工程文件,编译、建立波形文件,并设置时钟为100ns,生成网表文件后仿真。

3.5 QuartusⅡ下Test Bench仿真

3.5.1 Test Bench仿真

在quartusII下新建verilog文件,输入Test Benchverilog代码,其中,

initial

begin

trigger = 0;

i = 0;

nummismatches = 0;

on_first_change = 1'b1;

fid=$fopen("D:/work/data.txt

end

always @(Output)

begin

End

代码中fid=$fopen("D:/work/data.txt用于在D盘work文件夹下建立data.txt文件。

$fwrite(fid, "%d\\n", Output);用于写入Output数据。

3.5.2 导出Output数据使用Matlab绘图显示

在MATLAB中输入:

fid=fopen('D:\\work\\data.txt','r');

a=fscanf(fid,['%d' a '\\n'])

fid=fopen('D:\\work\\data.txt','r');

a=fscanf(fid,'%d')

fid=fopen('D:\\work\\data.txt','r');

a=fscanf(fid,['%d' a '\\n'])

plot(a)

四、设计结果及分析

4.1 simulink下算法级仿真分析

滤除低频10KHz中的3.3MHz,时钟为10M,采样率为10M,如图20:

图 20  10KHz中叠加3.3MHz正弦信号及其仿真

第一行为10KHz的正弦波,第二行为3.3MHz正弦波信号,第三行为两种频率正弦波信号的叠加,第四行为经FIR滤波器滤波后的波形。由图可知,叠加在10KHz中的3.3MHz的高频信号被滤除。以下分别是在10KHz中叠加3.3MHz、1MHz中叠加3.3MHz的情形:

图 21  20KHz中叠加3.3MHz正弦信号及其仿真

图 22  11MHz中叠加3.3MHz正弦信号及其仿真

4.2 QuartusII下时域仿真分析

QuartusII下首先使用波形文件仿真,时钟设置为100ns(10MHz),如图23:

图 23  QuartusII下FIR滤波器的时域仿真

4.3 Test Bench仿真分析

Test Bench文件由波形文件修改而来,时钟依然是100ns(10MHz),MATLAB绘图如下:

图 24  Test Bench仿真FIR并用MATLAB绘图

五、体会

通过这次课程设计,我掌握了EDA设计的基本方法和流程,同时熟悉了常用EDA工具的使用,对EDA也有了一个系统的认识。

在整个课程设计过程中,首先学习了FIR滤波器的原理、结构及实现方式,其次查找资料,以迄设计出完美的FIR滤波器。再次,通过QuartusII等EDA软件和IPCore实现FIR滤波器。整个过程大概分为两个阶段:第一阶段,FIR滤波器系数的设计。通过查找资料,我利用MATLAB下ToolBoxes中的Filter Designer&Analysis来设计滤波器的系数。这个工具可以直接输出实现要求的最小阶数的FIR滤波器系数,其中可选波纹法、窗函数法等设计方法进行设计。设计中发现,通带平坦度越好、过渡带越窄、阻带衰减越大、带外抑制度越好滤波器的阶数就越高,因此FIR滤波器的性能是与所占用的硬件资源成正相关的,设计中谋求一种既符合要求由节省硬件资源的方案。第二个阶段,FIR滤波器的实现。这个过程,查的资料最多,关键问题在于仿真和IPCore的调用。通过查找资料,使用过Modelsim、QuartusII等仿真工具,使用过Altera DSP Builder、MegaCore及Xilinx的Core generator,最终使用Altera DSP Builder完成设计。

六、参考文献

[1] 程佩青.数字信号处理教程.清华大学出版社,2007.

[2] 马建国,孟宪元.FPGA现代数字系统设计.北京:清华大学出版社,2010.

[3] 王城,薛小刚,钟信潮.FPGA/CPLD设计工具-Xilinx使用详解.中国人民邮电出版社,2005.

[4] 张威.MATLAB基础与编程入门.西安电子科技大学出版社,2008.

[5] 徐明远,邵玉斌.MATLAB仿真在通信与电子工程中的应用.西安电子科技大学出版社,2010.

七、附件:Test Bench verilog源代码

`timescale 1 ps/ 1 ps

module LowPassPro_vlg_sample_tst(

    Clock,

    clr,

    sampler_tx

);

input  Clock;

input  clr;

output sampler_tx;

reg sample;

time current_time;

always @(Clock or clr)

                                                                                

begin                                         

if ($time > 0)

 begin                                        

    if ($time == 0 || $time != current_time)  

    begin                                      

        if (sample === 1'bx)                  

            sample = 0;                       

        else                                  

            sample = ~sample;                 

    end                                          

    current_time = $time;                      

 end                                          

end                                           

assign sampler_tx = sample;

endmodule

module LowPassPro_vlg_check_tst (

    Output,sampler_rx

);

input [15:0] Output;

input sampler_rx;

reg [15:0] Output_expected;

reg [15:0] Output_prev;

reg [15:0] Output_expected_prev;

reg [15:0] last_Output_exp;

reg trigger;

integer i,fid;

integer nummismatches;

reg [1:1] on_first_change ;

initial

begin

trigger = 0;

i = 0;

nummismatches = 0;

on_first_change = 1'b1;

fid=$fopen("D:/work/data.txt

end

always @(Output)

begin

//if(ct1>1000)begin ct2 = ct2+1;end

    $fwrite(fid, "%d\\n", Output);

end

// update real /o prevs

always @(trigger)

begin

    Output_prev = Output;

end

// update expected /o prevs

always @(trigger)

begin

    Output_expected_prev = Output_expected;

end

// expected \\Output [ 15 ]

always

begin

    Output_expected[15] = 1'b0;

    Output_expected[15] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 14 ]

always

begin

    Output_expected[14] = 1'b0;

    Output_expected[14] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 13 ]

always

begin

    Output_expected[13] = 1'b0;

    Output_expected[13] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 12 ]

always

begin

    Output_expected[12] = 1'b0;

    Output_expected[12] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 11 ]

always

begin

    Output_expected[11] = 1'b0;

    Output_expected[11] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 10 ]

always

begin

    Output_expected[10] = 1'b0;

    Output_expected[10] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 9 ]

always

begin

    Output_expected[9] = 1'b0;

    Output_expected[9] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 8 ]

always

begin

    Output_expected[8] = 1'b0;

    Output_expected[8] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 7 ]

always

begin

    Output_expected[7] = 1'b0;

    Output_expected[7] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 6 ]

always

begin

    Output_expected[6] = 1'b0;

    Output_expected[6] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 5 ]

always

begin

    Output_expected[5] = 1'b0;

    Output_expected[5] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 4 ]

always

begin

    Output_expected[4] = 1'b0;

    Output_expected[4] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 3 ]

always

begin

    Output_expected[3] = 1'b0;

    Output_expected[3] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 2 ]

always

begin

    Output_expected[2] = 1'b0;

    Output_expected[2] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 1 ]

always

begin

    Output_expected[1] = 1'b0;

    Output_expected[1] = #50000 1'b1;

    #50000;

end 

// expected \\Output [ 0 ]

always

begin

    Output_expected[0] = 1'b0;

    Output_expected[0] = #50000 1'b1;

    #50000;

end 

// generate trigger

always @(Output_expected or Output)

begin

trigger <= ~trigger;

end

always @(posedge sampler_rx or negedge sampler_rx)

begin

`ifdef debug_tbench

    $display("Scanning pattern %d @time = %t",i,$realtime );

    i = i + 1;

    $display("| expected Output = %b | ",Output_expected_prev);

    $display("| real Output = %b | ",Output_prev);

`endif

    if (

        ( Output_expected_prev[0] !== 1'bx ) && ( Output_prev[0] !== Output_expected_prev[0] )

        && ((Output_expected_prev[0] !== last_Output_exp[0]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[0] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[0] = Output_expected_prev[0];

    end

    if (

        ( Output_expected_prev[1] !== 1'bx ) && ( Output_prev[1] !== Output_expected_prev[1] )

        && ((Output_expected_prev[1] !== last_Output_exp[1]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[1] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[1] = Output_expected_prev[1];

    end

    if (

        ( Output_expected_prev[2] !== 1'bx ) && ( Output_prev[2] !== Output_expected_prev[2] )

        && ((Output_expected_prev[2] !== last_Output_exp[2]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[2] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[2] = Output_expected_prev[2];

    end

    if (

        ( Output_expected_prev[3] !== 1'bx ) && ( Output_prev[3] !== Output_expected_prev[3] )

        && ((Output_expected_prev[3] !== last_Output_exp[3]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[3] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[3] = Output_expected_prev[3];

    end

    if (

        ( Output_expected_prev[4] !== 1'bx ) && ( Output_prev[4] !== Output_expected_prev[4] )

        && ((Output_expected_prev[4] !== last_Output_exp[4]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[4] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[4] = Output_expected_prev[4];

    end

    if (

        ( Output_expected_prev[5] !== 1'bx ) && ( Output_prev[5] !== Output_expected_prev[5] )

        && ((Output_expected_prev[5] !== last_Output_exp[5]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[5] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[5] = Output_expected_prev[5];

    end

    if (

        ( Output_expected_prev[6] !== 1'bx ) && ( Output_prev[6] !== Output_expected_prev[6] )

        && ((Output_expected_prev[6] !== last_Output_exp[6]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[6] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[6] = Output_expected_prev[6];

    end

    if (

        ( Output_expected_prev[7] !== 1'bx ) && ( Output_prev[7] !== Output_expected_prev[7] )

        && ((Output_expected_prev[7] !== last_Output_exp[7]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[7] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[7] = Output_expected_prev[7];

    end

    if (

        ( Output_expected_prev[8] !== 1'bx ) && ( Output_prev[8] !== Output_expected_prev[8] )

        && ((Output_expected_prev[8] !== last_Output_exp[8]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[8] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[8] = Output_expected_prev[8];

    end

    if (

        ( Output_expected_prev[9] !== 1'bx ) && ( Output_prev[9] !== Output_expected_prev[9] )

        && ((Output_expected_prev[9] !== last_Output_exp[9]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[9] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[9] = Output_expected_prev[9];

    end

    if (

        ( Output_expected_prev[10] !== 1'bx ) && ( Output_prev[10] !== Output_expected_prev[10] )

        && ((Output_expected_prev[10] !== last_Output_exp[10]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[10] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[10] = Output_expected_prev[10];

    end

    if (

        ( Output_expected_prev[11] !== 1'bx ) && ( Output_prev[11] !== Output_expected_prev[11] )

        && ((Output_expected_prev[11] !== last_Output_exp[11]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[11] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[11] = Output_expected_prev[11];

    end

    if (

        ( Output_expected_prev[12] !== 1'bx ) && ( Output_prev[12] !== Output_expected_prev[12] )

        && ((Output_expected_prev[12] !== last_Output_exp[12]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[12] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[12] = Output_expected_prev[12];

    end

    if (

        ( Output_expected_prev[13] !== 1'bx ) && ( Output_prev[13] !== Output_expected_prev[13] )

        && ((Output_expected_prev[13] !== last_Output_exp[13]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[13] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[13] = Output_expected_prev[13];

    end

    if (

        ( Output_expected_prev[14] !== 1'bx ) && ( Output_prev[14] !== Output_expected_prev[14] )

        && ((Output_expected_prev[14] !== last_Output_exp[14]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[14] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[14] = Output_expected_prev[14];

    end

    if (

        ( Output_expected_prev[15] !== 1'bx ) && ( Output_prev[15] !== Output_expected_prev[15] )

        && ((Output_expected_prev[15] !== last_Output_exp[15]) ||

            on_first_change[1])

    )

    begin

        $display ("ERROR! Vector Mismatch for output port Output[15] :: @time = %t",  $realtime);

        $display ("     Expected value = %b", Output_expected_prev);

        $display ("     Real value = %b", Output_prev);

        nummismatches = nummismatches + 1;

        on_first_change[1] = 1'b0;

        last_Output_exp[15] = Output_expected_prev[15];

    end

trigger <= ~trigger;

end

initial 

begin 

$timeformat(-12,3," ps",6);

#3000000;

if (nummismatches > 0)

    $display ("%d mismatched vectors : Simulation failed !",nummismatches);

else

    $display ("Simulation passed !");

$stop;

end 

endmodule

module LowPassPro_vlg_vec_tst();

// constants                                           

// general purpose registers

reg Clock;

reg clr;

// wires                                               

wire [15:0] Output;

wire sampler;                             

// assign statements (if any)                          

LowPassPro i1 (

// port map - connection between master ports and signals/registers   

    .Clock(Clock),

    .clr(clr),

    .\\Output (Output)

);

// Clock

always

begin

    Clock = 1'b0;

    Clock = #50000 1'b1;

    #50000;

end 

// clr

initial

begin

    clr = 1'b1;

end 

LowPassPro_vlg_sample_tst tb_sample (

    .Clock(Clock),

    .clr(clr),

    .sampler_tx(sampler)

);

LowPassPro_vlg_check_tst tb_out(

    .Output(Output),

    .sampler_rx(sampler)

);

endmodule下载本文

显示全文
专题