IQ调制
IQ调制
假设要发送的基带码元为,其中是同相分量,是正交分量。首先对码元做上变频 取其实部得到调制后的信号为
接收端收到的信号为 进行下变频 再通过积分器或者低通滤波器 得到原始码元.
DDS Compiler
DDS Compiler
设计原理
一个正弦波的幅度不是随时间线性变化的,但是相位是时间的线性函数。因此可以考虑用一个线性递增的变量存储相位,再将相位转换成相应的正弦波幅度。
首先存储一个周期的正弦波,然后将相位用比特量化,即平均分成份,以的频率每始终周期转动,则可以得到输出频率为的信号,
可以看出,输出频率是参考时钟频率、相位量化位宽、和相位增量(频率控制字)的函数。增加频率控制字,将得到更高频率的信号。
根据奈奎斯特采样定律,为了使波形不失真,需要满足,则有
始终小于,不妨将其看成是一个分频器,通过修改频率控制字分频参考时钟,获得所需要的频率。
组成结构
如图,直接式数字频率合成器(Direct Digital Synthesizer,DDS)主要由相位累加器、波形查找表、数模转换器和低通滤波器等部分组成。
其中的核心部分是相位累加器,由一个位累加器和位寄存器构成,在每个参考时钟上升沿,累加器将频率控制字与累加寄存器的输出相加,结果作为寄存器新的输入。如此反复, 当累加器累加满时, 就会发生溢出,完成一个周期, 即DDS合成信号的一个频率周期。
波形查找表(Lookup ...
侵入式链表
侵入式链表(Intrusive Linked
List)
设计思想
常用的链表是非侵入式链表,它的每个节点包含数据和指向下一个节点的指针(和一个指向前一个节点的指针)
12345struct ListNode { int data; struct ListNode *next; struct ListNode *prev;}ListNode;
在这种链表结构中,data是固定的,即一个链表中,每个节点存储的数据类型必须相同,这样的链表泛化能力比较差。
注:C++语言可以使用模板实现通用:
12345template <typename T>struct ListNode { struct ListNode *next; // link区域 T data; // data区域};
但这只不过是将重写代码的工作交给编译器完成,本质上数据和链表仍然是耦合的。
侵入式链表是在其内部直接包含链表节点:
12345678struct ListLink { struct ListLink *nex ...
二进制相移键控
二进制相移键控(BPSK)
基础
BPSK的时域表达式是
:待发送的二进制信息
:符号周期
:成型滤波器的冲激响应
:载波中心频率
:未必整数倍
MATLAB仿真
按照上图流程进行MATLAB仿真
调制与解调
设定参数:系统时钟频率为,根升余弦滤波器滚降系数,其它参数可修改
1234567sys_clk = 160e6;Rb = 5e6; % //FIXMERs = Rb; Ts = 1 / Rs;usmp_rate = sys_clk / Rs; % //FIXMEfc = 20e6; % //FIXMEhrc = 'rrc'; % //FIXME
随机生成num个二进制数,并对极化处理:
1234num = round(100000 * 10 ^ (EbNo / 10));b = randi([0 1], 1, num);b_sign = 1 - 2 * b;% b_sign = exp(1j * pi * b) % 1 ...
锁相环
锁相环(PLL)
时钟生成
晶振可以产生稳定的时钟周期,但频率只能是在兆赫兹的量级。PLL利用晶振作为参考时钟,可以输出一个更高频率的时钟信号,提供给时序电路使用。
如图所示,锁相环(Phase-Locked
Loop,PLL)由鉴相器(PD)、环路滤波器(LF)和压控振荡器(VCO)三部分组成。实现的是输出与输入相等,最终得到稳定的输出频率.
PLL的原理是其中的VCO的振荡频率随着输入电压变化而变化,它的输出就是整个PLL的输出,也就是我们最终拿到的时钟信号。VCO的输出会反馈回PLL,由PD比较他们两
者的相位。如果晶振相位稍快,就把VCO输入电压调低,如果晶振相位稍慢,就把VCO输入电压调高,从而得到稳定的高频时钟信号。
数据重定时
PLL还可以用来做时钟恢复和数据重定时。
如图所示,经过传输线后的信号波形变得不稳定。可以考虑将数据作为参考,输入到PLL中,恢复一个与数据同步的时钟,用该时钟信号和D触发器重新对数据采样,得到新的重定时数据。
参考资料
张肃文.高频电子线路.第5版[M].高等教育出版社,2009.432-458
时序分析
时序分析
时序约束
建立时间:在时钟上升沿的时间前数据必须是稳定的;
保持时间:时钟上升沿之后的时间内数据必须是稳定的;
传播延迟:时钟上升沿到输出端信号稳定所需要的时间;
污染延迟:时钟上升沿到输出端信号开始变化所需要的时间;
建立时间与保持时间
如左图所示,对的输入要在之前稳定,因此要满足关系: 如右图所示,在接收数据后要保持时间,这段时间内不能被干扰,因此组合逻辑的输入必须在之后,因此要满足关系:
时钟偏移与抖动
时钟偏移(Clock Skew)
时钟信号到达各寄存器的时间不同,将定义为两个时钟边沿的间隔。
如左图,由于CLK2比CLK1早了,因此输入到来要更提前,需满足关系
如右图,CLK2比CLK1晚了,因此前面组合逻辑的输出要再晚一段时间到达,才能保证不干扰本来的数据,需满足关系 注:相反的时钟信号关系不会影响上述的时序约束。
时钟抖动(Clock Jitter)
Skew会改变时钟边沿的顺序,不会改变时钟信号的占空比;时钟抖动会改变时钟信号的占空比。
考虑时钟抖动时,要考虑“最差的情况”。分析过程与时钟偏移(Clo ...
结构体成员变量的字节对齐
结构体成员变量的字节对齐
编译器版本(MinGW及其衍生品,比如TDM-GCC可能不支持#pragma pack(n), n>1,参见mingw-and-packed-struct-alignment-using-c11)
12345❯ gcc --versiongcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0Copyright (C) 2021 Free Software Foundation, Inc.This is free software; see the source for copying conditions. There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
本文讨论的对齐属性
123#pragma pack(n)__attribute__((packed));__attribute__((aligned(8)));
完整验证代码见文末
在Linux环境下char占字节 ...
垃圾回收机制
垃圾回收机制(以Java为例)
垃圾回收(GC)
垃圾回收(Garbage
Collection),指的是对内存堆中长时间未使用的对象进行回收。
在Java中,垃圾回收通常是由JVM的GC线程自动完成的,开发者不需要手动实现。
如何定义垃圾
引用计数算法
引用计数算法(Reachability
Counting)是通过在对象头中分配一个空间来存储该对象被引用的次数。如果该对象被其它对象引用,则它的引用计数加,如果删除对该对象的引用,那么它的引用计数就减1,当该对象的引用计数为0时,那么该对象就会被回收。
引用计数算法是将垃圾回收分摊到整个应用程序的运行当中,而不是在进行垃圾收集时挂起整个应用的运行,直到对堆中所有对象的处理都结束。因此,采用引用计数的垃圾收集不属于严格意义上的Stop-The-World的垃圾收集机制。
但是,现在JVM的垃圾回收机制是Stop-The-World的,考虑这个例子
123456789101112131415161718public class ReferenceCountingGC { public Object in ...
支持向量机
支持向量机(SVM)
支持向量机是一种用于分类的算法。如果数据是线性可分的,只需要将直线放置在让点距离平面距离最大的位置,寻找这个最大间隔的过程叫做最优化;如果数据不是线性可分的,需要用核函数改变维度,用超平面做分类……
线性SVM
如图,数据显然是线性可分的,这些将它们分类的直线称为决策面,每个决策面对应一个线性分类器。但是将它们分开的直线显然不止一条。目前和的分类效果相同,但如果再增加一个点(在和之间),就会出现分类错误。
图中虚线的位置由决策面的方向和距离决策面最近的几个样本位置决定,虚线穿过的样本点称为支持向量,中间的部分是分类间隔。具有最大间隔的决策面就是SVM要找的最优解。
数学建模
目标函数:希望使得什么指标最好,即分类间隔
优化对象:可以改变的影响因素,即决策面
优化对象(决策面)
在二维空间中,一条直线可以表示为 设其中,,是这条直线的法向量,是截距。把二维平面的直线推广到维空间,就得到了超平面方程 此时的,。
目标函数(分类间隔)
分类间隔的大小是支持向量的样本点到决策面距离的二倍,二维平面中,点到直线的距离公式是
...
反向传播算法
反向传播算法
当网络给出预测之后,需要根据预测值与实际标签的差异调整网络中的权重和偏置,以便模型在将来能够更好地预测。这个调整过程称为反向传播(误差计算→梯度计算→参数更新)。
神经网络的结构
假设一共有层网络,激活函数为,表示未激活的状态,表示激活后的状态。
损失函数为 损失函数对的偏导数为
基本方程
为了实现参数更新,我们需要计算和, 其中涉及到激活函数即,为了简化计算,先定义一个中间变量:
输出层的 推广到,得到
对于层,
其中中影响了图中红线所示部分 同理,可以得到
对于任意第层,
下面计算和,
算法流程
输入数据
前向传播
反向传播误差
梯度下降,更新参数
代码实现
1234567891011121314151617181920212223242526272829303132333435def backprop(self, x, y): """Return a tuple ``(nabla_b, nabla_w)`` representing the ...