FPGA实战--等精度频率测量

2023-11-19

      首先放置效果图:

          本次试验中采用的是等精度测频率,等精度测频的原理是产生一个1s的高电平,在高电平中对被测方波进行计数,所测得数字即该波形频率。具体等精度测量原理请参考:http://www.elecfans.com/d/591858.html

          注意点:在1s高电平上升沿时,被测信号也需要是上升沿,才能进行准确计数,代码相对简单

          本次实验功能,对信号测频,将测得频率以二进制32位通过uart发送给pc,对于pc发送得数据,将复制返回。下面将主要代码贴上:

顶层文件:Fre_measure.v

module Fre_measure(
                    input         clk,
						  input         rst_n,
						  input         clk_measure,
						  input         uart_rx,
						  
						  output        uart_tx
						);


wire[31:0]                        fre_cnt;		

						

Time_1s time_1s( 
                  .clk                (clk             ),
						.rst_n              (rst_n           ),
						.flag_1s            (flag_1s         )
                );

dff1 dff_1(
                  .clk_measure        (clk_measure     ),
						.flag_1s            (flag_1s         ),
						.clk_match          (clk_match       )
			 );
			 
Fre_cnt fre_cnt1(
                  .clk_measure        (clk_measure     ),
						.rst_n              (rst_n           ),
						.clk_match          (clk_match       ),
						.fre_cnt            (fre_cnt         )
					  );
					  
uart_test uart_test1(
                  .clk                (clk             ),
						.rst_n              (rst_n           ),
						.uart_rx            (uart_rx         ),
						.fre_cnt            (fre_cnt         ),
						.uart_tx            (uart_tx         )
						   );


endmodule

匹配模块,将1s延时和被测信号匹配:dff.v

module dff1(
             input flag_1s,
				 input clk_measure,
				 
				 output reg clk_match
           );
			  
always@(posedge clk_measure)
begin
    clk_match <= flag_1s;
end

endmodule

频率计数模块:Fre_cnt.v

module Fre_cnt(
                input                 clk_measure,
					 input                 rst_n,
					 input                 clk_match,
					  
					 output[31:0]          fre_cnt      
              );
				  
reg   [31:0]   fre_cnt_r1 = 32'b0;
reg   [31:0]   fre_cnt_r2 = 32'b0;


always@(negedge clk_match)
begin
	fre_cnt_r2 <= fre_cnt_r1;
end	


always@(posedge clk_measure or negedge rst_n)
begin
   if(!rst_n)
	fre_cnt_r1 <= 32'b0;
	else if(clk_match)
	fre_cnt_r1 <= fre_cnt_r1 + 32'b1;
	else
	fre_cnt_r1 <= 32'b0;
end

assign fre_cnt = fre_cnt_r2;

endmodule

0.5Hz方波产生(1s)高电平产生:Time_1s.v

module Time_1s(
                input       clk,
                input       rst_n,
					 
					 output reg  flag_1s=1'd0
					 );

					 
reg   [27:0]   timer;



