基于FPEG的SOC设计-mips指令系统-(verilog代码)

合集下载

mips 汇编代码

mips 汇编代码

MIPS汇编代码MIPS汇编代码是MIPS微处理器的汇编语言,由MIPS Technologies公司开发。

它是一种低级编程语言,允许程序员直接控制处理器的寄存器和指令。

MIPS汇编代码通常用于嵌入式系统和实时系统,因为它可以提供对硬件的精细控制和高性能。

MIPS汇编代码由一系列指令组成,每条指令由一个操作码和零个或多个操作数组成。

操作码指定要执行的操作,而操作数指定操作的参数。

MIPS汇编代码中的指令可以分为以下几类:算术和逻辑指令:这些指令用于执行算术和逻辑运算,例如加、减、乘、除、与、或、非等。

数据传送指令:这些指令用于在寄存器和内存之间传送数据。

控制流指令:这些指令用于控制程序的执行流程,例如跳转、分支、调用和返回等。

系统指令:这些指令用于与系统进行交互,例如加载和存储程序和数据、读写I/O设备等。

MIPS汇编代码通常使用以下语法:label: instruction operand1, operand2, ...其中,label是指令的标签,instruction是指令的操作码,operand1、operand2等是指令的操作数。

MIPS汇编代码的程序结构通常包括以下几个部分:数据段:数据段用于存储程序中使用的数据,包括常量、变量和数组等。

代码段:代码段用于存储程序的指令。

堆栈段:堆栈段用于存储程序的局部变量和临时数据。

MIPS汇编代码的编译过程通常包括以下几个步骤:预处理:预处理阶段将源代码中的宏和条件编译指令进行处理。

汇编:汇编阶段将源代码中的指令转换成机器码。

链接:链接阶段将汇编生成的机器码与库函数和系统库进行链接,生成可执行文件。

MIPS汇编代码的优点包括:高性能:MIPS汇编代码可以提供高性能,因为它可以直接控制处理器的寄存器和指令。

精细的控制:MIPS汇编代码允许程序员对硬件进行精细的控制,这对于嵌入式系统和实时系统非常重要。

可移植性:MIPS汇编代码可以移植到不同的MIPS处理器上,因为MIPS处理器具有相同的指令集架构。

MIPS指令集(共31条)

MIPS指令集(共31条)
;address=10000/4
注意:因为MIPS16只有16个16位的寄存器,所以JAL指令中$31改成$15, 所有立即数均无需扩展,LUI指令直接就是将立即数付给RT寄存器。
$1=0
if (rs < rt) rd=1 else rd=0 ;其中rs=$2,rt=$3, rd=$1
sltu
000000
rs
rt
rd
00000
101011
sltu $1,$2,$3
if($2<$3)
$1=1 else
$1=0
if (rs < rt) rd=1 else rd=0 ;其中rs=$2,rt=$3, rd=$1
goto PC+4+40
if (rs != rt) PC <- PC+4 + (sign-extend)immediate<<2
slti
001010
rs
rt
immediate
slti $1,$2,10
if($2<10)
$1=1 else
$1=0
if (rs <(sign-extend)immediate) rt=1 else rt=0 ;
PC <- rs
I-type
op
rs
rt
immediate
addi
001000
rs
rt
immediate
addi $1,$2,100
$1=$2+100
rt <- rs + (sign-extend)immediate ;其中rt=$1,rs=$2
addiu
001001

MIPS 指令系统和汇编语言

MIPS 指令系统和汇编语言

其中 A1 为目的操作数地址,A2 为源操作数地址。 指令的含义:(A1)OP(A2)→A1。 (3)一地址指令 一地址指令顾名思义只有一个显地址,它的指令格式为: OP A1
一地址指令只有一个地址, 那么另一个操作数来自何方呢?指令中虽未明显给出,但按事 先约定,这个隐含的操作数就放在一个专门的寄存器中。因为这个寄存器在连续性运算时,保 存着多条指令连续操作的累计结果,故称为累加寄存器(AC) 。 指令的含义:(AC)OP(A1)→AC (4)零地址指令 零地址指令格式中只有操作码字段,没有地址码字段,其格式为: OP 零地址的运算类指令仅用在堆栈计算机中的。 堆栈计算机没有一般计算机中必备的通用寄 存器,因此堆栈就成为提供操作数和保存运算结果的唯一场所。通常,参加运算的两个操作数 隐含地从堆栈顶部(栈顶和次栈顶单元)弹出,送到运算器中进行运算,运算的结果再隐含地 压入堆栈中。对于同一个问题,用三地址指令编写的程序最短,但指令长度(程序存储量)最 长;而用二、一、零地址指令来编写程序,程序的长度一个比一个长,但指令的长度一个比一 个短。
作码结构等,是一个很复杂的问题,它与计算机系统结构、数据表示方法、指令功能设计等都 密切相关。
指令的基本格式
一条指令就是机器语言的一个语句, 它是一组有意义的二进制代码, 指令的基本格式如下: 操作码字段 地址码字段
其中操作码指明了指令的操作性质及功能,地址码则给出了操作数的地址。 指令的长度是指一条指令中所包含的二进制代码的位数, 指令长度与机器字长没有固定的 关系,它可以等于机器字长,也可以大于或小于机器字长。通常,把指令长度等于机器字长的 指令称为单字长指令; 指令长度等于半个机器字长的指令称为半字长指令;指令长度等于两个 机器字长的指令称为双字长指令。 在一个指令系统中,若所有指令的长度都是相等的,称为定长指令字结构。定长结构指令 系统控制简单,但不够灵活。若各种指令的长度随指令功能而异,就称为变长指令字结构。现 代计算机广泛采用变长指令字结构,变长结构指令系统灵活,但指令的控制较复杂。 计算机执行一条指令所需要的全部信息都必须包含在指令中。 对于一般的双操作数运算类 指令来说,除去操作码之外,地址码字段中应包含以下信息: 第一操作数地址。 第二操作数地址。 操作结果存放地址。 这些信息可以在指令中明显的给出,称为显地址;也可以依照某种事先的约定,用隐含的 方式给出,称为隐地址。所以,从地址结构的角度可以分为三地址指令、二地址指令、一地址 指令和零地址指令。 (1)三地址指令 三地址指令格式为: OP A1 A2 A3

MIPS指令系统和MIPS体系结构

MIPS指令系统和MIPS体系结构
(4)选择“文件”->“载入程序”选项,加载样例程序 alltest.asm,然后查看“代码”窗口,查看程序所在的位置(起始地址为0x00000000)。
(5)查看“寄存器”窗口PC寄存器的值:[PC]=0X 00000000。
(6)执行load和store指令,步骤如下:
1)单步执行一条指令(F7)。
8)下一条指令地址为0X 0000000c,是一条无(有,无)符号载入字1(字节,半字,字)指令。
9)单步执行1条指令。
10)查看R1的值,[R1]=0X 128。
11)单步执行1条指令。
12)下一条指令地址为0X 00000014,是一条保存字(字节,半字,字)指令。
13)单步执行一条指令(F7)。
实验步骤
(1)启动MIPSsim(用鼠标双击MIPSsim.exe)。
(2)选择“配置”->“流水方式”选项,使模拟器工作在非流水方式。
(3)参照使用说明,熟悉MIPSsim模拟器的操作和使用方法。
可以先载入一个样例程序(在本模拟器所在的文件夹下的“样例程序”文件夹中),然后分别以
单步执行一条指令、执行多条指令、连续执行、设置断点等的方式运行程序,观察程序的执行情况,观察CPU中寄存器和存储器的内容的变化。
14)查看内存BUFFER处字的值,值为0X 00000018。
(7)执行算术运算类指令。步骤如下:
1)双击“寄存器”窗口中的R1,将其值修改为2。
2)双击“寄存器”窗口中的R2,将其值修改为3。
3)单步执行一条指令。
4)下一条指令地址为0x00000020,是一条加法指令。
5)单步执行一条指令。
6)查看R3的值,[R3]= 0x5。
2)下一条指令地址为=0X 00000004,是一条有(有,无)符号载入字节(字节,半字,字)指令。

