![cover](https://img-blog.csdnimg.cn/direct/0fb5063ae0ac42868dcba3ba77fb7fee.png)
HNU_CA_实验1--RISC-V指令理解
在本实验的主体部分(4.思考问题),这里主要采用的A橙的用电路图的方式,表示数据通路以及控制信号,以求达到更为形象的目的,故而并未严格详尽地模拟出每条指令码解码出的控制信号,这部分可以移步韩金轮的博客;
HNU_CA_实验1--RISC-V指令理解
参考(
A橙: A橙-CA-实验一
韩金轮: 韩金轮-CA-实验一
在本实验的主体部分(4.思考问题),这里主要采用的A橙的用电路图的方式,表示数据通路以及控制信号,以求达到更为形象的目的,故而并未严格详尽地模拟出每条指令码解码出的控制信号,这部分可以移步韩金轮的博客;
1.安装模拟器Ripes
(1)下载
下载途径:韩金轮的网盘+老师给的文件:Ripes下载-提取码:0928
解压缩:两个文件夹
文件夹Ripes-v2.2.6-1-g2a03b38-win-x86_64中的Ripes.exe即我们需要用到的应用程序;
(2)配置
双击打开上面的Ripes.exe后,点击上面的Edit->Settings;
选择Compiler->Compiler path;前面下载解压缩后有两个文件夹,这里就是用的另一个文件riscv64-unknown-elf-gcc-8.3.0-2020.04.1-x86_64-w64-mingw32中的bin,然后选择riscv64-unknown-elf-g++.exe,即配置完成
2.汇编代码
汇编代码其实有用的就是思考问题中问到的“A[i]=A[i-1]+1000;对应的汇编代码”,但是把整个汇编代码都过一遍,也是很有帮助的,也算复习一下计算机系统。
需要注意的是:
- 生成汇编代码的指令与之前学的不大一样,但大差不差,不清楚的可以查一下,或者老师发的指导书《指令集补充》;
- 另外,笔者并没有严格模拟出来汇编代码的执行过程,尤其对栈帧指针的操作部分,不过对整体理解影响不大。
(1)C程序
void main()
{
int A[100];
int i;
for(i=0;i<100;i++)
A[i]=i;
for(i=1;i<100;i++)
A[i]=A[i-1]+1000;
}
(2)汇编代码
00010074 <register_fini>:
10074: ffff0797 auipc x15 0xffff0
10078: f8c78793 addi x15 x15 -116
1007c: 00078863 beq x15 x0 16
10080: 00000517 auipc x10 0x0
10084: 19450513 addi x10 x10 404
10088: 1440006f jal x0 324 <atexit>
1008c: 00008067 jalr x0 x1 0
00010090 <_start>:
10090: 00002197 auipc x3 0x2
10094: d7018193 addi x3 x3 -656
10098: c3418513 addi x10 x3 -972
1009c: c5018613 addi x12 x3 -944
100a0: 40a60633 sub x12 x12 x10
100a4: 00000593 addi x11 x0 0
100a8: 260000ef jal x1 608 <memset>
100ac: 00000517 auipc x10 0x0
100b0: 16850513 addi x10 x10 360
100b4: 118000ef jal x1 280 <atexit>
100b8: 1bc000ef jal x1 444 <__libc_init_array>
100bc: 00012503 lw x10 0 x2
100c0: 00410593 addi x11 x2 4
100c4: 00000613 addi x12 x0 0
100c8: 07c000ef jal x1 124 <main>
100cc: 1140006f jal x0 276 <exit>
000100d0 <__do_global_dtors_aux>:
100d0: c341c783 lbu x15 -972 x3
100d4: 04079463 bne x15 x0 72
100d8: ffff0797 auipc x15 0xffff0
100dc: f2878793 addi x15 x15 -216
100e0: 02078863 beq x15 x0 48
100e4: ff010113 addi x2 x2 -16
100e8: 00001517 auipc x10 0x1
100ec: 50450513 addi x10 x10 1284
100f0: 00112623 sw x1 12 x2
100f4: 00000097 auipc x1 0x0
100f8: 000000e7 jalr x1 x0 0
100fc: 00c12083 lw x1 12 x2
10100: 00100793 addi x15 x0 1
10104: c2f18a23 sb x15 -972 x3
10108: 01010113 addi x2 x2 16
1010c: 00008067 jalr x0 x1 0
10110: 00100793 addi x15 x0 1
10114: c2f18a23 sb x15 -972 x3
10118: 00008067 jalr x0 x1 0
1011c: 00008067 jalr x0 x1 0
00010120 <frame_dummy>:
10120: ffff0797 auipc x15 0xffff0
10124: ee078793 addi x15 x15 -288
10128: 00078c63 beq x15 x0 24
1012c: c3818593 addi x11 x3 -968
10130: 00001517 auipc x10 0x1
10134: 4bc50513 addi x10 x10 1212
10138: 00000317 auipc x6 0x0
1013c: 00000067 jalr x0 x0 0
10140: 00008067 jalr x0 x1 0
00010144 <main>:
10144: 7161 c.addi16sp -432
10146: 1a812623 sw x8 428 x2
1014a: 1b00 c.addi4spn x8 432
1014c: fe042623 sw x0 -20 x8
10150: a005 c.j 32
10152: fec42783 lw x15 -20 x8
10156: 078a c.slli x15 2
10158: ff040713 addi x14 x8 -16
1015c: 97ba c.add x15 x14
1015e: fec42703 lw x14 -20 x8
10162: e6e7a623 sw x14 -404 x15
10166: fec42783 lw x15 -20 x8
1016a: 0785 c.addi x15 1
1016c: fef42623 sw x15 -20 x8
10170: fec42703 lw x14 -20 x8
10174: 06300793 addi x15 x0 99
10178: fce7dde3 bge x15 x14 -38
1017c: 4785 c.li x15 1
1017e: fef42623 sw x15 -20 x8
10182: a80d c.j 50
10184: fec42783 lw x15 -20 x8
10188: 17fd c.addi x15 -1
1018a: 078a c.slli x15 2
1018c: ff040713 addi x14 x8 -16
10190: 97ba c.add x15 x14
10192: e6c7a783 lw x15 -404 x15
10196: 3e878713 addi x14 x15 1000
1019a: fec42783 lw x15 -20 x8
1019e: 078a c.slli x15 2
101a0: ff040693 addi x13 x8 -16
101a4: 97b6 c.add x15 x13
101a6: e6e7a623 sw x14 -404 x15
101aa: fec42783 lw x15 -20 x8
101ae: 0785 c.addi x15 1
101b0: fef42623 sw x15 -20 x8
101b4: fec42703 lw x14 -20 x8
101b8: 06300793 addi x15 x0 99
101bc: fce7d4e3 bge x15 x14 -56
101c0: 0001 c.nop
101c2: 1ac12403 lw x8 428 x2
101c6: 615d c.addi16sp 432
101c8: 8082 c.jr x1
101ca: 0000 c.addi4spn x8 0
000101cc <atexit>:
101cc: 00050593 addi x11 x10 0
101d0: 00000693 addi x13 x0 0
101d4: 00000613 addi x12 x0 0
101d8: 00000513 addi x10 x0 0
101dc: 2080006f jal x0 520 <__register_exitproc>
000101e0 <exit>:
101e0: ff010113 addi x2 x2 -16
101e4: 00000593 addi x11 x0 0
101e8: 00812423 sw x8 8 x2
101ec: 00112623 sw x1 12 x2
101f0: 00050413 addi x8 x10 0
101f4: 28c000ef jal x1 652 <__call_exitprocs>
101f8: c2818793 addi x15 x3 -984
101fc: 0007a503 lw x10 0 x15
10200: 03c52783 lw x15 60 x10
10204: 00078463 beq x15 x0 8
10208: 000780e7 jalr x1 x15 0
1020c: 00040513 addi x10 x8 0
10210: 38c000ef jal x1 908 <_exit>
00010214 <__libc_fini_array>:
10214: ff010113 addi x2 x2 -16
10218: 00812423 sw x8 8 x2
1021c: 00001797 auipc x15 0x1
10220: 3dc78793 addi x15 x15 988
10224: 00001417 auipc x8 0x1
10228: 3d840413 addi x8 x8 984
1022c: 40f40433 sub x8 x8 x15
10230: 00112623 sw x1 12 x2
10234: 00912223 sw x9 4 x2
10238: 40245413 srai x8 x8 2
1023c: 02040263 beq x8 x0 36
10240: 00241493 slli x9 x8 2
10244: ffc48493 addi x9 x9 -4
10248: 00f484b3 add x9 x9 x15
1024c: 0004a783 lw x15 0 x9
10250: fff40413 addi x8 x8 -1
10254: ffc48493 addi x9 x9 -4
10258: 000780e7 jalr x1 x15 0
1025c: fe0418e3 bne x8 x0 -16
10260: 00c12083 lw x1 12 x2
10264: 00812403 lw x8 8 x2
10268: 00412483 lw x9 4 x2
1026c: 01010113 addi x2 x2 16
10270: 00008067 jalr x0 x1 0
00010274 <__libc_init_array>:
10274: ff010113 addi x2 x2 -16
10278: 00812423 sw x8 8 x2
1027c: 01212023 sw x18 0 x2
10280: 00001417 auipc x8 0x1
10284: 37040413 addi x8 x8 880
10288: 00001917 auipc x18 0x1
1028c: 36890913 addi x18 x18 872
10290: 40890933 sub x18 x18 x8
10294: 00112623 sw x1 12 x2
10298: 00912223 sw x9 4 x2
1029c: 40295913 srai x18 x18 2
102a0: 00090e63 beq x18 x0 28
102a4: 00000493 addi x9 x0 0
102a8: 00042783 lw x15 0 x8
102ac: 00148493 addi x9 x9 1
102b0: 00440413 addi x8 x8 4
102b4: 000780e7 jalr x1 x15 0
102b8: fe9918e3 bne x18 x9 -16
102bc: 00001417 auipc x8 0x1
102c0: 33440413 addi x8 x8 820
102c4: 00001917 auipc x18 0x1
102c8: 33490913 addi x18 x18 820
102cc: 40890933 sub x18 x18 x8
102d0: 40295913 srai x18 x18 2
102d4: 00090e63 beq x18 x0 28
102d8: 00000493 addi x9 x0 0
102dc: 00042783 lw x15 0 x8
102e0: 00148493 addi x9 x9 1
102e4: 00440413 addi x8 x8 4
102e8: 000780e7 jalr x1 x15 0
102ec: fe9918e3 bne x18 x9 -16
102f0: 00c12083 lw x1 12 x2
102f4: 00812403 lw x8 8 x2
102f8: 00412483 lw x9 4 x2
102fc: 00012903 lw x18 0 x2
10300: 01010113 addi x2 x2 16
10304: 00008067 jalr x0 x1 0
00010308 <memset>:
10308: 00f00313 addi x6 x0 15
1030c: 00050713 addi x14 x10 0
10310: 02c37e63 bgeu x6 x12 60
10314: 00f77793 andi x15 x14 15
10318: 0a079063 bne x15 x0 160
1031c: 08059263 bne x11 x0 132
10320: ff067693 andi x13 x12 -16
10324: 00f67613 andi x12 x12 15
10328: 00e686b3 add x13 x13 x14
1032c: 00b72023 sw x11 0 x14
10330: 00b72223 sw x11 4 x14
10334: 00b72423 sw x11 8 x14
10338: 00b72623 sw x11 12 x14
1033c: 01070713 addi x14 x14 16
10340: fed766e3 bltu x14 x13 -20
10344: 00061463 bne x12 x0 8
10348: 00008067 jalr x0 x1 0
1034c: 40c306b3 sub x13 x6 x12
10350: 00269693 slli x13 x13 2
10354: 00000297 auipc x5 0x0
10358: 005686b3 add x13 x13 x5
1035c: 00c68067 jalr x0 x13 12
10360: 00b70723 sb x11 14 x14
10364: 00b706a3 sb x11 13 x14
10368: 00b70623 sb x11 12 x14
1036c: 00b705a3 sb x11 11 x14
10370: 00b70523 sb x11 10 x14
10374: 00b704a3 sb x11 9 x14
10378: 00b70423 sb x11 8 x14
1037c: 00b703a3 sb x11 7 x14
10380: 00b70323 sb x11 6 x14
10384: 00b702a3 sb x11 5 x14
10388: 00b70223 sb x11 4 x14
1038c: 00b701a3 sb x11 3 x14
10390: 00b70123 sb x11 2 x14
10394: 00b700a3 sb x11 1 x14
10398: 00b70023 sb x11 0 x14
1039c: 00008067 jalr x0 x1 0
103a0: 0ff5f593 andi x11 x11 255
103a4: 00859693 slli x13 x11 8
103a8: 00d5e5b3 or x11 x11 x13
103ac: 01059693 slli x13 x11 16
103b0: 00d5e5b3 or x11 x11 x13
103b4: f6dff06f jal x0 -148
103b8: 00279693 slli x13 x15 2
103bc: 00000297 auipc x5 0x0
103c0: 005686b3 add x13 x13 x5
103c4: 00008293 addi x5 x1 0
103c8: fa0680e7 jalr x1 x13 -96
103cc: 00028093 addi x1 x5 0
103d0: ff078793 addi x15 x15 -16
103d4: 40f70733 sub x14 x14 x15
103d8: 00f60633 add x12 x12 x15
103dc: f6c378e3 bgeu x6 x12 -144
103e0: f3dff06f jal x0 -196
000103e4 <__register_exitproc>:
103e4: c2818793 addi x15 x3 -984
103e8: 0007a703 lw x14 0 x15
103ec: 14872783 lw x15 328 x14
103f0: 04078c63 beq x15 x0 88
103f4: 0047a703 lw x14 4 x15
103f8: 01f00813 addi x16 x0 31
103fc: 06e84e63 blt x16 x14 124
10400: 00271813 slli x16 x14 2
10404: 02050663 beq x10 x0 44
10408: 01078333 add x6 x15 x16
1040c: 08c32423 sw x12 136 x6
10410: 1887a883 lw x17 392 x15
10414: 00100613 addi x12 x0 1
10418: 00e61633 sll x12 x12 x14
1041c: 00c8e8b3 or x17 x17 x12
10420: 1917a423 sw x17 392 x15
10424: 10d32423 sw x13 264 x6
10428: 00200693 addi x13 x0 2
1042c: 02d50463 beq x10 x13 40
10430: 00170713 addi x14 x14 1
10434: 00e7a223 sw x14 4 x15
10438: 010787b3 add x15 x15 x16
1043c: 00b7a423 sw x11 8 x15
10440: 00000513 addi x10 x0 0
10444: 00008067 jalr x0 x1 0
10448: 14c70793 addi x15 x14 332
1044c: 14f72423 sw x15 328 x14
10450: fa5ff06f jal x0 -92
10454: 18c7a683 lw x13 396 x15
10458: 00170713 addi x14 x14 1
1045c: 00e7a223 sw x14 4 x15
10460: 00c6e633 or x12 x13 x12
10464: 18c7a623 sw x12 396 x15
10468: 010787b3 add x15 x15 x16
1046c: 00b7a423 sw x11 8 x15
10470: 00000513 addi x10 x0 0
10474: 00008067 jalr x0 x1 0
10478: fff00513 addi x10 x0 -1
1047c: 00008067 jalr x0 x1 0
00010480 <__call_exitprocs>:
10480: fd010113 addi x2 x2 -48
10484: c2818793 addi x15 x3 -984
10488: 01812423 sw x24 8 x2
1048c: 0007ac03 lw x24 0 x15
10490: 01312e23 sw x19 28 x2
10494: 01412c23 sw x20 24 x2
10498: 01512a23 sw x21 20 x2
1049c: 01612823 sw x22 16 x2
104a0: 02112623 sw x1 44 x2
104a4: 02812423 sw x8 40 x2
104a8: 02912223 sw x9 36 x2
104ac: 03212023 sw x18 32 x2
104b0: 01712623 sw x23 12 x2
104b4: 00050a93 addi x21 x10 0
104b8: 00058b13 addi x22 x11 0
104bc: 00100a13 addi x20 x0 1
104c0: fff00993 addi x19 x0 -1
104c4: 148c2903 lw x18 328 x24
104c8: 02090863 beq x18 x0 48
104cc: 00492483 lw x9 4 x18
104d0: fff48413 addi x8 x9 -1
104d4: 02044263 blt x8 x0 36
104d8: 00249493 slli x9 x9 2
104dc: 009904b3 add x9 x18 x9
104e0: 040b0463 beq x22 x0 72
104e4: 1044a783 lw x15 260 x9
104e8: 05678063 beq x15 x22 64
104ec: fff40413 addi x8 x8 -1
104f0: ffc48493 addi x9 x9 -4
104f4: ff3416e3 bne x8 x19 -20
104f8: 02c12083 lw x1 44 x2
104fc: 02812403 lw x8 40 x2
10500: 02412483 lw x9 36 x2
10504: 02012903 lw x18 32 x2
10508: 01c12983 lw x19 28 x2
1050c: 01812a03 lw x20 24 x2
10510: 01412a83 lw x21 20 x2
10514: 01012b03 lw x22 16 x2
10518: 00c12b83 lw x23 12 x2
1051c: 00812c03 lw x24 8 x2
10520: 03010113 addi x2 x2 48
10524: 00008067 jalr x0 x1 0
10528: 00492783 lw x15 4 x18
1052c: 0044a683 lw x13 4 x9
10530: fff78793 addi x15 x15 -1
10534: 04878a63 beq x15 x8 84
10538: 0004a223 sw x0 4 x9
1053c: fa0688e3 beq x13 x0 -80
10540: 18892783 lw x15 392 x18
10544: 008a1733 sll x14 x20 x8
10548: 00492b83 lw x23 4 x18
1054c: 00f777b3 and x15 x14 x15
10550: 00079e63 bne x15 x0 28
10554: 000680e7 jalr x1 x13 0
10558: 00492783 lw x15 4 x18
1055c: f77794e3 bne x15 x23 -152
10560: 148c2783 lw x15 328 x24
10564: f92784e3 beq x15 x18 -120
10568: f5dff06f jal x0 -164
1056c: 18c92783 lw x15 396 x18
10570: 0844a583 lw x11 132 x9
10574: 00f77733 and x14 x14 x15
10578: 00071c63 bne x14 x0 24
1057c: 000a8513 addi x10 x21 0
10580: 000680e7 jalr x1 x13 0
10584: fd5ff06f jal x0 -44
10588: 00892223 sw x8 4 x18
1058c: fb1ff06f jal x0 -80
10590: 00058513 addi x10 x11 0
10594: 000680e7 jalr x1 x13 0
10598: fc1ff06f jal x0 -64
0001059c <_exit>:
1059c: 00000593 addi x11 x0 0
105a0: 00000613 addi x12 x0 0
105a4: 00000693 addi x13 x0 0
105a8: 00000713 addi x14 x0 0
105ac: 00000793 addi x15 x0 0
105b0: 05d00893 addi x17 x0 93
105b4: 00000073 ecall
105b8: 00054463 blt x10 x0 8
105bc: 0000006f jal x0 0
105c0: ff010113 addi x2 x2 -16
105c4: 00812423 sw x8 8 x2
105c8: 00050413 addi x8 x10 0
105cc: 00112623 sw x1 12 x2
105d0: 40800433 sub x8 x0 x8
105d4: 00c000ef jal x1 12 <__errno>
105d8: 00852023 sw x8 0 x10
105dc: 0000006f jal x0 0
000105e0 <__errno>:
105e0: c3018793 addi x15 x3 -976
105e4: 0007a503 lw x10 0 x15
105e8: 00008067 jalr x0 x1 0
(3)main函数的分析
思考问题中只问到了第二个for循环的A[i]=A[i-1]+1000;对应的汇编代码;
00010144 <main>:
10144: 7161 c.addi16sp -432
10146: 1a812623 sw x8 428 x2
1014a: 1b00 c.addi4spn x8 432
1014c: fe042623 sw x0 -20 x8
10150: a005 c.j 32
10152: fec42783 lw x15 -20 x8
10156: 078a c.slli x15 2
10158: ff040713 addi x14 x8 -16
1015c: 97ba c.add x15 x14
1015e: fec42703 lw x14 -20 x8
10162: e6e7a623 sw x14 -404 x15
10166: fec42783 lw x15 -20 x8
1016a: 0785 c.addi x15 1
1016c: fef42623 sw x15 -20 x8
10170: fec42703 lw x14 -20 x8
10174: 06300793 addi x15 x0 99
10178: fce7dde3 bge x15 x14 -38
1017c: 4785 c.li x15 1
1017e: fef42623 sw x15 -20 x8
10182: a80d c.j 50
10184: fec42783 lw x15 -20 x8
10188: 17fd c.addi x15 -1
1018a: 078a c.slli x15 2
1018c: ff040713 addi x14 x8 -16
10190: 97ba c.add x15 x14
10192: e6c7a783 lw x15 -404 x15
10196: 3e878713 addi x14 x15 1000
1019a: fec42783 lw x15 -20 x8
1019e: 078a c.slli x15 2
101a0: ff040693 addi x13 x8 -16
101a4: 97b6 c.add x15 x13
101a6: e6e7a623 sw x14 -404 x15
101aa: fec42783 lw x15 -20 x8
101ae: 0785 c.addi x15 1
101b0: fef42623 sw x15 -20 x8
101b4: fec42703 lw x14 -20 x8
101b8: 06300793 addi x15 x0 99
101bc: fce7d4e3 bge x15 x14 -56
101c0: 0001 c.nop
101c2: 1ac12403 lw x8 428 x2
101c6: 615d c.addi16sp 432
101c8: 8082 c.jr x1
101ca: 0000 c.addi4spn x8 0
①分配栈空间
//
10144: 7161 c.addi16sp -432
10146: 1a812623 sw x8 428 x2
1014a: 1b00 c.addi4spn x8 432
②第一个循环
//【初始i=0】:然后进行循环条件判断
1014c: fe042623 sw x0 -20 x8 //[x8-20]存储的是i,此处是初始化为0
10150: a005 c.j 32 //无条件跳转到PC[0x10150]+32[0x20]=[0x10170]
//【循环体A[i]=i】:暨10178条件跳转的位置
10152: fec42783 lw x15 -20 x8 //把[x8-20]中的i 读到x15中
10156: 078a c.slli x15 2 //对x15中的i左移2位,即变为4*i
10158: ff040713 addi x14 x8 -16 // 把[x8-16]中的A数组的起始地址 读到x14中
1015c: 97ba c.add x15 x14 //把x15(4*i)和x14(&A[0])相加,得到数组中的第i个数的地址&A[i],然后赋给x15
1015e: fec42703 lw x14 -20 x8 //把[x8-20]中的i 读到x14中
10162: e6e7a623 sw x14 -404 x15 //把x14(i)赋给x15(&A[i])-404的内存地址中【A[i]=i】
//【i++】
10166: fec42783 lw x15 -20 x8 //把[x8-20]中的i 读到x15中
1016a: 0785 c.addi x15 1 //对x15中的i加1,然后赋给x15
1016c: fef42623 sw x15 -20 x8 //把x15(加1之后的i)赋给[x8-20]
//【循环条件i<100】:暨10150无条件跳转的位置
10170: fec42703 lw x14 -20 x8 //把[x8-20]中的i 读到x14中
10174: 06300793 addi x15 x0 99//把x0(0)+99=0 赋给x15
10178: fce7dde3 bge x15 x14 -38 //比较x15(99)和x14(i),若99>=i,则跳转到PC[0x10178]-38[0x26]=[0x10152]
③第二个循环
//【初始i=1】:然后进行循环条件判断
1017c: 4785 c.li x15 1//"C.LI 指令被扩展为 addi rd, x0, imm[5:0]",这里就是赋值1给x15
1017e: fef42623 sw x15 -20 x8 // //把x15(初始为1)赋给[x8-20],即i
10182: a80d c.j 50 //无条件跳转到PC[0x10182]+50[0x32]=[0x101b4]
x15中的A[i] 中【A[i]=i】
//【循环体A[i]=A[i-1]+1000】:暨101bc条件跳转的位置
//取A[i-1]到x15
10184: fec42783 lw x15 -20 x8 //把[x8-20]中的i 读到x15中
10188: 17fd c.addi x15 -1 //对x15中的i减一
1018a: 078a c.slli x15 2 //对x15中的(i-1)左移2位,即变为4*(i-1)
1018c: ff040713 addi x14 x8 -16 // 把[x8-16]中的A数组的起始地址 读到x14中
10190: 97ba c.add x15 x14 //把x15(4*(i-1))和x14(&A[0])相加,得到数组中的第i-1个数A[i-1],然后赋给x15
10192: e6c7a783 lw x15 -404 x15 //把x15中的A[i-1] 存到x15中
//把A[i-1]加1000,存到x14
10196: 3e878713 addi x14 x15 1000 //把x15中的A[i-1] 加上1000,然后存到x14中
//把A[i-1]+1000,存到A[i]
1019a: fec42783 lw x15 -20 x8 //把[x8-20]中的i 读到x15中
1019e: 078a c.slli x15 2 //对x15中的i左移2位,即变为4*i
101a0: ff040693 addi x13 x8 -16// 把[x8-16]中的A数组的起始地址 读到x13中
101a4: 97b6 c.add x15 x13 //把x15(4*i)和x13(&A[0])相加,得到数组中的第i个数的地址&A[i],然后赋给x15
101a6: e6e7a623 sw x14 -404 x15 //把x14(A[i-1]+1000)赋给x15(&A[i])-404的内存地址中【A[i]=A[i-1]+1000】
//【i++】
101aa: fec42783 lw x15 -20 x8 //把[x8-20]中的i 读到x15中
101ae: 0785 c.addi x15 1 //对x15中的i加1,然后赋给x15
101b0: fef42623 sw x15 -20 x8 //把x15(加1之后的i)赋给[x8-20]
//【循环条件i<100】:暨10182无条件跳转的位置---与第一个循环的“i<100”基本一致
101b4: fec42703 lw x14 -20 x8 //把[x8-20]中的i 读到x14中
101b8: 06300793 addi x15 x0 99 //把x0(0)+99=0 赋给x15
101bc: fce7d4e3 bge x15 x14 -56 //比较x15(99)和x14(i),若99>=i,则跳转到PC[0x101c0]-56[0x38]=[0x10184]
④退出main
101c0: 0001 c.nop
// 退出main的栈
101c2: 1ac12403 lw x8 428 x2
101c6: 615d c.addi16sp 432
// 跳转到x1(ra-返回地址)
101c8: 8082 c.jr x1
101ca: 0000 c.addi4spn x8 0
另:404的分析
以第一个循环为例,对10162处的-404进行分析:
//【循环体A[i]=i】:暨10178条件跳转的位置
10152: fec42783 lw x15 -20 x8 //把[x8-20]中的i 读到x15中
10156: 078a c.slli x15 2 //对x15中的i左移2位,即变为4*i
10158: ff040713 addi x14 x8 -16 // 把[x8-16]中的A数组的起始地址 读到x14中
1015c: 97ba c.add x15 x14 //把x15(4*i)和x14(&A[0])相加,得到数组中的第i个数的地址&A[i],然后赋给x15
1015e: fec42703 lw x14 -20 x8 //把[x8-20]中的i 读到x14中
10162: e6e7a623 sw x14 -404 x15 //把x14(i)赋给x15(&A[i])-404的内存地址中【A[i]=i】
前者是在Ubuntu中按之前计算机系统的方式,进行的反汇编:
创建test.c后,把c程序写进去,运行指令为:
gcc -o test.c test
objdump -S test
3.各部件及主要控制信号
在局部地考虑下面思考问题中各指令的关键控制信号和数据通路之前,我们先总览一下RISC-V 32I Core 设计图中的各部件及主要控制信号。
应当注意的是,一下子看这么多部件、信号,可能看不过来,也并不很明白是什么意思。但是笔者认为先走马观花地过一遍是有所裨益的。有个印象,然后后面不清楚的时候再回头来看。
(1)HarzardUnit
流水线冲突处理模块;
作用:
- 插入气泡stall;
- 定向路径(前递,转发)forward;
- 冲刷流水段flush,组合逻辑电路,信号说明:
输入:
-
ICacheMiss, DCacheMiss:因为指令以流水线的方式执行,所以前面指令的访存会影响后面的指令。
- ICacheMiss 指令缓存未命中:下一条指令不能进入取指阶段,需要让流水线暂停,等待查找指令;
- DCacheMiss数据缓存未命中:下一条指令不能进入访存阶段,需要让流水线暂停,等待查找数据;
-
BranchE,JalrE,JalD: 控制相关处理信号
- 作用的部件:NPC Generator;
- BranchE,JalrE,JalD:
- 最后一个字母:代表流水线的哪个阶段(E-Execute执行,D-Decode译码;下同);【了解一下简称是什么意思也很有用】
- BranchE:分支使能
- JalrE,JalD:条件跳转使能;JalrE需要用到寄存器,JalD只用到立即数;
-
Rs1D,Rs2D,Rs1E,Rs2E,RdE,RdM,RdW
- 最后一个字母:D-Decode译码,E-Execute执行,M-Memory访存,W-WriteBack写回;
- 第一个字母R:寄存器;
- 第二个字母:s-source源寄存器,d-destination目标寄存器;
- 数字:多个寄存器可用的话,就编下号;
-
RegReadE:标记A1和A2对应的寄存器值是否被用到。
-
MemToRegE: 标志EX段从data mamory加载数据到寄存器
-
RegWriteM,RegWriteW: 标记MEM段和WB段是否有目标寄存器写入操作。
输出: -
StallF,FlushF: IF段插入气泡(维持状态不变)/冲刷(清零)
-
StallD,FlushD: ID段插入气泡/冲刷
-
StallE,FlushE:EX段插入气泡/冲刷
-
StallM,FlushM:MEM段插入气泡/冲刷
-
StallW,FlushW:WB段插入气泡/冲刷
-
Forward1E,Forward2E: 定向路径控制信号
(2)ControlUnit
控制模块(译码器);
输出:
- JalD: NPC Generator接受JalT的使能;
- JalrD: JarlE,NPC Generator接受JralT的使能;
- RegWriteD:RegWriteE->RegWriteM->RegWriteW,是否写入寄存器;
- MemToRegD:MemToRegE->MemToRegM->MemToRegW,是否从data memory读取数据到寄存器
- MemWriteD: MemWrite->MemWriteM,共4bit,指示data memory的四个字节中哪些需要写入 ;
- LoadNpcD:是否计算PC+4存入rd寄存器;
- RegReadD: 标志两个源寄存器的使用情况;用于forward处理
- RegReadD[1] ==1,表示A1对应的寄存器值被使用到了;
- RegReadD[0]== 1,表示A2对应的寄存器值被使用到了,
- BranchTypeD: 表示不同分支类型
- AluContrlD: 表示不同算数逻辑运算种类
- AluSrc1D: Alu输入源Operand1的选择 (寄存器值、PC值)
- AluSrc2D: Alu输入源Operand2的选择 (寄存器值、立即数)
- ImmType: 立即数编码格式类型
(3)NPC_Generator
用来生成Next PC值的模块,根据不同的跳转信号选择不同的新PC值;
输入:
-
指令:
- PCF:旧的PC值;
- JalrTarget:jalr指令的对应的跳转目标
- BranchTarget:branch指令的对应的跳转目标
- JalTarget:jal指令的对应的跳转目标
-
使能
- BranchE:Ex阶段的Branch指令确定跳转;
- JalD:ID阶段的Jal指令确定跳转 ;
- JalrE:Ex阶段的Jalr指令确定跳转;
- 分支预测:PCF接入的就是分支预测;若预测选中,可以不用等到EX阶段判断条件,可以直接在ID阶段计算出跳转地址就写入NPC
输出:
- PC_In:NPC的值
(4)RegisterFile
寄存器组:时钟周期的上升沿写,下降沿读;
x0:0号寄存器值始终为32’b0;
读
- 输入:A1,A2;需要访问的寄存器编号;
- 输出:RD1,RD2;访问寄存器当前在寄存器组的值;
写:从ID阶段一直传递到WB阶段
- WD3:写回的数据;
- A3:写回的目标寄存器编号;
- RegWriteW:写回使能
(5)ImmOperandUnit
立即数扩展单元:利用正在被译码的指令的部分编码值,生成不同类型的32bit立即数
可以简单地认为:IN接受译码的指令/数据;输出想得到的立即数;
- 扩展立即数:传递给执行阶段;
- 计算Jal跳转目标地址:传给NPC generator;对于无条件跳转Jal,控制单元在这个阶段就可以发出控制信号JalD,进行跳转了;
(6)BranchDecision
跳转判断单元;
输入
- BranchTypeE:指定的分支类型;如bge,bne等;
- Reg1,Reg2:进行比较的两个操作数;操作数来源:
- 取值阶段,或者执行和访存阶段
输出
- BranchE:判断结果输出;
(7)ALU
算数逻辑运算单元;
输入:
- Operand1和Operand2:两个操作数;经过Forward,AluSrc选择的;操作数来源有:
- ID阶段读取的寄存器值;
- EX、MEM阶段的数据前推结果;
- 立即数
- AluContrl:执行对应的运算;
- 算术运算:如±*/
- 逻辑运算;
- Jalr指令:将rs1的值的最低位设置为0后通过AluOut传递给NPC generator,进行跳转。
输出: - AluOut:结果输出
(8)DataExt
输入:
- IN(DM_RD):从Data Memory中load的32bit字;
- LoadedBytesSelect:从32bit字中挑选出我们需要的字节;
- IN是4B(32位字),OUT是1B(8位);所以需要从4B中选出1B;
- RegWriteW:表示是否写入寄存器;
输出:
- OUT:表示要写入寄存器的最终值
4.思考问题
找出循环A[i]=A[i-1]+1000;对应的汇编代码,思考以下问题:
(1)分析指令add x15, x14, x15
题目:(x是指以x开头的通用寄存器),写出该指令在流水线五个阶段(IF、ID、EX、MEM和WB)关键的控制信号(参考RISC V电路设计图),并通过分析指出数据通路。
- 指令功能:x14(数组A的地址)+ x15(偏移量4*(i-1))—》x15(A[i-1]的地址)
- 汇编代码:
之所以给出多条,是因为指令以流水线的执行方式,前面指令的执行、访存、写回等操作会影响当前指令;
10188: 17fd c.addi x15 -1
1018a: 078a c.slli x15 2
1018c: ff040713 addi x14 x8 -16
10190: 97ba c.add x15 x14
①IF
- 执行行为:PC值为10190,读取该地址的指令,将指令传送到ID阶段。
- 关键控制信号:
- JalrE,JalE,BrE:均为非使能状态,因为前几条指令没有分支与跳转;
- JalrE,JalE,BrE:均为非使能状态,因为前几条指令没有分支与跳转;
②ID
- 关键控制信号:
- A1:0xE,表示x14寄存器,从寄存器组中读值,传给EX阶段;
- A2:0xF,表示x15寄存器,从寄存器组中读值,传给EX阶段;
- AluContrlD:执行加法;
- AluSrc1D、AluSrc2D:选择操作数;
- 数据:
- 目标数据:1018c的x14,1018a的x15;
- 问题:目标数据所在指令现在在访存/执行,并未写回RegisterFile,所以ID阶段读的x14、x15并非我们想要的数据,而是旧数据。
- 解决:会在EX阶段,通过forward解决。
③EX
- 关键控制信号:
- Forward1E:0x2,选择访存阶段的1018c的x14;【访存阶段前推】
- Forward2E:0x1,选择写回阶段的1018a的x15;【写回阶段前推】
- AluSrc1E、AluSrc2E:选择上面的x14,x15;
- AluContrlE:执行加法;
- 数据:
- 目标数据:1018c的x14,1018a的x15;
- 解决:通过forward:
- 通过Forward1E,将访存阶段的1018c的x14由AluoutM读到本指令的EX阶段,进行操作数选择;
- 通过Forward2E,将写回阶段的1018a的x15由写回线路读到本指令的EX阶段,进行操作数选择;
④MEM
本指令只涉及寄存器间的读取、运算、写回;不涉及访存;
- 关键控制信号:
- LoadNPCM:非使能;表示选择ALuoutM传递到写回阶段
- LoadNPCM:非使能;表示选择ALuoutM传递到写回阶段
⑤WB
-
关键控制信号:
- MemToRegW:非使能;表示最右边的二路选择器选择ReultW(值即上面传过来的AluoutM),写回到RegisterFile中的WD3;
- RegWriteW:使能;写回到RegisterFile中的RegWriteW,对寄存器组中的A3写回数据WD3;
-
数据:
- RdW:0xF;写回到RegisterFile中的A3,表示写回的目标寄存器是x15;
- RdW:0xF;写回到RegisterFile中的A3,表示写回的目标寄存器是x15;
⑥数据通路
(2)分析指令bge x15, x14, -56
题目:写出该指令在流水线五个阶段(IF、ID、EX、MEM和WB)关键的控制信号(参考RISC V电路设计图),并通过分析指出数据通路。
- 指令功能:判断x15>=x14;若为true,则跳转到当前PC-56的位置;
- 汇编代码:
101b0: fef42623 sw x15 -20 x8
101b4: fec42703 lw x14 -20 x8
101b8: 06300793 addi x15 x0 99
101bc: fce7d4e3 bge x15 x14 -56
①IF
- 执行行为:PC值为101bc,读取该地址的指令,将指令传送到ID阶段。
- 关键控制信号:
- JalrE,JalE,BrE:均为非使能状态,因为前几条指令没有分支与跳转;
- JalrE,JalE,BrE:均为非使能状态,因为前几条指令没有分支与跳转;
②ID
-
关键控制信号:
- A1:0xF,表示x15寄存器,从寄存器组中读值,传给EX阶段;
- A2:0xE,表示x14寄存器,从寄存器组中读值,传给EX阶段;
- Immediate Operand Unit:扩展出来-56,然后计算PC-56,传递给EX阶段;
- AluSrc1D、AluSrc2D:选择操作数;
- BranchType:分支类型bge;
-
数据:
- 目标数据:101b8的x15,101b4的x14;
- 问题:目标数据所在指令现在在访存/执行,并未写回RegisterFile,所以ID阶段读的x14、x15并非我们想要的数据;
③EX
- 关键控制信号:
- Forward1E:0x2,选择访存阶段的101b8的x15;【访存阶段前推】
- Forward2E:0x1,选择写回阶段的101b4的x14;【写回阶段前推】
- AluSrc1E、AluSrc2E:选择上面的x14,x15;
- BrType:bge类型分支,判断op1>=op2
- BrE:使能;进行跳转
预测是否跳转 | 预测是否正确 | 处理 |
---|---|---|
跳转 | 正确 | flush冲刷流水线;取跳转目标指令 |
跳转 | 不正确 | 在下一周期重新取指 |
不跳转 | 正确 | 继续正常指令 |
不跳转 | 不正确 | 在EX阶段将跳转目标写入NPC |
这里画的是最后一种情况,在EX阶段将跳转目标BrNPC写入BrT;
- 数据:
- 目标数据:101b8的x15,101b4的x14;
- 解决:通过forward:
- 通过Forward1E,将访存阶段的101b8的x15由AluoutM读到本指令的EX阶段,进行操作数选择;
- 通过Forward2E,将写回阶段的101b4的x14由写回线路读到本指令的EX阶段,进行操作数选择;
④MEM
本指令只涉及寄存器间的读取、比较;不涉及访存;
- 关键控制信号:
- LoadNPCM:无影响;因为没有写回,所以选什么数据传到WB也没用;
⑤WB
- 关键控制信号:
- RegWriteW:非使能;没有寄存器需要写回;
- MemToRegW:无影响;RegWriteW为非使能,选什么数据都无影响;
⑥数据通路
(3)分析指令lw x15, -20 x8
题目:写出该指令在流水线五个阶段(IF、ID、EX、MEM和WB)关键的控制信号(参考RISC V电路设计图),并通过分析指出数据通路。
- 指令功能:把[x8-20]地址中的值,加载到x15中;
- 汇编代码:
101a0: ff040693 addi x13 x8 -16
101a4: 97b6 c.add x15 x13
101a6: e6e7a623 sw x14 -404 x15
101aa: fec42783 lw x15 -20 x8
①IF
- 执行行为:PC值为101aa,读取该地址的指令,将指令传送到ID阶段。
- 关键控制信号:
- JalrE,JalE,BrE:均为非使能状态,因为前几条指令没有分支与跳转;
- JalrE,JalE,BrE:均为非使能状态,因为前几条指令没有分支与跳转;
②ID
-
关键控制信号:
- A1:0x8,表示x8寄存器,从寄存器组中读值,传给EX阶段;
- Immediate Operand Unit:扩展出来-20,传递给EX阶段,
-
数据:
- 目标数据:x8;
- 问题:前面流水线的指令并没有写回x8,所以我们从RegisterFile读到的x8就是想要的值,不需要再从前面指令的访存或写回阶段forward了;
③EX
-
关键控制信号:
- Forward1E:0x0,选择ID阶段从RegisterFile中读到的x8;
- Forward2E:无影响;因为后面的AluSrcE会选立即数ImmE(-20);
- AluSrc1E、AluSrc2E:选择上面的x8,立即数ImmE(-20);
- AluContrlE:ADDOP信号;执行加法操作;
-
数据:
- 目标数据:x8;
- 问题:前面流水线的指令并没有写回x8,所以我们从RegisterFile读到的x8就是想要的值,不需要再从前面指令的访存或写回阶段forward了;
④MEM
- 关键控制信号:
- LoadNPCM:无影响;因为写回WB阶段从DataMemory中读数据,不会选择ResultW;
- MemWriteM:非使能;读取数据,并不向DataMemory中写入数据;
- 数据:
- AluoutM:ALU的运算结果作为地址,从DataMemory中读Data[x8-20]的值,传递给WB阶段;
- AluoutM:ALU的运算结果作为地址,从DataMemory中读Data[x8-20]的值,传递给WB阶段;
⑤WB
- 关键控制信号:
- RegWriteW:使能;需要写回寄存器x15;
- MemToRegW:使能;表示从DataMemory中写回到RegisterFile,同时使最右边的二路选择器选择OUT;
- RdW:写回阶段的目标寄存器为0xF,即x15;
⑥数据通路
(4)分析指令sw x15, -20 x8
题目:写出该指令在流水线五个阶段(IF、ID、EX、MEM和WB)关键的控制信号(参考RISC V电路设计图),并通过分析指出数据通路。
- 指令功能:把x15中的值,加载到地址为[x8-20]的DataMemory中;
- 汇编代码:
101a6: e6e7a623 sw x14 -404 x15
101aa: fec42783 lw x15 -20 x8
101ae: 0785 c.addi x15 1
101b0: fef42623 sw x15 -20 x8
①IF
- 执行行为:PC值为101b0,读取该地址的指令,将指令传送到ID阶段。
- 关键控制信号:
- JalrE,JalE,BrE:均为非使能状态,因为前几条指令没有分支与跳转;
- JalrE,JalE,BrE:均为非使能状态,因为前几条指令没有分支与跳转;
②ID
-
关键控制信号:
- A1:0x8,表示x8寄存器,从寄存器组中读值,传给EX阶段;
- A2:0xF,表示x15寄存器,从寄存器组中读值,传给EX阶段;
- Immediate Operand Unit:扩展出来-20,传递给EX阶段;
-
数据:
- 目标数据:x8,上一条指令101ae中的x15;
- 问题:
- x8:从RegisterFile读到的x8就是想要的值;(不需forward)
- x15:本指令在EX阶段时,目标x15在访存阶段;本指令在访存阶段时,目标x15在写回阶段;(不需forward-写回阶段)
③EX
- 关键控制信号:
- Forward1E:0x0,选择ID阶段从RegisterFile中读到的x8;
- Forward2E:无影响;因为后面的AluSrcE会选立即数ImmE(-20);
- AluSrc1E、AluSrc2E:选择上面的x8,立即数ImmE(-20);
- AluContrlE:ADDOP信号;执行加法操作;
- 数据:
- 目标数据:x8,上一条指令101ae中的x15;
- 问题:
- x8:从RegisterFile读到的x8就是想要的值;
- x15:本指令在EX阶段时,目标x15在访存阶段;但此时ALU在执行(x8-20)的计算,无法读访存阶段的x15;只能放在下一阶段进行;
④MEM
- 关键控制信号:
- LoadNPCM:无影响;因为WB阶段不会写回寄存器;
- MemWriteM:使能;向DataMemory中写入数据;
- 数据:
- AluoutM:写入地址;[x8-20]
- StoreDataM:写入数据;即上一条指令写回x15的数据;
电路图中未画出StoreDataM的数据来源,应该和执行阶段的操作数选择一样,可以选择寄存器读取的值或先前指令的计算结果。
⑤WB
- 关键控制信号:
- RegWriteW:非使能;不需要写回寄存器;
⑥数据通路
(5)简述BranchE信号的作用
题目:简述BranchE信号的作用。
- 作用:表示分支条件是否为True;
- 步骤:
- 根据BrType,比较rs1和rs2的值;
- 若为True,则BrE为使能,表示需要跳转;然后NPC generator写入跳转的目标地址;
- 动态分支预测:跳转目标地址可能在ID阶段(JalNPC)就已经写入,EX阶段只是通过BrE验证预测是否正确;
预测是否跳转 | 预测是否正确 | 处理 |
---|---|---|
跳转 | 正确 | flush冲刷流水线;取跳转目标指令 |
跳转 | 不正确 | 在下一周期重新取指 |
不跳转 | 正确 | 继续正常指令 |
不跳转 | 不正确 | 在EX阶段将跳转目标写入NPC |
1.预测不跳转,且正确:
指令1/2/3在流水线中顺序执行;其中指令1是条件跳转指令;不妨设指令1的目标指令为指令7;
执行序号 | CLK1 | CLK2 | CLK3 | CLK4 | CLK5 | CLK6 | CLK7 |
---|---|---|---|---|---|---|---|
1 | IF(PC+=4) | ID(计算JalNPC) | EX(BrE=0,BrNPC=JalNPC) | MEM | WB | ||
2 | IF(PC+=4)(指令2) | ID(指令2) | EX | MEM | WB | ||
3 | IF(PC+=4)(指令3) | ID(指令3) | EX | MEM | WB | ||
4 | IF(PC+=4)(指令4) | ID | EX | MEM |
2.预测不跳转,且错误:
指令1/2/3在流水线中顺序执行;其中指令1是条件跳转指令;不妨设指令1的目标指令为指令7;
执行序号 | CLK1 | CLK2 | CLK3 | CLK4 | CLK5 | CLK6 | CLK7 |
---|---|---|---|---|---|---|---|
1 | IF(PC+=4) | ID(计算JalNPC) | EX(BrE=1,BrNPC=JalNPC) | MEM | WB | ||
2 | IF(PC+=4)(指令2) | ID(指令2) | flush | flush | flush | ||
3 | IF(PC+=4)(指令3) | flush | flush | flush | flush | ||
4 | IF(PC=BrT)(指令7) | ID | EX | MEM |
无条件跳转:
条件分支:
(6)不同跳转 target 的选择的优先级
题目:NPC Generator 中对于不同跳转 target 的选择有没有优先级?如果有,请举例并分析。如果没有,请解释原因。
- 跳转Target
- JalrT:
- 无条件跳转地址;取出rs1的值并将最低位设置为0,作为跳转地址;
- 在EX阶段计算;
- JalT:
- 无条件跳转地址;PC+Imm(offset);
- 在ID阶段计算,
- BrT:
- 分支跳转目标地址;
- 在EX阶段计算;
- PCF:PC+=4;
- 默认目标地址–下一条指令;
- 在IF阶段计算;
- JalrT:
- 使能:
- JalrE:EX阶段得到;
- JalD:ID阶段得到;
- BrE: EX阶段得到;
- BrT和JalrT的选择优先于JalT的选择
- 处于执行阶段的指令是先执行的,因此应该按照执行阶段的跳转目标地址进行跳转;
4.附加思考题
(1)需要插入气泡(NOP指令)的冲突
Harzard模块中,有哪几类冲突需要插入气泡(NOP指令),分别使流水线停顿几个周期。(提示:有三类冲突)
- 三类冲突:
- 结构冲突:由资源(memory,register,cacheMiss)冲突产生;
- 数据冲突:相邻指令对相同的数据对象读写产生的冲突
- 控制冲突:分支和跳转指令修改NPC导致的冲突
①结构冲突
解决方法:
- 存储器:使用分离的InstructionMemory和DataMemory;
- 寄存器:读写在一个时钟周期的前半和后半;
- 缓存未命中:
- 指令缓存未命中:下一条指令不能进入IF阶段
- 数据缓存未命中:下一条指令不能进入MEM阶段
- 处理:当Harzard单元接收到DCacheMiss或ICacheMiss时,需要让流水线暂停多个周期。
②数据冲突
1)三种数据冲突
- RAW:写后读
- WAR,WAW:读后写,写后写;(在顺序执行的标量处理器中不会出现)
2)RAW写后读冲突:forward解决
- 出现场景:当前指令的源操作数是先前指令的结果
- 举例:add x15 x14
c.slli x15 2
addi x14 x8 -16
c.add x15 x14
- 解决:数据前推forward–Harzard单元
- 出现场景:
- RegWrite、RegRead同时为使能状态;
- 源寄存器、写入目的寄存器相同
- 出现场景:
3)RAW写后读冲突:forward不能解决
- 举例:
lw x15 -20 x8
addi x14 x15 -16
- 解释:
- addi在EX阶段需要x15的值;
- 此时lw在MEM阶段,访问Data[x8-20],还未写回x15;
- 解决:stall暂停流水线
- 出现场景:
- MemToRegE为使能状态;
- rs寄存器、rd寄存器为同一个寄存器
- 实现结果:
- EX及之前的阶段暂停,MEM、WB阶段继续;
- 暂停一个周期,lw写回的结果就可以前推回执行周期;
- 出现场景:
(2)flush和stall信号的控制
Harzard模块中,采用静态分支预测器,即默认不跳转,遇到branch指令时,如何控制flush和stall信号?
harzard单元检测到branch指令,发出flush信号;
- 冲刷EX阶段及之前的部分;
- MEM、WB阶段继续执行,完成之前的指令。
预测未命中的情况:
- 下一条指令正常执行,在需要跳转时,后两条指令无效,写入NPC,对于IF,ID和EX,flush信号为true,冲刷流水线。不需要暂停流水线。下一周期重新取址执行新的指令
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)