always@(posedge clk or negedge rst_n)
begin
   if(!rst_n)
   timer <= 28'd0;
   else if(timer == 28'd49_999_999)
	begin
	flag_1s <= ~flag_1s;
   timer <= 28'd0;
	end
   else
   timer <= timer + 28'd1;
end

endmodul

uart通信模块:uart_test.v

module uart_test(
	input                        clk,
	input                        rst_n,
	input                        uart_rx,
	input[31:0]                  fre_cnt, 	
	output                       uart_tx
);

parameter                        CLK_FRE = 50;
localparam                       IDLE =  0;
localparam                       SEND =  1;  
localparam                       WAIT =  2;   
reg[7:0]                         tx_data;
reg[7:0]                         tx_str;
reg                              tx_data_valid;
wire                             tx_data_ready;
reg[7:0]                         tx_cnt;
wire[7:0]                        rx_data;
wire                             rx_data_valid;
wire                             rx_data_ready;
reg[31:0]                        wait_cnt;
reg[3:0]                         state;

assign rx_data_ready = 1'b1;

always@(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		wait_cnt <= 32'd0;
		tx_data <= 8'd0;
		state <= IDLE;
		tx_cnt <= 8'd0;
		tx_data_valid <= 1'b0;
	end
	else
	case(state)
		IDLE:
			state <= SEND;
		SEND:
		begin
			wait_cnt <= 32'd0;
			tx_data <= tx_str;

			if(tx_data_valid == 1'b1 && tx_data_ready == 1'b1 && tx_cnt < 8'd36)
			begin
				tx_cnt <= tx_cnt + 8'd1; 
			end
			else if(tx_data_valid && tx_data_ready)
			begin
				tx_cnt <= 8'd0;
				tx_data_valid <= 1'b0;
				state <= WAIT;
			end
			else if(~tx_data_valid)
			begin
				tx_data_valid <= 1'b1;
			end
		end
		WAIT:
		begin
			wait_cnt <= wait_cnt + 32'd1;

			if(rx_data_valid == 1'b1)
			begin
				tx_data_valid <= 1'b1;
				tx_data <= rx_data;  
			end
			else if(tx_data_valid && tx_data_ready)
			begin
				tx_data_valid <= 1'b0;
			end
			else if(wait_cnt >= CLK_FRE * 1000000) 
				state <= SEND;
		end
		default:
			state <= IDLE;
	endcase
end

//combinational logic
//Send "HELLO ALINX\r\n"
always@(*)
begin
	case(tx_cnt)

		8'd0:  tx_str <= fre_cnt[31]+8'd48;
		8'd1:  tx_str <= fre_cnt[30]+8'd48;
		8'd2:  tx_str <= fre_cnt[29]+8'd48;
		8'd3:  tx_str <= fre_cnt[28]+8'd48;
		8'd4:  tx_str <= fre_cnt[27]+8'd48;
		8'd5:  tx_str <= fre_cnt[26]+8'd48;
		8'd6:  tx_str <= fre_cnt[25]+8'd48;
		8'd7:  tx_str <= fre_cnt[24]+8'd48;
		8'd8:  tx_str <= fre_cnt[23]+8'd48;
		8'd9:  tx_str <= fre_cnt[22]+8'd48;
		8'd10:  tx_str <= fre_cnt[21]+8'd48;
		8'd11:  tx_str <= fre_cnt[20]+8'd48;
		8'd12:  tx_str <= fre_cnt[19]+8'd48;
		8'd13:  tx_str <= fre_cnt[18]+8'd48;
		8'd14:  tx_str <= fre_cnt[17]+8'd48;
		8'd15:  tx_str <= fre_cnt[16]+8'd48;
		8'd16:  tx_str <= fre_cnt[15]+8'd48;
		8'd17:  tx_str <= fre_cnt[14]+8'd48;
		8'd18:  tx_str <= fre_cnt[13]+8'd48;
		8'd19:  tx_str <= fre_cnt[12]+8'd48;
		8'd20:  tx_str <= fre_cnt[11]+8'd48;
		8'd21:  tx_str <= fre_cnt[10]+8'd48;
		8'd22:  tx_str <= fre_cnt[9]+8'd48;
		8'd23:  tx_str <= fre_cnt[8]+8'd48;
		8'd24:  tx_str <= fre_cnt[7]+8'd48;
		8'd25:  tx_str <= fre_cnt[6]+8'd48;
		8'd26:  tx_str <= fre_cnt[5]+8'd48;
		8'd27:  tx_str <= fre_cnt[4]+8'd48;
		8'd28:  tx_str <= fre_cnt[3]+8'd48;
		8'd29:  tx_str <= fre_cnt[2]+8'd48;
		8'd30:  tx_str <= fre_cnt[1]+8'd48;
		8'd31:  tx_str <= fre_cnt[0]+8'd48;
		8'd32:  tx_str <= " ";
		8'd33:  tx_str <= " ";
		8'd34:  tx_str <= " ";
		8'd35:  tx_str <= "\r";
		8'd36:  tx_str <= "\n";
		default:tx_str <= 8'd0;
	endcase
end



uart_rx#
(
	.CLK_FRE(CLK_FRE),
	.BAUD_RATE(115200)
) uart_rx_inst
(
	.clk                        (clk                      ),
	.rst_n                      (rst_n                    ),
	.rx_data                    (rx_data                  ),
	.rx_data_valid              (rx_data_valid            ),
	.rx_data_ready              (rx_data_ready            ),
	.rx_pin                     (uart_rx                  )
);

uart_tx#
(
	.CLK_FRE(CLK_FRE),
	.BAUD_RATE(115200)
) uart_tx_inst
(
	.clk                        (clk                      ),
	.rst_n                      (rst_n                    ),
	.tx_data                    (tx_data                  ),
	.tx_data_valid              (tx_data_valid            ),
	.tx_data_ready              (tx_data_ready            ),
	.tx_pin                     (uart_tx                  )
);
endmodule

 串口通信设置:波特率115200,8位数据位,1位停止位,无校验,下面是串口通信截图,系统时钟为50M,下图为测量数据,输出信号数据为49999950,误差50hz,误差精度为0.000001,理论测量最大应该可达到200M左右,但由于实验条件有限无法测试。10M以下几乎没误差,而且板子时钟频率越高则越精准。

      以上就是本次实战的主要内容,上述有误还请指出,如果需要原工程可留言,大家一起进步,一起实践~

 

要工程的同学比较多,在这把下载链接贴上

https://download.csdn.net/download/VCA821/12899478

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FPGA实战--等精度频率测量 的相关文章

  • Verilog HDL ?操作员

    什么是 用 Verilog 做什么 例如 以下命令是什么意思 input first din input 7 0 din output 127 0 parity reg 127 0 parity wire 7 0 feedback assi
  • 在 C 中操作 80 位数据类型

    我正在用 C 实现一些加密算法 其中涉及 80 位密钥 特定操作涉及将密钥旋转移位 x 个位数 我已经尝试过 long double 类型 如果我没记错的话 它是 80 位 但这不适用于位移运算符 我能想到的唯一替代方案是使用 10 个元素
  • 信号连接到以下多个驱动器

    我尝试运行以下命令并收到此错误 这是 Verilog 代码 module needle input referrence input penalty output index 7 0 inout input itemsets input r
  • 如何在RTL中使用时钟门控?

    我正在对一些时钟进行门控latch以及我设计中的逻辑 我在综合和布局布线方面没有太多经验 在 RTL 中实现时钟门控的正确方法是什么 示例1 always comb begin gated clk clk latch update en e
  • VHDL门控时钟如何避免

    我收到了避免使用门控时钟的建议 因为它可能会导致松弛和时序限制问题 但我想问一下我可以认为什么是门控时钟 例如 此代码对时钟进行门控 因为 StopCount 对它进行门控 process ModuleCLK begin if rising
  • 如何获取值数组作为 plusargs?

    如何获取值数组作为参数 我需要从命令行获取一组未定义大小的命令 如何将这些参数放入数组或队列中 Eg CMDS READ WRITE READ N WRITE 它应该被带到一个数组中 value plusargs不支持数组 但支持字符串 看
  • Verilog 错误:必须连接到结构网络表达式

    我收到错误 output or inout port Qout must be connected to a structural net expression 我评论了下面代码中发生错误的行 代码被修剪 压缩 我搜索了答案 似乎我无法将输
  • 在verilog中将wire值转换为整数

    我想将电线中的数据转换为整数 例如 wire 2 0 w 3 b101 我想要一个将其转换为 5 并将其存储在整数中的方法 我怎样才能以比这更好的方式做到这一点 j 1 for i 0 i lt 2 i i 1 begin a a w i
  • VHDL 中的 BRAM_INIT

    我正在模拟基于处理器的设计 其中程序存储器内容保存在 BRAM 中 我正在使用 VHDL 推断 BRAM 实现程序存储器 我试图避免使用 CoreGen 因为我想保持设计的可移植性 最终该设计将进入 FPGA 我想看看是否有一种方法可以使用
  • 如何使用 don't cares 参数化 case 语句?

    我有一条称为输入的电线 我想检测前导的数量 我正在尝试创建一个模块 该模块使用下面的 case 语句根据前导零的数量更改输出数据 然而 输入的大小是可参数化的 如果 X 是固定值 4 我将创建一个 case 语句 case input 4
  • 我们可以在 C 或 SystemVerilog 中使用 ifdef MACROS 中的条件吗?

    我想要那样的东西 ifdef N O gt N I define GREATER 1 else define LESSER 1 endif 但做不到 有什么解决方案或阅读吗 我很努力地想要做到这一点 但是却做不到 Verilog 不提供这样
  • 在 Mac OS X 10.6.8 上用什么来编译和模拟 Verilog 程序?

    作为教学大纲的一部分 我需要模拟 Verilog 程序 但是 我的大学使用 Xilinx ISE 但它不适用于 Mac 因此 请帮助我提供最好的软件以及有关如何安装和使用它们的一些详细步骤 你可以尝试伊卡洛斯 Verilog http iv
  • 对象 <名称> 未声明

    这是我的代码 据我所知 LEDs被定义为 module sevenseg LEDs in output reg 6 0 LEDs input 3 0 in always in begin case in 0 LEDs 7 b1000000
  • 开始后跟冒号和变量是什么意思?

    什么是data mux意思是这里 它只是块的名称吗 if PORT CONFIG 32 P0 1 b1 begin data mux end 这些是块名称 它们特别适用于generate块 例如 您可以定义一个generate块如 genv
  • 在 Verilog 中判断总线是否包含单个 x 的最佳方法是什么?

    我有一个监控总线的测试台 总线内的一些信号 位 可以是 1 bx 由于多种原因 我需要知道总线内是否有任何信号是 1 bx 如果总线包含任何 x 测试 不用于综合 仅用于模拟目的 的最佳方法是什么 我曾希望我可以使用减少或然后使用 但这似乎
  • 标识符必须用端口模式声明:busy。 (Verilog)

    我有如下所示的 Verilog 代码 当我编译它时 我收到以下错误消息 并且代码的第一行突出显示 Error 标识符必须用端口模式声明 busy Code module main clk rst start busy ready cnt s
  • 具有 +1 逻辑的 4 位计数器 D 触发器

    我正在尝试通过 Verilog 实现带有 1 逻辑的 D 触发器计数器 但是我收到了很多有关网络多个常量驱动程序的错误代码 有人可以帮我吗 这是到目前为止的代码 module LAB clk clear Enable Q input clk
  • Verilog 中的 If 语句和分配连线

    我试图弄清楚基于组合逻辑分配电线的基础知识 I have wire val wire x wire a wire b always begin if val 00 I want to assign x a if val 01 I want
  • 在 Verilog 程序中使用连续分配?

    在 Verilog 程序中使用连续赋值是否可能和 或有用 例如 是否有任何理由将assign里面一个always堵塞 例如这段代码 always begin assign data in Data end 此外 是否可以用这种方法生成顺序逻
  • 如何修复实例上的错误:未定义的变量 B?

    我想编译此 Verilog 代码 但在实例中出现错误B模块中的MultiP module error 1 Undefined variable B error 2 near Adder1 syntax error unexpected ID

随机推荐

  • c++直角坐标系与极坐标系的转换_平面向量的奇技淫巧——斜坐标系的一系列低级研究...

    事先说明 笔者初三 如在叙述中有不严谨的地方 还请诸位指出 自当感激不尽 一 什么是斜坐标系 众所周知 我们目前平面中使用相当广的坐标系是笛卡尔发明的平面直角坐标系 然而 笛卡尔真的只使用了这一种坐标系吗 显然不是的 事实上 笛卡尔最先使用
  • Odoo免费开源ERP订单锁货的应用实施技巧分享

    Odoo是世界排名第一的免费开源ERP 其应用市场上有3万多个功能插件可供下载使用 几乎涵盖各行各业的企业业务管理流程 包括库存管理 销售管理 采购管理 制造管理 维修保养 网站电商 市场营销 项目管理 HR 财务 PLM等等 并且源码交付
  • 服务器备案的网站名称怎么填写,公安备案网站名称怎么写?

    最近很多新老用户接到西安网警打来电话让进行公安网安备案 要求通过全国互联网安全管理服务平台进行公安联网备案 客户俗称 公安备案网站名称怎么写 依据 计算机信息网络国际联网安全保护管理办法 相关规定 各网站在工信部备案成功后 需在网站开通之日
  • 迪杰斯特拉算法(Dijkstra)-Java实现

    迪杰斯特拉算法也是求两点之间最短路径的算法 它的思想和普利姆算法有点相似 不断通过已找到点集合和未找到点之间的集合之间的最短路径 这个算法需要用到三个数组 一个是存储结点是否已经访问 一个是结点到起始点的最短距离 还有一个是结点到起始点第一
  • Java实现简单版SVM

    Java实现简单版SVM 最近的图像分类工作要用到latent svm 为了更加深入了解svm 自己动手实现一个简单版的 之所以说是简单版 因为没有用到拉格朗日 对偶 核函数等等 而是用最简单的梯度下降法求解 其中的数学原理我参考了http
  • 解决Adobe Flash Player已不再受支持的问题

    1 问题展示 我们在访问某些网站时 可能会出现Adobe Flash Player已不再受支持的问题 具体如下图所示 这会对我们的日常生活需求产生极大的不便 因此迫切需要一个能够解决此问题的方法 其实很简单 具体操作请看下面的步骤 2 下载
  • 移动端+PC端图片预览+手势缩放等功能合集

    话不多说 直接上代码 大家可按需求功能复制使用 window onload function 点击图片进入预览 var Dom document querySelector preview Dom onclick function var
  • 接口如何实现多态

    抽象类是用来继承的 不能被实例化 抽象类里可以有成员变量 接口中没有 1 抽象类里的抽象方法 只有在子类实现了才能使用 2 抽象类里的普通方法 可被子类调用 3 接口里的方法 都被默认修饰为public abstract类型 4 接口里的变
  • 记录1年免费亚马逊AWS云服务器申请方法过程及使用技巧

    转载 http www itbulu com free aws html 早年我们才开始学习网站建设的时候 会看到且也会寻找免费主机商 主要原因是那时候提供免费主机的商家还是比较靠谱的 而且那时候主机商并不是很多且成本也比较大 我们深知听到
  • linux上层app调用驱动底层的过程详解

    APP应用程序 gt 应用框架层 gt 硬件抽象层 gt 硬件驱动程序 一 硬件驱动层 进入kernel drivers文件夹中 创建一文件夹 放入驱动程序 包括头文件 C文件 Makefile Kconfig 同时对drivers下的Ma
  • 滚动屏幕或缩放屏幕,使用节流

    场景 滚动屏幕 onScroll 缩放屏幕 resize 如果需要统计用户滚动屏幕或缩放屏幕的行为作出相应的网页反应 容易导致网络的阻塞 mounted window addEventListener resize this throttl
  • 基于聚类的异常值检测算法依据及python实现

    假设数据集D被聚类算法划分到k个类C C1 C2 CK 对象p 的离群因子of3 p 定义为 与所有类间距的加权平均值 其中 D 为样本数量 Cj 为第j个聚类群体样本数量 d p cj 为样本p与第j个聚类中心的距离 其中cj表示第j个聚
  • LeetCode·每日一题·1851. 包含每个查询的最小区间·优先队列(小顶堆)

    题目 示例 思路 离线查询 输入的结果数组queries 是无序的 如果我们按照输入的queries 本身的顺序逐个查看 时间复杂度会比较高 于是 我们将queries 数组按照数值大小 由小到大逐个查询 这种方法称之为离线查询 位运算 离
  • ExtJS之 Proxy数据代理

    ExtJS之 Proxy数据代理 代理种类截图 ExtJS提供的数据代理主要分为两大类 1 客户端代理 Ext data proxy Client 2 服务器代理 Ext data proxy Server 这两个类 都继承自 Ext da
  • Ansible的简介及部署

    1 ansible简介 1 1 什么是ansible ansible是一款开源自动化平台 是一个配置管理工具 自动化运维工具 1 2 ansible的优点 跨平台支持 人类可读自动化 ansible提供linux Windows unix和
  • 类的一些内置方法

    一 slots 用来取代 dict 优势是省内存 附加功能是只能创建slots 定义好的key 注意 不要乱用 用了就没有 dic 方法了 class Foo slots name age 这里可以是列表或者单个字符串 定义key值 f1
  • 解决matplotlib画图中文乱码

    一 下载字体 以SimHei字体为例 下载SimHei ttf文件 在python环境下输入 import matplotlib print matplotlib path 输出matplotlib的安装环境 放在该路径下的mpl data
  • 彻底删除SVN版本库某一文件夹或文件

    基础描述 要彻底删除SVN版本库某一文件夹或文件 可采取这种方法 举例说明 例 假设SVN库路径为E svn project 库中的目录结构为 Trunk Software test exe 删除Software 目录下的test exe文
  • 赫尔德不等式详细证明

    赫尔德不等式详细证明 k 1n akbk k 1n ak p 1 p k 1n bk q 1 q 1 sum k 1 n left a k b k right leqslant sum k 1 n left a k right p 1 p
  • FPGA实战--等精度频率测量

    首先放置效果图 本次试验中采用的是等精度测频率 等精度测频的原理是产生一个1s的高电平 在高电平中对被测方波进行计数 所测得数字即该波形频率 具体等精度测量原理请参考 http www elecfans com d 591858 html