02-1MIPS指令与汇编

02-1MIPS指令与汇编

一、 MIPS简介
基于龙芯2E处理器的千元的PC、1999元的笔记本电脑、 意法半导体3000万元购买龙芯2E 5年的生产和销售权, 国产操作系统内核在龙芯2E上测试成功。 龙芯2E微处理器是一款实现64位MIPSⅢ指令集的通用 RISC处理器,与X86指令架构互不兼容;芯片面积 6.8mm×5.2mm;最高工作频率为1GHz;实测功耗5-7瓦。 龙芯2E在1GHz主频下SPEC CPU2000的实测分值达到 500分,综合性能达到了高端Pentium Ⅲ以及中低端 Pentium 4处理器的水平。 龙芯2F
一、 MIPS简介
由于与X86指令的不 兼容,龙芯2E无法运 行现有的Windows 32/64位操作系统, 和基于Windows的 众多应用软件。
龙芯2E笔记本电脑运行 OpenOffice打开Word文档
二、MIPS体系结构
指令集体系结构类型:寄存器——寄存器型
(1)寄存器的特点 (2)整数乘法单元和寄存器 (3)寻址方式 (4)存储器和寄存器中的数据类型 (5)流水线冒险
如果没有全局指针,存取一个静态数据区域 的值需要两条指令:
一条是获取有编译器和loader决定好的32位的地 址常量。 另外一条是对数据的真正存取。
为了使用$ gp, 编译器在编译时刻必须知道 一个数据是否在$ gp的64K范围之内。 并不是所有的编译和运行系统支持gp的使用。
MIPS 通用寄存器的使用
二、 MIPS体系结构——(1)寄存器
MIPS 包含32个通用寄存器 硬件没有强制性的指定寄存器 使用规则,但是在实际使用 中,这些寄存器的用法都遵循 一系列约定 寄存器约定用法引入了一系列 的寄存器约定名。在使用寄存 器的时候,要尽量用这些约定 名或助记符,而不直接引用寄 存器编号

SoC硬件综合设计中基于Verilog语言的接口程序设计

SoC硬件综合设计中基于Verilog语言的接口程序设计

第20卷第3期2006年06月 江苏科技大学学报(自然科学版)Journal of J iangsu University of Science and Technol ogy(Natural Science Editi on)Vo1120No13Jun.2006文章编号:1673-4807(2006)03-0073-04SoC硬件综合设计中基于Ver ilog语言的接口程序设计张 辉1,於跃成2(1.武汉船舶职业技术学院,湖北武汉430050; 2.江苏科技大学电子信息学院,江苏镇江212003)摘 要:针对系统芯片SoC(Syste m2on2Chi p)设计中I P复用问题,提出了一种基于状态机FS M(FiniteState Machine)自动生成的SoC硬件接口综合设计方法,给出了基于Veril og语言的接口程序设计,通过实例仿真验证了该方法的可行性。

该方法可以自动化生成接口程序,对于缩短SoC芯片设计时间,提高I P复用程度等方面提供了一种新的方法。

关键词:系统芯片;I P;状态机;接口综合;Veril og中图分类号:TP303 文献标识码:AI n terface D esi gn Ba sed on Ver ilog Languagei n SoC Hardware I n terface Syn thesisZHAN G Hu i1,YU Yuecheng2(1.W uhan I nstitute of Shi pbuilding Technol ogy,W uhan Hubei430050,China;2.School of Electr onics and I nfor mati on,Jiangsu University of Science and Technol ogy,Zhenjiang J iangsu212003,China) Abstract:A i m ing at the p r oble m of I P dup licate usage in the design of SoC(Syste m2on2a2Chi p),a hardware interface synthesis method is p resented based on the aut omatic generating by the finite state machine.The in2 terface p r ogra m based on the hard ware descri p ti on language Veril og is given.The way t o f or mulate the interface p r ogra m is given.The method is verified thr ough the p ractical exa mp le.The interface p r ogra m can be generated aut omatically by using the method.The ne w method may shorten the design ti m e of SoC and s olve the dup licate usage of I P.Key words:syste m2on2chi p;intellectual p r operty;finite state machine;interface synthesis;Veril og0 引 言随着信息产业的迅猛发展,以深亚微米工艺和I P核重用技术为支撑的系统芯片SoC(Syste m2on2Chi p)技术正成为国际超大规模集成电路未来发展的总体趋势。

04MIPS指令系统(1)_447408859

04MIPS指令系统(1)_447408859

微机原理(计算机原理)第4讲MIPS指令系统(1)1MIPS体系结构概述数据处理指令数据传送指令分支与跳转指令MIPS指令格式第4讲MIPS指令系统(1)MIPS诞生于1980年代,是最早的RISC处理器之一,也是目前销量最好的RISC处理器之一,从游戏机到路由器,再到SGI的超级计算机,都可以看到MIPS CPU 的应用MIPS起源于Stanford大学John Hennessy教授的研究成果。

Hennessy于1984年在硅谷创立了MIPS公司()John L. Hennessy出版了两本著名的教科书:Computer Organization and Design : TheHardware/Software Interface(计算机组成与设计:硬件/软件接口)Computer Architecture : A QuantitativeApproach(计算机体系结构:量化方法)MIPS=Microprocessor without InterlockedPipeline Stages,无互锁流水级的微处理器MIPS的另一个含义是每秒百万条指令——Millions of instructions per secondMIPS体系结构的发展MIPS体系结构经历了以下几代MIPS I——该指令集用于最初的32位处理器,至今仍然很流行,R2000、R3000都是MIPS I的实现MIPS II——MIPS I的升级,最初为R6000定义,失败MIPS III——应用于R4000的64位指令集MIPS IV——MIPS III的升级,应用于R5000和R1000032个通用寄存器可供编程使用:$0~$31,其中$0无论写入什么永远返回0$31被子程序调用指令(“跳转与链接指令”)用来保存返回地址除此以外,所有寄存器都可以在任何指令中以相同方式使用——真正通用通用寄存器的习惯用法和命名寄存器编号助记符用法0zero永远为01at用做汇编器的临时变量2-3v0, v1用于过程调用时返回结果4-7a0-a3用于过程调用时传递参数8-15t0-t7临时寄存器。

06MIPS指令系统(3)_665108544

06MIPS指令系统(3)_665108544

