当前位置: 首页 > news >正文

FPGA_学习_13_方差计算小模块

测距器件APD的性能与器件本身的温度、施加在APD的偏置电压息息相关。 在不同的温度下,APD的偏压对测距性能的影响非常大。 要确定一个合适的APD的偏压Vopt,首先你要知道当前温度下,APD的击穿电压Vbr,一般来讲,Vopt = Vbr – ΔV,ΔV基本是个固定的值。如果要使用算法找到Vbr,通过寻找APD采集信号的噪声方差的剧变点去寻找Vbr是一个不错的方式。 如下图所示,当方差从10以下,突然剧变到45.31,信号噪声方差剧变4倍不止。我们就可以定义此处偏压43.8V为击穿电压Vbr。 那么要在FPGA实现此功能,首先需要在FPGA中实现方差的计算,这也是本文的内容。 这算是脱离例程,第一个本人自己设计的FPGA小模块。

1 CSDN C知道

ChatGPT已经火爆的不行了,猪如何在ChatGPT的风口起飞,这个问题还真是为难。 不过使用ChatGPT倒是不难,CSDN推出了基于ChatGPT的C知道,功能还是比较强大的。我也赶一下时髦,我对C知道问了一个问题:请帮我用Verilog写一个计算方差的算法。

module VarianceCalculator (input clk,input rst,input [N-1:0] data_in,input valid_in,output reg [31:0] variance,output reg valid_out
);reg [N-1:0] sum;reg [N-1:0] square_sum;reg [31:0] mean;reg [31:0] count;always @(posedge clk or posedge rst) beginif (rst) beginsum <= 'b0;square_sum <= 'b0;mean <= 'b0;count <= 'b0;valid_out <= 0;end else if (valid_in) beginsum <= sum + data_in;square_sum <= square_sum + (data_in * data_in);count <= count + 1;if (count == N-1) beginmean <= sum / N;variance <= square_sum / N - (mean * mean);valid_out <= 1;endendendendmodule

 从算法上来讲,计算方差倒不是一个很难的问题,比如用平方的均值减去均值的平方(平方的期望减去期望的平方)。 C知道提供的Verilog代码就是这样算的,是没有问题的。 但直接拿来用,还是存在少许问题。 不过C知道已经很强大了,是很有参考价值的。

2 纯时序逻辑实现 V1.0

我已记不清从哪里接受了一个写Verilog代码的观念,就是:一个时序逻辑(always块),只写一个变量。这样做的好处是,修改调试非常方便,可以根据仿真结果看哪个变量有问题,然后我就专门去修改那个变量对应的时序逻辑。 不过坏处是,它不如全部变量写到一个时序逻辑里面那样,一眼看到算法的全貌。不过,我不管它的坏处是啥,总之这是我接受的观念,也是我后续编写FPGA代码的风格和态度。

下面给出,我用纯时序逻辑写的方差计算FPGA代码。

2.1 Verilog代码

