原创 零基础学FPGA(十六)第一片IC——精简指令集RISC_CPU设计精讲

2014-11-20 14:53 3250 10 13 分类: FPGA/CPLD 文集: FPGA/CPLD

    不得不说,SDRAM的设计是我接触FPGA以来调试最困难的一次设计,早在一个多月以前,我就开始着手想做一个SDRAM方面的教程,受特权同学影响,开始学习《高手进阶,终极内存技术指南》这篇论文,大家都知道这篇文章是学习内存入门的必读文章,小墨同学花了一些时间在这上面,说实话看懂这篇文章是没什么问题的,文件讲的比较直白,通俗易懂,很容易入手。当了解了SDRAM工作方式之后,我便开始写代码,从特权同学的那篇经典教程里面,我认真研读代码的来龙去脉,终于搞懂了特权同学的设计思想,并花了一些时间将代码自己敲一遍,并加上自己的注释360桌面截图20141119135138.jpg

然而设计并没有像我想象的那么简单,代码设计好之后还要经过仿真,时序约束,仿真总体来说还好,但是时序约束我接触的很少,于是又去学时序约束方面的知识,由于控制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,
            ADD = 3'b010,
            AND = 3'b011,
            XOR = 3'b100,
            LDA = 3'b101,
            STO = 3'b110,
            JMP = 3'b111;
后13位代表地址码,指令寄存器将读回来的数据分成指令码opcode[2:0]和地址码ir_addr[12:0],状态控制器读回指令码进行译码,看是什么指令,然后根据指令的内容操作其他部件,若为写数据则打开RAM进行写数据,若为计算则将数据送到算数运算器进行算数运算,若为跳转指令则地址指向下一地址,下次读取指令的时候就跳过一个地址执行等等

  三、各模块精讲

     本次设计的cpu共包含8个模块,下面我来一一讲解

1.时钟发生器

360桌面截图20141119142639.jpg
本模块的用来产生分频信号,外部50M的时钟,做8分频输出,此8分频信号用来控制地址多路器的输出,由于之后我们要用到8状态的状态机,因此这里做成8分频,至于具体原因,我们后面再讲,然后是一个算数运算器的使能信号,每一个8分频信号到来之前有一个算术运算器使能信号的高脉冲,意思就是,每一此状态机循环开始之前做一次运算
360桌面截图20141119143436.jpg
360桌面截图20141119143528.jpg
才有状态机的方式来设计分频信号避免了使用计数器计数的方法来延时,提高了程序的可读性和速度
 
2.指令寄存器
360桌面截图20141119143810.jpg
 
本模块的作用是将来自ROM的16位数据寄存并分为高三位的指令码和低13位的地址码
360桌面截图20141119144948.jpg
指令寄存器分两次读取ROM中的数据
 
3.累加器
360桌面截图20141119145119.jpg
 
算数运算器的初值位0,来自ROM的数据经算数运算器处理之后输出到累加器,累加器使能信号到来时,再将这份数据送到算数运算器作为初值,与下次从ROM中读回的数据进行算数运算
360桌面截图20141119145644.jpg
 
4.算数运算器
360桌面截图20141119145855.jpg
 
算术运算器先判断来自ROM的高三位指令码是何种指令,然后将来自ROM中的数据和来自累加器中的数据进行算数运算,并将结果输出。如果算数运算器中的数据是0的话,那么有一个高脉冲zero输出
360桌面截图20141119150218.jpg
 
5.数据控制器
360桌面截图20141119150409.jpg
 
如果想将算数运算器的结果保存起来,输出到RAM,那么可以选通数据控制器,将数据输出到RAM,配合指令STO
360桌面截图20141119150617.jpg
 
6.地址多路器
 
360桌面截图20141119150723.jpg
 
8分频时钟的前半周期用来读取ROM中指定地址的数据,后半周期用来进行指令操作,所以前半个周期需要从指定ROM中读数据,所以输出地址应为pc_addr,后半个周期用来处理指令,那么要操作的肯定是从ROM中读回的13位地址,即ir_addr,并将其输出
 
360桌面截图20141119151231.jpg
 
7.程序计数器
 
360桌面截图20141119151320.jpg
 
刚开始从ROM中读取数据的地址是pc_addr,是0地址,若为跳转指令,则需要将从ROM中读回的13位地址码作为新地址给pc_addr,等下一个8分频时钟到来时就读取该地址的指令,实现跳转指令的目的。如果不是跳转指令,那么pc_addr加1指向下一地址,继续执行
360桌面截图20141119151727.jpg
 
8.状态控制器
 
360桌面截图20141119151905.jpg
 
 
状态控制器,即我们的状态机,使我们本次设计的核心部件,状态机共用了8个状态
          前两个状态用来读取ROM中的16位数据,需要两个时钟,也就是需要两个状态。
          第三个状态等待一个时钟周期,目的是要凑够8个状态,因为8分频时钟的后半个周期需要4个状态来完成,故前半周期也需要4个状态,由于前半周期只需要读取数据和地址指向下一地址即可,故需凑一个状态
 
          第四个状态地址加1 ,指向下一地址
          第五到八个状态用来分析指令和执行指令,若为跳转指令,则控制程序计数器改变目标地址,若为跳过下一条指令,则控制程序计数器pc_addr地址加4,若为运算指令,则将控算数运算器进行相应的逻辑运算,若为LDA写入指令,则将读回的数据放入累加器中等等,具体操作指令的含义见下图
 
