简易CPU入门:打开一个已有的工程,了解本专栏CPU代码工程

在上一节,我是讲解了大如何来建立一个工程。并且呢,在Quartus软件与ModelSim软件已经关联好了的情况下,如何来进行两个软件的联合仿真。在本节呢,我们不是要来新建一个工程了,本节,我们需要的是打开一个已有的工程。

既然是打开一个已有的工程,那么,我们就可以打开一个有趣的工程,我们本专栏所使用的CPU代码工程。

一般地,流行的教材与博客,在写操作系统与CPU教程的时候,都是说,从零开始,逐步地来增加代码。这种方法,优点是循序渐进,对读者比较友好一些。但是,我并不准备采用这种做法。

为什么我不想采用这种做法呢?

写完了某一个模块的代码以后,再往里面添加新代码的时候,往往是说,我自己都忘记了,我究竟是在哪些地方添加了代码,哪里删除或者是修改了代码。

而且,如果是逐步地增加代码,万一自己之前的代码有bug,那么,后面在调试代码的时候,发现了自己以前的bug,那么,处理起来,也很麻烦。

之所以不采取流行的教材的做法,主要的原因,其实还是我自身的编程能力还不够。以我现有的能力,编写出来一个基础的CPU,已经是很不容易了。如果,再让我从零开始,逐步地来领着大家实现一个CPU,那么,这对我来讲,难度就太大了。

在这里,我是打算,直接将整个的CPU代码工程展现给大家。

这个工程的代码量,个人觉得,也还算是可以吧。我会尽量地,将其讲解清楚。

一.   下载本专栏的配套CPU代码工程

我将我的这个CPU代码工程,已经是上传到CSDN里面了。下面,是这一资源的链接。

简易CPU入门项目代码

下载的时候,可能会需要大家花费一点资源积分,或者说,你可能需要花点钱。

下载的难度并不高。这个资源包,它是一个zip压缩包。解压缩以后,里面是整个的项目。

二.   打开CPU代码工程

首先呢,请大家在下载了这个名为【cpu_me01.zip】的压缩包文件以后,将其解压缩到某一个路径下面。注意,这个路径中,不要有中文、空格和特殊符号。

完成了资源包的下载和解压缩以后,请大家打开Quartus软件。

然后呢,我们一起来打开这个已有的工程。步骤如下。

第1步,依次点击【File】,【Open Project】菜单项,打开【Open Project】对话框,过程如下图所示。

图1
图2

第2步,在图2所示的【Open Project】对话框里面,浏览到本代码项目的工程文件。对于这个项目,我在写代码的时候,我将工程文件设置在【cpu_me01】文件夹里面了,工程文件的名字为【cpu_me01.qpf】。请大家根据自己的情况,浏览到你的本地的【cpu_me01】文件夹里面的【cpu_me01.qpf】工程文件,结果如下图所示。

图3

第3步,浏览到【cpu_me01.qpf】工程文件以后,点击选中它,如图3左侧的红色框线所示。然后呢,点击图3的右侧红色框线所示的【打开】按钮。然后呢,这个CPU代码工程,也就打开了。

三.   了解本CPU工程的文件组织结构

打开【cpu_me01】文件夹以后,里面的东西如下图所示。

图4

在写作这个CPU代码的时候,我并没有采用之前给大家讲解建立工程的时候所用项目文件结构。而是采用了其他的文件组织结构。

在图4里面,【doc】文件夹是有的。这里面是存放着一些个文档。

图4里面没有设置【rtl】文件夹。取而代之地,我是设置了【code】文件夹,用于存放全部的设计代码,以及一部分的test bench代码。

我也没有设置【sim】文件夹,而是设置了【test_bench】文件夹,其作用和【sim】文件夹是一样的,都是用来存储着test bench文件的。不过,我的这个项目,它的文件组织结构,还是比较混乱的。当初,我去写这个CPU的时候,我是写了一部分的设计块代码以后,就去写一个test bench代码文件,以验证设计快能否正常运行。并且,这些中间的test bench文件,往往是和它所验证的设计块文件,位于同一个路径里面。只有最终的,对整个的工程作验证的test bench文件,我是放在了【test_bench】文件夹里面。

这还不算,在我的这个代码工程里面,目前大概只有【test_bench】文件夹里面的测试块文件是可用的。其余的以【tb_】开头的测试文件,应该都是不可用的。

这样的组织方式并不好。之所以会这样子来组织着,那是因为,写完了整个的CPU代码工程以后,我偷点懒,不乐意去认真地整理着整个的项目,所以,好多的不用的test bench文件,我也没有去清理。

图4里面还有一个【ip_core】文件夹,用于存放由Quartus软件生成的ip核。

