自己动手写CPU之第四阶段(4)——Makefile文件建立

将陆续上传本人写的新书《自己动手写CPU》(尚未出版),今天是第14篇,我尽量每周四篇

4.4.6 编写Makefile文件

为了得到指令存储器初始化文件,我们需要输入4条命令,有点麻烦,最好只输入一条命令就可以了,这需要使用到Makefile文件。在汇编程序inst_rom.S所在目录下新建一个Document,文件名为Makefile,内容如下。

ifndef CROSS_COMPILE
CROSS_COMPILE = mips-sde-elf-
endif
CC = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump

OBJECTS = inst_rom.o

export	CROSS_COMPILE

# ********************
# Rules of Compilation
# ********************

all: inst_rom.data

%.o: %.S
	$(CC) -mips32 $< -o [email protected]

inst_rom.om: ram.ld $(OBJECTS)
	$(LD) -T ram.ld $(OBJECTS) -o [email protected]

inst_rom.bin: inst_rom.om
	$(OBJCOPY) -O binary $<  [email protected]

inst_rom.data: inst_rom.bin
	./Bin2Mem.exe -f $< -o [email protected]

clean:
	rm -f *.o *.om *.bin *.data

这是一个很简单的Makefile,借助于它介绍Makefile的组成。Makefile的前半部分是一些变量的定义,比如:定义CC为mips-sde-elf-as,定义LD为mips-sde-elf-ld,其中引用了预定义的变量CROSS_COMPILE。Makefile的后半部分定义了多个目标,有all、clean等,采用的语法如下:

目标:依赖文件
      命令

上述形式表示的意思是:(1)要想得到“目标”,那么需要执行“命令”;(2)“目标”依赖于“依赖文件”,当“依赖文件”中至少一个文件比“目标”文件新时,“命令”才被执行。在上面Makefile的“命令”中使用了Makefile一些预定义的变量,含义如下:

	$<     表示第一个依赖文件的名称
        [email protected]     表示目标的完整名称

所以上述Makefile可以解读如下:

(1)用户输入make all,要求得到目标all,目标all的依赖文件是inst_rom.data,要先得到inst_rom.data

(2)要得到inst_rom.data,需要依赖文件inst_rom.bin。

(3)要得到inst_rom.bin,需要依赖文件inst_rom.om。

(4)要得到inst_rom.om,需要依赖文件$(OBJECTS),其中OBJECTS是预定义变量,其值为inst_rom.o,所以此处就是需要依赖文件inst_rom.o。

(5)要得到inst_rom.o,需要依赖文件inst_rom.S,该文件已经提供,满足依赖条件,所以会执行命令$(CC) –mips $< -o [email protected],实际就是如下命令,执行后得到inst_rom.o。

mips-sde-elf-as –mips inst_rom.S –o inst_rom.o

(6)得到inst_rom.o后,满足了目标inst_rom.om的依赖条件,所以可以进一步得到inst_rom.om,通过执行命令$(LD) -T ram.ld $(OBJECTS)-o [email protected],实际就是通过如下命令得到inst_rom.om。

mip-sde-elf-ld -T ram.ld inst_rom.o –o inst_rom.om

(7)得到inst_rom.om后,满足了目标inst_rom.bin的依赖条件,所以可以进一步得到inst_rom.bin,通过执行命令$(OBJCOPY) -O binary$<  [email protected],实际就是通过如下命令得到inst_rom.bin。

mip-sde-elf-objcopy -O binary inst_rom.om inst_rom.bin

(8)得到inst_rom.bin后,满足了目标inst_rom.data的依赖条件,所以可以进一步得到inst_rom.data,通过执行命令./Bin2Mem.exe -f $< -o [email protected],实际就是通过如下命令得到inst_rom.data。

./Bin2Mem.exe -f inst_rom.bin –o inst_rom.data

(9)得到inst_rom.data,满足了目标all的依赖条件,从而实现目标all。

有了Makefile文件,我们在终端中输入“make all”就可以完成所有的过程了。简单总结一下从测试程序得到指令存储器ROM初始化文件的步骤。

(1)编写源代码,当然是汇编代码,文件名为inst_rom.S。

(2)复制本节编写的Makefile、Bin2Mem.exe、ram.ld到源代码所在目录。

