多周期 mips mips分支指令会使pc+4吗

MIPS中的分支延迟槽和存储延时槽 - 为程序员服务
MIPS中的分支延迟槽和存储延时槽
看《see mips run》
读到MIPS中的分支延迟槽和存储延时槽,刚开始不是很理解,经过一些琢磨,大概明白了其中的原理。
程序员通常不用太关注这2件事情,因为通常汇编器会帮程序员做好这些事情,除非程序员在写汇编程序时,明确通过汇编器控制指令.set noreorder告诉汇编器接下来的指令要按照程序本来的顺序进行编译,而不是汇编器自己进行指令顺序的优化。
以下的汇编代码,都是已经告诉汇编器不要进行优化,按照指令本身的顺序进行编译。
分支延迟槽
以下是最初的MIPS五级流水线示意图。
可以看到一条指令被分成了5个阶段:取指,从源寄存器读取内容,逻辑运算,内存读取,写回到寄存器。
当第一条指令的ALU结束时,第二条指令的RD阶段也已经结束了。
那 么如果第一条指令是分支跳转指令,那么在ALU阶段才会知道要不要跳转,以及跳转的目标指令地址是多少。而此时,第二条指令已经刚好结束RD,第三条指令 已经到了IF阶段。如果这个时候CPU直接跳转到目标指令地址去执行,那么就需要清空现有流水线,从新的指令地址开始IF,RD。因为分支跳转后面的指令 不能被执行啊,程序已经跳转了呀。这样就相当于原先第2条指令的IF和RD操作,第3条指令的IF操作,这些CPU已经做过的工作,都白做了。因为CPU 此时是从的新的地址重新开始嘛!这叫流水线“冒泡”。
做这些工作也是需要耗费CPU时间的呀,MIPS设计者们,觉得十分浪费。于是就发明了一个叫分支延迟槽的东西。
以下是有分支延迟槽的MIPS 五级流水线示意图。
对 比上面的两张图就会看出,在第二张图中,如果第一条指令是分支跳转指令,那么不用经历整个ALU阶段才能得到要不要跳转的结果,以及跳转到哪里去。现在只 需要半个ALU的时间就得到了结果和目标地址。这时,第二条指令才刚刚开始RD阶段,而CPU就已经知道要跳到哪里去了,并且第3条指令就可以从新的地址 去取指令来执行。也就是说这个时候CPU的流水线是连贯的,不需要临时清空一下。不过这样做带来了一个新的问题,那就是在目标指令(也就是图中的第3条指 令)执行的前面,第2条指令就执行完毕了。
也就是说在CPU知道要跳转的地址了(上图的第一条指令),到执行目标地址指令(上图的第3条指令)之间,会执行第2条指令,也就是说紧跟着分支跳转指令的那条指令。这条指令通常叫做“分支延迟槽”里面的指令。
所以要注意几件事情:
“分支延迟槽”里面的指令,在目标跳转指令前面执行,所以“分支延迟槽”里面的指令不能修改目标跳转指令会用到的寄存器或者变量的内容,否则程序很容易搞错。
“分支延迟槽”里面的指令,通常可以被加以利用会做一些比较意义的事情,例如清零内存之类的。
这就相当于什么呢?举个例子:int strcmp (char *a0, char *a1) {
char t0, t1, t2;
/* first load moved to loop end,
so load for first iteration here */
t0 = a0[0];
while (1) {
/* first byte */
t1 = a1[0];
if (t0 == 0)
if (t0 != t1)
/* second byte */
t2 = a0[-1]; /* we already incremented a0 */
t1 = a1[1]; /* didn’t increment a1 yet*/
if (t2 == 0)
/* label t21 in assembler */
return t2 - t1;
if (t1 != t2)
/* label t21 in assembler */
return t0 = a0[0];
t0 = a0[0];
/* label t01 in assembler */
return t0 - t1;
}被汇编器编译成(没有优化顺序):#include &mips/asm.h&
#include &mips/regdef.h&
LEAF(strcmp)
.set noreorder
lbu t0, 0(a0)
: lbu t1, 0(a1)
beq t0, zero, .t01 # load delay slot
addu a0, a0, 2 # branch delay slot
bne t0, t1, .t01
lbu t2, -1(a0) # branch delay slot
lbu t1, 1(a1) # load delay slot
beq t2, zero, .t21
addu a1, a1, 2
beq t2, t1, 1b
lbu t0, 0(a0)
.t21: j ra
subu v0, t2, t1
# branch delay slot
.t01: j ra
subu v0, t0, t1 # branch delay slot
.set reorder
END(strcmp)可以看到在上面的bne t0, t1, .t01 ,紧跟后面的指令用的是t2,而不是t0,就是因为跳转之前这条指令会先执行的,然后再跳转到.t01的地方去执行。
存储延迟槽
流水线的还有一个后果就是,一条加载指令的数据在下一条指令的ALU阶段的开始才从高速缓存或者内存中去取,所以在下一条指令中不能使用加载的数据。
如下图所示:
第一条指令是要从内存加载数据,则在他的MEM阶段才能取到数据,所以在第2条指令中不能数据。第2条指令就是存储延时槽指令。
紧跟着在加载指令之后的指令位置称为加载延迟槽,一个优化的编译器将试图对程序隐藏这件事情,也就是说程序写汇编程序时可以不用关心这件事情,除非程序通过.set noreorder指令明确告诉汇编器要插手处理这件事情。
在现代的MIPS中,加载指令是互锁的,如果你试图过早使用加载的结果,CPU会一直等待直到结果到达。而在以往的cpu中,没有互锁,试图这样做会导致不可预知的后果。
一般情况下,好的汇编器会帮忙程序员处理这两件事情,除非程序员需要亲自动手优化程序。
淡泊以明志,宁静以致远。
原文地址:, 感谢原作者分享。
您可能感兴趣的代码program counter - MIPS - JAL confusion: $ra = PC+4 or PC+8? - Stack Overflow
Insights on the world's developers
Demographics. Technologies. Salaries. Career satisfaction.
I'm having trouble understanding how the instruction jal works in the MIPS processor.
My two questions are:
a) What is the value stored in R31 after "jal": PC+4 or PC+8?
b) If it's really PC+8, what happens to the instruction at PC+4? Is it executed before the jump or is it never executed?
In Patterson and Hennessy (fourth edition), pg 113:
"jump-and-link instruction: An instruction that jumps to and address and simultaneously saves the address of the following instruction in a register ($ra in MIPS)"
"program counter (PC): The register containing the address of the instruction in the program being executed"
After reading those two statements, it follows that the value saved in $ra should be (PC+4).
However, in the MIPS reference data (green card) that comes with the book, the jal instruction's algorithm is defined like this:
"Jump and Link : jal : J : R[31]=PC+8;PC=JumpAddr"
also states that "it's really PC+8", but strangely, after that it says that since pipelining is an advanced topic "we'll assume the return address is PC+4".
I come from 8086 assembly, so I'm aware that there's a big difference between returning to an address and to the one following it, because programs won't work if I just assume something that's not true. Thanks.
The address in $ra is really PC+8. The instruction immediately following the jal instruction is in the "". It is executed before the function is entered, so it shouldn't be re-executed when the function returns.
Other branching instructions on the Mips also have branch delay slots.
The delay slot is used to do something useful in the time it takes to execute the jal instruction.
15.9k32855
I got the same question. Googled this excellent answer of Richard and also another link I wish to add here.
The link is
with this wonderful explanation of double adding 4 to the PC.
So the actual execution has two additions: 1) newPC=PC+4 by pipelining and 2) another addition $ra=newPC+4 by the jal instruction resulting the effective $ra = (address of the jal instruction)+8.
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
rev .25527
Stack Overflow works best with JavaScript enabled1、深入理解MIPS―CPU指令系统的功能和工作;3、熟练掌握用VerilogHDL语言设计多周期;4、熟练掌握对多周期存储器的仿真实验验证和硬件测;二、实验要求;1、深入理解MIPS―CPU指令系统的功能和工作;3、熟练掌握用VerilogHDL语言设计多周期;三、实验原理;实现上述原理框图根据功能将其分划分为控制单元(c;(1).控制单元(cunit)是
1、深入理解MIPS―CPU指令系统的功能和工作原理; 2、掌握多周期CPU的工作原理和逻辑功能实现;
3、熟练掌握用Verilog HDL语言设计多周期存储器的方法;
4、熟练掌握对多周期存储器的仿真实验验证和硬件测试两种调试方法; 5、通过对多周期CPU的运行情况进行观察和分析,进一步加深理解。
二、实验要求
1、深入理解MIPS―CPU指令系统的功能和工作原理; 2、掌握多周期CPU的工作原理和逻辑功能实现;
3、熟练掌握用Verilog HDL语言设计多周期存储器的方法;
三、实验原理
实现上述原理框图根据功能将其分划分为控制单元(cunit)、执行单元(eunit)、指令单元(iunit)以及存储单元(munit)四大模块。
(1).控制单元(cunit)是多周期微处理器的核心控制微处理器取指令、指令译码和指令执行等工作。主要由指令译码器控制器(outputs control)、算术逻辑运算控制器(ALU control)两 个子模块组成。
(2).执行单元(eunit)主要由寄存器堆(registers)和算术逻辑单元(ALU)两个子模块组成。其中寄存器是微处理器最基本的元素MIPS系统的寄存器堆由32个32位寄存器组成而ALU则是微处理器的主要功能部件执行加、减、比较等算术运算和与、或、或非、异或等逻辑运算。指令单元(iunit)的作用是决定下一条指令的地址PC值。
(3).存储单元(munit)由存储器(memory)、指令寄存器(instruction register)和存储数据寄存 器(memory data register)组成。
四、实验内容
1、设计一个32位MIPS多周期CPU具体的要求如下:
至少运行下列的6类32条MIPS指令。
(1)算术逻辑指令and、sub、addi
(2)逻辑运算指令and、0r、xor、 andi、 ori、xori (3)位移指令sll、srl、sra (4)条件分支指令beq、bne、 (5)无条件跳转指令j、jr
(6)数据传送指令lw、sw 2.设计一个存储器
五、实验环境与设备
电脑,电箱。
六、实验代码设计(含符号说明)
寄存器元件代码:
module regfile (rna,rnb,d,wn,we,clk,clrn,qa,qb);
input [4:0]
input [31:0]
output [31:0] qa,
[31:0] register [1:31];
qa = (rna == 0) ? 0 : register[rna];
qb = (rnb == 0) ? 0 : register[rnb];
always @ (posedge clk or negedge clrn) begin
if (clrn == 0) begin
for (i=1; i&32; i=i+1)
register[i] &= 0;
else begin
if ((wn != 0) && (we == 1))
register[wn] &=
//r1-r31 //read //read
end endmodule
32位四选一选择器:
module mux4x32 (a0,a1,a2,a3,s,y);
[31:0] a0,a1,a2,a3;
input [1:0]
output [31:0]
function [31:0]
input [31:0] a0,a1,a2,a3;
input [1:0]
2'b00: select = a0;
2'b01: select = a1;
2'b10: select = a2;
2'b11: select = a3;
endfunction
y = select (a0,a1,a2,a3,s); endmodule
5位二选一选择器:
module mux2x5 (a0,a1,s,y);
input [4:0] a0,a1;
output[4:0]
y = s ? a1 : a0; endmodule
32位二选一选择器:
module mux2x32 (a0,a1,s,y);
[31:0] a0,a1;
output [31:0]
y = s ? a1 : a0; endmodule
存储器元件:
module mcmem (clk, dataout, datain, addr, we, inclk, outclk);
input [31:0]
input [31:0]
clk, we, inclk,
output [31:0]
write_enable = we & ~
lpm_ram_dq
(.data(datain),.address(addr[7:2]),.we(write_enable),.inclock(inclk),.outclock(outclk),.q(dataout));
ram.lpm_width
ram.lpm_widthad
ram.lpm_indata
= &registered&;
ram.lpm_outdata
= &registered&;
ram.lpm_file
= &mcmem.mif&;
ram.lpm_address_control = &registered&; endmodule
控制部件:
module mccu (op, func, z, clock, resetn, wpc, wir, wmem, wreg, iord, regrt, m2reg, aluc, shift, alusrca, alusrcb, pcsource, jal, sext, state);
output reg
wpc, wir, wmem, wreg, iord, regrt, m2
output reg [3:0]
output reg [1:0] alusrcb,
output reg
shift, alusrca, jal,
output reg [2:0]
[2:0] next_
parameter[2:0] sif = 3'b000,
sid = 3'b001,
sexe = 3'b010,
// EXE state
smem = 3'b011,
// MEM state
swb = 3'b100;
wire r_type,i_add,i_sub,i_and,i_or,i_xor,i_sll,i_srl,i_sra,i_
wire i_addi,i_andi,i_ori,i_xori,i_lw,i_sw,i_beq,i_bne,i_lui,i_j,i_
and(r_type,~op[5],~op[4],~op[3],~op[2],~op[1],~op[0]);
and(i_add,r_type, func[5],~func[4],~func[3],~func[2],~func[1],~func[0]);
and(i_sub,r_type, func[5],~func[4],~func[3],~func[2], func[1],~func[0]);
and(i_and,r_type, func[5],~func[4],~func[3], func[2],~func[1],~func[0]);
and(i_or, r_type, func[5],~func[4],~func[3], func[2],~func[1], func[0]);
and(i_xor,r_type, func[5],~func[4],~func[3], func[2], func[1],~func[0]);
and(i_sll,r_type,~func[5],~func[4],~func[3],~func[2],~func[1],~func[0]);
and(i_srl,r_type,~func[5],~func[4],~func[3],~func[2], func[1],~func[0]);
and(i_sra,r_type,~func[5],~func[4],~func[3],~func[2], func[1], func[0]);
and(i_jr, r_type,~func[5],~func[4], func[3],~func[2],~func[1],~func[0]);
and(i_addi,~op[5],~op[4], op[3],~op[2],~op[1],~op[0]);
and(i_andi,~op[5],~op[4], op[3], op[2],~op[1],~op[0]);
and(i_ori, ~op[5],~op[4], op[3], op[2],~op[1], op[0]);
and(i_xori,~op[5],~op[4], op[3], op[2], op[1],~op[0]);
包含各类专业文献、文学作品欣赏、生活休闲娱乐、行业资料、各类资格考试、专业论文、中学教育、高等教育、幼儿教育、小学教育、实验四 多周期CPU与存储器实验_图文20等内容。 
 本科实验报告 实验名称: 多周期机制 CPU 的实现 1...进制的指令编码,并且 加载到处理器中的指令存储器中...存储字 加减与或 异或 移动 比较 转移 4 操作描述...  计算机组成与原理+实验五 CPU组成与机器指令执行周期实验报告_计算机硬件及网络_...(4).置 SW7-SW0 为 5CH,按 QD 按钮,将 5CH 写入存储器 01H 单元.AR...  四、实验步骤 1、电路结构设计与逻辑设计 电路结构设计与逻辑设计 1 多周期处理...存储器 Addres s Dataou WE t Detain CS OE M U X WRITEZERO A ZERO ...  .4.12 一、 实验室名称: 主楼 A2-412 二、 实验项目名称:单周期 CPU 的...存储器地址的计算方法与 load 相同。 7、对于 beq address 指令 //if(Z==0...  实验目的 1. 2. 3. 4. 掌握单周期CPU数据通路图的构成、原理及其设计方法;...其中指令和数据各存储在不同存储器中,即有指令存储器和数据存储器。 访问存储...  CPU组成与机器指令执行周期实验_计算机硬件及网络_IT...注意:由于设置通用寄存器时会破坏存储 器单元的数据,...2. 3. 4. 务必做好实验预习,这样在实验中才能...  单周期CPU实验报告_计算机硬件及网络_IT/计算机_专业资料。MIPS CPU Verilog 和...数据寄存器(Registers) :在此程序中功能和实现基本和数据存储器相同,但在实 际...  台运行环境与调试方法,掌握基本 CPU 的设计,为自行设计多 级流水 CPU 打好...③在将测试文 件 EX2.txt 编译并下载到实验台上的存储器中后,要首先按实验...  实验目的 (1) (2) (3) (4) 掌握单周期 CPU 数据通路图的构成、原理及其...其中指令和数据各存储在不同存储器中,即有指令存储器和数据存储器。 访问存储...君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
计算机组织与系统结构第六章习题答案
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口Google力挺MIPS后PC时代终演三国志
 作者: 谢慧超 编辑:
  【IT168 资讯】PC时代,INTEL与AMD形成&双寡头&格局,但战略判断的错失与技术跟进的迟缓,导致在后PC时代(移动互联)远远落后规模比它们少得多的ARM。凭借前瞻的眼光,与独到商业模式的建立,ARM俨然成为后PC时代的寡头。不过,随着Google副总裁,安卓之父andy rubin承认全球首款安卓4.0平板花落MIPS,再联想到Goolge早前宣布安卓4.0将向X86开源,可以断定,后PC时代的三国争霸已提前上演。  视频展示位置  微软结盟ARM 谷歌拉拢X86和MIPS  后PC时代的三国格局,很大程度上来自于微软和Google两大巨头的暗战。早于CES 2011,微软就宣布下一个版本的Windows将同时支持ARM架构,微软Windows和Windows Live部门总裁斯Steven Sinofsky曾表示,&支持ARM架构展示了Windows软件的灵活性和弹性,以及世界级的开发理念。我们将继续改进Windows,从而在最广泛的硬件平台和产品形态上向消费者提供其所需的功能。&微软暗送秋波,ARM亦投怀送抱,ARM总裁Tudor Brown回应,微软需要ARM,借助兼容ARM处理器的Windows操作系统,微软终将在移动互联网领域确立重要地位。▲  面对激流涌动,一直以称雄全球移动互联市场为目标的Google自然见招拆招,除了继续保持和ARM的良好关系,同时不忘给踌躇满志的intel x86,以及一直曲高和寡的MIPS投放橄榄枝,以合纵连横的策略,建立更广阔的处理器架构平台阵营,以便占领移动互联终端设备操作系统更多的份额。这次Google官方第一次确认,不是AMR,也不是X86,而是基于MIPS机构开发的,采用君正Xbusrt处理器的平板作为全球首发,足以看出Goolge在后PC时代的战略野心。▲  安卓4.0首发MIPS 三国之势确立  Google此次从最底层的芯片架构角度出发,从ARM到X86再到MIPS的全面开放,不仅有利于推动芯片设计的交互竞争与技术创新,而且有利于Android 4.0系统在不同消费需求、不同产品类型、不同市场区间的有序竞争与多元发展。在此基础上,安卓平板市场必将上演更精彩的大战。作为市场领导者,ARM依然会保持增长势头,目前,全球平板出货最好的苹果和三星,用的是ARM,通过全球100多个合作伙伴,ARM一直在拓展市场,但随着CPU可选范围的扩大,ARM估计会迎来X86与MIPS的强力挑战。在INTEL的强力推动下,X86将在制约其发展的功耗上再下功夫,未来表现依然值得期待。▲  在得到Google官方高调认可后,MIPS的市场前景更让人兴奋。作为全球最大的平板制造与出口市场,同时有可能成为全球最大的平板市场,中国在移动互联设备竞争过程的地位不容小觑。关键一点是,国内的龙芯,君正,炬力均在中国,如果MIPS得到品牌商和用户的认可,那么将带动整个平板产业链的洗牌与变革。  无论如何,三国争霸势在必行,对于平板玩家来说,这是喜闻乐见的现象。在Google力挺下,MIPS能否与X86一起冲破ARM的封锁圈?相信答案很快就揭晓。
大学生分期购物销量榜
已有条评论

我要回帖

更多关于 mips单周期cpu中断 的文章

 

随机推荐