除了【doc】,【code】,【test_bench】和【ip_core】之外,其余的文件夹,均为Quartus软件自动生成。

下图所示的几个文件,也是由Quartus软件生成的。

图5

其中,【.qpf】后缀格式的文件,是Quartus软件生成的工程文件。【qsf】,其实就是【Quartus Project File】的意思。

想要了解本项目的文件组织结构,我们主要需要去了解的,并不是由Quartus软件自动生成的文件或文件夹,而是我们自己设置的文件与文件夹。

(一)项目说明.docx

在【cpu_me01】文件夹里面,有一个word文档,它的文件名为【项目说明.docx】。在这里,我是对项目里面的一些个概念与机制作出了说明。这个呢,大家可以自己去阅读一下。我当初写这个说明文档,是为了给下载了本CPU项目的,且并未在我当前的这个CSDN专栏博客里面进行学习的人准备的。

因为,使用本项目的人,有可能是学习本专栏的人,也有可能是没有学习本专栏的人。我需要向这些没有学习本专栏的人,介绍一下本CPU项目。为了介绍本项目,【项目说明.docx】成为了几个工程介绍文件的其中一个。

(二)doc文件夹

【cpu_me01/doc】路径下面,有好几个东西,内容如下。

图6

名为【CPU规划】的word文档和txt文档,讲了我的一些个CPU规划。这是我当初在琢磨着,如何来设计这款CPU的时候,写的草稿。属于是说,我还没有完成这个CPU代码工程的时候,在设计各个模块的时候,所形成的草案。

两个截图文件,也是我在仿真测试某某设计模块的时候,所形成的东西。大家可以不必去看这俩截图文件。

至于系统运行流程,这个呢,属于是说,我为了给下载了本项目代码,而又没有学习本专栏的网友准备的一个说明文件,以告诉这些网友本代码的运行机制。

【新文件1.txt】,这个是我在写代码的过程中,所形成的一个中间文件。对于大家来讲,它已经是没啥用了。

为啥会形成这个中间文件呢?

写代码的时候,常常需要对照一些个代码。所需要对照的代码,有可能有好几块。如果,不同的代码块位于不同的文件中,那么,我就只需要将相应的代码文件显示对应的代码块就可以了。而有的时候,偏偏是说不同的代码块位于同一个代码文件中,那么,为了对照的方便,为了复制粘贴的方便,我就将一些个代码片段,拷贝到【新文件1.txt】里面了。本来呢,也可以将这些个临时的代码片段放在notepad++的临时的文件里面的。不过,我担心自己不小心将其删掉啥的,就在【doc】文件夹里面,设置了【新文件1.txt】这个文档,用于存放一些个我需要用到的代码片段。

(三)ip_core文件夹

这个文件夹里面,存放的是我用Quartus所生成的ip核。每一种ip核,我是分别放在了不同的文件夹里面。我们来看一看【ip_core】文件夹里面的内容。

图7

在图7里面,有两个文件夹,这两个文件夹的名字,都是我所申请的ip核的名字。

第一个ip核,名字是【ram_256x16】。这个ip核,用于模拟ram,也就是用来模拟着内存条。我是用它来存放着数据的。

假定说,我们想要实现一个指令,【mov al, [0x12]】,这一条指令,我是采用了英特尔格式的汇编指令的格式。它的意思是,从内存0x12这一单元,取出一个1字节的数,放入al寄存器里面。

在上面的汇编指令里面,0x12,它是一个内存单元的地址,也就是一个ram的地址。当我们需要从某某内存单元读取数据,或者是蒋某某数据写入某一个内存单元的时候,我们所用的模拟的内存条,就是【ram_256x16】。

那么,【ram_256x16】中的256x16是什么意思呢?256是说,这个模拟内存,它的内存单元的数量,是256个。16是说,每一个内存单元,其位宽为16位。也就是,这个模拟ram的尺寸,为256个16位,也就是256个2字节的容量,总共是512字节。

对于生活中使用的内存条来讲,512字节肯定是不够用的,512M我们都嫌少。现在,新出的电脑都在用win10,win11系统,最起码的,得是配置4G内存。我自己去选择内存容量的时候,8G打底,16G我觉得比较满意。

对于实用的计算机系统来讲,配置512字节的内容,那就太少了,根本不够用。然而,对于我们的这个简易CPU来讲,512字节已经是很够用了。实际上,根本用不到这么多。64字节,128字节都已经是很够用了。设置256x16的容量,我还是为了以防万一,为了让这个简易CPU显得阔气一点。

这样的话,【ram_256x16】,我就讲完了。那么,下面的【ram_diusk_256x16】,又是怎么回事呢?

一个现实的计算机系统,我们会用到硬盘。然后呢,计算机上电以后,会将硬盘中的代码加载到内存当中,然后CPU去运行内存中的代码。