(3)打开终端,路径调整到源代码所在目录,输入“make all”。

经过上述步骤,即可得到能够在ModelSim仿真中使用的指令存储器ROM初始化文件inst_rom.data。

最后,我们可以增加一步,使用工具mips-sde-elf-objdump对inst_rom.om进行反汇编,从而得到指令与其二进制字的对应。如下。

mips-sde-elf-objdump -D inst_rom.om > inst_rom.asm

得到inst_rom.asm文件,使用记事本打开该文件,内容如图4-31所示。重点是图中使用黑框包围的部分,其对应的就是测试程序的4条指令。每一行分为三列:左边一列是指令地址,中间一列是指令对应的二进制字,右边是汇编指令。注意:这里的指令进行了变化,虽然测试程序都是ori指令,但是这里都改为了li指令,li是汇编指令,ori是机器指令,两者是相等的。

li rt, immediate   =>   ori rt,$0,immediate

另外,此处的寄存器没有使用$1、$2、$3、$4这种方式,而是使用了约定命名。MIPS32中通用寄存器的约定命名可以参考第1章的表1-1。有了inst_rom.asm文件,在进行仿真波形分析的时候,有助于将仿真波形中的32bit二进制指令字与汇编程序中的指令对应,便于分析。

可以修改Makefile文件,使得在编译得到inst_rom.data的同时得到反汇编文件inst_rom.asm,具体修改方法不再详述,读者可以参考本书附带光盘的Code\Chapter4\TestAsm目录下的Makefile文件。

4.5 第一条指令实现小结

本章是很重要的一章,而且内容相对比较杂,在此做一小结,主要做了四项工作。

(1)本章通过实现指令ori,搭建了一个原始的五级流水线结构,这也是OpenMIPS的核心,当然,目前OpenMIPS还只能执行ori指令,后续会逐步丰富。

(2)实现了一个用于测试的最小SOPC,仅仅包括处理器OpenMIPS、指令存储器ROM,并编写了Test Bench测试文件。

(3)在ModelSim中通过仿真验证了ori指令实现的正确性,也验证了OpenMIPS五级流水线实现的正确性。

(4)详细介绍了从汇编代码编写的测试程序得到仿真中使用的指令存储器初始化文件的过程,同时,利用Makefile简化了这个过程。

第一条指令ori实现代码的下载地址:

http://download.csdn.net/detail/leishangwen/7686717

自己动手写CPU之第四阶段(4)——Makefile文件建立

时间: 2024-11-05 20:46:03

自己动手写CPU之第四阶段(4)——Makefile文件建立的相关文章

自己动手写CPU之第四阶段(2)——验证第一条指令ori的实现效果

将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第12篇,我尽量每周四篇 书名又之前的<自己动手写处理器>改为<自己动手写CPU> 4.3 验证OpenMIPS实现效果 4.3.1指令存储器ROM的实现 本节将验证我们的OpenMIPS是否实现正确,包含:流水线是否正确.ori指令是否实现正确.在验证之前,需要首先实现指令存储器,以便OpenMIPS从中读取指令. 指令存储器模块是只读的,其接口如图4-7所示,还是采用左边是输入接口,右边是输出接口的方式绘

自己动手写CPU之第四阶段(3)——MIPS编译环境的建立

将陆续上传本人写的新书<自己动手写CPU>(尚未出版).今天是第13篇.我尽量每周四篇 4.4 MIPS编译环境的建立 OpenMIPS处理器在设计的时候就计划与MIPS32指令集架构兼容,所以能够使用MIPS32架构下已有的GNU开发工具链.本节将说明怎样安装使用GNU开发工具链以及怎样制作Makefile文件.从而以更加方便.快捷.自己主动的方式对測试程序进行编译.并得到指令存储器ROM的初始化文件inst_rom.data. 4.4.1 VisualBox的安装与设置 GNU工具链要安装

自己动手写CPU之第七阶段(2)——简单算术操作指令实现过程

