实验二 频率计 - 图文

更新时间:2024-05-16 05:13:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实验二 Xilinx_ISE 软件使用与数字系统设计相关实验

一、 实验目的

1. 学习并理解 利用Xilinx IP核生成应用系统的原理。 2. 学习并理解 Xilinx DDS核和除法器核。 3. 学习并理解 波形发生器原理。 4. 学习并理解频率计的原理。

二、 实验条件

PC机

Xilinx ISE13.1 软件 USB下载线

Digilent Adept软件(2.0或更新版) Xilinx大学计划开发板Basys2

三、 预习要求

阅读实验原理及参考资料,了解利用Xilinx IP核生成应用系统的原理,学习Xilinx DDS核和除法器核实现的基本原理,了解Xilinx DDS核和除法器核的基本用法,学习并理解利用可编程器件实现波形发生器与频率计的原理,

四、 实验原理

1. Xilinx IP core基本操作

IP Core就是预先设计好、经过严格测试和优化过的电路功能模块,如乘法器、FIR滤波器、PCI接口等,并且一般采用参数可配置的结构,方便用户根据实际情况来调用这些模块。随着FPGA规模的增加,使用IP core完成设计成为发展趋势。

IP Core生成器(Core Generator)是Xilinx FPGA设计中的一个重要设计工具,提供了大量成熟的、高效的IP Core为用户所用,涵盖了基本单元、调试与验证、FPGA结构与特征、标准总线接口、数字信号处理、视频与图像处理、汽车与工业、通信、无线等大类,从简单的基本设计模块到复杂的处理器一应俱全。能够大幅度减轻设计人员的工作量,提高设计可靠性。

Core Generator最重要的配置文件的后缀是.xco,既可以是输出文件又可以是输入文件,包含了当前工程的属性和IP Core的参数信息。

启动Core Generato有两种方法,一种是在ISE中新建IP类型的源文件,另一种是双击运行[开始] [程序] [Xilinx ISE 9.1i] [Accessories] [Core Generator]。限于篇幅,本节只以调用加法器IP Core为例来介绍第一种方法。

在工程管理区单击鼠标右键,在弹出的菜单中选择New Source,选中IP类型,在File Name文本框中输入adder(注意:该名字不能出现英文的大写字母),然后点击Next按键,进入IP Core目录分类页面,如图4-13所示。

4.1. 直接数字式频率合成-DDS原理

直接数字式频率合成( Direct Digital Frequency synthesis, 简称 DDS) 相对于直接频率合成( DS) 和锁相频率合成( PLL) 等频率合成方式具有频率转换时间短, 频率,相位和幅度均可程序控制以及频率分辨率高和稳定度好、实现方便灵活等优点。因此利用DDS 芯片或 FPGA 进行设计,可以简化设计流程、 提高设计效率。随着集成电路工艺水平的飞速发展, DDS 技术已在工程中得到了广泛应用。

图 1是 DDS的基本原理图。在每个 fclk 到来时, 相位累加器将上一时钟周期的累加结果和频率增量Δθ( 频率控制字) 进行累加, 累加结果的高位作为正/ 余弦查表( LU T )的地址, 输出对应地址上的波形数据 sin(θ( n) ) 或cos(θ(n) ) , 由外部数模转换器 DA C针对所生成的数字信号重构波形, 经低通滤波后输出平滑的模拟信号波形。

DDS的输出频率为:

θ

f out =Δθ f clk / 2B(n ) ( 1) 频率分辨率为:

θ

Δf = f clk / 2B(n ) ( 2)

传统基于FPGA 的 DDS设计方法是利用硬件描述语言 VHDL 或 Verilog 来设计相位累加器、 LUT ( 数据查表)以及控制逻辑。此方式程序代码量较大、 设计效率偏低且使用较多 FPGA 资源。基于 Xilinx 公司系列 FPGA IP CORE 的 DDS 设 计方 法, 直 接从 CoreGenerator 中调用 DDS IP CORE 即可实现DDS 核心功能,无需编写内部代码,设计简单方便。

4.2. FPGA IP CORE

