COLOR YOUR NIGHT

一生一芯

P3R

F阶段

A B P1 P2 N1 N2 Y
0 0 1 1 0 0 1
0 1 1 0 0 1 0
1 0 0 1 1 0 0
1 1 0 0 1 1 0

该门电路是或非门,使用6个晶体管


用其他门电路搭建或门使用晶体管数量为6+6+6+2+2=22,表达式为Y=$A\overline{B}+\overline{A}B$


化简后的异或门使用的晶体管数量为4+4+6=14,表达式为Y=$$\overline{\overline{A+B}+AB}$$,使用或非门与非门越多,晶体管越少


异或门分析

A B P1 N1 P2 N2 P3 N3 Y
0 0 1 0 1 0 1 0 0
0 1 1 0 0 1 0 1 1
1 0 0 1 1 0 1 0 1
1 1 0 1 0 1 0 1 0

同或门:$$Y=AB+\overline{A}\overline{B}=AB+\overline{A+B}=\overline{\overline{AB}(A+B)}$$


16-4 encoder

A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 Y3 Y2 Y1 Y0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1

优先编码器的套路是采用多输入的有n-1个非门输入的与门来屏蔽低位输入。


3位4选1选择器的意思是,输入和输出的位宽都是3位,可用3个并行的4选1选择器完成,它们公用一套线路

D3 D2 D1 D0 S1 S0 Y
X X X 000 0 0 000
X X 001 X 0 1 001
X 010 X X 1 0 010
011 X X X 1 1 011

full adder

Cin A B S Cout
0 0 0 0 0
0 0 1 1 0
0 1 0 1 0
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1
1 1 0 0 1
1 1 1 1 1

S=Cin^A^B; Cout=AB+Cin(A+B)


half sub

A B 差Difference 借位C
0 0 0 0
0 1 1 1
1 0 1 0
1 1 0 0

full sub

A B 来自低位的借位输入Cin D 向高位的借位输出Cout
0 0 0 0 0
0 0 1 1 1
0 1 0 1 1
0 1 1 0 1
1 0 0 1 0
1 0 1 0 0
1 1 0 0 0
1 1 1 1 1

与非门SR锁存器

$$\overline{S}$$ $$\overline{R}$$ Q
1 1 保持
1 0 0
0 1 1
0 0 禁止

D锁存器

WE D S R Q
0 0 0 0 保持
0 1 0 0 保持
1 0 0 1 0
1 1 1 0 1

F4

数列求和