微机原理(计算机原理)第6讲MIPS指令系统(3)1MIPS模拟器MIPS汇编语言语法MIPS汇编程序实例第6讲MIPS指令系统(3)SPIM是主要的MIPS模拟器,能够运行和调试MIPS汇编语言程序SPIM支持Uinx、Windows等多个操作系统平台/正文段数据与堆栈段SPIM消息MARSMARS 是MIPS Assembler and RuntimeSimulator (MIPS汇编器和运行时模拟器)的缩写能够运行和调试MIPS汇编语言程序MARS采用Java开发,跨平台/KenVollmar/MARS/MIPS模拟器MIPS模拟器通过系统调用指令(syscall) 提供了一组类似操作系统的服务调用方法:将系统调用代码装入$v0(寄存器编号2)寄存器将参数(如果有)装入$a0~$a3(寄存器编号4~7)或$f12寄存器Syscall返回值保存在$v0或$f0寄存器中代码系统调用参数结果1print integer$a02print float$f123print double$f124print string$a05read integer integer in $v0 6read float float in $f07read double double in $f0 8read string$a0=buffer, $a1=length9sbrk$a0=amount address in $v0 10exit代码系统调用参数结果11print char$a012read char char in $v013open$a0=file name(string),$a1=flags, $a2=mode file descriptor (fd) in $v014read$a0 =fd, $a1=buffer,$a2=length num chars read in $v015write$a0 =fd, $a1=buffer,$a2=length num chars write in $v016close$a0 =fd 17exit2$a0=resultHello world.textmain:la$a0, str4li $v0,syscall# print stringli$v0, 10syscall# exit.data.align 2str:.asciiz"Hello world."内存布局内存最低端保留,其上是正文段(代码段)正文段之上是静态数据段,存放全局常量和其他静态数据静态数据段之上为分配动态数据的堆栈由用户内存区的高地址端开始,栈空间由高地址向低地址增长各部分地址由软件规定,并非MIPS 体系结构的一部分栈动态数据(堆)静态数据正文(指令)保留系统内存区Hello world栈动态数据(堆)静态数据正文(指令)保留系统内存区.textmain:la $a0, str li $v0, 4syscall li $v0, 10syscall .data .align 2str:.asciiz "Hello world."7fffeffc100400001001000000400000MARS 约定MIPS模拟器MIPS汇编语言语法MIPS汇编程序实例第6讲MIPS指令系统(3)整型数据:支持十进制、十六进制、八进制,表示法和C语言相同十进制数前不可以有无效的0八进制数加前导0十六进制加前导0x浮点型数据:表示方法<尾符>d1[.d2][e|E<阶符>d3]其中,d1、d2、d3都是十进制数例如:36.25e-2字符串:表示形式与C语言类似,以双引号为标志遵守C语言的“\”使用规则:换行——\n制表符——\t引号——\”标识符由字母、数字、下划线(_)、点(.)构成,但不能以数字开头指令助记符等保留字不能作标识符MIPS汇编程序语句格式指令与伪指令语句[Label:] <op> Arg1, [Arg2], [Arg3] [#comment]汇编命令(directive)语句[Label:] .Directive [arg1], [arg2], . . . [#comment] Label:为可选的标号,#comment为可选的注释伪指令伪指令(Pseudo-instructions)是为编程方便而对指令集进行的扩展,并非真正的指令。

5.5 MIPS指令概述

5.5 MIPS指令概述

计算机组成原理第五章指令系统5.5 MIPS指令概述1MIPS指令概述■MIPS (Microprocessor without Intellocked Pipleline Stages)是80年代初期由斯坦福大学Hennessy教授领导的研究小组研制成功;■属于精简指令集计算机RISC(Reduced Instruction Set Computer);■MIPS指令集有MIPS I,MIPS II,MIPS III,MIPS IV,MIPS V,MIPS32,和MIPS64多个版本;■早期主要用于嵌入式系统,如Windows CE的设备,路由器,家用网关和视频游戏机,现在已经在PC机、服务器中得到广泛应用1MIPS指令概述■MIPS指令集有以下特点:♦简单的Load/Store结构♦易于流水线CPU设计♦易于编译器开发♦MIPS指令的寻址方式非常简单,每条指令的操作也非常简单2MIPS 指令格式概述000000R s R t shamtR d 6bits funct5bits 5bits 5bits 5bits 6bitsR 型指令OP R s R t 6bits 立即数5bits 5bits16bits I 型指令OP 6bits 立即数26bits J 型指令■只有三种指令格式♦Rs,Rt 分别为第一、二源操作数;Rd 为目标操作数;♦双目、Load/Store: Rs 和立即数是源操作数,Rt 为目标操作数;♦条件转移: Rs,Rt 均为源操作数;♦26位立即数作为跳转目标地址的部分地址寄存器名寄存器编号用途说明$s00保存固定的常数0$at 1汇编器的临时变量$v0~$v12~3子函数调用返回结果$a0~$a34~7函数调用参数1~3$t0~$t78~15临时变量,函数调用时不需要保存和恢复$s0~$s716~23函数调用时需要保存和恢复的寄存器变量$t8~$t924~25临时变量,函数调用时不需要保存和恢复$k0~$k126~27中断、异常处理程序使用$gp28全局指针变量(Global Pointer)$sp 29堆栈指针变量(Stack Pointer)$fp 30帧指针变量(Frame Pointer)$ra31返回地址(Return Address)3MIPS 寄存器♦还有32个32位单精度浮点寄存器f 0-f 31♦还有2个32位乘、商寄存器H i 和L 0;乘法法分别存放64位乘积的高、低32位;除法时分别存放余数和商。

MIPS指令系统(2010-4-22)资料

MIPS指令系统(2010-4-22)资料

Page
8
加立即数
常数相加指令
g = g + 4; Lw $t0, 0($s3) add $s1,$s1,$t0 # $t0=4 # g=g+4 (in MIPS)
注释
(in C) $s3=Address(4)
立即数相加指令
addi $s3,$s3,4
指令 实例
add $s1,$s2,$s3
32 registers in MIPS
$0, $1, $2, … $30, $31
Page 4
32个MIPS寄存器
寄存器编号 0 1 2~3 4~7 MIPS助记符 $Zero $at $v0~$v1 $a0~$a3 释义 固定值为0 汇编器保留 函数调用返回值 函数调用参数 4个参数 备注 硬件置位
MIPS指令系统
TANZHIHU
汇编语言 CPU主要工作:执行指令
指令是CPU执行最主要的操作
不同类型的CPU执行不同指令集
Instruction Set Architecture (ISA). Intel 80x86 (Pentium 4), IBM/Motorola PowerPC (Macintosh), MIPS, Intel IA64, ...
8~15
16~23 24~25
$t0~$t7
$s0~$s7 $t8~$t9
暂存寄存器
通用寄存器 暂存寄存器
8个参数
调用之前需保存 2个
26~27 28
29 30 31
$k0~$k1 $gp
$sp $fp $ra
操作系统保留 全局指针
堆栈指针 帧指针 函数返回地址
Page

类MIPS单周期微处理器设计实验报告

类MIPS单周期微处理器设计实验报告

课程名称:微机原理与接口技术实验类MIPS单周期微处理器设计1.实验任务、目标利用Verilog HDL语言,基于Xilinx FPGA nexys4实验平台,设计一个能够执行以下MIPS指令集的单周期类MIPS处理器,要求完成所有支持指令的功能仿真,验证指令执行的正确性,要求编写汇编程序将本人学号的ASCII码存入RAM的连续内存区域。

▪支持基本的算术逻辑运算如add,sub,and,or,slt,andi指令▪支持基本的内存操作如lw,sw指令▪支持基本的程序控制如beq,j指令(由于特殊情况,此次实验仅完成Reg、ALU、ALUCtr三个模块并分别加以仿真和验算)2.微处理器各个模块硬件设计原理、verilog代码(1)Reg设计Reg是指令操作地主要对象,MIPS微处理器中一共32个32位寄存器。

该模块输入为 RsAddr,RtAddr,WriteAddr,RegWr,WriteData,clk,reset有两项输出 RsData,RtData。

其中当复位信号reset为1时所有寄存器清零,当复位信号为0且写信号有效时数据才写入writedata寄存器。