`timescale 1ns / 1psmodule VarCalculatorV1(input   wire            clk             ,input   wire            rst_n           ,input   wire    [7:0]   data_in         ,input   wire            valid_in        ,output  reg     [15:0]  variance        ,output  reg             valid_out
);//==================================================================
//                        Parameter define
//==================================================================
parameter       N = 256;//==================================================================
//                        Internal Signals
//==================================================================
reg     [31:0]  count;
reg     [15:0]  sum;
reg     [31:0]  square_sum;
reg     [7:0]   mean;//----------------------------- valid_out -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginvalid_out <= 1'b0;     endelse if (count == N+1)beginvalid_out <= 1'b1;endelse beginvalid_out <= 1'b0;end
end//----------------------------- variance -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginvariance <= 'd0;     endelse if (valid_in==1'b1 && count >= N+1 )beginvariance <= (square_sum >> 8) - (mean * mean);endelse beginvariance <= 'd0;end
end//----------------------------- count -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) begincount <= 'd0;     endelse if (valid_in==1'b1)beginif (count == N+2) begincount <= 'd0;endelse begincount <= count + 1'b1;endendelse begincount <= 'd0;end
end//----------------------------- sum -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginsum <= 'd0;     endelse if (valid_in==1'b1)beginif (count < N) beginsum <= sum + data_in;endelse if(count == N || count == N+1) beginsum <= sum;endelse if(count == N+2) beginsum <= 'd0;endendelse beginsum <= 'd0;end
end//----------------------------- square_sum -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginsquare_sum <= 'd0;     endelse if (valid_in==1'b1)beginif (count < N) beginsquare_sum <= square_sum + data_in*data_in;endelse if(count == N || count == N+1) beginsquare_sum <= square_sum;endelse if(count == N+2) beginsquare_sum <= 'd0;endendelse beginsquare_sum <= 'd0;end
end//----------------------------- mean -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginmean <= 'd0;     endelse if (valid_in==1'b1)beginif (count >= N) beginmean <= sum >> 8;endelse beginmean  <= 'd0;endendelse beginsum <= 'd0;end
endendmodule

啰嗦几句废话哈,由于需要验证代码的准确性,因此我们对其进行了ModelSim仿真。 本来呢,由于ModelSim的仿真代码我不是很熟悉, 我还不太会使用仿真代码来创建一个我想要的data_in。所以,我在仿真的时候,在用到data_in的地方,我都是用模块内部的计数变量count来代替的。(也就是说,我们计算的是从0~255这256个数的方差)。后来仿真成功确定了代码的准确性之后,我重新去调整我的仿真代码,使得我给到这个模块的data_in变量和模块内部的count变量是一样的。

下面给出对应的ModelSim仿真代码。

2.2 ModelSim仿真代码

`timescale 1ns/1ps
module tb_VarCalculator (); /* this is automatically generated */// clockreg clk;reg rst_n;reg  [7:0] data_in;reg        valid_in;wire [15:0] variance;wire        valid_out;parameter N = 256;VarCalculatorV1 #(.N(N)) inst_VarCalculator (.clk       (clk),.rst_n     (rst_n),.data_in   (data_in),.valid_in  (valid_in),.variance  (variance),.valid_out (valid_out));initial beginclk <= 1'b0;forever #(10) clk = ~clk;endinitial beginrst_n <= 1'b0;#10rst_n <= 1'b1;endinitial beginvalid_in <= 1'b0;#10valid_in <= 1'b1;endreg [15:0] tb_count;initial begintb_count <= 'd0;data_in <= 'd0;#10// 仿真代码中for循环是比较值得后续学习参考的for(tb_count = 1; tb_count <= N+3; tb_count = tb_count + 1) begin#20if(tb_count<='d255) begindata_in <= tb_count; endelse beginif (tb_count=='d258) begintb_count <= 'd0;enddata_in <= 'd0; end                endendendmodule

仿真的时候,有个小技巧,真的好方便,特别提高仿真效率。

2.3 高效仿真小技巧

首先找到如下图所示的仿真编译文件 tb_VarCalculator_compile.do。

 打开这个文件,注释最后一行。

 修改完这个编译文件后, 后续你如果你的仿真代码或者你的功能模块代码有任何的改动,你改了之后先保存。

然后在ModelSim命令行输入三个命令(第一次输入后,后面你用上键↑下键↓就能快速输入了),编译 → 重启 → 运行。

就可以实现快速修改代码仿真。

2.4 仿真结果

 

分析一下仿真结果

1、可以看到仿真代码给出的data_in在0~255部分是和咱们模块内部的count变量一模一样的。仿真代码里面的for循环还是有点东西的,相信以后的仿真肯定可以借鉴。

2、仿真结果5588也是非常接近咱们用MatLAB算的0~255的方差的。 不能完全相等的原因是,我们的数据量个数是2^8,所以我们的除法是用的位移运算实现的。肯定会存在一定的误差。

3、咱们方差的计算结果延迟的3帧,

        1 首先时序逻辑肯定是要延迟1帧的,所以我在求所有数据的和、求所有数据的平方和的时候,就已经延迟了1帧。  

        2 其次,得到所有数据的和之后,我计算了所有数据的均值,这里又延迟了一帧。

        3 最后,在得到所有数据的均值之后,我又求了所有数据的平方和的均值 减去 均值的平方。

因此咱们总共延迟了三帧。 甚至我都担心最后一步在一个时钟周期内算不过来,还能再进行拆分,不过呢,这样延迟更多了,可能变成4帧或者5帧的。

这个很多帧延迟经常让人难以接受,所以我们下面用组合逻辑进行优化。

3 时序逻辑+组合逻辑 V2.0

组合逻辑是没有时钟延迟的。

当我用时序逻辑,求了所有数据的和,以及所有数据的平方和之后(延迟1帧)。

我可以用组合逻辑,就在当前时钟周期,立即得到:均值、均值的平方、平方和的均值、以及用平方和的均值减去均值的平方得到方差。

那么最终得到的方差,也只会延迟1帧。

3.1 Verilog代码