360桌面截图20141119152940.jpg
 
 
各个模块设计好之后将其组装便完成了我们的cpu设计,组装后的顶层模块见下图
 
360桌面截图20141119153255.jpg
       这样,我们的cpu就设计完成了,当然设计完成之后还要进行仿真,要仿真就还需要外围电路,包括存期指令程序ROM,存取数据的RAM,地址译码器等,由于ROM和RAM是不可综合的,但是我们可以在仿真的时候模拟。
       由于每篇文章最多只能上传20张图片,所以今天的教程就到此为止吧,具体的仿真过程和ROM、RAM的设计小墨同学将在下一篇文章中介绍,下一篇文章中将会提到modolsim SE的使用,test bench的书写,前面的博客中虽然也略有提及,但并不系统,下一篇文章将会以本次设计为例,给大家介绍仿真的全过程,希望大家大力支持,下面附上部分仿真的图片和测试结果供大家参考
 
波形仿真
360桌面截图20141119154152.jpg
 
 
     此外,以后小墨同学的文章将在EDNchina和北京至芯科技官方技术论坛同时更新,至芯科技的官方技术论坛也有很多的资料供大家下载,里面也有小墨的专题板块,希望广大网友和爱好者的大力支持~
http://www.fpgaw.com/
小墨同学专版网址
http://www.fpgaw.com/thread-78527-1-1.html
下面是至芯科技官方网站,夏宇闻教授和那里的老师都超好的~有意愿接受FPGA培训的可以找工作人员咨询
http://www.zxopen.com/
       以后小墨同学的教程会跟这款开发板配套,想跟小墨同学一起学习,一起进步的的可以考虑一下购买一块开发板,毕竟学习要舍得投资嘛,下面是开发板淘宝链接
http://item.taobao.com/item.htm?spm=a230r.1.14.18.YdZFbX&id=40547871864&ns=1&abbucket=13#detail
 
 
谢谢各位大神的支持,这篇文章写了几个小时,纯手打~
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

文章评论3条评论)

登录后参与讨论

用户1870125 2016-2-1 17:43

太强了

用户377235 2014-11-21 18:15

cpu设计出来怎么把程序写进去啊?编译器?

用户403664 2014-11-21 10:19

腻害~~
相关推荐阅读
小墨同学 2015-09-10 10:28
零基础学FPGA( 三十二) 写在京城,多级FIR半带滤波器的FPGA实现
        每次到京城来总不能忘了出去逛逛吧,偌大的北京城去哪呢?炙热的大太阳烤的哪都不想去了,幸好这次有亲戚来北京旅游,搭个顺风车便出去转了一下。这次的闲逛可没有上次那么感叹,上次主要是去的...
小墨同学 2015-08-29 15:19
零基础学FPGA(三十三)多相结构抽取滤波器笔记
        前两篇文章已经介绍过了,在多速率信号处理中,CIC滤波器和FIR半带滤波器应用的非常广泛,由于CIC滤波器的特殊结构,使得它非常适合采样速率远远大于信号速率的情况时的抽取跟内插滤波...
小墨同学 2015-08-29 15:18
零基础学FPGA(三十一)写在京城,Hogenauer CIC抽取滤波器的FPGA实现笔记
         实习完还没几天,突然接到北京至芯雷总的电话,让我赶往北京来做一些事情,就这样,我的又一趟北京之旅开始了。         上次来北京还是今年1月份,冬天嘛,京城光秃秃的一片,...
小墨同学 2015-08-05 20:50
【博客大赛】零基础学FPGA (二十六)必会! 从静态时序分析到SDRAM时序收敛(上篇)
    好像小墨有这么一个习惯啊,就是每篇文章的开头总喜欢叨叨几句啊~既然这样,那我们今天也聊几句好了,总感觉直接就开始学习专业知识有点让人看不进去~     今天我们就说说生活吧~时间很快啊,...
小墨同学 2015-07-26 21:57
[博客大赛]零基础学FPGA(三十) IIR数字滤波器的FPGA实现笔记
      然而暑假已经过了快一半,想想也是挺快的,前一段时间学校安排实习,在长沙待了一段时间,说是实习,感觉却是像是度假,住着酒店,100多号人,想想都觉的热闹。实习搞得是Java安卓,当然我也...
小墨同学 2015-06-17 09:50
[博客大赛] 零基础学FPGA (二十九)滤波器开篇,线性相位FIR滤波器的FPGA实现
        也是有一段时间不写博客了啊,主要是这学期的实验课太多,每天都是在写预习报告,实验报告中度过,也快到考试月了啊,感觉又要忙起来了,今天就抽点时间来开个头,开什么头呢?对!就如标题所示...
我要评论
3
10
关闭 站长推荐上一条 /2 下一条