将陆续上传本人写的新书<自己动手写CPU>,今天是第25篇,我尽量每周四篇 亚马逊的预售地址如下,欢迎大家围观呵! http://www.amazon.cn/dp/b00mqkrlg8/ref=cm_sw_r_si_dp_5kq8tb1gyhja4 China-pub的预售地址如下: http://product.china-pub.com/3804025 7.2 简单算术操作指令实现思路 虽然简单算术操作指令的数目比较多,有15条,但实现方式都是相似的,与前几章逻辑.移位操作指令的实现方式也

自己动手写CPU之第七阶段(3)——简单算术操作指令实现过程(续)

将陆续上传本人写的新书<自己动手写CPU>,今天是第26篇,我尽量每周四篇 China-pub的预售地址如下(有目录.内容简介.前言): http://product.china-pub.com/3804025 亚马逊的预售地址如下,欢迎大家围观呵! http://www.amazon.cn/dp/b00mqkrlg8/ref=cm_sw_r_si_dp_5kq8tb1gyhja4 为了实现简单算术指令,需要修改译码阶段的ID模块.执行阶段的EX模块,上一篇博文中已经介绍了对译码阶段ID模块的

自己动手写CPU之第六阶段(2)——移动操作指令实现思路

将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第21篇,我尽量每周四篇 6.2 移动操作指令实现思路 6.2.1 实现思路 这6条移动操作指令可以分为两类:一类是不涉及特殊寄存器HI.LO的指令,包括movn.movz:另一类是涉及特殊寄存器HI.LO的指令,包括mfhi.mflo.mthi.mtlo.前一类很好实现,基本思路与第5章实现逻辑.移位操作指令时类似,只需要修改ID.EX模块即可.后一类涉及到特殊寄存器HI.LO,需要为OpenMIPS添加HI.LO寄存器,以及相应

自己动手写CPU之第七阶段(1)——简单算术操作指令说明

将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第24篇,我尽量每周四篇 本章将实现MIPS32指令集架构定义的所有算术操作指令,共有21条,按照OpenMIPS实现这些指令的方式,可以分为三类,分别介绍如下. (1)简单算术操作指令 共有15条,包括加法.减法.比较.乘法等指令,这些指令在流水线的执行阶段都只需要一个时钟周期,而且实现思路很直观,与第4章添加逻辑操作指令类似,只需修改译码阶段的ID模块.执行阶段的EX模块,即可实现. (2)乘累加.乘累减指令 共有4条:乘累加m

自己动手写CPU之第五阶段(4)——逻辑、移位与空指令的实现

将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第18篇,我尽量每周四篇 5.5 修改OpenMIPS以实现逻辑.移位操作与空指令 为了实现逻辑.移位操作与空指令(其中nop.ssnop不用特意实现,可以认为是特殊的逻辑左移指令sll),只需要修改OpenMIPS的如下两个模块. 修改译码阶段的ID模块,用以实现对上述指令的译码. 修改执行阶段的EX模块,使其按照译码结果进行运算. 5.5.1 修改译码阶段的ID模块 首先给出如下宏定义,都在文件defines.v中定义,读者可以

自己动手写CPU之第五阶段(2)——OpenMIPS对数据相关问题的解决措施

将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第16篇,我尽量每周四篇 5.2 OpenMIPS对数据相关问题的解决措施 OpenMIPS处理器采用数据前推的方法来解决流水线数据相关问题.通过补充完善图4-4原始的数据流图,添加部分信号使得可以完成数据前推的工作,如图5-7所示.主要是将执行阶段的结果.访存阶段的结果前推到译码阶段,参与译码阶段选择运算源操作数的过程. 图5-8给出了为实现数据前推而对OpenMIPS系统结构所做的修改.有两个方面. (1)将处于流水线执行阶段的

自己动手写CPU之第六阶段(1)——移动操作指令说明

将陆续上传本人写的新书<自己动手写CPU>(尚未出版),今天是第20篇,我尽量每周四篇 本章将实现移动操作指令,首先在6.1节介绍了MIPS32指令集架构中定义的移动操作指令的格式.作用,接着在6.2节给出移动操作指令实现思路,介绍了修改后的数据流图.新出现的数据相关问题及其解决措施,并给出了修改后的OpenMIPS系统结构图.在6.3节列出了详细的修改过程.本章最后通过一个测试程序验证移动操作指令是否实现正确. 6.1 移动操作指令说明 MIPS32指令集架构中定义的移动操作指令共有6条:m