Core Generator 是Xilinx 公司系列FPGA 集成开发环境 ISE的子设计工具, 其将原有重复使用的设计思路或方法模块化、 集成化、 标准化后进行封装 IP CORE, 供以后设计直接使用。Core Generator 中的所有 IP CORE 都是Xilinx 以及第三方合作伙伴提供并经过验证的, 其中有些复杂的 IP CORE 需要另行付费才能使用, 绝大部分简单IP 只要有集成开发环境 ISE 使用授权就可以使用。为保护知识产权, 所有 IP 都不公开内部代码, 只提供外部接口定义和操作技术文档。

4.3. Xilinx DDS核

图 2 是启动 ISE Core Generator 调用的 DDS IPCORE 界面1。在设置选项中 DDS Clock Rate( DDS时钟)、Frequency Resolution( 频率分辨率)、 输出数据宽度要设定固定值; Out put Frequency( 输出频率) 是可编程的, 只需设置初始值。Core Generator 会根据 DDS 时钟和频率分辨率自动配置累加器数据宽度和数据表深度。 图 3为 DDS IP CORE模块外部接口定义。模块定义了输入端口(DAT A)和输出端口( SINE、 COSINE) 、 地址端口( A) 、 时钟使能端口( CE)、 RDY 和 RFD 握手信号( 可选) 、 SCLR (同步清零端, 可选) 、 CHANNEL ( 输出通道指示, 用于多通道 DDS) 。

图 2 ISE DDS IPCORE使用界面

图 4为单通道 DDS 时序图。模块在 CE 为‘0’ ( 无效) 、 WE 为‘1’ 时, 分别将相位增量( 频率控制字) 和初始相位( PHASE OFFSET )读入, 在CE 有效(CE 为‘1’ ) 后的一个时钟周期内输出DDS 数据,同时RDY 有效。

4.3.1 频率调节

通过修改DDS 的控制字即可实现输出频率的调节,本电路设计的频率输出范围为 300~ 600 Hz, DDS 时钟 f clk为 10 MHz, 由外部有源 50 MHz晶振提供, 经FPGA 内部5分频得到, DDS相位累加器宽度B?? (n) 为28 bits。根据式( 1 ) , 可计 算出相应的频率 控制字范围为 8053110 ~16106110 ,由 DSP 将控制字发送给 FPGA 实现频率的调节。据式( 2) 可知, 本设计的频率分辨率为 0. 04 Hz。 4.3. 2 相位调节

由于本例中IP CORE 的密封性, 不能实现对直接累加寄存器 D2的操作, 通常通过改变累加寄存器的状态来实现相位调节的方法不适合本设计。考虑到 DDS 时钟 f clk也是影响相位的因素, 本设计采用“吞时钟”方法来实现对信号相位的调节。FPGA 中实现“吞时钟”调相的原理如图 5所示。

用 DDS 数据输出最高位 S INE( 7) 采用边沿触发方式触发DSP 中断 INT 0, 分频时钟Cclk 触发DSP 中断INT 1。DSP 在 INT 0相邻两次中断时间内,对 Cclk进行计数得到一个波形周期内计数值 N360 , 此数值对应相位为 360°。0~ 360°之间的任意相位θ对应的计数值 Nθ可以由此得到。当调整相位时, DSP将 Nθ写至 FPGA 中定义的预置减法计数器, 计数器开始计数, 当计数器输出 Qn ~ Q0 不全为零时,与门A1输出为‘0’ , DDS停止运行;当计数输出Qn ~ Q0全为零时, 计数器停止计数, 等待下一次预置值, 与门A1输出 fclk= Cclk, DDS继续运行, 此时波形相位已延迟了 θ 。 本设计相位分辨率为 0. 02° 。 4.3. 3 幅度调节

输出波形的重构与幅度调节是通过双通道 DAC 芯片TLC7528实现的,原理图如图 6 所示。DAC 采用直通模式( 使能 CS信号和写WR 信号已经接地) , 通道 A 的输出作为通道 B的参考电压来控制通道 B的输出幅度。通道A、 B 根据通道选择信号 select 分时使用总线 DB, 其VHDL 语言描述为:

DB< = Sine when ( select = %1 %) else ( others = >Amp) , ( Amp为通道 A 输出幅度值) 。通道 A 的参考电压为+ 5 V, 电压调节分辨率为 5/ 255 &0. 02 V, 即通道 B 波形幅度控制精度为0. 02 V。

4.4. 直接测频方法

常用的直接测频方法主要有测频法和测周期法两种。