1
2
3
4
5
6
7
8
0: li r0, 10   # 这里是十进制的10
1: li r1, 0
2: li r2, 0
3: li r3, 1
4: add r1, r1, r3
5: add r2, r2, r1
6: bner0 r1, 4
7: bner0 r3, 7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
PC r0 r1 r2 r3
(0, 0, 0, 0, 0) # 初始状态
(1, 10, 0, 0, 0) # 执行PC为0的指令后, r0更新为10, PC更新为下一条指令的位置
(2, 10, 0, 0, 0) # 执行PC为1的指令后, r1更新为0, PC更新为下一条指令的位置
(3, 10, 0, 0, 0) # 执行PC为2的指令后, r2更新为0, PC更新为下一条指令的位置
(4, 10, 0, 0, 1) # 执行PC为3的指令后, r3更新为1, PC更新为下一条指令的位置
(5, 10, 1, 0, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 1, 1, 1) # 执行PC为5的指令后, r2更新为r2+r1, PC更新为下一条指令的位置
(4, 10, 1, 1, 1) # 执行PC为6的指令后, 因r1不等于r0, 故PC更新为4
(5, 10 ,2, 1, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10 ,2, 3, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(4, 10, 2, 3, 1) # 执行PC为6的指令后, 因r1不等于r0, 故PC更新为4
(5, 10, 3, 3, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 3, 6, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(4, 10, 3, 6, 1) # 执行PC为6的指令后, 因r1不等于r0, 故PC更新为4
(5, 10, 4, 6, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 4, 10, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(4, 10, 4, 10, 1) # 执行PC为6的指令后,因r1不等于r0, 故PC更新为4
(5, 10, 5, 10, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 5, 15, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(4, 10, 5, 15, 1) # 执行PC为6的指令后,因r1不等于r0, 故PC更新为4
(5, 10, 6, 15, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 6, 21, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(4, 10, 6, 21, 1) # 执行PC为6的指令后,因r1不等于r0, 故PC更新为4
(5, 10, 7, 21, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 7, 28, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(4, 10, 7, 28, 1) # 执行PC为6的指令后,因r1不等于r0, 故PC更新为4
(5, 10, 8, 28, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 8, 36, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(4, 10, 8, 36, 1) # 执行PC为6的指令后,因r1不等于r0, 故PC更新为4
(5, 10, 9, 36, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 9, 45, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(4, 10, 9, 45, 1) # 执行PC为6的指令后,因r1不等于r0, 故PC更新为4
(5, 10, 10, 45, 1) # 执行PC为4的指令后, r1更新为r1+r3, PC更新为下一条指令的位置
(6, 10, 10, 55, 1) # 执行PC为5的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(7, 10, 10, 55, 1) # 执行PC为6的指令后,r1等于r0,PC更新为下一条指令的位置
(7, 10, 10, 55, 1) # 执行PC为7的指令后,因r3不等于r0,PC更新为7
此后PC一直更新为7,处理器陷入死循环,数列求和结果存在r2中

10以内奇数列求和

1
2
3
4
5
6
7
8
9
10001001    # 0: li r0, 9
10010001 # 1: li r1, 1
10100000 # 2: li r2, 0
10110010 # 3: li r3, 2
00101001 # 4: add r2, r2, r1
00010111 # 5: add r1, r1, r3
00101001 # 6: add r2, r2, r1
11010101 # 7: bner0 r1, 5
11100011 # 8: bner0 r3, 8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PC r0 r1 r2 r3
(0, 0, 0, 0, 0) # 初始状态
(1, 9, 0, 0, 0) # 执行PC为0的指令后, r0更新为9, PC更新为下一条指令的位置
(2, 9, 1, 0, 0) # 执行PC为1的指令后, r1更新为1, PC更新为下一条指令的位置
(3, 9, 1, 0, 0) # 执行PC为2的指令后, r2更新为0, PC更新为下一条指令的位置
(4, 9, 1, 0, 2) # 执行PC为3的指令后, r3更新为2, PC更新为下一条指令的位置
(5, 9, 1, 1, 2) #执行PC为4的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(6, 9, 3, 1, 2) #执行PC为5的指令后,r1更新为r1+r3,PC更新为下一条指令的位置
(7, 9, 3, 4, 2) #执行PC为6的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(5, 9, 3, 4, 2) #执行PC为7的指令后,因r1不等于r0,PC更新为5
(6, 9, 5, 4, 2) #执行PC为5的指令后,r1更新为r1+r3,PC更新为下一条指令的位置
(7, 9, 5, 9, 2) #执行PC为6的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(5, 9, 5, 9, 2) #执行PC为7的指令后,因r1不等于r0,PC更新为5
(6, 9, 7, 9, 2) #执行PC为5的指令后,r1更新为r1+r3,PC更新为下一条指令的位置
(7, 9, 7, 16, 2) #执行PC为6的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(5, 9, 7, 16, 2) #执行PC为7的指令后,因r1不等于r0,PC更新为5
(6, 9, 9, 16, 2) #执行PC为5的指令后,r1更新为r1+r3,PC更新为下一条指令的位置
(7, 9, 9, 25, 2) #执行PC为6的指令后,r2更新为r2+r1,PC更新为下一条指令的位置
(8, 9, 9, 25, 2) #执行PC为7的指令后,r1等于r0,PC更新为8
(8, 9, 9, 25, 2) #执行PC为8的指令后,因r3不等于r0,PC更新为8
#此后PC一直更新为8,处理器陷入死循环,数列求和结果存在r2中

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

/* 1 */ int main() {
/* 2 */ int sum = 0;
/* 3 */ int i = 1;
/* 4 */ do {
/* 5 */ sum = sum + i;
/* 6 */ i = i + 1;
/* 7 */ } while (i <= 10);
/* 8 */ printf("sum = %d\n", sum);
/* 9 */ return 0;
/* 10*/ }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PC sum i
(2, ?, ?) # 初始状态
(3, 0, ?) # 执行PC为2的语句后, sum更新为0, PC更新为下一条语句的位置
(5, 0, 1) # 执行PC为3的语句后, i更新为1, PC更新为下一条语句的位置(第4行无有效操作, 跳过)
(6, 1, 1) # 执行PC为5的语句后, sum更新为sum + i, PC更新为下一条语句的位置
(7, 1, 2) # 执行PC为6的语句后, i更新为i + 1, PC更新为下一条语句的位置
(5, 1, 2) # 执行PC为7的语句后, 由于循环条件i <= 10成立, 因此重新进入循环体
(6, 3, 2) # 执行PC为5的语句后, sum更新为sum + i, PC更新为下一条语句的位置
(7, 3, 3) # 执行PC为6的语句后, i更新为i + 1, PC更新为下一条语句的位置
(5, 3, 3) # 执行PC为7的语句后, 由于循环条件i <= 10成立, 因此重新进入循环体
(6, 6, 3) # 执行PC为5的语句后, sum更新为sum + i, PC更新为下一条语句的位置
(7, 6, 4) # 执行PC为6的语句后, i更新为i + 1, PC更新为下一条语句的位置
(5, 6, 4) # 执行PC为7的语句后, 由于循环条件i <= 10成立, 因此重新进入循环体
(6, 10, 4) # 执行PC为5的语句后, sum更新为sum + i, PC更新为下一条语句的位置
(7, 10, 5) # 执行PC为6的语句后, i更新为i + 1, PC更新为下一条语句的位置
(5, 10, 5) # 执行PC为7的语句后, 由于循环条件i <= 10成立, 因此重新进入循环体
(6, 15, 5) # 执行PC为5的语句后, sum更新为sum + i, PC更新为下一条语句的位置
(7, 15, 6) # 执行PC为6的语句后, i更新为i + 1, PC更新为下一条语句的位置
(8, 15, 6) # 执行PC为7的语句后, 由于循环条件i <= 10不成立, 因此跳出循环体
(9, 15, 6) # 执行PC为8的语句后, 打印sum的值,PC更新为下一条语句的位置
#执行PC为9的语句后, 程序结束运行

数列求和电路的状态

CLK B0 B1 B2 B3 A0 A1 A2 A3 A4 A5 S0 S1 S2 S3 S4 S5
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
2 0 1 0 0 1 0 0 0 0 0 1 1 0 0 0 0
3 1 1 0 0 1 1 0 0 0 0 0 1 1 0 0 0
4 0 0 1 0 0 1 1 0 0 0 0 1 0 1 0 0
5 1 0 1 0 0 1 0 1 0 0 1 1 1 1 0 0
6 0 1 1 0 1 1 1 1 0 0 1 0 1 0 1 0
7 1 1 1 0 1 0 1 0 1 0 0 0 1 1 1 0
8 0 0 0 1 0 0 1 1 1 0 0 0 1 0 0 1
9 1 0 0 1 0 0 1 0 0 1 1 0 1 1 0 1
10 0 1 0 1 1 0 1 1 0 1 1 1 1 0 1 1

F5

数列求和机器码

1
2
3
4
5
6
7
8
10001010    # 0: li r0, 10
10010000 # 1: li r1, 0
10100000 # 2: li r2, 0
10110001 # 3: li r3, 1
00010111 # 4: add r1, r1, r3
00101001 # 5: add r2, r2, r1
11010001 # 6: bner0 r1, 4
11011111 # 7: bner0 r3, 7
1
2
3
4
5
6
7
8
8a
90
a0
b1
17
29
d1
df

优化10以内奇数和指令序列

1
2
3
4
5
6
7
8
10001001    # 0: li r0, 9
10010001 # 1: li r1, 1
10100001 # 2: li r2, 1
10110010 # 3: li r3, 2
00010111 # 4: add r1, r1, r3
00101001 # 5 add r2, r2, r1
11010001 # 6: bner0 r1, 4
11011111 # 7: bner0 r3, 7
1
2
3
4
5
6
7
8
89
91
a1
b2
17
29
d1
df

已完成sCPU!


out rs指令,在七段数码管输出结果

op rs xxxx
01 10 xxxx

11100011 # 7: bner0 r3, 8

01100000 #8: out r2


F6

  1. PC寄存器的位宽是多少?

    答:32位

  2. GPR共有多少个? 每个GPR的位宽是多少?

    答:GPR共有32个,每个的位宽是32位

  3. R[0]和sISA的R[0]有什么不同之处?

    答:RV32I的R[0]通过硬连线设置为0,不可改变;sISA的R[0]可以自由设置值。

  4. 指令编码的位宽是多少? 指令有多少种基本格式?

    答:指令编码的位宽是32位,指令有R, I, S, B, U, J种基本格式。

  5. 在指令的基本格式中, 需要多少位来表示一个GPR? 为什么?

    答:需要5位来表示一个GPR,因为有32个GPR,5位二进制数可以表示32个编号。

  6. add指令的格式具体是什么?

    add rd, rs1, rs2

  7. 还有一种基础指令集称为RV32E, 它和RV32I有什么不同?

    RV32E只有16个寄存器,从x0到x15.


imm[11:0] rs1 000 rd 0010011 ADDI

addi rd, rs1, imm

addi是I-Type,它将一个立即数和rs1的内容相加后存到rd中。


已完成F阶段

视频链接https://www.bilibili.com/video/BV1pKz7BSEVc/


祝你愉快,一生一芯成员。

LOG_END // DISCONNECTED

S.Link Contacts

SOCIAL LINKS