ASIC实验报告8位CPU的设计.docx
- 文档编号:23883398
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:10
- 大小:309.83KB
ASIC实验报告8位CPU的设计.docx
《ASIC实验报告8位CPU的设计.docx》由会员分享,可在线阅读,更多相关《ASIC实验报告8位CPU的设计.docx(10页珍藏版)》请在冰豆网上搜索。
ASIC实验报告8位CPU的设计
ASIC设计实验报告
学院:
电子工程学院
学号:
2014*******
姓名:
王闯
指导老师:
刘雯
2014年11月13日
一、实验目的:
通过对ASIC实验课的学习,应当学会以下几点:
1.熟悉Linux操作系统的应用环境,基本命令行的应用,以及对vi编辑器熟练应用。
2.熟练掌握Verilog编程语言,包括基本组合逻辑电路的实现方法,基本时序逻辑电路的实现方法,怎样使用预定义的库文件,利用always块实现组合逻辑电路的方法已经着重了解assign与always两种组合逻辑电路实现方法之间的区别,深入了解阻塞赋值与非阻塞赋值的概念以及应用的差别,有限状态机(FSM)实现复杂时序逻辑的方法,以及学会在Linux系统环境当中应用Synopsys工具VCS进行仿真。
3.熟悉电路设计当中的层次化、结构化的设计方法。
4.熟悉CPU当中有哪些模块组成,模块之间的关系,以及其基本的工作原理。
5.学会利用汇编语言设计程序,注意代码规范性要求。
二、实验要求:
按照实验指导书上的要求即:
CPU各个模块的Verilog语言代码的编写、编译及仿真正确,并在规定的时间内完成。
要求对CPU进行语言级系统仿真结果正确之后,利用该实验当中采用的八个汇编关键字,编写一个能够实现某种功能的小程序。
然后对其中的控制器电路进行综合,并检查Timing和Power,进行门级仿真。
3、实验内容:
设计一个8位RISC_CPU系统。
(RISC:
ReducedInstructionSetComputer),它是一种八十年代才出现的CPU,与一般的CPU相比,不仅只是简化了指令系统,而且通过简化指令系统使计算机的结构更加简单合理,从而提高了运算速度。
从实现的方法上,它的时序控制信号部件使用了硬布线逻辑,而不是采用微程序控制方式,故产生控制序列的速度要快的多,因为省去了读取微指令的时间。
此CPU所具有的功能有:
(1)取指令:
当程序已在存储器中时,首先根据程序入口地址取出一条程序,为此要发出指令地址及控制信号。
(2)分析指令:
即指令译码。
是对当前取得的指令进行分析,指出它要求什么操作,并产生相应的操作控制命令。
(3)执行指令:
根据分析指令时产生的“操作命令”形成相应的操作控制信号序列,通过运算器,存储器及输入/输出设备的执行,实现每条指令的功能,其中包括对运算结果的处理以及下条指令地址的形成。
从上述具有的功能可以总结出,它有八个独立的逻辑部件所组成:
时钟发生器、指令寄存器、累加器、ALU、数据控制器、状态控制器、程序计数器以及地址选择器。
在本实验报告当中会一一对各个模块设计进行介绍。
四、实验设计过程:
(一).多路选择器的设计(MUX)
在该模块设计当中,练习的是组合逻辑电路的设计方法,其中assign赋值语句最为常用,其特点是能够连续赋值。
其中关键程序代码为:
assignout=(!
sel)?
a:
(sel)?
b:
{size{1’bx}};
实现的功能是当sel=0时out输出a的数据,当sel=1时输出b的数据,此外则输出高阻态x。
该模块在CPU当中所起的作用是选择输出的地址是PC(程序计数)地址(pc_addr)还是跳转的目标地址(ir_addr)。
该模块编译运行的结果为:
从上图显示的结果可以看出,当sel=0时,out输出a,当sel=1时,out输出b,达到了我们实验的要求。
(2)、五位计数器的设计(Counter):
在该模块设计当中,采用的时序逻辑电路的设计方法。
该模块在整个CPU当中充当程序计数器的作用,提供指令的地址,以便CPU读取指令。
在CPU取新指令时,用程序计数器的值作为存储器地址;在执行指令时,用指令中的地址部分作为存储器地址。
在该模块主要应用了always块以及@(posedgeclk)或者@(negedgeclk)来表达时序逻辑。
主要想法是每当clk的上升沿或下降沿到来时计一次数。
还有就是采用异步清零端rst_,来把计数器清零。
采用同步置数端load来置入data此时的数据。
以下是运行的实验结果:
从上述实验结果截图上可以看出,Counter设计实现了计数,达到实验目的。
(3)、八位寄存器的设计(Register):
在该模块当中,也是采用了时序逻辑电路的设计方法。
在该模块当中主要练习了模块的调用、寄存器的例化、时钟例化和怎样添加检测信号。
该模块在CPU当中主要是作为指令的寄存,在执行指令时,用指令中的地址部分作为存储器地址。
该寄存器采用八位寄存器,电路设计里面应该含有八个D触发器,采用模块调用的模式,使得设计条理更加清晰,简便。
其中,每条指令为一个字节,即八位。
高3位是操作码,低5位是地址。
(CPU的地址总线为8位)本设计的数据总线为8位,所以每条指令取一次就可以达到。
以下是该模块的运行结果:
从上面实验结果截图来看,每当时钟信号的下降沿到来时,数据data,都会移入相应的D触发器当中,out也有相应的输出,达到了寄存的目的。
(四)、指令译码电路(Alu):
在该模块当中,主要运用了组合逻辑的设计方法,实现了通过电路对指令的判断,对输入数据执行相应的操作,包括加、与、或和传数据,并且无论是指令作用的数据还是指令本身的变化,结果都会做出及时的反应。
显然,这是一个较复杂的组合逻辑电路,如果仅采用assign语句,表达起来非常复杂。
在该模块当中,主要采用了always块,所谓电平敏感的触发条件是指在@后的括号内的任何一个电平发生变化就能触发always块的动作,并且运用了case结构进行分支判断,不但设计思想得到直观的体现,而且代码看起来非常整齐、便于理解。
在该模块当中,zero信号与out信号是不相关的,可以采用两个always块实现两者之间的并行赋值,并采用了语句内部的延时赋值。
采用case结构,最末一个语句必须加上default语句,除非case语句中的条件句中选择取值能够完全覆盖其中表达式的取值,否则生成的电路当中就会出现意想不到的锁存器,甚至引发错误。
再者,out输出需要延时3.5ns,zero输出1.2ns,因此在过程语句当中采用非阻塞赋值。
运行的实验结果如下图:
从上图中可以看出,当opcode=010,即ADD指令,输入data=10101010
Accum=00110011,执行的结果out=11011101,zero=0,可以看出运算的结果是正确的,达到了设计的目的。
(五)、存储器电路的设计:
在该模块当中,设计了存储器的仿真模型,该存储器模型具有双向数据总线及异步处理功能。
存储器中存放了要执行的指令和相应数据。
存储器的读写信号由控制器给出。
存储器的地址来源有两个:
程序计数器和指令寄存器。
在该模块设计当中主要应用了assign赋值语句,当存储器写的时候,data要赋高阻态,因为从Inout端口的结构可以看出,如果输出输入存在“线与”结构。
否则,则将“线与”后的值存储,导致存储数据错误。
模块当中关键语句为:
Assigndata=(read)?
memory[addr]:
8h’z;always@(posedgewrite)memory[addr]=data;
(六)、设计时序逻辑时采用阻塞赋值与非阻塞赋值的区别:
阻塞赋值与非阻塞赋值,在教材中我们已经了解了它们之间的在语法上的区别以及所得到的电路结构上的区别。
在always块中阻塞赋值可以理解为赋值语句是顺序执行的,而非阻塞赋值可以理解为赋值语句是并行执行的。
在该模块当中主要用了阻塞与非阻塞赋值的对比,从赋值的时间顺序中看出两者的本质区别。
阻塞赋值b1=a;c1=b1;,非阻塞赋值b2<=a;c2<=b2;该模块的运行结果产生的波形图为:
从上图当中可以看出,当clk的第一个上升沿到来时,阻塞赋值的b1,c1同时得到了更新,而非阻塞赋值的,只有b2得到了更新,而c2则要得到下一个时钟上升沿到来时才会得到更新。
其实,从运行结果就可以看出,阻塞赋值可以立即得到赋值,a,b和c之间就像导线连接在一起,而非阻塞赋值,b与a,c与b之间都是通过一个D触发器一样连接在一起。
(七)、控制器的设计(Control):
在该模块当中,主要是利用有限状态机实现复杂时序逻辑电路的设计。
状态机是CPU的控制核心,用于产生一系列的控制信号,启动或停止某些模块。
CPU何时进行读指令读写I/O端口,RAM区等操作,都是由状态机来控制的。
状态机的当前状态,由变量state记录,state的值就是当前这个指令周期中已经过的时钟数(从零计起),下一个状态采用变量nexstate记录。
在该模块当中,状态机有八个状态构成,由八个时钟周期组成,前四个时钟周期用来从存储器取数据,后四个时钟周期发出不同的控制信号,以控制指令的进行。
在状态机设计当中,通常采用两个always块语句来描述,一个用来描述状态的转移,一个用来描述每个状态的表达式,这样做的好处在于通过并行结构实现nexsate值与输出值可以同时得到更新。
每个状态内,目标变量都是{sel,rd,ld_ir,inc_pc,halt,ld_pc,data_e,ld_ac,wr},状态与状态之间的赋值方式应采用阻塞赋值,因为从阻塞赋值的方式上可以看出,即在任何一个语句处于赋值更新时,其他语句不会操作,因此,不会出现当多个状态同时满足时造成目标变量最终不知接受哪一个赋值驱动源数据的矛盾状态。
如果采用非阻塞赋值,当存在多个状态同时满足时,目标变量只会接受最接近过程结束的那一个状态赋的值。
至于,状态内部的变量赋值,即sel,rd,ld_ir,inc_pc,halt,ld_pc,data_e,ld_ac,wr需要同时得到更新则应该采用具有并行赋值功能的非阻塞赋值。
此外,还可以采用格雷码来消除状态转换时产生的毛刺现象。
该模块的测试结果如下图所示:
(八)、通过对各个模块的调用实现CPU的设计:
在该模块当中,主要学习和使用层次化、结构化设计方法,通过各个模块之间的调用实现自顶向下的CPU设计。
在Verilog语言中,被引用的子模块在综合时作为其父模块的一部分被综合,形成相应的电路结构。
在进行模块实例引用时,必须注意的是模块之间对应的端口,即子模块的端口与父模块的内部信号必须明确无误地一一对应,否则容易产生意想不到的后果。
在本实验中,实现了一个八位CPU系统。
它的八个独立逻辑部件已分别在前面的设计中完成,在这里将它们合并为一个模块显得目的明确、层次清晰。
五、CPU的测试
在CPU测试当中主要用来测试CPU的性能。
通过该CPU当中八个操作指令即HLT、SKZ、ADD、AND、XOR、LDA、STO、JMP来编写实现基底q=3的等比数列也是实现的3的n次方数列,代码如下:
111_00011//JMPLOOP进入循环体
@03101_11010//03LOOP:
LDAFN1把FN1的数据读到累加器accum当中
010_11011//04ADDTEMP1与TEMP1相加
010_11100//05ADDTEMP2再与TEMP2相加
110_11010//06STOFN1将accum寄存的数据存储到FN1中
101_11010//07LDAFN1将FN1的值读到accum当中
110_11011//08STOTMEP1TENP1/2记录此时FN1的值,便再次循环用
110_11100//09STOTEMP2
100_11101//0AXORLIMIT将此时accum中的数据与LIMIT异或(比较)
001_00000//0BSKZ若accum为0,跳转DONE,反之,向下执行
111_00011//0CJMPLOOP跳转到循环体的开始,继续循环
000_00000//0DDONE:
HLT暂停
101_11111//0EAGAIN:
LDAONE以下是防止程序跑飞,而变量设初值
110_11010//0FSTOFN1
101_11110//10LDAZERO
110_11100//11STOTEMP2
110_11011//12STOTEMP1
111_00011//13JMPLOOP
@1A00000001//1AFN1存储变量FN1的值
00000000//1BTEMP1中间量
00000000//1CTEMP2中间量
11110011//1DLIMIT循环体满足的最大值243
00000000//1EZERO赋值用的0值
00000001//1FONE赋值用的1值
上述循环体执行的过程是,第一次循环,FN1=1,TEMP1=TMEP2=0,结束时,FN1=1。
第二循环,FN1=1,TEMP1=TMEP2=1,结束时,FN1=3。
第三次结束FN1=9,…,直到FN1=243时,跳出循环。
测试的结果打印图为:
六、总结
通过对ASIC实验的学习,自己认识了Linux系统,掌握了一些基本命令行,也学习了VerilogHDL。
在学习的过程当中,自己也遇到了不少的困难,就像在做Control当中的状态间目标变量赋值时,因为没有考虑阻塞赋值与非阻塞赋值之间的区别,在做程序调试时吃尽了苦头,还有就是在做调用各个模块实现自顶向下的CPU设计时,要把前面的所有实验模块集中到一块,出现了很多错误,包括语法的错误,某个变量没有定义,位宽不一致,程序陷入死循环等等,值得庆幸的是,刘雯老师的耐心指导,和不少同学的热心帮助解答,再加上自己的不懈努力,终于克服困难,顺利完成了实验的要求。
自己也找到了在哪些方面的不足,在接下来的时间里,更会加倍训练。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ASIC 实验 报告 CPU 设计