测频法就是在确定的闸门时间 Tw 内,记录被测信号的变化周期数(或脉冲个数)Nx,则被测信号的频率为:fx=Nx/Tw。

测周期法需要有标准信号的频率 fs,在待测信号的一个周期Tx内,记录标准频率的周期数 Ns,则被测信号的频率为:fx=fs/Ns。

这两种方法的计数值会产生±1个字误差,并且测试精度与计数器中记录的数值 Nx或 Ns有关。为了保证测试精度,一般对于低频信号采用测周期法;对于高频信号采用测频法。本实验采用的是测频法。

首先给出闸门开启信号(预置闸门上升沿),此时计数器并不开始计数,而是等到被测信号的上升沿到来时,计数器才真正开始计数。

然后预置闸门关闭信号(下降沿)到时,计数器并不立即停止计数,而是等到被测信号的上升沿到来时才结束计数,完成一次测量过程。可以看出,实际闸门时间τ与预置闸门时间τ并不严格相等,但差值不超过被测信号的一个周期

设在一次实际闸门时间τ中计数器对被测信号的计数值为 Nx,对标准信号的计数值为 Ns。 标准信号的频率为 fs,则被测信号的频率为

fx?Nxfs Ns (1)

由式(1)可知,若忽略标频 fs的误差,则等精度测频可能产生的相对误差为

??|fxc?fx|?100% fxe (2)

其中 fxe为被测信号频率的准确值。 在测量中,由于fx 计数的起停时间都是由该信号的上升测触发的,在闸门时间τ内对 fx 的计数Nx 无误差(τ=NxTx);

对 fs的计数Ns最多相差一个数的误差,即|ΔNs|≤1,其测量频率为

fxe?Nxfs

Ns??Ns (3)

将式(1)和(3)代入式(2),并整理得:

δ=|ΔNs|/Ns≤1/Ns=1/(τ2fs)

??|?Ns|11??fs NsNs?由上式可以看出,测量频率的相对误差与被测信号频率的大小无关,仅与闸门时间和标准信号频率有关,即实现了整个测试频段的等精度测量。 闸门时间越长,标准频率越高,测频的相对误差就越小。

标准频率可由稳定度好、精度高的高频率晶体振荡器产生,在保证测量精度不变的前提下,提高标准信号频率,可使闸门时间缩短,即提高测试速度。

为了减少运算,本实验将闸门时间设置为 1s,那么所测频率Fx = Nx, 即只要在1s 内对所测信号的周期进行计数即可. 4.5 实验步骤举例

1) 点击WINDOWS 桌面上的ISE图标,双击打开。

2) 如果第一次使用会出现一个启动说明,可取消。然后点击左上角的标题栏,点击

File-> New Project ,输入工程名称 freq。

3) 选择对应开发板的上FPGA的器件,封装,速度等级。

4) 新建好工程后,在Project选项中选择Add Source,添加top.v、 freq.v、

data_process1.v 、data_process2.v、test_wave.v和 2 个 IP 核gen_dds.xco 及 freq_chufaqi_2.xco。

工程主要包括 4个模块:生成测试信号模块 test_wave、 计算最大值和最小值模块data_process1、波形转化模块 data_process2以及频率计计算并译码显示模块 freq。

系统管脚定义 input clk, input reset, input switch,

output [6:0] segdat, output [3:0] sl, output dp

Test_wave模块:

生成三角波和利用DDS生成正弦波,位数为12bit (可自行设置); 利用系统提供的IP核DDS生成gen_dds.xco,在输入时钟信号clk,复位信号reset与控制选择信号switch的控制下生成正弦波与三角波;信号输出为12位数据data_out。

Freq 模块:

生成闸门信号1s,对输入波形的频率做计数计算,并译码显示。 在输入时钟信号clk,复位信号reset的控制下, 对输入信号clk_test进行计数,生成计数信号en,生成闸门信号1s---second,在闸门信号内对输入波形的频率计数进行处理,产生计数结果,并生成输出信号en_out与数码管显示控制信号[3:0] sl,与数码管7段分段数据控制信号[6:0] segdat 。

input clk, input reset,

input clk_test, output en_out, output [6:0] segdat

output [3:0] sl, 注意: 置低有效!

Data_process1 模块:

计算输入波形的最大值和最小值;