同样的一个内存,既要存放着程序指令,也要存放着程序所要用到的数据。

而在我这里,我采取了和许多的流行的CPU同样的做法,让程序指令与数据分开来。让【ram_256x16】ip核来模拟着内存条,专门地用来存放程序数据。让【ram_disk_256x16】来模拟着硬盘,专门地用来存放程序指令。既然是用来模拟着硬盘,何不写成【disk_256x16】呢?这是因为,我为了简化处理,在这个简易的计算机系统中,省去了从模拟“硬盘”中往内存ram中加载程序指令的步骤。

如果真的要写一个从模拟硬盘中往模拟ram加载程序指令的代码模块,那么,这就已经是形成了一个简易的BIOS了。BIOS,就是基本输入输出系统的意思。对应着旧一点的电脑的BIOS,或者是对应着新电脑的UEFI。

我暂时还不想写太复杂的东西,所以,就直接申请一个ip核,用它来模拟着一个硬盘,同时假定,这个硬盘里面的数据,相当于在开机的时候,就已经是被加载到了内存里面了,我自己就不去专门写从硬盘到内存的加载代码了。

如此一来,【ram_256x16】ip核与【ram_disk_256x16】ip核,都是用来模拟着ram的。但是呢,这个模拟ram,又有所不同,一个是用来模拟着内存条,从内存读取数据,或者是往内存写入数据的时候,用的模拟内存,是【ram_256x16】。而当我们读取程序指令的时候,我们用的模拟ram,是【ram_disk_256x16】。也就是,前者专门用于存放程序数据,用于模拟着从内存中读写数据的操作。而后者则是专门用于存放着程序指令,用于模拟着从指令内存中读取程序指令。

不知道大家听懂了没有。希望你能够听懂吧。如果你没有听懂,那我得说一声抱歉了,这一块,我的表达能力有限了。有好的讲解建议的,欢迎联系我。

(四)code文件夹

这个文件夹,存放的主要是各种设计文件。我们看一看这个文件夹里面的内容。

图8

图8所示的东西,我觉得是很帅气的。最上面的,是【ALU】文件夹。ALU大家应该都知道吧?它就是大名鼎鼎的算术逻辑单元。不过,我估计,我这里所谓的算术逻辑单元,它和流行的处理器的算术逻辑单元,应该是不一样的。

我们来看一看【ALU】里面的内容。

图9

在图9里面,【ALU.v】用于实现总的算术逻辑的模块。然后呢,其余的代码文件,都是【xxx_cell.v】的格式。其中的【xxx】,代码本代码模块所实现的操作。l例如【add_cell.v】实现的是加法操作。

xxx的值实现的功能
add加法
sub减法
multi乘法
div除法
mod取余数
and按位与
or按位或
not逻辑非
xor按位异或
left_shift逻辑左移
right_shift逻辑右移

需要注意的是not运算,本来它在汇编代码里应该是指按位取反。不过,我在写代码的时候,将其设置 为逻辑非了。大家有兴趣的话,也可以在学完了本CPU项目代码以后,将其更改为按位取反。更改的难度,其实并不高。大家学完了本专栏以后,我相信,你能够做到。

看完了ALU以后。我们往下看。

大家回到图8。ALU以后,是【Ctrl_Center】,也就是控制中心。控制中心,算是本项目的核心模块了。它的代码量是最大的。我在书写这一模块的代码的时候,所花费的时间是较长的。并且呢,很多时候,某些个代码,本来可以新建代码文件的,但是我不愿意新建代码文件,我也把它放在了控制中心里面。它很复杂。

在正式讲解代码的时候,控制中心,是大家要去花费一点力气来学习的。

控制中心模块,是本项目的分量最大的一个模块。

控制中心之后,是【Instruct_Unit】,也就是指令单元。

我们来看一看里面的内容,如下图所示。

图10

在图10里面,【instruct_unit.v】是指令单元的总体的模块。其余的几个代码文件,是单独的某一条机器指令,或者叫做汇编指令的实现文件。

指令单元之后,是几个【.v】文件,如下图所示。

图11

在图11里面,【cpu_top.v】,它是整个项目的顶层模块文件。

【sys_init.v】,是系统初始化代码。

【get_intryct.v】,这个是取指令单元,用于从【ram_disk_256x16】中读取程序指令。读取到的指令,送入【decode_unit.v】里面。

【decode_unit.v】,它是译码单元,也就是传说中的译码器。用来对指令进行译码操作。

结束语

到了这里,本CPU项目代码的整体结构,我就算是介绍完了。

接下来,我打算去讲解一下实际的代码逻辑。

那么,大家在学习本项目代码的时候,最需要注意的,大概会是控制中心的模块代码了。

祝大家学习进步。

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值