首页
游戏
影视
直播
广播
听书
音乐
图片
更多
看书
微视
主播
统计
友链
留言
关于
论坛
邮件
推荐
我的硬盘
我的搜索
我的记录
我的文件
我的图书
我的笔记
我的书签
我的微博
Search
1
在IC617中进行xa+vcs数模混仿
81 阅读
2
virtuoso和empyrean alps模拟仿真和混仿教程
74 阅读
3
科普:Memory Compiler生成的Register file和SRAM有何区别?
73 阅读
4
后仿中$setup,$hold与$setuphold
44 阅读
5
文档内容搜索哪家强? 15款文件搜索软件横向评测
35 阅读
默认分类
芯片市场
数字电路
芯片后端
模拟电路
芯片验证
原型与样片验证
算法与架构
DFX与量产封装
PC&Server OS设置
移动OS设置
软件方案
新浪备份
有道备份
登录
Search
标签搜索
python
Docker
vscode
linux
systemverilog
vcs
STM32
PyQT
EDA
FPGA
gvim
cadence
Alist
xilinx
UVM
uos
macos
package
MCU
risc-v
bennyhe
累计撰写
378
篇文章
累计收到
31
条评论
首页
栏目
默认分类
芯片市场
数字电路
芯片后端
模拟电路
芯片验证
原型与样片验证
算法与架构
DFX与量产封装
PC&Server OS设置
移动OS设置
软件方案
新浪备份
有道备份
页面
游戏
影视
直播
广播
听书
音乐
图片
看书
微视
主播
统计
友链
留言
关于
论坛
邮件
推荐
我的硬盘
我的搜索
我的记录
我的文件
我的图书
我的笔记
我的书签
我的微博
搜索到
378
篇与
的结果
2025-09-21
用Python设计芯片?开源设计语言PyGears亮相!
近日,加州大学洛杉矶分校引入了一种新的硬件描述语言PyGears,以实现基于可重用组件和高级 Python 构造的敏捷芯片设计理念。PyGears 是对快速发展的软件世界的回应,这要求硬件设计与可扩展和智能未来的需求保持同步。据官网介绍PyGears 是一种免费的开源硬件描述语言 (HDL),该门语言可作为 Python 库实现,专注于函数式编程、模块组合和同步。按照他们的说法,PyGears 的出现旨在将芯片设计的复杂性转变为简单、灵活且具有成本效益的开发过程,该过程遵循可扩展和智能的方式来构建未来。该框架允许您使用 Python 结构设计硬件并将其编译为可综合的 SystemVerilog 或 Verilog 代码。内置模拟器允许您使用任意 Python 代码及其大量库来验证您的硬件模块。PyGears 使连接模块 得容易 ,并具有内置的同步机制,可帮助您构建正确的并行系统。PYGEAR 的创造者Bogdan Vukobratovic表示:“PyGears 的诞生是为了捕捉我在职业生涯中发现的所有有用的良好实践,该工具可以显着加快复杂架构的硬件实现,尤其是当它们与 AI 范式相关时。这应该是创建下一代芯片设计的一个良好开端,但这个目标需要我们所有人为硬件开发做出贡献并确定其方向。否则,未来的人工智能世界将不可持续。”据报道,通过在 VLSI 信号处理课程中采用它, 加州大学洛杉矶分校 Samueli 工程学院 开始建立一个通过软件范式观察硬件的社区,目标是通过使用更灵活和可组合的模块来加速硬件设计和验证。“芯片设计变得越来越复杂,成本越来越高,开发周期越来越长,”加州大学洛杉矶分校电气和计算机工程教授 Dejan Markovic博士说。“PyGears 通过采用由志同道合的贡献者社区构建的可重用组件的模块化硬件构建来解决这些挑战。这对于小型和大型工程团队都非常有效。硬件设计和验证基于Python环境,减少了软硬件领域的壁垒。我们的愿景是让软件人员能够编写硬件代码。”“软件的最大限制是硬件发展速度相对较慢,” Lux Capital 的合伙人Shahin Farshchi说。“PyGears 站在巨人的肩膀上,将硬件设计加速到接近‘编码’的速度,这将带来神奇的新用例,为定义市场的产品和公司提供支持。”PyGears的创建者兼 Anari AI 研发负责人Bogdan Vukobratovic博士表示,当前的工具行业倾向于对硬件开发中的所有组件进行低级优化和低级控制。另一方面,PyGears 提供对所有方面直至最低层的控制,使流程效率提高数倍。他还强调,构建复杂的架构需要具有更高开发敏捷性的系统。根据斯坦福大学教授 Boris Murmann博士的说法。,“新硬件设计工具的开发可以极大地受益于开源解决方案。为了让硬件行业摆脱石器时代并使其更加敏捷,我们需要社区塑造的新概念。”除了 UCLA 学生和其他大学,PyGears 团队已经 向硬件团队和有兴趣改进 HDL 的个人开放社区,使硬件设计更加高效和以结果为导向。附部分说明截图
2025年09月21日
1 阅读
0 评论
0 点赞
2025-09-20
MMU那些事儿
EET0P2020年12月27日03:47MMU 诞生之前:在传统的批处理系统如 DOS 系统,应用程序与操作系统在内存中的布局大致如下图:应用程序直接访问物理内存,操作系统占用一部分内存区。操作系统的职责是“加载”应用程序,“运行”或“卸载”应用程序。如果我们一直是单任务处理,则不会有任何问题,也或者应用程序所需的内存总是非常小,则这种架构是不会有任何问题的。然而随着计算机科学技术的发展,所需解决的问题越来越复杂,单任务批处理已不能满足需求了。而且应用程序需要的内存量也越来越大。而且伴随着多任务同时处理的需求,这种技术架构已然不能满足需求了,早先的多任务处理系统是怎么运作的呢?程序员将应用程序分段加载执行,但是分段是一个苦力活。而且死板枯燥。此时聪明的计算机科学家想到了好办法,提出来虚拟内存的思想。程序所需的内存可以远超物理内存的大小,将当前需要执行的留在内存中,而不需要执行的部分留在磁盘中,这样同时就可以满足多应用程序同时驻留内存能并发执行了。从总体上而言,需要实现哪些大的策略呢?所有的应用程序能同时驻留内存,并由操作系统调度并发执行。需要提供机制管理 I/O 重叠,CPU 资源竞争访问。虚实内存映射及交换管理,可以将真实的物理内存,有可变或固定的分区,分页或者分段与虚拟内存建立交换映射关系,并且有效的管理这种映射,实现交换管理。这样,衍生而来的一些实现上的更具体的需求:竞争访问保护管理需求:需要严格的访问保护,动态管理哪些内存页/段或区,为哪些应用程序所用。这属于资源的竞争访问管理需求。高效的翻译转换管理需求:需要实现快速高效的映射翻译转换,否则系统的运行效率将会低下。高效的虚实内存交换需求:需要在实际的虚拟内存与物理内存进行内存页/段交换过程中快速高效。总之,在这样的背景下,MMU 应运而生,也由此可见,任何一项技术的发展壮大,都必然是需求驱动的。这是技术本身发展的客观规律。内存管理的好处为编程提供方便统一的内存空间抽象,在应用开发而言,好似都完全拥有各自独立的用户内存空间的访问权限,这样隐藏了底层实现细节,提供了统一可移植用户抽象。 以最小的开销换取性能最大化,利用 MMU 管理内存肯定不如直接对内存进行访问效率高,为什么需要用这样的机制进行内存管理,是因为并发进程每个进程都拥有完整且相互独立的内存空间。那么实际上内存是昂贵的,即使内存成本远比从前便宜,但是应用进程对内存的寻求仍然无法在实际硬件中,设计足够大的内存实现直接访问,即使能满足,CPU 利用地址总线直接寻址空间也是有限的。内存管理实现总体策略从操作系统角度来看,虚拟内存的基本抽象由操作系统实现完成:处理器内存空间不必与真实的所连接的物理内存空间一致。 当应用程序请求访问内存时,操作系统将虚拟内存地址翻译成物理内存地址,然后完成访问。 从应用程序角度来看,应用程序(往往是进程)所使用的地址是虚拟内存地址,从概念上就如下示意图所示,MMU 在操作系统的控制下负责将虚拟内存实际翻译成物理内存。从而这样的机制,虚拟内存使得应用程序不用将其全部内容都一次性驻留在内存中执行: 节省内存:很多应用程序都不必让其全部内容一次性加载驻留在内存中,那么这样的好处是显而易见,即使硬件系统配置多大的内存,内存在系统中仍然是最为珍贵的资源。所以这种技术节省内存的好处是显而易见的。 使得应用程序以及操作系统更具灵活性。操作系统根据应用程序的动态运行时行为灵活的分配内存给应用程序。使得应用程序可以使用比实际物理内存多或少的内存空间。MMU 以及 TLBMMU(Memory Management Unit)内存管理单元:一种硬件电路单元负责将虚拟内存地址转换为物理内存地址所有的内存访问都将通过 MMU 进行转换,除非没有使能 MMU。TLB(Translation Lookaside Buffer)转译后备缓冲器: 本质上是 MMU 用于虚拟地址到物理地址转换表的缓存这样一种架构,其最终运行时目的,是为主要满足下面这样运行需求:多进程并发同时并发运行在实际物理内存空间中,而 MMU 充当了一个至关重要的虚拟内存到物理内存的桥梁作用。那么,这种框架具体从高层级的概念上是怎么做到的呢?事实上,是将物理内存采用分片管理的策略来实现的,那么,从实现的角度将有两种可选的策略:固定大小分区机制可变大小分区机制固定大小区片机制通过这样一种概念上的策略,将物理内存分成固定等大小的片: 每一个片提供一个基地址 实际寻址,物理地址=某片基址+虚拟地址 片基址由操作系统在进程动态运行时动态加载这种策略实现,其优势在于简易,切换快速。但是该策略也带来明显的劣势: 内部碎片:一个进程不使用的分区中的内存对其他进程而言无法使用 一种分区大小并不能满足所有应用进程所需。可变大小分区机制内存被划分为可变大小的区块进行映射交换管理: 需要提供基址以及可变大小边界,可变大小边界用于越界保护。实 际寻址,物理地址=某片基址+虚拟地址那么这种策略其优势在于没有内部内存碎片,分配刚好够进程所需的大小。但是劣势在于,在加载和卸载的动态过程中会产生碎片。分页机制分页机制采用在虚拟内存空间以及物理内存空间都使用固定大小的分区进行映射管理。从应用程序(进程)角度看内存是连续的 0-N 的分页的虚拟地址空间。物理内存角度看,内存页是分散在整个物理存储中这种映射关系对应用程序不可见,隐藏了实现细节。分页机制是如何寻址的呢?这里介绍的设计理念,具体的处理器实现各有细微差异:虚拟地址包含了两个部分:虚拟页序号 VPN(virtual paging number)以及偏移量虚拟页序号 VPN是页表(Page Table)的索引页表(Page Table)维护了页框号(Page frame number PFN)物理地址由PFN::Offset进行解析。举个栗子,如下图所示:还没有查到具体的物理地址,憋急,再看一下完整解析示例:如何管理页表对于 32 位地址空间而言,假定 4K 为分页大小,则页表的大小为 100MB,这对于页表的查询而言是一个很大的开销。那么如何减小这种开销呢?实际运行过程中发现,事实上只需要映射实际使用的很小一部分地址空间。那么在一级页机制基础上,延伸出多级页表机制。 以二级分页机制为例:单级页表已然有不小的开销,查询页表以及取数,而二级分页机制,因为需要查询两次页表,则将这种开销再加一倍。那么如何提高效率呢?其实前面提到一个概念一直还没有深入描述 TLB,将翻译工作由硬件缓存 cache,这就是 TLB 存在的意义。 TLB 将虚拟页翻译成 PTE,这个工作可在单周期指令完成。TLB 由硬件实现完全关联缓存(并行查找所有条目)缓存索引是虚拟页码缓存内容是 PTE则由 PTE+offset,可直接计算出物理地址TLB 加载谁负责加载 TLB 呢?这里可供选择的有两种策略:由操作系统加载,操作系统找到对应的 PTE,而后加载到 TLB。格式比较灵活。MMU 硬件负责,由操作系统维护页表,MMU 直接访问页表,页表格式严格依赖硬件设计格式。总结一下从计算机大致发展历程来了解内存管理的大致发展策略,如何衍生出 MMU,以及固定分片管理、可变分片管理等不同机制的差异,最后衍生出单级分页管理机制、多级分页管理机制、TLB 的作用。从概念上相对比较易懂的角度描述了 MMU 的诞生、机制,而忽略了处理器的具体实现细节。作为从概念上更深入的理解 MMU 的工作机理的角度,还是不失为一篇浅显易懂的文章。
2025年09月20日
4 阅读
0 评论
0 点赞
2025-09-20
Python 必杀技:用 print() 函数实现的三个特效
print() 应该是初学者最先接触到的第一个 Python 函数,因为几乎所有的启蒙课程都是从 print('Hello world') 开始的。事实上, print() 也是程序员使用频率最高的函数之一,同时也是很多程序员喜欢的代码调试利器。但是关于 print() 函数,你真的了解吗?打字机效果不了解 print() 的 flush 参数,很难实现下图所示的打字机效果:动图封面print() 像个调皮的小朋友,你让他帮你打印,他一定会做,但未必是立即去做,也许会攒够了多个打印任务才执行一次。设置 flush=True,可以让这位小朋友立刻去执行命令。 import time def printer(text, delay=0.2): """打字机效果""" for ch in text: print(ch, end='', flush=True) time.sleep(delay) printer('玄铁重剑,是金庸小说笔下第一神剑,持之则无敌于天下。')旋转式进度指示Linux 系统文本界面下,最常用的进度指示是用横竖斜杠构成的旋转图案。动图封面Python也可以轻松实现这个效果,秘诀就在于 '\b' 字符。 '\b' 相当于键盘上的退格键,可以让我们把刚刚打印过的最后一个字符擦掉重新打印。这个效果,同样需要设置参数 flush 为真。 import time def waiting(cycle=20, delay=0.1): """旋转式进度指示""" for i in range(cycle): for ch in ['-', '\\', '|', '/']: print('\b%s'%ch, end='', flush=True) time.sleep(delay) waiting() 反转字符顺序,就可以改变旋转方向。将第一个字符 '-' 改成 '-- ',还可以实现这样的效果:动图封面覆盖式打印效果'\b' 的作用是回退一个字符,'\r' 则可以退回到行首。借助于 '\r',可以实现整行覆盖式的打印效果:动图封面需要注意的是,整行覆盖的话,新的字符串长度不能小于原字符串长度,否则会留下前一次的打印内容。这个效果,同样需要设置参数 flush 为真。 import time def cover(cycle=100, delay=0.2): """覆盖式打印效果""" for i in range(cycle): s = '\r%d'%i print(s.ljust(3), end='', flush=True) time.sleep(delay) cover()
2025年09月20日
1 阅读
0 评论
0 点赞
2025-09-18
通俗易懂的AI知识体系图及其产业链全景图
科技先锋2018年08月27日08:01
2025年09月18日
1 阅读
0 评论
0 点赞
2025-09-17
一个简单的8位处理器完整设计过程及verilog代码
来源: EETOP BBS 作者:weiboshe一个简单的8位处理器完整设计过程及verilog代码,适合入门学习参考,并含有作者个人写的指令执行过程(点击下方 阅读原文 到论坛可下载源码)CPU定义我们按照应用的需求来定义计算机,本文介绍一个非常简单的CPU的设计,它仅仅用来教学使用的。我们规定它可以存取的存储器为64byte,其中1byte=8bits。所以这个CPU就有6位的地址线A[5:0],和8位的数据线D[7:0]。我们仅定义一个通用寄存器AC(8bits寄存器),它仅仅执行4条指令如下:除了寄存器AC外,我们还需要以下几个寄存器:地址寄存器 A[5:0], 保存6位地址。程序计数器 PC[5:0],保存下一条指令的地址。数据寄存器 D[7:0],接受指令和存储器来的数据。指令寄存器 IR[1:0],存储指令操作码。2. 取指设计 在处理器执行指令之前,必须从存储器取出指令。其中取指执行以下操作:1〉 通过地址端口A[5:0]从地址到存储器2〉 等待存储器准备好数据后,读入数据。由于地址端口数据A[5:0]是从地址寄存器中读出的,所以取指第一个执行的状态是Fetch1: AR<—PC接下来cpu发出read信号,并把数据从存储器M中读入数据寄存器DR中。同时pc加一。Fetch2: DR<—M,PC<—PC+1接下来把DR[7:6]送IR,把DR[5:0]送ARFetch3: IR<—DR[7:6],AR<—DR[5:0] 3. 指令译码Cpu在取指后进行译码一边知道执行什么指令,对于本文中的CPU来说只有4条指令也就是只有4个执行例程,状态图如下:4. 指令执行对译码中调用的4个例程我们分别讨论:4.1 ADD指令ADD指令需要CPU做以下两件事情:1〉 从存储器取一个操作数2〉 把这个操作数加到AC上,并把结果存到AC所以需要以下操作:ADD1: DR<—MADD2: AC<—AC+DR4.2 AND指令AND指令执行过程和ADD相似,需要以下操作:AND1: DR<—MAND2: AC<—AC^DR4.3 JMP指令 JMP指令把CPU要跳转的指令地址送PC,执行以下操作JMP1: PC<—DR[5:0]4.4INC指令INC指令执行AC+1操作INC1: AC<—AC+1总的状态图如下:5 建立数据路径 这一步我们来实现状态图和相应的寄存器传输。首先看下面的状态及对应的寄存器传输: Fetch1: AR<—PCFetch2: DR<—M,PC<—PC+1Fetch3: IR<—DR[7:6],AR<—DR[5:0]ADD1: DR<—MADD2: AC<—AC+DRAND1: DR<—MAND2: AC<—AC^DRJMP1: PC<—DR[5:0]INC1: AC<—AC+1为了设计数据路径,我们可以采用两种办法:1〉创造直接的两个要传输组件之间的直接路径2〉在CPU内部创造总线来传输不同组件之间的数据首先我们回顾一下可能发生的数据传输,以便确定各个组件的功能。特别的我们要注意把数据载入组件的各个操作。首先我们按照他们改变了那个寄存器的数据来重组这些操作。得到如下的结果:AR:AR<—PC;AR<—DR[5:0]PC:PC<—PC+1;PC<—DR[5:0]DR:DR<—MIR:IR<—DR[7:6]AC:AC<—AC+DR;AC<—AC^DR;AC<—AC+1现在我们来看每个操作来决定每个组件执行什么样的功能,AR,DR,IR三个组件经常从其他的组件载入数据(从总线),所以只需要执行一个并行输入的操作。PC和AC能够载入数据同时也能够自动加一操作。下一步我们把这些组件连接到总线上来,如图所示:如上图所示,各个组件与总线之间通过三态连接,防止出现总线竞争。AR寄存器送出存储器的地址,DR寄存器用于暂存存数起来的数据。到现在为止我们还没有讨论有关的控制信号,我们现在只是保证了所有的数据传输能够产生,我们将在后面章节来使这些数据传输正确的产生---控制逻辑。现在我们来看以下者写数据传输中有没有不必要的传输:1〉 AR仅仅提供数据给存储器,所以他不需要连接到总线上。2〉 IR不通过总线提供数据给任何组件,所以他可以直接输出到控制单元(后面章节)。3〉 AC不提供数据到任何的组件,可以不连接到总线上。4〉 总线是8bit宽度的,但是有些传输是6bit或者2bit的,我们必须制定寄存器的那几位送到总线的那几位。5〉 AC要可以载入AC和DR的和或者逻辑与的值,数据路径中还需要进行运算的ALU。由此我们做以下工作:1〉 去掉AR,IR, AC与总线的连接。2〉 我们约定寄存器连接是从总线的低位开始的。AR,PC连接到Bus[5:0],由于IR是接受DR[7:6]的,所以可以连接到总线的Bus[7:6]。3〉 我们设定,AC作为ALU的一个输入,另一个输入来自总线Bus。下面我们检查是否有争用总线的情况,幸运的是这里没有。修改后的CPU内部组织图如下:ALU设计这个CPU的ALU执行的功能就是两个操作数相加、逻辑与。这里不作详细介绍。电路如如下: 控制单元 我们来考虑如何产生数据路径所需的控制信号,有两种方法:硬布线逻辑和为程序控制。这里我们用硬布线逻辑来实现。这个简单的CPU需要的控制逻辑由三个部件组成: 1〉计数器: 用于保存现在的状态 2〉译码器: 生成各个状态的控制信号 3〉其他的组合逻辑来产生控制信号一个通用的控制单元原理图如下: 对于这个CPU来说,一共有9个状态。所以需要一个4bit的计数器和一个4-16的译码器。接下来的工作就是按照前面的状态转换图来对状态进行赋值。 首先考虑如何的对译码输出状态进行赋值才能达到最佳状态。我们按照以下规则: 1〉给Fetch1赋计数器的0值,并用计数器的清零端来达到这个状态。由这个CPU的状态图可以看出,除了Fetch1状态外的状态都只能由一个状态转化而来,Fetch1需要从4个分支而来,这4个分支就可以发出清零信号(CLR)来转移到Fetch1。 2〉把连续的状态赋连续的计数器值,这样就可以用计数器的INC输入来达到状态的转移。 3〉给每个例程的开始状态赋值时,要基于指令的操作码和这个例程的最大状态数。这样就可以用操作码来生成计数器的LD信号达到正确的状态转移。首先,在Fetch3状态发出LD信号,然后要把正确的例程地址放到计数器的输入端。对这个CPU来说,我们考虑以地址1 [IR] 0作为计数器的预置输入。则得到状态编码如下:如上表所示,下面我们需要设计产生计数器的LD、INC、CLR等信号,总的控制单元的逻辑如下图:下面我们用这些译码信号来产生数据路径控制所必需的AR、PC、DR、IR、M和ALU的控制信号。首先考虑寄存器AR,他在Fetch1状态取PC的值,并在Fetch3状态取DR[5:0]的值,所以我们得到ARLOAD=Fetch1 or Fetch3。以此类推我们可以得到如下结果:PCLOAD=JMP1PCINC=Fetch2DRLOAD=Fetch1or ADD1 or AND1ACLOAD=ADD2 or AND2IRLOAD=Fetch3对于ALU的控制信号ALUSEL是用来控制ALU做逻辑或者算数运算的,所以有:ALUSEL=AND2对于片内总线的控制较为复杂,我们先来看DR,对于DR他只在Fetch3、AND2 、ADD2和JMP1状态占用总线进行相信的数据传输,所以有:DRBUS=Fetch3 or AND2 or ADD2 or JMP1其他类似有:MEMBUS=Fetch2or ADD1 or AND1PCBUS=Fetch1最后,控制单元需要产生存储器的读信号(READ),它发生在Fetch2、ADD1、AND1三个状态:READ=Fetch2or ADD1 or AND1这样我们得到了总的控制逻辑,完成了整个CPU的设计。8. 设计验证 我们执行如下指令进行设计验证,0:ADD41:AND52:INC3:JMP04:27H5:39H指令执行过程如下(初始化所有寄存器为全零态):
2025年09月17日
8 阅读
0 评论
0 点赞
1
...
9
10
11
...
76