在输入时钟信号clk,复位信号reset, 输入使能信号enable的控制下,对输入信号[11:0] data_in进行计数,在当前闸门周期,产生输入波形的最大值[11:0]data_max_out和最小值[11:0] data_min_out作为输出信号供给data_process2模块使用;

input clk, input reset, input enable,

input [11:0] data_in,

output reg[11:0] data_max_out, output reg[11:0] data_min_out

Data_process2 模块:

input clk, input reset, input enable,

input [11:0] data_in, input [11:0] data_max, input [11:0] data_min, output test_clk

将输入波形的数据做处理,转化为脉冲波的形式以便计数;

在输入时钟信号clk,复位信号reset, 输入使能信号enable的控制下,对输入信号[11:0] data_in根据输入数据 [11:0] data_max和 [11:0] data_min产生输出信号test_clk供给Freq 模块使用;

5) 利用系统提供的IP核DIVIDER生成gen_dds.xco和freq_chufaqi_2.xco,

6) 添加完文件我们可以从原文件窗口看到被添加的文件,如下图所示。

7) 进行综合后可得整个工程的电路模块连接图。 4.6 实验仿真

为了更快地仿真,将闸门信号设为设为 0.01s,输入波形正弦波其频率为1000hz,则输出频率为10hz。

4.6.1 Test_wave模块

生成三角波和利用DDS生成正弦波,位数为12bit

Data_process1 模块(计算最大值和最小值)

将模块 U3 的信号添加到波形窗口,然后让仿真时间达到 20ms以上,如上图所示,当enable=‘1’时,对输入数据 data_in进行比较处理,寻找最大值和最小值;当 enable=‘0’且 en=‘1’时,将最大值传递给data_max_out,将最小值传递给 data_min_out,可得最大值为 4094,最小值为 2.

4.6.2 data_process2(生成测试脉冲信号 test_clk )

最大值 data_max=4094,最小值 data_min=2,则 data_average= data_max+ data_min )/2,data_average=2048。当 enable=‘0’时,当 data_in >= data_average,en = ‘1’;否则,en=‘0’。从而,将输入波形转化为脉冲波(方波)的形式,以便计数。

4.6.3 freq 模块(计算频率并译码显示)

当 second=‘0’时且 en=‘1’时,fosc_flash信号开始进行计数+1。因为闸门信号我们在仿真时设置为 0.01s,输入波形的频率为 1000hz,所以得到的理论值应该是 10hz。如上图所示,fosc_flash 计数到 10 则停止计数,说明结果是正确的。然后当 second=‘1’时,将 fosc_flash信号传递给 fosc信号。

接着,通过一个扫描信号 count1[11:10]不断将 fosc信号的值传递给 disp_dat以做译码,并显示在 4位数码管上。由上图可得,最终译码的结果是正确的。

4.7 创建约束

1) 添加top.ucf文件到工程中,其部分管脚约束如下所示:

NET \ #MCLK 100m/50m/25m #NET \ #UCLK NET \ //????

TIMESPEC TS_clk = PERIOD \ //?????

NET \ #SW0

NET \ #SW1 //???

NET \ #AN3 NET \ #AN2 NET \ #AN1 NET \ #AN0 NET \ #DP NET \ #CG NET \ #CF NET \ #CE NET \ #CD NET \ #CC NET \ #CB NET \ #CA

# PlanAhead generated IO constraints

NET \ NET \NET \NET \NET \NET \

NET \NET \NET \NET \NET \NET \NET \

NET \

2) 点击top.vhd顶层文件,直接双击process窗口里的generate programming file,生成

top.bit下载文件 4.8 下载实验及结果

1) 通过Adept软件把设计的 bit文件下载到目标器件中。

2) 下载成功后,将 SW0 和 SW1 都拨在 LOW 的位置,就可以在开发板的数码管

上看到显示“1000”。注意,在下载到板子上之前,将闸门信号改为 1s。

五、 实验内容与步骤

1. 学习及验证实验项目:

按照实验指导书4.5节所示步骤,建立工程项目,生成DDS及除法器核,进行时序仿

真,验证所设计功能,然后进行编译,正确生成所需下载.bit类型文件。下载配置文件到实验板BASYS2上,观察验证实验现象。

2. 设计实验项目

? 功能要求: 基本要求

