
不得不说,SDRAM的设计是我接触FPGA以来最难调试的设计。早在一个多月前,我就开始做SDRAM的教程。受特权同学的影响,我开始学习《进阶进阶》论文《终极记忆技术指南》,大家都知道这篇文章是学习记忆入门的必读文章。小墨花了一些时间在上面。说实话,看懂这篇文章是没有问题的,比较直接,通俗易懂,容易上手,了解了SDRAM的工作方法后,就开始写代码了,从特权同学的经典教程,我仔细研究了代码的来龙去脉,终于明白了特权同学的设计思路,并花了一些时间自己输入代码。再次,用你自己的评论
本文引用地址:
然而,设计并不像我想象的那么简单。代码设计好之后,需要经过仿真,时序约束,仿真一般都不错,但是我对时序约束接触的很少,所以就去学习时序约束。控制SDRAM时钟运行到100MHZ,时序约束可以看作是本设计的关键部分。由于时序要求不高,因此之前的设计可以不受约束地实现。学习时序约束可以看作是一个漫长的过程。经过这段时间的学习,小默也开始反思自己的跨度是不是有点大,设计SDRAM的过程确实有点费力。因此,小墨决定暂时放弃SDRAM。教学,我以后发Nios II文章的时候会讲到SDRAM。
这次,我们将首先学习CPU的设计。这个设计看似简单,但一步一步完成却需要一些耐心和精力。本文主要介绍Risc_CPU的设计流程和代码分析。下一篇小墨会和大家分享test bench的编写和仿真测试,帮助大家一步步学习这个cpu的设计。那么,我们就开始今天的教学。吧~
一、 设计前的准备
在开始设计之前,我们首先要知道 CPU 是什么。CPU是中央处理器,是计算机的核心部件。小陌就简单讲讲CPU的工作过程。首先,我们计算机的程序和数据都存储在我们计算机的内存中。上电后cpu需要从第一条指令的地址取指令,即取指令。取到的指令需要解码时钟模块是什么意思,告诉cpu指令是干什么用的,也就是分析指令。当指令的内容已知时,CPU需要生成一个操作指令来完成相应的操作,即执行该指令。因此,任何一种 CPU 都应至少包含以下组件:
1.算术计算器
2.累加器
3.指令计数器
4.指令寄存器和解码器
5.时序控制器
二. 工作原理
在这个设计中,我们假设 ROM 加载了我们的程序指令,稍后我们将向其中加载数据。程序指令是16位的,cpu一次读8位,分两次读,再读出来。数据存储在指令寄存器中。
16位数据的高三位代表指令代码
HLT = 3’b000,
SKZ = 3’b001,
添加 = 3’b010,
AND = 3’b011,
异或 = 3’b100,
LDA = 3’b101,
STO = 3’b110,
JMP = 3’b111;
最后 13 位代表地址码。指令寄存器将读取的数据分为指令码opcode[2:0]和地址码ir_addr[12:0]。状态控制器读回指令码进行解码,看看是什么指令,然后根据指令的内容来操作其他组件。如果是写入数据,打开RAM写入数据。如果是计算,则将数据发送给算术运算符进行算术运算。如果是跳转指令,则该地址指向下一个地址,下一次读取指令时,跳过一个地址,等等。
三、每个模块的密集讲座
本次设计的CPU一共包含8个模块。让我一一解释。
1.时钟发生器
该模块用于产生分频信号,外部50M时钟用于8分频输出。这个8分频信号用来控制地址多路复用器的输出。由于后面我们会用到一个8态的状态机,这里就做成了8分频。至于具体原因,我们后面再讲,然后是算术运算符的使能信号。在每8个分频信号到来之前,有一个算术运算符使能信号的高脉冲,这意味着每-在状态机循环开始之前做一次运算
仅采用状态机方法设计分频信号,利用计数器计数方法避免了延迟,提高了程序的可读性和速度。
2.指令寄存器
该模块的作用是将ROM中的16位数据进行寄存器和划分为高3位指令码和低13位地址码。
指令寄存器两次读取ROM中的数据
3.累加器
算术运算符的初始值为 0。来自 ROM 的数据经过算术运算符处理,然后输出到累加器。当累加器使能信号到达时,该数据作为初始值发送给算术运算符。ROM中读回的数据用于算术运算
4.算术计算器
算术运算器首先判断来自ROM的指令代码的高三位是什么指令,然后对来自ROM的数据和来自累加器的数据进行算术运算,并输出结果。如果算术运算符中的数据为0,则有高脉冲零输出
5.数据控制器
如果要保存算术运算的结果并输出到RAM,可以选择数据控制器,将数据输出到RAM,配合指令STO
6.地址多路复用器
8分频时钟的前半周期用于读取ROM中指定地址的数据,后半周期用于执行指令操作,所以前半周期需要从指定地址读取数据ROM,所以输出地址应该是pc_addr,后半周期用来处理指令,那么从ROM读回的13位地址一定是13位地址,即ir_addr,并输出
7.程序计数器
一开始从ROM中读取数据的地址是pc_addr,也就是0地址。如果是跳转指令,需要从ROM读回的13位地址码作为新地址给pc_addr,等待下一个8分频时钟。当读取地址的指令时,跳转指令的目的就实现了。如果不是跳转指令,则pc_addr加1指向下一个地址,继续执行
8.状态控制器
状态控制器,我们的状态机,是我们设计的核心组件,状态机共享 8 个状态
前两个状态用于读取ROM中的16位数据,需要两个时钟,即需要两个状态。
第三个状态等待一个时钟周期,目的是补8个状态,因为8分频时钟的后半周期需要4个状态才能完成,所以前半个周期也需要4个状态,因为第一个半个周期只需要读取 只需要把数据和地址指向下一个地址,所以需要补一个状态
第四个状态地址加1指向下一个地址
第五至第八状态用于分析指令并执行指令。如果是跳转指令,控制程序计数器改变目标地址。如果下一条指令被跳过,则控制程序计数器pc_addr地址加4。如果是运算指令,则控制算术运算符会进行相应的逻辑运算。如果是LDA写指令,读回的数据会放入累加器等。具体操作指令的含义如下图所示。
每个模块设计组装完成后时钟模块是什么意思,我们的cpu设计就完成了。组装好的顶层模块如下图所示。
这样,我们的cpu设计就完成了。当然,设计完成后,我们还需要进行仿真。为了模拟,我们还需要外围电路,包括存储指令程序ROM,访问数据的RAM,地址解码器等,由于ROM和RAM。是不可合成的,但是我们可以边模拟边模拟。
由于每篇文章最多只能上传20张图片,今天的教程到此结束。具体的仿真过程以及ROM和RAM的设计将在下一篇文章中介绍。说到modolsim SE的使用和test bench的编写,虽然在之前的博客中提到过,但是并不系统。下一篇将以这个设计为例,为大家介绍仿真的全过程。希望在您的大力支持下,下面附上部分模拟图片和测试结果供大家参考
波形模拟
感谢大家的支持,这篇文章写了几个小时,纯手写~
fpga相关文章:什么是fpga
负离子发生器相关文章:负离子发生器原理
粉尘粒子计数器相关文章:粉尘粒子计数器原理
离子色谱相关文章:离子色谱原理
请登录后发表评论
注册
社交帐号登录