`timescale 1ns / 1psmodule VarCalculator(input   wire            clk      ,input   wire            rst_n    ,input   wire    [7:0]   data_in ,input   wire            valid_in,output  wire    [15:0]  variance,output  reg             valid_out
);//==================================================================
//                        Parameter define
//==================================================================
parameter       N = 256;//==================================================================
//                        Internal Signals
//==================================================================
reg     [31:0]  count;
reg     [15:0]  sum;
reg     [31:0]  square_sum;
wire    [7:0]   mean;
wire    [23:0]  square_mean;
wire    [15:0]  mean_square;assign square_mean = square_sum >> 8;
assign mean_square = mean * mean;
assign variance = ( valid_in==1'b1 && count == N ) ? (square_mean - mean_square) : 'd0;
assign mean = (valid_in==1'b1 && count == N) ? (sum >> 8) : 'd0;//----------------------------- valid_out -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginvalid_out <= 1'b0;     endelse if (count == N-1)beginvalid_out <= 1'b1;endelse beginvalid_out <= 1'b0;end
end//----------------------------- count -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) begincount <= 'd0;     endelse if (valid_in==1'b1)beginif (count == N) begincount <= 'd0;endelse begincount <= count + 1'b1;endendelse begincount <= 'd0;end
end//----------------------------- sum -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginsum <= 'd0;     endelse if (valid_in==1'b1)beginif (count == N) beginsum <= 'd0;                       endelse beginsum <= sum + data_in;endendelse beginsum <= 'd0;end
end//----------------------------- square_sum -----------------------------
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginsquare_sum <= 'd0;     endelse if (valid_in==1'b1)beginif (count == N) beginsquare_sum <= 'd0;                     endelse beginsquare_sum <= square_sum + data_in*data_in;endendelse beginsquare_sum <= 'd0;end
endendmodule

3.2 仿真结果

从仿真结果可看出,方差计算仍然正确,但是延迟只有1帧。 另外,其实咱们的verilog代码也要比V1.0版本精简一些。

本文之所得:

                1、ModelSim高效仿真小技巧(其实在前面的博文已经强调过一次,再次强调一遍,真的很高效)

                2、一个时序逻辑模块里面,尽量只给一个变量赋值。

                3、用组合逻辑可以优化时序逻辑的延迟。

相关文章:

FPGA_学习_13_方差计算小模块

测距器件APD的性能与器件本身的温度、施加在APD的偏置电压息息相关。 在不同的温度下&#xff0c;APD的偏压对测距性能的影响非常大。 要确定一个合适的APD的偏压Vopt&#xff0c;首先你要知道当前温度下&#xff0c;APD的击穿电压Vbr&#xff0c;一般来讲&#xff0c;Vopt Vb…...

如何安装多个版本的python,python可以装两个版本吗

这篇文章主要介绍了可不可以在同一台计算机上安装多个python版本&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 1、不同版本的python不能安装到同一台计算机上 可以的&#…...

深入理解JVM:Java使用new创建对象的流程

1、创建对象的几种方式 ①new 对象 ②反射 ③对象的复制 ④反序列化 2、创建对象流程 先看看常量池里面有没有&#xff0c;如果有&#xff0c;就用常量池的看这个类有没有被加载过&#xff0c;如果没有&#xff0c;就执行类加载以及类的初始化。&#xff08;对象的大小&#…...

【MySQL】索引与B+树

【MySQL】索引与B树 索引概念前导硬件软件方面 索引的理解单个page多个page引入B树B树的特征为什么B树做索引优于其他数据结构&#xff1f;聚簇索引与非聚簇索引辅助索引 索引的创建主键索引的创建和查看唯一键索引的创建和查看普通索引的创建和查看复合索引全文索引索引的其他…...

“使用Spring Boot快速构建Java Web应用“

标题&#xff1a;使用Spring Boot快速构建Java Web应用 摘要&#xff1a;本文介绍了如何使用Spring Boot快速构建Java Web应用。通过Spring Boot的自动配置和约定优于配置的特性&#xff0c;开发人员可以轻松地搭建一个简单且高效的Web应用。本文将通过一个示例代码详细演示Sp…...

面试题汇总——设计模式

简单介绍 设计模式共有23种,创建型模式5种,结构型模式7种,行为型模式11种 创建型: 关注对象的创建过程,将对象的创建和使用分开,在使用对象时无须知道对象的创建细节。对象实例化的模式,创建型模式用于解耦对象的实例化过程。单例模式、工厂方法模式、抽象工厂模式、建造…...

Java SpringMvc

0目录 java SpringMvc拓展 1.SpringMvc 创建工程&#xff0c;导入依赖 配置 web.xml文件 配置Spring配置文件&#xff0c;resources目录下新建applicationContext.xml 控制层配置 新建list.jsp并测试 Web.xml详解 如果required是true必须要传参 设置默…...

JVM运行时区域——对象创建内存分配过程

新创建的对象&#xff0c;都存放在伊甸园区域&#xff0c;当垃圾回收时&#xff0c;将伊甸园区域的垃圾数据销毁&#xff0c;然后将存活的对象转移到幸存者0区域&#xff0c;之后创建的新的对象还是存放在伊甸园区域&#xff0c;等到再次垃圾回收后&#xff0c;将伊甸园区域和幸…...

Springboot项目排除Bean的方法

前言&#xff1a; 在最近工作中&#xff0c;相关业务代码需要引用一个工具包。原来的同事在工具包中&#xff0c;封装了Spring AOP切面的Bean&#xff0c;但是这样的工具包非常不友好&#xff0c;工具包不应该有这些特殊的处理。有了这些特殊的处理&#xff0c;引用方也要特殊处…...

阿里云国际版云服务器防火墙设置

阿里云国际版云服务器防火墙设置 入侵防御页面为您实时展示云防火墙拦截流量的源IP、目的IP、阻断应用、阻断来源和阻断事件详情等信息。本文介绍了入侵防御页面展示的信息和相关操作&#xff0c;下面和012一起来了解阿里云国际版云服务器防火墙设置&#xff1a; 前提条件 您需…...

科技资讯|苹果开放Vision Pro头显开发套件申请,此前曝光三款电池

苹果今天宣布面向开发人员&#xff0c;正式接受 Vision Pro 头显开发套件申请&#xff0c;从而帮助其开发和测试应用程序。 苹果官方页面介绍&#xff0c;开发人员在获得 Vision Pro 头显开发套件之外&#xff0c;还可以获得设备设置和入门方面的帮助&#xff0c;与 Apple 专…...

Langchain 的 LLMChain

Langchain 的 LLMChain 1. 开始使用运行 LLM 链的其他方式解析输出从字符串初始化 LLMChain 是一个简单的链&#xff0c;它围绕语言模型添加了一些功能。它在整个LangChain中广泛使用&#xff0c;包括在其他链和代理中。 LLMChain 由 PromptTemplate 和语言模型&#xff08;LL…...

100天精通Golang(基础入门篇)——第17天:深入解析Go语言中的指针

&#x1f337; 博主 libin9iOak带您 Go to Golang Language.✨ &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &#x1f30a; 《I…...

第七章:WILDCAT: 弱监督学习的深度卷积神经网络用于图像分类、点位定位和分割

0.摘要 本文介绍了WILDCAT&#xff0c;一种深度学习方法&#xff0c;它旨在通过对齐图像区域来获得空间不变性和学习强烈局部化特征。我们的模型仅使用全局图像标签进行训练&#xff0c;并致力于三个主要的视觉识别任务&#xff1a;图像分类、弱监督的逐点对象定位和语义分割。…...

Axios-post请求下载文件

场景背景 1.一般来说&#xff0c;都是使用get请求后台接口&#xff0c;如此后台返回文件流于浏览器&#xff0c;则可直接下载。 2.那么除一般情况&#xff0c;就有特殊情况&#xff0c;比如你的请求接口参数特别长&#xff0c;此时便不可使用get请求&#xff0c;get请求的参数…...

视频增强技术-对比度增强

在图像处理中&#xff0c;由于获取的图像质量不好&#xff0c;需要通过对比度增强来提升图片质量&#xff0c;主要解决的是由于图像灰度级范围较小造成的对比度较低的问题&#xff0c;作用是使图像的灰度级范围放大&#xff0c;从而让图像更加清晰。主要对比度增强方法包括线性…...

uni-app点击按钮弹出提示框(以弹窗的形式显示),选择确定和取消

学习目标&#xff1a; 学习目标如下所示&#xff1a; uni-app点击提交按钮后弹出提示框&#xff0c;&#xff08;以弹窗的形式显示&#xff09;,提示用户是否确认提交&#xff08;即确定和取消&#xff09;&#xff0c;点击确定后调用真正的提交方法&#xff0c;将数据传给后端…...

linux部署es+kibana

部署kibana与es 3.4.1、拷贝文件 首先把elasticsearch-7.3.1-linux-x86_64.tar.gz 和kibana-7.3.1-linux-x86_64.tar.gz拷贝到linux上&#xff0c;比如我是拷贝/usr/local 目录下 3.4.2、解压文件 然后分别执行tar -zxvf elasticsearch-7.3.1-linux-x86_64.tar.gz和tar -zx…...

二十三种设计模式第十七篇--迭代子模式

迭代子模式是一种行为型设计模式&#xff0c;它允许你按照特定方式访问一个集合对象的元素&#xff0c;而又不暴露该对象的内部结构。迭代子模式提供了一种统一的方式来遍历容器中的元素&#xff0c;而不需要关心容器的底层实现。 该模式包含以下几个关键角色&#xff1a; 迭…...

《零基础入门学习Python》第056讲:论一只爬虫的自我修养4:网络爬图

今天我们结合前面学习的知识&#xff0c;进行一个实例&#xff0c;从网络上下载图片&#xff0c;话说我们平时闲来无事会上煎蛋网看看新鲜事&#xff0c;那么&#xff0c;熟悉煎蛋网的朋友一定知道&#xff0c;这里有一个 随手拍 的栏目&#xff0c;我们今天就来写一个爬虫&…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...