(其中0号寄存器永远为0)具体代码如下:module RegFile(input [4:0] RsAddr,input [4:0] RtAddr,input [4:0] WriteAddr,input RegWr,input [31:0] WriteData,input clk,input reset,output [31:0] RsData,output [31:0] RtData);reg [31:0] regs[0:31];assign RsData =(RsAddr==5'b0) ? 32'b0:regs[RsAddr];assign RtData =(RtAddr==5'b0) ? 32'b0:regs[RtAddr];integer i;always @(negedge clk) //下降沿回写到寄存器if(!reset&RegWr)regs[WriteAddr]=WriteData;else if(reset)for(i=0;i<32;i=i+1)regs[i]=4*i; //寄存器的值初始化为编号乘以4Endmodule(2)ALU设计微处理器支持add,sub,and,or,slt运算指令,需要用ALU单元实现运算,同时sw,lw,beq等指令也要用到ALU单元计算地址,比较数据,因此我们设计此模块输入为in1,in2,(此处要设置为signed类型,不然无法执行slt指令),ALUctr两个输出Res,zero。

【转载】MIPS汇编指令

【转载】MIPS汇编指令

【转载】MIPS汇编指令MIPS指令特点:1、所有指令都是32位编码;2、有些指令有26位供目标地址编码;有些则只有16位。

因此要想加载任何一个32位值,就得用两个加载指令。

16位的目标地址意味着,指令的跳转或子函数的位置必须在64K以内(上下32K);3、所有的动作原理上要求必须在1个时钟周期内完成,一个动作一个阶段;4、有32个通用寄存器,每个寄存器32位(对32位机)或64位(对64位机);5、本身没有任何帮助运算判断的标志寄存器,要实现相应的功能时,是通过测试两个寄存器是否相等来完成的;6、所有的运算都是基于32位的,没有对字节和对半字的运算(MIPS里,字定义为32位,半字定义为16位);7、没有单独的栈指令,所有对栈的操作都是统一的内存访问方式。

因为push和pop指令实际上是一个复合操作,包含对内存的写入和对栈指针的移动;8、由于MIPS固定指令长度,所以造成其编译后的二进制文件和内存占用空间比x86的要大,(x86平均指令长度只有3个字节多一点,而MIPS是4个字节);9、寻址方式:只有一种内存寻址方式。

就是基地址加一个16位的地址偏移;10、内存中的数据访问必须严格对齐(至少4字节对齐)11、跳转指令只有26位目标地址,再加上2位的对齐位,可寻址28位的空间,即256M。

意思即是说,在一个C程序内,goto语句只能跳转到它之前的128M和之后的128M这个地址空间之内12、条件分支指令只有16位跳转地址,加上2位的对齐位,共18位寻址空间,即256K。

意思即是说,在一个C程序内,if语句只能跳转到它之前的128K和之后的128K这个地址空间之内;13、MIPS默认不把子函数的返回地址(就是调用函数的受害指令地址)存放到栈中,而是存放到$31寄存器中;这对那些叶子函数有利。

如果遇到嵌套的函数的话,有另外的机制处理;14、流水线效应。

由于采用了高度的流水线,结果产生了一些对程序员来说可见的效应,需要注意。

基于MIPS指令集的RISC微处理器数据通路的设计与实现

基于MIPS指令集的RISC微处理器数据通路的设计与实现
The microprocessor is the core of embedded systems, it determines the performance of the entire embedded system. The MIPS instruction format is clear and compact; it can simplify the design of the microprocessor architecture, and achieves relatively good performance. The ultimate design is based on the MIPS instruction set, and it has five stages pipeline.
流水线是提高微处理器性能的重要方法,在对单周期数据通路设计的基础上, 对流水线数据通路进行详细分析,设计了流水线寄存器,最终建立了基于 MIPS 指令 集的五级流水线数据通路。
设计完成后,对流水线数据通路进行仿真,然后下载到 FPGA 开发板进行验证。 最终的数据通路支持 34 条指令,主频达 40 M HZ。 关键字: 片上系统,精简指令集微处理器,流水线,数据通路
嵌入式系统中,微处理器是核心,决定了整个嵌入式系统的性能。MIPS 指令格 式清晰、紧凑,采用 MIPS 指令设计微处理器可以简化体系结构的设计,并得到比较 好的性能。最终的设计以 MIPS 指令集为基础,实现了五级流水 RISC 微处理器。
根据对 MIPS 指令集的研究,选取了待实现的指令,及指令寻址方式。通过对指 令执行过程的详细分析,设计和实现了各逻辑功能模块,包括:存储指令和数据的存 储模块、高速提供运算操作数的寄存器堆、完成操作数运算的算术逻辑单元、对 16 位操作数进行扩展的符号扩展单元。在完成各模块设计后,设计和实现了单周期 RISC 数据通路。

mips汇编语言代码示例

mips汇编语言代码示例

mips汇编语言代码示例MIPS汇编语言代码示例:计算两个数的和MIPS汇编语言是一种基于RISC(精简指令集计算机)架构的汇编语言,它被广泛应用于嵌入式系统、数字信号处理、计算机视觉等领域。

本文将以计算两个数的和为例,介绍MIPS汇编语言的基本语法和指令。

我们需要了解MIPS汇编语言的寄存器。

MIPS架构中有32个通用寄存器,分别用$0~$31表示。

其中,$0$寄存器始终为$0$,$1~$3寄存器用于函数调用,$4~$7寄存器用于保存函数调用时的参数,$8~$15寄存器用于保存临时变量,$16~$23寄存器用于保存全局变量,$24~$25寄存器用于保存函数调用时的返回值,$26~$27寄存器用于保存系统调用的参数,$28寄存器用于保存全局指针,$29寄存器用于保存栈指针,$30寄存器用于保存帧指针,$31寄存器用于保存程序计数器。

接下来,我们可以编写计算两个数的和的MIPS汇编语言代码。

假设我们要计算$a+b$的值,可以使用以下代码:```.dataa: .word 2b: .word 3sum: .word 0.text.globl mainmain:lw $t0, alw $t1, badd $t2, $t0, $t1sw $t2, sumli $v0, 10syscall```我们使用.data段定义了三个变量:$a$、$b$和$sum$。

$a$和$b$分别被初始化为$2$和$3$,$sum$被初始化为$0$。

接着,我们使用.text段定义了一个全局函数$main$,并使用.globl指令将其声明为全局函数。

在$main$函数中,我们首先使用lw指令将$a$和$b$的值分别加载到$t0$和$t1$寄存器中。

然后,我们使用add指令将$t0$和$t1$的值相加,并将结果保存到$t2$寄存器中。

最后,我们使用sw指令将$t2$的值存储到$sum$变量中。

最后,我们使用li指令将$v0$寄存器设置为$10$,并使用syscall指令退出程序。

(完整word版)MIPS流水线CPU的verilog实现

(完整word版)MIPS流水线CPU的verilog实现

一、实验目的1.了解提高CPU性能的方法。

2.掌握流水线MIPS微处理器的工作原理。

3.理解数据冒险、控制冒险的概念以及流水线冲突的解决方法。

4.掌握流水线MIPS微处理器的测试方法。

二、实验任务设计一个32位流水线MIPS微处理器,具体要求如下:1.至少运行下列MIPS32指令。

(1)算术运算指令:ADD、ADDU、SUB、SUBU、ADDI、ADDIU。

(2)逻辑运算指令:AND、OR、NOR、XOR、ANDI、ORI、XORI、SLT、SLTU、SLTI、SLTIU。

(3)移位指令:SLL、SLLV、SRL、SRLV、SRA。

(4)条件分支指令:BEQ、BNE、BGEZ、BGTZ、BLEZ、BLTZ。

(5)无条件跳转指令:J、JR。

(6)数据传送指令:LW、SW。

(7)空指令:NOP。

2.采用5级流水线技术,对数据冒险实现转发或阻塞功能。

3.在XUP Virtex-Ⅱ Pro 开发系统中实现MIPS微处理器,要求CPU的运行速度大于25MHz。

三、实验原理1.总体设计流水线是数字系统中一种提高系统稳定性和工作速度的方法,广泛应用于高档CPU的架构中。

根据MIPS处理器的特点,将整体的处理过程分为取指令(IF)、指令译码(ID)、执行(EX)、存储器访问(MEM)和寄存器会写(WB)五级,对应多周期的五个处理阶段。

如图3.1所示,一个指令的执行需要5个时钟周期,每个时钟周期的上升沿来临时,此指令所代表的一系列数据和控制信息将转移到下一级处理。

图3.1 流水线流水作业示意图由于在流水线中,数据和控制信息将在时钟周期的上升沿转移到下一级,所以规定流水线转移变量命名遵守如下格式:名称_流水线级名称例如:在ID级指令译码电路(Decode)产生的寄存器写允许信号RegWrite在ID级、EX级、MEM级和WB级上的命名分别为RegWrite_id、RegWrite_ex、RegWrite_mem和RegWrite_wb。

基于可重构SOC平台的嵌入式MPEG2解码器设计

基于可重构SOC平台的嵌入式MPEG2解码器设计

基于可重构SOC平台的嵌入式MPEG2解码器设计
杨波;陈陵都;刘忠立;朱明程
【期刊名称】《电子器件》
【年(卷),期】2008(031)004
【摘要】利用FPGA的可重构特点,建立一个可重构的SOC设计平台.该平台第一层为可重构的FPGA,第二层为利用FPGA资源搭建的LEON2 SOC系统,由RISC 处理器软核、AMBA总线以及IP模块结构组成,第三层是应用层,在SOC系统的基础上实现各种应用.为了实现这个目标,SOC系统中的IP模块应该具有两个特点:即插即用和参数化.基于该平台,成功实现了嵌入式MPEG2视频解码器的不同应用.证明了可重构的设计平台能够满足不同的应用需求.
【总页数】4页(P1280-1283)
【作者】杨波;陈陵都;刘忠立;朱明程
【作者单位】中国科学院半导体研究所,北京,100083;中国科学院半导体研究所,北京,100083;中国科学院半导体研究所,北京,100083;深圳大学信息工程学院,深圳,518060
【正文语种】中文
【中图分类】TN919.81;TN47
【相关文献】
1.基于SoC平台的H.264解码器IP核设计 [J], 邵振;郑世宝;杨宇红
2.基于SoC平台的H.264/MPEG-4 AVC解码器设计 [J], 周娅;王宏远;罗彬
3.基于SoC平台的AVS可变长解码器设计 [J], 许苑丰;陈泳恩;刘玮;王鹏
4.基于SoC平台的AVS可变长解码器设计 [J], 许苑丰;陈泳恩;刘玮;王鹏
5.一种基于SoC平台设计的AVS解码器软硬件分区结构 [J], 周密
因版权原因,仅展示原文概要,查看原文内容请购买。

基于FPEG的SOC设计-mips指令系统-(verilog代码)

基于FPEG的SOC设计-mips指令系统-(verilog代码)

//-------------------------------------------------------//基于FPEG的SOC设计// mips.v// Model of subset of MIPS processor described in Ch 1//-------------------------------------------------------// top level design for testingmodule top #(parameter WIDTH = 8, REGBITS = 3)();reg clk;reg reset;wire memread, memwrite;wire [WIDTH-1:0] adr, writedata;wire [WIDTH-1:0] memdata;// instantiate devices to be testedmips #(WIDTH,REGBITS) dut(clk, reset, memdata, memread, memwrite, adr, writedata);// external memory for code and dataexmemory #(WIDTH) exmem(clk, memwrite, adr, writedata, memdata);// initialize testinitialbeginreset <= 1; # 22; reset <= 0;end// generate clock to sequence testsalwaysbeginclk <= 1; # 5; clk <= 0; # 5;endalways@(negedge clk)beginif(memwrite)if(adr == 5 & writedata == 7)$display("Simulation completely successful");else $display("Simulation failed");endendmodule// external memory accessed by MIPSmodule exmemory #(parameter WIDTH = 8)(clk, memwrite, adr, writedata, memdata);input clk;input memwrite;input [WIDTH-1:0] adr, writedata;output reg [WIDTH-1:0] memdata;reg [31:0] RAM [(1<<WIDTH-2)-1:0];wire [31:0] word;initialbegin$readmemh("memfile.dat",RAM);end// read and write bytes from 32-bit wordalways @(posedge clk)if(memwrite)case (adr[1:0])2'b00: RAM[adr>>2][7:0] <= writedata;2'b01: RAM[adr>>2][15:8] <= writedata;2'b10: RAM[adr>>2][23:16] <= writedata;2'b11: RAM[adr>>2][31:24] <= writedata;endcaseassign word = RAM[adr>>2];always @(*)case (adr[1:0])2'b00: memdata <= word[31:24];2'b01: memdata <= word[23:16];2'b10: memdata <= word[15:8];2'b11: memdata <= word[7:0];endcaseendmodule// simplified MIPS processormodule mips #(parameter WIDTH = 8, REGBITS = 3)(input clk, reset,input [WIDTH-1:0] memdata,output memread, memwrite,output [WIDTH-1:0] adr, writedata);wire [31:0] instr;wire zero, alusrca, memtoreg, iord, pcen, regwrite, regdst;wire [1:0] aluop,pcsource,alusrcb;wire [3:0] irwrite;wire [2:0] alucont;controller cont(clk, reset, instr[31:26], zero, memread, memwrite,alusrca, memtoreg, iord, pcen, regwrite, regdst,pcsource, alusrcb, aluop, irwrite);alucontrol ac(aluop, instr[5:0], alucont);datapath #(WIDTH, REGBITS)dp(clk, reset, memdata, alusrca, memtoreg, iord, pcen,regwrite, regdst, pcsource, alusrcb, irwrite, alucont,zero, instr, adr, writedata);endmodulemodule controller(input clk, reset,input [5:0] op,input zero,output reg memread, memwrite, alusrca, memtoreg, iord,output pcen,output reg regwrite, regdst,output reg [1:0] pcsource, alusrcb, aluop,output reg [3:0] irwrite);parameter FETCH1 = 4'b0001;parameter FETCH2 = 4'b0010;parameter FETCH3 = 4'b0011;parameter FETCH4 = 4'b0100;parameter DECODE = 4'b0101;parameter MEMADR = 4'b0110;parameter LBRD = 4'b0111;parameter LBWR = 4'b1000;parameter SBWR = 4'b1001;parameter RTYPEEX = 4'b1010;parameter RTYPEWR = 4'b1011;parameter BEQEX = 4'b1100;parameter JEX = 4'b1101;parameter LB = 6'b100000;parameter SB = 6'b101000;parameter RTYPE = 6'b0;parameter BEQ = 6'b000100;parameter J = 6'b000010;reg [3:0] state, nextstate;reg pcwrite, pcwritecond;// state registeralways @(posedge clk)if(reset) state <= FETCH1;else state <= nextstate;// next state logicalways @(*)begincase(state)FETCH1: nextstate <= FETCH2;FETCH2: nextstate <= FETCH3;FETCH3: nextstate <= FETCH4;FETCH4: nextstate <= DECODE;DECODE: case(op)LB: nextstate <= MEMADR;SB: nextstate <= MEMADR;RTYPE: nextstate <= RTYPEEX;BEQ: nextstate <= BEQEX;J: nextstate <= JEX;default: nextstate <= FETCH1; // should never happenendcaseMEMADR: case(op)LB: nextstate <= LBRD;SB: nextstate <= SBWR;default: nextstate <= FETCH1; // should never happenendcaseLBRD: nextstate <= LBWR;LBWR: nextstate <= FETCH1;SBWR: nextstate <= FETCH1;RTYPEEX: nextstate <= RTYPEWR;RTYPEWR: nextstate <= FETCH1;BEQEX: nextstate <= FETCH1;JEX: nextstate <= FETCH1;default: nextstate <= FETCH1; // should never happenendcaseendalways @(*)begin// set all outputs to zero, then conditionally assert just the appropriate onesirwrite <= 4'b0000;pcwrite <= 0; pcwritecond <= 0;regwrite <= 0; regdst <= 0;memread <= 0; memwrite <= 0;alusrca <= 0; alusrcb <= 2'b00; aluop <= 2'b00; pcsource <= 2'b00;iord <= 0; memtoreg <= 0;case(state)FETCH1:beginmemread <= 1;irwrite <= 4'b1000;alusrcb <= 2'b01;pcwrite <= 1;endFETCH2:beginmemread <= 1;irwrite <= 4'b0100;alusrcb <= 2'b01;pcwrite <= 1;endFETCH3:beginmemread <= 1;irwrite <= 4'b0010;alusrcb <= 2'b01;pcwrite <= 1;endFETCH4:beginmemread <= 1;irwrite <= 4'b0001;alusrcb <= 2'b01;pcwrite <= 1;endDECODE: alusrcb <= 2'b11;MEMADR:beginalusrca <= 1;alusrcb <= 2'b10;endLBRD:beginmemread <= 1;iord <= 1;endLBWR:beginregwrite <= 1;memtoreg <= 1;endSBWR:beginmemwrite <= 1;iord <= 1;endRTYPEEX:beginalusrca <= 1;aluop <= 2'b10;endRTYPEWR:beginregdst <= 1;regwrite <= 1;endBEQEX:beginalusrca <= 1;aluop <= 2'b01;pcwritecond <= 1;pcsource <= 2'b01;endJEX:beginpcwrite <= 1;pcsource <= 2'b10;endendcaseendassign pcen = pcwrite | (pcwritecond & zero); // program counter enable endmodulemodule alucontrol(input [1:0] aluop,input [5:0] funct,output reg [2:0] alucont);always @(*)case(aluop)2'b00: alucont <= 3'b010; // add for lb/sb/addi2'b01: alucont <= 3'b110; // sub (for beq)default: case(funct) // R-Type instructions6'b100000: alucont <= 3'b010; // add (for add)6'b100010: alucont <= 3'b110; // subtract (for sub)6'b100100: alucont <= 3'b000; // logical and (for and)6'b100101: alucont <= 3'b001; // logical or (for or)6'b101010: alucont <= 3'b111; // set on less (for slt)default: alucont <= 3'b101; // should never happenendcaseendcaseendmodulemodule datapath #(parameter WIDTH = 8, REGBITS = 3)(input clk, reset,input [WIDTH-1:0] memdata,input alusrca, memtoreg, iord, pcen, regwrite, regdst,input [1:0] pcsource, alusrcb,input [3:0] irwrite,input [2:0] alucont,output zero,output [31:0] instr,output [WIDTH-1:0] adr, writedata);// the size of the parameters must be changed to match the WIDTH parameterparameter CONST_ZERO = 8'b0;parameter CONST_ONE = 8'b1;wire [REGBITS-1:0] ra1, ra2, wa;wire [WIDTH-1:0] pc, nextpc, md, rd1, rd2, wd, a, src1, src2, aluresult,aluout, constx4;// shift left constant field by 2assign constx4 = {instr[WIDTH-3:0],2'b00};// register file address fieldsassign ra1 = instr[REGBITS+20:21];assign ra2 = instr[REGBITS+15:16];mux2 #(REGBITS) regmux(instr[REGBITS+15:16], instr[REGBITS+10:11], regdst, wa);// independent of bit width, load instruction into four 8-bit registers over four cyclesflopen #(8) ir0(clk, irwrite[0], memdata[7:0], instr[7:0]);flopen #(8) ir1(clk, irwrite[1], memdata[7:0], instr[15:8]);flopen #(8) ir2(clk, irwrite[2], memdata[7:0], instr[23:16]);flopen #(8) ir3(clk, irwrite[3], memdata[7:0], instr[31:24]);// datapathflopenr #(WIDTH) pcreg(clk, reset, pcen, nextpc, pc);flop #(WIDTH) mdr(clk, memdata, md);flop #(WIDTH) areg(clk, rd1, a);flop #(WIDTH) wrd(clk, rd2, writedata);flop #(WIDTH) res(clk, aluresult, aluout);mux2 #(WIDTH) adrmux(pc, aluout, iord, adr);mux2 #(WIDTH) src1mux(pc, a, alusrca, src1);mux4 #(WIDTH) src2mux(writedata, CONST_ONE, instr[WIDTH-1:0],constx4, alusrcb, src2);mux4 #(WIDTH) pcmux(aluresult, aluout, constx4, CONST_ZERO, pcsource, nextpc);mux2 #(WIDTH) wdmux(aluout, md, memtoreg, wd);regfile #(WIDTH,REGBITS) rf(clk, regwrite, ra1, ra2, wa, wd, rd1, rd2);alu #(WIDTH) alunit(src1, src2, alucont, aluresult);zerodetect #(WIDTH) zd(aluresult, zero);endmodulemodule alu #(parameter WIDTH = 8)(input [WIDTH-1:0] a, b,input [2:0] alucont,output reg [WIDTH-1:0] result);wire [WIDTH-1:0] b2, sum, slt;assign b2 = alucont[2] ? ~b:b;assign sum = a + b2 + alucont[2];// slt should be 1 if most significant bit of sum is 1assign slt = sum[WIDTH-1];always@(*)case(alucont[1:0])2'b00: result <= a & b;2'b01: result <= a | b;2'b10: result <= sum;2'b11: result <= slt;endcaseendmodulemodule regfile #(parameter WIDTH = 8, REGBITS = 3)(input clk,input regwrite,input [REGBITS-1:0] ra1, ra2, wa,input [WIDTH-1:0] wd,output [WIDTH-1:0] rd1, rd2);reg [WIDTH-1:0] RAM [(1<<REGBITS)-1:0];// three ported register file// read two ports combinationally// write third port on rising edge of clock// register 0 hardwired to 0always @(posedge clk)if (regwrite) RAM[wa] <= wd;assign rd1 = ra1 ? RAM[ra1] : 0;assign rd2 = ra2 ? RAM[ra2] : 0;endmodulemodule zerodetect #(parameter WIDTH = 8)(input [WIDTH-1:0] a,output y);assign y = (a==0);endmodulemodule flop #(parameter WIDTH = 8)(input clk,input [WIDTH-1:0] d,output reg [WIDTH-1:0] q);always @(posedge clk)q <= d;endmodulemodule flopen #(parameter WIDTH = 8)(input clk, en,input [WIDTH-1:0] d,output reg [WIDTH-1:0] q);always @(posedge clk)if (en) q <= d;endmodulemodule flopenr #(parameter WIDTH = 8)(input clk, reset, en,input [WIDTH-1:0] d,output reg [WIDTH-1:0] q);always @(posedge clk)if (reset) q <= 0;else if (en) q <= d;endmodulemodule mux2 #(parameter WIDTH = 8)(input [WIDTH-1:0] d0, d1,input s,output [WIDTH-1:0] y);assign y = s ? d1 : d0;endmodulemodule mux4 #(parameter WIDTH = 8)(input [WIDTH-1:0] d0, d1, d2, d3,input [1:0] s,output reg [WIDTH-1:0] y);always @(*)case(s)2'b00: y <= d0;2'b01: y <= d1;2'b10: y <= d2;2'b11: y <= d3;endcaseendmodule。

基于SoC FPGA的MIPS处理器验证平台设计

基于SoC FPGA的MIPS处理器验证平台设计

基于SoC FPGA的MIPS处理器验证平台设计
张伟;梁蓓
【期刊名称】《电子技术与软件工程》
【年(卷),期】2017(000)002
【摘要】随着集成电路制程工艺的迅猛发展,数字集成电路复杂度越来越高,这对集成电路的验证带来了严峻挑战。

相比软件仿真,数字芯片采用FPGA进行逻辑验证,可以大大提高验证的速度。

近年来,So CFPGA的出现对于验证平台的设计提供了一种新的启发。

本文提出一种基于So CFPGA的MIPS处理器验证平台的设计。

采用ZYNQ芯片中的ARM主处理器实时控制监测MIPS从处理器的运行状态,来达到验证MIPS处理器的目的。

同时ARM主处理器运行Linux操作系统,在不需要断电重新配置的情况下,通过执行不同的C程序实现不同功能的验证,大大提高了MIPS处理器的验证效率。

【总页数】2页(P62-63)
【作者】张伟;梁蓓
【作者单位】贵州大学大数据与信息工程学院,贵州省贵阳市550025
【正文语种】中文
【中图分类】TP332
【相关文献】
1.基于FPGA的无线传感器网络SoC验证平台设计 [J], 虞致国;黄召军;陈子逢;万书芹;魏斌
2.基于FPGA的SoC/IP 验证平台的设计与应用 [J], 罗鹏;许应;封君
3.基于 FPGA 的 ARM SoC 原型验证平台设计 [J], 王丹;代雪峰
4.基于FPGA的单周期MIPS处理器设计与实现 [J], 王雨桐;刘威;李林瑛
5.基于FPGA的六级流水线MIPS处理器设计 [J], 孙巧稚;施慧彬
因版权原因,仅展示原文概要,查看原文内容请购买。

基于MIPS内核的HDTV-SoC平台总线接口模块

基于MIPS内核的HDTV-SoC平台总线接口模块

基于MIPS内核的HDTV-SoC平台总线接口模块在系统级芯片(SoC)的设计当中,MIPS 的RISC 处理器是一种应用非常广泛的嵌入式CPU,它具有高性能、低功耗的特点,可以很方便地集成到一个完整的片上系统之中,使开发者能够专注于用户IP 模块的设计。

MIPS 架构的处理器占据了数字机顶盒微处理器和解码器用CPU 架构市场领域的领先地位。

在MIPS 家族的产品当中,32 位的4KcTM 处理器是具有代表性的一款,它采用了MIPS32 的CPU 架构,支持MIPS IITM 指令集。

在本文介绍的SoC 系统设计中,就采用了MIPS32TM4KcTM 处理器作为芯片的CPU 内核。

在当前的数字消费电子市场领域,基于SoC 平台的HDTV 芯片是所有数字电视接收及播放设备的核心器件。

SoC 芯片具体到HDTV 解码系统,就是把MPEG-2 解复用(DeMux)、音视频解码(AVD)、视频格式转换(VTP)、画面后处理(OSD)以及接口I/O 控制等功能模块都集成在一块芯片上。

而要把众多功能复杂的系统控制模块和用户IP 模块集成到一个芯片上并使其能够协调工作,就必须设计好各个模块之间的接口。

本文针对高清数字电视SoC 平台的项目,提出了系统总线接口模块(Host Bus Inter Face,HIF)的设计方案,并进行了仿真实验。

HIF 模块在系统中的主要功能HDTV-SoC 平台是一个功能强大、结构复杂的系统,本文重点介绍了SoC 架构中片上总线控制器的设计。

片上总线能够提供针对特定应用的灵活多样的集成方法,它需要结构简单,速度快捷,在单芯片中实现多资源互联。

HDTV-SoC 系统的总线结构如电路功能模块设计由上文所述可知,HIF 电路设计主要分为3 个模块:寄存器读写模块,双口RAM 读写模块和中断处理模块。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//-------------------------------------------------------//基于FPEG的SOC设计// mips.v// Model of subset of MIPS processor described in Ch 1//-------------------------------------------------------// top level design for testingmodule top #(parameter WIDTH = 8, REGBITS = 3)();reg clk;reg reset;wire memread, memwrite;wire [WIDTH-1:0] adr, writedata;wire [WIDTH-1:0] memdata;// instantiate devices to be testedmips #(WIDTH,REGBITS) dut(clk, reset, memdata, memread, memwrite, adr, writedata);// external memory for code and dataexmemory #(WIDTH) exmem(clk, memwrite, adr, writedata, memdata);// initialize testinitialbeginreset <= 1; # 22; reset <= 0;end// generate clock to sequence testsalwaysbeginclk <= 1; # 5; clk <= 0; # 5;endalways@(negedge clk)beginif(memwrite)if(adr == 5 & writedata == 7)$display("Simulation completely successful");else $display("Simulation failed");endendmodule// external memory accessed by MIPSmodule exmemory #(parameter WIDTH = 8)(clk, memwrite, adr, writedata, memdata);input clk;input memwrite;input [WIDTH-1:0] adr, writedata;output reg [WIDTH-1:0] memdata;reg [31:0] RAM [(1<<WIDTH-2)-1:0];wire [31:0] word;initialbegin$readmemh("memfile.dat",RAM);end// read and write bytes from 32-bit wordalways @(posedge clk)if(memwrite)case (adr[1:0])2'b00: RAM[adr>>2][7:0] <= writedata;2'b01: RAM[adr>>2][15:8] <= writedata;2'b10: RAM[adr>>2][23:16] <= writedata;2'b11: RAM[adr>>2][31:24] <= writedata;endcaseassign word = RAM[adr>>2];always @(*)case (adr[1:0])2'b00: memdata <= word[31:24];2'b01: memdata <= word[23:16];2'b10: memdata <= word[15:8];2'b11: memdata <= word[7:0];endcaseendmodule// simplified MIPS processormodule mips #(parameter WIDTH = 8, REGBITS = 3)(input clk, reset,input [WIDTH-1:0] memdata,output memread, memwrite,output [WIDTH-1:0] adr, writedata);wire [31:0] instr;wire zero, alusrca, memtoreg, iord, pcen, regwrite, regdst;wire [1:0] aluop,pcsource,alusrcb;wire [3:0] irwrite;wire [2:0] alucont;controller cont(clk, reset, instr[31:26], zero, memread, memwrite,alusrca, memtoreg, iord, pcen, regwrite, regdst,pcsource, alusrcb, aluop, irwrite);alucontrol ac(aluop, instr[5:0], alucont);datapath #(WIDTH, REGBITS)dp(clk, reset, memdata, alusrca, memtoreg, iord, pcen,regwrite, regdst, pcsource, alusrcb, irwrite, alucont,zero, instr, adr, writedata);endmodulemodule controller(input clk, reset,input [5:0] op,input zero,output reg memread, memwrite, alusrca, memtoreg, iord,output pcen,output reg regwrite, regdst,output reg [1:0] pcsource, alusrcb, aluop,output reg [3:0] irwrite);parameter FETCH1 = 4'b0001;parameter FETCH2 = 4'b0010;parameter FETCH3 = 4'b0011;parameter FETCH4 = 4'b0100;parameter DECODE = 4'b0101;parameter MEMADR = 4'b0110;parameter LBRD = 4'b0111;parameter LBWR = 4'b1000;parameter SBWR = 4'b1001;parameter RTYPEEX = 4'b1010;parameter RTYPEWR = 4'b1011;parameter BEQEX = 4'b1100;parameter JEX = 4'b1101;parameter LB = 6'b100000;parameter SB = 6'b101000;parameter RTYPE = 6'b0;parameter BEQ = 6'b000100;parameter J = 6'b000010;reg [3:0] state, nextstate;reg pcwrite, pcwritecond;// state registeralways @(posedge clk)if(reset) state <= FETCH1;else state <= nextstate;// next state logicalways @(*)begincase(state)FETCH1: nextstate <= FETCH2;FETCH2: nextstate <= FETCH3;FETCH3: nextstate <= FETCH4;FETCH4: nextstate <= DECODE;DECODE: case(op)LB: nextstate <= MEMADR;SB: nextstate <= MEMADR;RTYPE: nextstate <= RTYPEEX;BEQ: nextstate <= BEQEX;J: nextstate <= JEX;default: nextstate <= FETCH1; // should never happenendcaseMEMADR: case(op)LB: nextstate <= LBRD;SB: nextstate <= SBWR;default: nextstate <= FETCH1; // should never happenendcaseLBRD: nextstate <= LBWR;LBWR: nextstate <= FETCH1;SBWR: nextstate <= FETCH1;RTYPEEX: nextstate <= RTYPEWR;RTYPEWR: nextstate <= FETCH1;BEQEX: nextstate <= FETCH1;JEX: nextstate <= FETCH1;default: nextstate <= FETCH1; // should never happenendcaseendalways @(*)begin// set all outputs to zero, then conditionally assert just the appropriate onesirwrite <= 4'b0000;pcwrite <= 0; pcwritecond <= 0;regwrite <= 0; regdst <= 0;memread <= 0; memwrite <= 0;alusrca <= 0; alusrcb <= 2'b00; aluop <= 2'b00; pcsource <= 2'b00;iord <= 0; memtoreg <= 0;case(state)FETCH1:beginmemread <= 1;irwrite <= 4'b1000;alusrcb <= 2'b01;pcwrite <= 1;endFETCH2:beginmemread <= 1;irwrite <= 4'b0100;alusrcb <= 2'b01;pcwrite <= 1;endFETCH3:beginmemread <= 1;irwrite <= 4'b0010;alusrcb <= 2'b01;pcwrite <= 1;endFETCH4:beginmemread <= 1;irwrite <= 4'b0001;alusrcb <= 2'b01;pcwrite <= 1;endDECODE: alusrcb <= 2'b11;MEMADR:beginalusrca <= 1;alusrcb <= 2'b10;endLBRD:beginmemread <= 1;iord <= 1;endLBWR:beginregwrite <= 1;memtoreg <= 1;endSBWR:beginmemwrite <= 1;iord <= 1;endRTYPEEX:beginalusrca <= 1;aluop <= 2'b10;endRTYPEWR:beginregdst <= 1;regwrite <= 1;endBEQEX:beginalusrca <= 1;aluop <= 2'b01;pcwritecond <= 1;pcsource <= 2'b01;endJEX:beginpcwrite <= 1;pcsource <= 2'b10;endendcaseendassign pcen = pcwrite | (pcwritecond & zero); // program counter enable endmodulemodule alucontrol(input [1:0] aluop,input [5:0] funct,output reg [2:0] alucont);always @(*)case(aluop)2'b00: alucont <= 3'b010; // add for lb/sb/addi2'b01: alucont <= 3'b110; // sub (for beq)default: case(funct) // R-Type instructions6'b100000: alucont <= 3'b010; // add (for add)6'b100010: alucont <= 3'b110; // subtract (for sub)6'b100100: alucont <= 3'b000; // logical and (for and)6'b100101: alucont <= 3'b001; // logical or (for or)6'b101010: alucont <= 3'b111; // set on less (for slt)default: alucont <= 3'b101; // should never happenendcaseendcaseendmodulemodule datapath #(parameter WIDTH = 8, REGBITS = 3)(input clk, reset,input [WIDTH-1:0] memdata,input alusrca, memtoreg, iord, pcen, regwrite, regdst,input [1:0] pcsource, alusrcb,input [3:0] irwrite,input [2:0] alucont,output zero,output [31:0] instr,output [WIDTH-1:0] adr, writedata);// the size of the parameters must be changed to match the WIDTH parameterparameter CONST_ZERO = 8'b0;parameter CONST_ONE = 8'b1;wire [REGBITS-1:0] ra1, ra2, wa;wire [WIDTH-1:0] pc, nextpc, md, rd1, rd2, wd, a, src1, src2, aluresult,aluout, constx4;// shift left constant field by 2assign constx4 = {instr[WIDTH-3:0],2'b00};// register file address fieldsassign ra1 = instr[REGBITS+20:21];assign ra2 = instr[REGBITS+15:16];mux2 #(REGBITS) regmux(instr[REGBITS+15:16], instr[REGBITS+10:11], regdst, wa);// independent of bit width, load instruction into four 8-bit registers over four cyclesflopen #(8) ir0(clk, irwrite[0], memdata[7:0], instr[7:0]);flopen #(8) ir1(clk, irwrite[1], memdata[7:0], instr[15:8]);flopen #(8) ir2(clk, irwrite[2], memdata[7:0], instr[23:16]);flopen #(8) ir3(clk, irwrite[3], memdata[7:0], instr[31:24]);// datapathflopenr #(WIDTH) pcreg(clk, reset, pcen, nextpc, pc);flop #(WIDTH) mdr(clk, memdata, md);flop #(WIDTH) areg(clk, rd1, a);flop #(WIDTH) wrd(clk, rd2, writedata);flop #(WIDTH) res(clk, aluresult, aluout);mux2 #(WIDTH) adrmux(pc, aluout, iord, adr);mux2 #(WIDTH) src1mux(pc, a, alusrca, src1);mux4 #(WIDTH) src2mux(writedata, CONST_ONE, instr[WIDTH-1:0],constx4, alusrcb, src2);mux4 #(WIDTH) pcmux(aluresult, aluout, constx4, CONST_ZERO, pcsource, nextpc);mux2 #(WIDTH) wdmux(aluout, md, memtoreg, wd);regfile #(WIDTH,REGBITS) rf(clk, regwrite, ra1, ra2, wa, wd, rd1, rd2);alu #(WIDTH) alunit(src1, src2, alucont, aluresult);zerodetect #(WIDTH) zd(aluresult, zero);endmodulemodule alu #(parameter WIDTH = 8)(input [WIDTH-1:0] a, b,input [2:0] alucont,output reg [WIDTH-1:0] result);wire [WIDTH-1:0] b2, sum, slt;assign b2 = alucont[2] ? ~b:b;assign sum = a + b2 + alucont[2];// slt should be 1 if most significant bit of sum is 1assign slt = sum[WIDTH-1];always@(*)case(alucont[1:0])2'b00: result <= a & b;2'b01: result <= a | b;2'b10: result <= sum;2'b11: result <= slt;endcaseendmodulemodule regfile #(parameter WIDTH = 8, REGBITS = 3)(input clk,input regwrite,input [REGBITS-1:0] ra1, ra2, wa,input [WIDTH-1:0] wd,output [WIDTH-1:0] rd1, rd2);reg [WIDTH-1:0] RAM [(1<<REGBITS)-1:0];// three ported register file// read two ports combinationally// write third port on rising edge of clock// register 0 hardwired to 0always @(posedge clk)if (regwrite) RAM[wa] <= wd;assign rd1 = ra1 ? RAM[ra1] : 0;assign rd2 = ra2 ? RAM[ra2] : 0;endmodulemodule zerodetect #(parameter WIDTH = 8)(input [WIDTH-1:0] a,output y);assign y = (a==0);endmodulemodule flop #(parameter WIDTH = 8)(input clk,input [WIDTH-1:0] d,output reg [WIDTH-1:0] q);always @(posedge clk)q <= d;endmodulemodule flopen #(parameter WIDTH = 8)(input clk, en,input [WIDTH-1:0] d,output reg [WIDTH-1:0] q);always @(posedge clk)if (en) q <= d;endmodulemodule flopenr #(parameter WIDTH = 8)(input clk, reset, en,input [WIDTH-1:0] d,output reg [WIDTH-1:0] q);always @(posedge clk)if (reset) q <= 0;else if (en) q <= d;endmodulemodule mux2 #(parameter WIDTH = 8)(input [WIDTH-1:0] d0, d1,input s,output [WIDTH-1:0] y);assign y = s ? d1 : d0;endmodulemodule mux4 #(parameter WIDTH = 8)(input [WIDTH-1:0] d0, d1, d2, d3,input [1:0] s,output reg [WIDTH-1:0] y);always @(*)case(s)2'b00: y <= d0;2'b01: y <= d1;2'b10: y <= d2;2'b11: y <= d3;endcaseendmodule。

相关文档
最新文档