1) 使用Digilent Basys 开发板可输出2KHZ正弦波信号(仿真),

2) 输出正弦波信号的同时,可输出同频方波信号,并用示波器验证。

3) 可对该信号进行计数,并在Digilent Basys 开发板上显示频率计数结果(精确到Hz)。 发挥部分

1) 可通过拨码或按键输入指定所生成输出信号的频率; 2) 增加输出波形的路数(各路之间可手动设置同步关系); 3) 实现输出信号的DA转换(附加必要外围电路); 4) 增加输出波形的种类(如三角波、锯齿波等)。 5) 幅度可调;

6) 输出信号类型、频率、幅度的手动设置输入控制;

7) 可测量外部输入到Digilent Basys 开发板允许的电压信号的频率(注意校验信号幅度峰

值<3.3V与注意共地与连接关系!),并在Digilent Basys 开发板上显示频率计数结果。 8) 利用Digilent Basys 开发板VGA输出接口实现波形发生器与频率计用户界面。 9) 增加输入计数信号波形的路数;

10) 11) 12) ?

提高所设计实现的波形发生器与频率计的量程与精度; 用户自定义波形的输入与产生 其他功能与性能。 设计步骤与要求:

1) 简要说明所实现系统的基本原理。

2) 在Xilinx ISE13.1 软件中,编写输入所设计的源程序文件。 3) 对源程序进行编译及仿真分析(注意合理设置,以便能够在验证逻辑的基础上尽快

得出仿真结果)。 4) 输入管脚约束文件,对设计项目进行编译与逻辑综合,生成下载所需.bit类型文件。 5) 在Basys2实验板上下载所生成的.bit文件,观察验证所设计的电路功能。

附录:生成DDS核流程

(1) 点击“project- New Source”,输入要生成的核的名称 gen_dds。

(2) 点击“next”,找到 DDS核

(3) 点击 next并点击 finish,出现DDS Compiler的参数编辑界面

选择50MHz时钟;

通道数为1(多通道用途;用法?) 参数选择选择为系统参数(???)

Spurious Free Dynamic Range =70dB(????) 决定输出位宽;

频率分辨率取0.004Hz(????,好像0.4Hz所得结果不行?) 决定相位位宽; 这两个系统参数配合选择确定系统数据位宽!(如何配合确定?)

(4)设置好相应参数,时钟为50m,输出数据的位数为 12 位,点击next

(5) 对相移和 offset做设置,并输出正弦波,点击 next

(6) 可设置生成 DDS 的类型和输出指示信号,用户可自行设置。点击 next

(7) 设置生成波形的频率为1KHz(即0.001MHz),点击 next

top.v

