- 博客(129)
- 资源 (3)
- 收藏
- 关注
原创 零点和极点到底影响了什么?什么是最小相位系统?
零点和极点到底影响了什么?什么是最小相位系统? 零点、极点、稳定、因果、最小相位是信号系统中经常听到名词,也许有的同学对这些概念有所了解,但对它们之间的关系却不甚了解,这篇文章我们就来看一下,它们之间到底有什么关系?零点和极点是怎么对系统产生应影响的? 下面我们先来看几个信号系统中的基本概念,知道了这几个概念才能继续深入下去。1. 信号系统基本概念1.1 静态系统和动态系统 如果一个离散系统在任意时刻n的输出至多依赖于同一时刻的输入样本,而与过去或者将来的输入样本无关,那么该系统就称为静态的
2021-01-28 14:27:35 19754
原创 为什么高斯白噪声的平均功率等于方差?
功率和方差这两个概念,一个是表示信号的强度,一个是表示随机信号的一个统计量,为什么高斯白噪声的平均功率会等于它的方差呢?什么是高斯白噪声? 维基百科上给出的解释是:在通信领域中指的是一种功率谱函数是常数(即白噪声),且幅度服从高斯分布的噪声信号。因其可加性、幅度服从高斯分布且为白噪声的一种而得名。自相关函数 高斯白噪声是一种平稳的随机过程,假设该过程为$ \xi (t) $,那么其自相关函数的定义如下:R(τ)=E[ξ(t)ξ(t+τ)]R(\tau) = E[\xi(t) \xi(t+
2021-01-17 23:52:54 8433
原创 如何写出高性能的Python之缓存的应用
缓存有什么作用? 能看到这篇文章的同学,应该都对缓存这个概念不陌生,CPU中也有一级缓存、二级缓存和三级缓存的概念。缓存可以解决哪些问题?我们直接把网上的一段话放上来:性能——将相应数据存储起来以避免数据的重复创建、处理和传输,可有效提高性能。比如将不改变的数据缓存起来,例如国家列表等,这样能明显提高web程序的反应速度;稳定性——同一个应用中,对同一数据、逻辑功能和用户界面的多次请求时经常发生的。当用户基数很大时,如果每次请求都进行处理,消耗的资源是很大的浪费,也同时造成系统的不稳定。例如
2021-01-07 23:54:39 254
原创 Python高性能计算之修饰符wraps
修饰符functools.wraps 其实整个functools模块都值得讲一下,我们后面会出一个专门的文章来讲。今天我们先来看下functools.wraps。 在本节内容开始前,首先要了解什么是修饰符?可以参考我们之前整理的一篇文章。Python修饰符详解,这这篇文章中我们可以看到,修饰器的一般形式是:def works_for_all(func): def inner(*args, **kwargs): print("I can decorate any functi
2020-12-06 23:08:28 189 1
原创 Python修饰符 详解
修饰符(有的也翻译成装饰符、装饰器,英文叫decorator)是Python中一个很有意思的feature,它可以向已经写好的代码中添加功能。这其实也叫元编程,因为程序的一部分在编译的时候尝试修改程序的另一部分。高阶函数 在学习Python的修饰符前,我们要知道几个a概念,首先是Python中的所有东西都是对象,所有我们定义的变量、类甚至与于函数,都是对象。函数是对象是个什么概念呢?就是函数之间可以相互赋值:def first(msg): pritn(msg) first("Hello")
2020-12-06 14:17:55 6507 1
原创 System Generator 教程
System Generator & Vivado HLS数字信号处理教程(暨FPGA高级数字信号处理教程)已经发布,包含如下内容可能有同学会有疑问,FPGA数字信号处理的教程网上有很多,为什么还要再出一个?当然是我们不一样,而且我们的教程更加系统性和实用性。目前市面上绝大多数的教程都是在讲Vivado中的数字信号处理相关的IP的应用,而我们本次教程使用的工具是System Generator和HLS,其中System Generator中的IP跟Vivado中的IP用法很像,但用Sys
2020-12-05 11:49:56 2119
原创 Python嵌套函数 闭包 详解
1. 什么是嵌套函数 嵌套函数就是在函数中定义函数,英文叫nested functiondef outer(x): def inner(): print(x) inner()这也很好理解,在函数outer中定义了另外一个函数inner,而inner也必须在outer中被调用才能执行。我们还可以直接把内容定义的函数当做返回值:def outer(x): def inner(): print(x) return inner()这样
2020-11-30 08:59:53 1335
原创 IMU标定(二)随机误差的标定
IMU标定(二)随机误差的标定一、allan方差基本原理 allan方差是一种时域分析技术,一般用于仪器的噪声研究,是公认的IMU参数分析方法,其主要思路是利用不同相关时间内所表现的不同特征来描述各种噪声源,其噪声模型为:σ2(τ)=∑n=−22Cnτn\sigma^2(\tau)= \sum_{n=-2}^2C_n\tau^nσ2(τ)=n=−2∑2Cnτn 对于IMU来说,主要包含五类噪声源,量化噪声Q,角度随机游走N,零偏不稳定性B,速率随机游走K,速率爬坡R,这五类噪声源的具体推
2020-11-29 20:29:00 1606 1
原创 Python常用操作的复杂度
我们前面讲过list、deque、堆、字典树等高性能计算的技巧,这一节我们来整理一下Python中常用操作的时间复杂度。本文中的N表示容器的元素数量,K表示参数中元素的数量或参数的值。listlst = list(range(10,20))l1 = list(range(100,105))操作时间复杂度描述lst[2]O(1)访问元素lst.pop()O(1)弹出最后一个值lst.append(l1)O(1)在末尾添加元素lst.exte
2020-11-22 13:39:05 487
原创 Python高性能计算之字典树
很多同学可能没有听过字典树,它也被称为前缀树,虽然知名度不高,但在某些地方很有用,它在列表中查找与前缀匹配的字符串方面,速度极快,因此非常适合用来实现输入时查找和自动补全功能。 Python的标准库中并未提供字典树,但我们可以通过pytricia这个库来实现。下面我们先来看下用Python标准库中的方法来实现前缀匹配的功能。 首先,定义一个包含随机字符串的列表,字符串中的字符均为大写字母:from random import choicefrom string import ascii_up
2020-11-21 21:20:01 523
原创 Python高性能计算之堆
很多Python的初学者可能对Python中的堆不太了解,堆是一种用于快速查找并提取集合中最大值或最小值的数据结构,它的典型用途就是按照优先级处理一系列的任务。 我们在前面讲列表和双端队列时,讲到过列表中的查找操作的时间复杂度是O(N),但如果列表是有序的,我们就可以使用模块bisect实现时间复杂度为O(log(N))的查找操作。但虽然查找的时间缩短了,但如果要再进行插值,时间复杂度依然是O(N)。而堆是一种效率更高的数据结构,其元素插入操作和最大值提取操作的时间复杂度都是O(log(N))。
2020-11-20 13:16:38 245
原创 Python高性能计算之字典
在Python中,字典是以散列映射的方式实现的,在插入、删除和访问元素方面的时间复杂度都是O(1)。 在Python3.5及之前的版本中,字典是无序集合,但从Python3.6开始,字典能够保留元素的插入顺序 散列映射就是将key和value关联的一种数据结构,散列函数就是哈希(hash)函数。熟悉哈希函数的朋友应该知道,哈希函数的冲突是不可避免的,但我们平时在使用Python的字典时,无需考虑这个因素,因为大多数情况下,默认的冲突解决方案都是有效的。 上一节“Python高性能计算之列表”
2020-11-19 09:31:43 571 1
原创 如何确定插值滤波器的阶数
在信号处理中,滤波器的系数我们往往都是通过MATLAB来设计,只要我们知道滤波器的通带截止频率和阻带起始频率,就可以通过MATLAB中的fdatool(在MATLAB2020中使用filterDesigner)来设计滤波器了。 我们使用归一化的参数来设计,通带截止频率是025,阻带起始频率是0.3,通带内纹波是0.2,阻带衰减是60dB,参数设置如下: 那么问题来了,对于插值滤波器,如何确定通带和阻带的频率呢?这就涉及到我们刚开始学习数字信号处理时的插值和抽取理论。当信号抽取时,在数字频率上,
2020-11-17 22:39:45 6773
原创 IMU标定
6轴IMU包含3轴加速度计与3轴陀螺仪(9轴IMU还包含磁力计),加速度计输出三轴独立的加速度信号,陀螺仪输出独立的三轴角速度信号。下面重点分析一下IMU的误差模型。一、IMU误差来源1.1 轴偏角误差(Axis Misalignments)理想情况下,XYZ三轴相互正交,且加速度计与陀螺仪相互重合,但一般加速度计与陀螺仪分开制造,其坐标系并不重合,且加速度计与陀螺仪三轴也分开制造,其三轴也不完全正交,因此带来了轴偏角误差,用公式TTT表示轴偏角误差的变换矩阵。其中陀螺仪与加速度计的轴偏角通过坐标系转
2020-11-16 23:20:09 5209 1
原创 Python高性能计算之列表
接下里的系列文章中,我们将讲一下Python高性能计算,如何提高Python的计算性能?有哪些好用的库?请持续关注我们。第一节我们先来讲列表。 Python列表是有序的元素集合,在Python中是使用大小可调整的数组实现的。数组是一种基本的数据结构,由一系列连续的内存单元组成,其中每个内存单元都包含指向一个Python对象的引用。 列表在访问、修改和增加元素方面,速度都非常快。其中访问和修改元素,都需要从底层数组的相应位置获取对象引用,因此其复杂度是O(1)。增加元素的话,跟C++中的Vecto
2020-11-15 17:29:44 317
原创 Vivado HLS教程整理(一)任意精度数据类型
本文整理自高亚军老师的Vivado HLS视频教程,完整的笔记在公众号“Quant_Times"中回复”HLS“即可获取。System Generator & HLS数字信号处理教程暨FPGA高级数字信号处理教程:System Generator & HLS数字信号处理教程1. HLS新的数据类型C/C++数据类型:其中HLS中不支持char16_t和char32_t两种数据类型。在C/C++中,所有的数据位宽都是基于8-bit,即位宽都是8-bit的倍数,当在逻辑中使用时,会明
2020-11-14 22:45:33 1578
原创 Python教程之粒子运动轨迹动态绘图
(本文整理自《Python高性能》) 今天我们来讲一下Python中的动态绘图库–matplotlib.animation,以粒子运动轨迹为例来说明如何绘制动态图。 假设按照圆周运动,如下图所示:为了模拟这个运动,我们需要如下信息:粒子的起始位置、速度和旋转方向。因此定义一个通用的Particle类,用于存储粒子的位置及角速度。class Particle: def __init__(self, x, y, ang_vel): self.x = x se
2020-08-30 17:51:43 8090
原创 Hold Time违例,该如何解决
首先,我们要知道的是,Hold Time违例,是因为时钟绕的太远,到达时间太晚。而且综合之后给出的时序报告都是估计值,因此综合之后可以不考虑Hold Time,只考虑Setup Time;即便此时Hold Time违例,我们也不需要去理会。在Place Design之后再去看Hold Time,如果此时Hold Time的违例比较小(比如-0.05ns),还是不需要理会的,因为工具在布线时会修复Hold,但如果Slack太大了,无法修复了,就会牺牲setup来弥补hold。这里补充一下综合实现的步骤:
2020-08-12 18:28:14 6994 2
原创 Vivado时序收敛技术(二) 时序违例的根本原因及解决方法
本文整理自Xilinx公开课:Vivado时序收敛技术。有些知识在公开课中讲的并不是很细,因此我又对齐进行了整理,分为了几篇文章。有很多内容也在我的时序约束课程中讲到过,都是免费课程,大家可以在我的知乎专栏上找到。FPGA Times如果出现了时序违例,我们会关注两点:为什么会出现时序违例?如何解决?首先我们要搞清楚时序是在哪个阶段违例:在综合阶段或者post opt阶段出现了时序违例,那么很有可能的原因如下:添加的时序约束没有生效约束过于严苛综合选项设置不正确电路设计中延
2020-08-11 09:40:55 6216
原创 Vivado时序收敛技术(一) Baseline基础理论
本文整理自Xilinx公开课:Vivado时序收敛技术。有些知识在公开课中讲的并不是很细,因此我又对齐进行了整理,分为了几篇文章。有很多内容也在我的时序约束课程中讲到过,都是免费课程,大家可以在我的知乎专栏上找到。FPGA Times如何知道该约束哪些时钟? 使用report_clock_networks指令或使用约束向导来查看有哪些主时钟需要约束和输入的主时钟是否被约束。report_clock_networks -name primaryClock如何检查时钟的约束? 使
2020-08-10 17:29:10 1308
原创 GPU编程3--GPU内存深入了解
emsp; 我们在GPU的基本概念一节中,讲到过GPU中的内存模型,但那一节只是对模型的简单介绍,这一节,我们对GPU的内存进行更加深入的说明。 首先来回顾一下GPU中的内存:每个线程都有自己的私有本地内存(Local Memory)和Resigter每个线程都包含共享内存(Shared Memory),可以被线程中所有的线程共享,其生命周期与线程快一致所有的线程都可以访问全局内存(Global Memory)只读内存块:常量内存(Constant Memory)和纹理内存(Texture M
2020-08-08 19:28:32 1437
原创 使用SystemVerilog简化FPGA中的接口
FPGA工程师们应该都会吐槽Verilog的语法,相当的不友好,尤其是对于有很多接口的模块,像AXI4/AXI-Lite这种常用的总线接口,动不动就好几十根线,写起来是相当费劲。 当然现在Xilinx推荐使用纯bd文件的方式来设计FPGA,这样HDL代码就会少了很多。但我们大多数的工程还是无法避免使用HDL来连接两个module。所以本文就推荐使用SystemVerilog来简化FPGA中接口的连接方式。 也许很多FPGA工程师对SystemVerilog并不是很了解,因为以前的FPGA开发工具
2020-07-20 23:50:25 733 2
原创 Simulink/System Generator中自动布线
该工具适用于Matlab2011b之后的版本,如果layout type被设为了GraphPlot,就需要2015b之后的版本。关于layout type后面会讲到。将解压后的文件夹放到Matlab的搜索路径下,什么是Matlab的搜索路径? 很简单的一种方式就是在Matlab的命令行窗口下输入"path",就可以打印出来,如下图。这里,我放到了第一个路径下。执行sl_refresh_customizations指令,刷新context menu双击这个.mltbx文件会弹..
2020-06-30 14:30:40 2926
原创 GPU编程2---CUDA核函数和线程配置
CUDA核函数 在GPU上执行的函数称为CUDA核函数(Kernel Function),核函数会被GPU上多个线程执行,我们可以在核函数中获取当前线程的ID。// CUDA核函数的定义__global__ void addKernel(int *c, const int *a, const int *b){ int i = threadIdx.x; c[i] = a[i] + b[i];}// CUDA核函数调用addKernel<<<Dg,Db, Ns
2020-06-29 12:47:12 2186
原创 GPU编程1--- GPU中的基本概念
硬件资源 在硬件上,GPU的资源有SP和SM。SP:最基本的处理单元,streaming processor,也称为CUDA core。最后具体的指令和任务都是在SP上处理的。GPU进行并行计算,也就是很多个SP同时做处理。我们所说的几百核心的GPU值指的都是SP的数量;SM:多个SP加上其他的一些资源组成一个streaming multiprocessor。也叫GPU大核,其他资源如:warp scheduler,register,shared memory等。SM可以看做GPU的心脏(对比CP
2020-06-26 11:32:40 716
原创 ubuntu 18.04 安装Kaldi教程(总结安装过程中碰到的坑)
在Ubuntu 18.04上安装Kaldi时,按照《Kaldi 语音识别实战》书中的步骤进行,但发现在安装过程中碰到了很多问题。基本上每一步都有问题,所以就总结了一下碰到的一些坑,朋友们可以参考一下。(在进行安装前要保证显卡的驱动和Cuda都已经安装好)下载Kaldi代码,Github: Kaldi切换到下载的kaldi文件夹,并查看依赖库是否安装:cd kalditools/extras/check_dependencies.sh由于是第一次安装,所以很多依赖库应该都是没有的,会出现
2020-06-15 19:26:34 3560 4
原创 Xilinx FPGA Partial Reconfiguration 部分重配置 详细教程
Partial Reconfiguration(部分重配置)在现在的FPGA应用中越来越常见,我们这次的教程以Project模式为例来说明部分重配置的操作过程。 这里我们使用的Vivado版本是2017.2,使用的例程是Vivado自带的wavegen工程,并在工程中增加一个计数器模块,如下图所示这个模块的代码也很简单,就是加1计数module count_add( input clk, input rst, output reg [7:0]
2020-06-11 18:07:49 7906 5
原创 为什么信号的时宽带宽积是常数?
E(w)=∑n=−∞+∞n∣w(n)∣2∥w∥22E(w)=\frac{\sum_{n=-\infty}^{+\infty} n|w(n)|^{2}}{\|w\|_{2}^{2}} E(w)=∥w∥22∑n=−∞+∞n∣w(n)∣2Δ(w)=∑n=−∞+∞(n−E(w))2∣w(n)∣2∥w∥22\Delta(w)=\sqrt{\frac{\sum_{n=-\infty}^{+\infty}(n-E(w))^{2}|w(n)|^{2}}{\|w\|_{2}^{2}}}Δ(w)=∥w∥22∑n=
2020-06-08 22:05:30 7832 1
原创 Matlab中相见恨晚的命令(持续更新)
知乎上有个“有哪些让人相见恨晚的Matlab命令”的话题,很多答主提供的命令确实很实用,为了更方便大家的学习,我就知乎上的答案和我自己想到的都综合整理成了一篇文章,把我觉得很实用的指令整理出来。知乎原答案链接dbstop if error 如果运行出错,matlab会自动停在出错的那一行,并保存相关变量,非常好用的指令,谁用谁知道。配合这个指令一起使用的是dbup和dbdown,这两个指令用于workspace间切换查看变量调试,dbup是调到上层workspace,dbdown是返回。li
2020-05-27 20:16:46 1122
原创 Matlab中短时傅里叶变换 spectrogram和stft的用法
在Matlab中,做短时傅里叶变换需要使用函数spectrogram,而在Matlab2019中,引入了一个新的函数stft,下面我们就来看下这两个函数都如何使用。 短时傅里叶变换的基本原理就是将数据分段加窗,做fft,在分段时会有overlap,因此一个向量的短时傅里叶变换结果是一个矩阵。了解了这点,下面的函数及参数就更加容易理解了。spectrogram参数列表 先来看spectrogram函数,在更早期的版本中,这个函数的名字是specgram,几种常用的用法如下:spectrogr
2020-05-25 19:22:29 17982 8
原创 搞定Markdown中的图片,一劳永逸的方法!
经常用markdown写博客的朋友一定都体会过markdown图片的蛋疼之处,并不是说图片的这用引用方式不好,而且图片要放到什么服务器上? 以我个人为例,写了一篇markdown,想在不修改任何地方的同时适用于各种平台。 刚开始使用markdown时,图片都放到github上,但github空间有限,而且主要问题是国内的网站访问github经常会有问题,导致图片显示不出来。 后来又想了个办法,由于我一直在用有道云写笔记,所以就在有道云markdown文件的同一个目录下建一个名为pic的笔记,
2020-05-23 17:16:40 5554 1
原创 C++ map和unordered_map详解
概述 C++中map和unordered_map提供的是一种键值对容器,在实际开发中会经常用到,它跟Python的字典很类似,所有的数据都是成对出现的,每一对中的第一个值称之为关键字(key),每个关键字只能在map中出现一次;第二个称之为该关键字的对应值(value)。map和unordered_map ...
2020-05-20 13:13:56 965
原创 Matlab中fft与fwelch有什么区别?如何用fft求功率谱?
讲这个话题,就要先搞清楚频谱、功率谱的概念,可参考我的另一篇文章信号的频谱 频谱密度 功率谱密度 能量谱密度的区别做信号处理的朋友应该都会fft比较熟悉,就是求傅里叶变换。我在这里也不再去讲这个函数了,但需要注意的一点...
2020-05-10 23:29:11 6514 4
原创 C++ const使用教程,有哪些需要注意的地方?
常量在C++中经常用到,用关键字const表示,它是常数变量,也就是说,它仍然是变量,而不是常数。什么区别呢?编译器会为变量在内存中分配地址空间,而常数是编译器在编译过程中记录在内存表里一个实体。常量定义const int a = 10;在定义完之后,就不能再修改常量a的值了。如果是在不同的文件中使用,需要用到关键字externextern const int a ;这样表示...
2020-05-03 11:41:58 177
原创 Vivado中jobs和threads的区别?选择多个jobs能加快实现速度么?
在用Vivado对工程编译时,会弹出下面的对话框:备注:虽然FPGA不能叫编译,但很多工程师为了方便起见,将综合+实现+生成bit文件的过程统称为编译了,这种说法大家理解就好。很多工程师都会选择多个jobs进行编译,以为这样会更快一些,而且这个jobs的数量跟本地CPU的线程数是一致的,这就更加让工程师们认为这个选项就是多线程编译了。 但对Vivado更加熟悉的工程师,肯定会知道...
2020-04-26 13:12:35 2485 4
原创 C++ 内联函数 inline的详细分析
1. 什么是内联函数? 就是使用了关键字inline的函数,如inline int max(int a, int b){ return a > b ? a : b;}2. 内联函数有什么作用? C++在调用函数时,会执行一系列的操作:将参数push到堆栈中将返回地址push到堆栈中准备返回值将所有push到堆栈的东西都pop出来 这一系列的操作无疑增...
2020-04-23 09:54:07 393
原创 C++ vector用法详解
vector概述 vector是种容器,类似数组一样,但它的size可以动态改变。 vector的元素在内存中连续排列,这一点跟数组一样。这意味着我们元素的索引将非常快,而且也可以通过指针的偏移来获取vector中的元素。 但连续排列也带来了弊端,当我们向vector中间插入一个数据时,整个vector的size变大,在内存中就需要重新分配空间,常规的做法是直接申请一个新的array,...
2020-04-21 14:36:23 2857
原创 Vivado中模块封装成edif和dcp
我们完成Vivado的工程后,大部分情况不能把整个工程的源代码都直接给客户或者其他工程师,需要我们先进行一些封装后再给他们,就像软件代码中会编译成dll后再Release给别人。 在Vivado中,常用的三种封装形式有三种:IPedifdcp这三种封装形式在使用上都是相似的,都是我们只提供模块的接口让用户去调用。 这篇文章我们讲一下封装成edif和dcp的步骤、区别、注意事...
2020-03-01 16:13:09 8662 5
原创 FPGA中除法是怎么实现的?
在FPGA中,我们怎么实现除法操作?最简单的方法当然是调IP Core。 在Divider Generator的IP Core中,我们可以选择有/无符号数进行除法,还可以选择除法的延迟。当然,延迟越小,占用的资源就越多。 虽然有IP可以直接调用,但我们还是要了解FPGA中除法的原理,手动来写一个除法器。FPGA中除法原理 两个32的无符号整数除法,被除数a除以除...
2020-02-15 16:56:57 10704
原创 什么是噪声温度?-174dBm/Hz又是什么?
在信号处理系统中,我们经常会听到噪声温度这个概念,而且噪声温度的量纲也是K(凯氏温度), 那噪声温度是什么意思呢?为什么会用温度来衡量噪声的大小?K和℃的换算关系:[℃] = [K] - 273.15我们常说的绝对零度就是−273.15℃,即0K。 首先,要明确的一点是:噪声温度其实就是噪声功率的一种表示方法,至于为什么要用温度来表示功率大小?直接用功率不好么? 要解释噪声温...
2020-02-11 13:25:05 28921 3
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人