module top( input clk, input reset,

input switch, //选择正弦波与三角波?;频率不同;1000 v.s. 1526? output [6:0] segdat, output [3:0] sl, //数码管选择信号; output dp );

wire [11:0] data_temp,data_max_temp,data_min_temp; //initial data_temp = 12'h0;

//initial data_max_temp = 12'h0; //initial data_min_temp = 12'h1; wire test_clk,enable;

assign dp = 1'b1;

test_wave U1 ( //???---层次化设计方式?;单元定义? .clk(clk), //??管脚定义? .reset(reset),

.switch(switch), //波形选择;

.data_out(data_temp) //所产生的正弦波或三角波; );

freq U2 (

.clk(clk), .reset(reset),

.clk_test(test_clk), //来自data_process2 .en_out(enable), .sl(sl),

.segdat(segdat) );

data_process1 U3 ( .clk(clk), .reset(reset), .enable(enable), .data_in(data_temp),

.data_max_out(data_max_temp), .data_min_out(data_min_temp) );

data_process2 U4 ( .clk(clk), .reset(reset), .enable(enable), .data_in(data_temp),

.data_max(data_max_temp), .data_min(data_min_temp), .test_clk(test_clk) ); Endmodule

test_wave.v

module test_wave( input clk, input reset,

input switch, output [11:0] data_out //所产生的正弦波或三角波; );

reg [15:0] data_temp; //计数器? wire [11:0] sine_data; reg [11:0] data_out_temp; wire rdy;

gen_dds U6 ( //引用IP核DDS单元产生所需正弦信号; .clk(clk), // input clk

.rdy(rdy), // ouput rdy

.sine(sine_data)); // ouput [11 : 0] sine

always @ (posedge clk or posedge reset) begin

if (reset)

data_temp = 16'h0; else

data_temp = data_temp +1; //正常时钟下计数; end

always @ (posedge clk or posedge reset) begin

if (reset)

data_out_temp = 12'h0; else if (switch)

data_out_temp = data_temp[14:3]; //???????开关为1取三角波? else

data_out_temp = sine_data; //开关为0取sine? end

assign data_out = data_out_temp; //数据输出; endmodule

DDS IP核文档参见:

C:\\Xilinx\\13.1\\ISE_DS\\ISE\\coregen\\ip\\xilinx\\dsp\\com\\xilinx\\ip\\dds_compiler_v4_0\\doc\\dds_ds558.pdf

Table 1: Core Signal Pinout Name Direction Description CLK Input Rising edge clock REG_SELECT(1) Input Address select for writing DATA to the phase increment (PINC) and the phase offset (POFF) registers. When REG_SELECT = 0, PINC registers are selected. When REG_SELECT = 1, POFF registers are selected. This pin will only exist if both POFF and PINC are programmable. ADDR[M-1:0](1) Input This bus is used to address up to 16 channels. The number of bits in ADDR is 1 for 2 channels, 2 for 3 or 4 channels, 3 for 5 to 8 channels, and 4 for 9 to 16 channels. This bus will exist if either PINC or POFF is programmable and there are multiple channels. WE(1) Input Write enable - active High. Enables a write operation to the PINC or POFF registers. CE(1) Input Clock enable - active High. CE must be High during normal core operation, but it is not required to be active during a write access to the PINC or POFF registers. DATA[N-1:0] (1) Input Time shared data bus. The DATA port is used for supplying values to the PINC or POFF memories. The value input to DATA describes

SCLR(1) Input PINC_IN[N-1:0](1) Input POFF_IN[N-1:0](1) PHASE_IN[N-1:0](1) Input Input RDY(1) RFD(1) Output Output CHANNEL[M-1:0](1) Output a phase angle. DATA port width (N) is determined by the Phase Width parameter, selected or displayed on the GUI. If the bus is N bits wide, a full circle is cut into 2N phase segments, so the ranges [0, 2N -1] and [-2N-1, 2N-1 -1] both describe a full circle. Because of this it makes no difference if this port is considered signed or unsigned. Both PINC and POFF registers are fixed point. So, if lower precision values are all that is required for one or the other, these values must be right-justified and input to the upper bits of the DATA bus. For example, if DATA width is 8 bits, but POFF only needs to be 1/8, 2/8, 3/8, etc., the 3 bits used to describe the phase offset must be bits 7:5 of the DATA port. Synchronous clear - active High. When SCLR is asserted, the accumulator and channel counter are reset. Depending upon the Latency of the core, RDY may also deasserted (further details given later). The outputs of the core, CHANNEL, SINE, COSINE and PHASE_OUT are undefined following SCLR until RDY is active. SCLR does not reset PINC or POFF registers, and a write to these registers may occur when SCLR is active. Streaming input for Phase Increment. This input allows DDS output frequency to be modulated. Streaming input for Phase Offset. This input allows DDS output phase to be modulated. For use when the DDS is configured as SIN/COS LUT only. This is the phase input to the SIN/COS LUT. Output data ready - active High. Indicates when the output samples are valid. Ready for data - active High. RFD is a dataflow control signal present on many Xilinx LogiCORE cores. In the context of the DDS, it is supplied only for consistency with other LogiCORE cores. This optional port is always tied High. Channel index. Indicates which channel is currently available at the output when the DDS SINE[P-1:0](1) COSINE[P-1:0](1) Output Output PHASE_OUT[N-1:0](1) Output 1. Denotes optional pin. Freq.c

`timescale 1ns / 1ps

is configured for multi-channel operation. This is an unsigned signal. Its width is determined by the number of channels. It is qualified by RDY. Sine time-series. Port width (P) is determined by the Output Width parameter. Cosine time-series. Port width (P) is determined by the Output Width parameter. Phase output, supplied in synchronism with SINE and COSINE outputs. ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: //

// Create Date: 14:21:01 06/22/2011 // Design Name:

// Module Name: freq // Project Name: // Target Devices: // Tool versions: // Description: //

// Dependencies: //

// Revision:

// Revision 0.01 - File Created // Additional Comments: //

////////////////////////////////////////////////////////////////////////////////// module freq( input clk, input reset,

input clk_test, output en_out,

//计数脉冲输入; //闸门信号;

output [3:0] sl, output [6:0] segdat );

reg[25:0] count;

reg[15:0] fosc; //freq reg reg[15:0] fosc_flash; //update freq reg[6:0] segdat_reg; reg[3:0] sl_reg;

//????

reg[3:0] disp_dat; //data to display reg flag_flash; //indicate update reg second; reg en1,en2;

always @ (posedge clk or posedge reset) //??? begin

if (reset) end

assign en = en1 && (!en2);

always @ (posedge clk or posedge reset) //generate 1s??? begin

if (reset) end

begin

count = 0;

second = 0; end else begin

//计数处理

if (count == 26'd49999999)

begin

second = ~second;

count = 26'd0; end

//复位处理;

//???

begin

//复位处理;

wire en;

en1 <= 1'b0;

en2 <= 1'b0; end else begin

//输入数据

en2 <= en1;

en1 <= clk_test;

end

count = count +1;

end

always @ (count[11:10]) //scan to output data from reg begin

case(count[11:10]) end

always @ (disp_dat) // 数码管显示处理 begin

case(disp_dat)

always @ (count[11:10]) begin

case (count[11:10]) end

always @ (posedge clk or posedge reset) begin

if(reset)

begin

fosc_flash[15:0] = 16'h0;

//复位处理;

2'b00: sl_reg = 4'b1110; //scan ge wei 2'b01: sl_reg = 4'b1101; //scan shi wei 2'b10: sl_reg = 4'b1011; //scan bai wei 2'b11: sl_reg = 4'b0111; //scan qian wei endcase

// 数码管显示动态刷新;

4'h0: segdat_reg = 7'b0000001; //0 4'h1: segdat_reg = 7'b1001111; //1 4'h2: segdat_reg = 7'b0010010; //2 4'h3: segdat_reg = 7'b0000110; //3 4'h4: segdat_reg = 7'b1001100; //4 4'h5: segdat_reg = 7'b0100100; //5 4'h6: segdat_reg = 7'b0100000; //6 4'h7: segdat_reg = 7'b0001111; //7 4'h8: segdat_reg = 7'b0000000; //8 4'h9: segdat_reg = 7'b0000100; //9 default: segdat_reg = 7'b0000001; //0 endcase

2'b00: disp_dat = fosc[3:0]; 2'b01: disp_dat = fosc[7:4]; 2'b10: disp_dat = fosc[11:8]; 2'b11: disp_dat = fosc[15:12]; endcase

//频率计数显示取值;

end

fosc = 16'h0;

end else

//在闸门信号内进行频率计数

begin

flag_flash = 1;

fosc_flash[3:0] = fosc_flash[3:0]+1; if(fosc_flash[3:0]>4'h9) begin

fosc_flash[3:0] = 4'h0;

fosc_flash[7:4] = fosc_flash[7:4]+1; if(fosc_flash[7:4]>4'h9) begin

fosc_flash[7:4] = 4'h0;

fosc_flash[11:8] = fosc_flash[11:8]+1; if(fosc_flash[11:8]>4'h9) begin

fosc_flash[11:8] = 4'h0;

fosc_flash[15:12] = fosc_flash[15:12]+1; if(fosc_flash[15:12]>4'h9) fosc_flash[15:12]=4'h0; end

if(!second & en)

end end

end

else if((second)&&(flag_flash))

begin

flag_flash=0;

end

fosc[15:0] = fosc_flash[15:0]; fosc_flash = 16'h0; end

assign segdat = segdat_reg; assign sl = sl_reg; assign en_out = second;

endmodule

data_process1

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: //

// Create Date: 17:02:33 06/26/2011 // Design Name:

// Module Name: data_process1 // Project Name: // Target Devices: // Tool versions: // Description: //

// Dependencies: //

// Revision:

// Revision 0.01 - File Created // Additional Comments: //

////////////////////////////////////////////////////////////////////////////////// module data_process1( input clk, input reset, input enable,

input [11:0] data_in,

output reg[11:0] data_max_out, output reg[11:0] data_min_out );

reg [11:0] data_max,data_min,temp1,temp2; reg en1,en2; wire en;

always @ (posedge clk or posedge reset) begin

if (reset)

begin

data_max <= 12'b000000000000; data_min <= 12'b111111111111; end

else if (!enable) if (en) begin

data_max <= 12'b000000000000; data_min <= 12'b111111111111;

//在en为低阶段;

//时钟计数;

//复位处理; //????

end else begin

temp1 <= data_in;

temp2 <= data_in; data_max <= temp1; data_min <= temp2;

if (temp1 <= 12'b111111111111) if (temp1 > data_max)

data_max <= temp1; else

data_max <= data_max;

//找最小值

//找最大值

// // end

if (temp2 >= 12'b000000000000) if (temp2 < data_min)

data_min <= temp2; else

data_min <= data_min;

end

always @ (posedge clk or posedge reset) //??? begin

if (reset) end

assign en = (!en1) && (en2);

always @ (posedge clk or posedge reset) begin

if (reset)

begin

data_max_out <= 12'b000000000000;

data_min_out <= 12'b111111111111; end

else if(en) begin

data_max_out <= data_max;

data_min_out <= data_min; end

//??

begin

en1 <= 1'b0;

en2 <= 1'b0; end else begin

en2 <= en1;

en1 <= enable;

end

end

endmodule

data_process2

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: //

// Create Date: 17:36:36 06/26/2011 // Design Name:

// Module Name: data_process2 // Project Name: // Target Devices: // Tool versions: // Description: //

// Dependencies: //

// Revision:

// Revision 0.01 - File Created // Additional Comments: //

////////////////////////////////////////////////////////////////////////////////// module data_process2( input clk, input reset, input enable,

input [11:0] data_in, input [11:0] data_max, input [11:0] data_min, output test_clk ); reg en; wire rfd;

reg[1:0] divisor = 2'b10; wire[1:0] frac;

wire [12:0] temp1,temp2,temp3,data_average;

//assign temp1[11:0] = data_max; //assign temp2[11:0] = data_min;

//assign temp1[12] = 1'b0; //assign temp2[12] = 1'b0; //assign temp3 = (temp1+temp2);

//temp1[12:0] <= {1'b0,data_max_temp[11:0]}+; //temp2[12:0] <= {1'b0,data_min_temp[11:0]};

assign temp3 = {1'b0,data_max[11:0]}+{1'b0,data_min[11:0]};

freq_chufaqi_2 U5 (

//???

.clk(clk), // input clk .rfd(rfd), // ouput rfd

.dividend(temp3), // input [12 : 0] dividend .divisor(divisor), // input [1 : 0] divisor

.quotient(data_average), // ouput [12 : 0] quotient .fractional(frac)); // ouput [1 : 0] fractional

//

//求和;

always @ (posedge clk or posedge reset) begin

if (reset) end

assign test_clk = en;

endmodule 0 1 2 3 4 5 6 7 8 9 频率 50MHz 25MHz 12.5MHz 6.25MHz 3.125MHz 1.5625MHz 781.25KHz 390.625KHz 195.3125KHz 97.65625 KHz 周期 20ns 40ns 80ns 160ns 320ns 640ns 1.28us 2.56us 5.12us 10.24us 20.48us 40.96us 17 18 19 20 en = 1'b0; else if(!enable)

if (data_in >= data_average)

en = 1'b1; else

en = 1'b0;

频率 381.4697265625Hz 190.73486328125Hz 95.367431640625 47.6837158203125 周期 2.62144 ms 1.048576 ms 10 48.828125 KHz 11 24.4140625 12 12.20703125 KHz 13 6.103515625 KHz 81.92us 163.84us 14 3.0517578125 KHz 327.68us 15 1.52587890625 KHz 655.36us 16 762.939453125Hz

1.31072ms 1

C:\\Xilinx\\13.1\\ISE_DS\\ISE\\coregen\\ip\\xilinx\\dsp\\com\\xilinx\\ip\\dds_compiler_v4_0\\doc\\ dds_ds558.pdf

C:\\Xilinx\\13.1\\ISE_DS\\ISE\\coregen\\ip\\xilinx\\dsp\\com\\xilinx\\ip\\div_gen_v3_0\\doc\\div_gen_ds530.pdf

本文来源:https://www.bwwdw.com/article/i5k7.html

Top