一生一芯F5

实现取值功能

题目

通过多路选择器实现一个ROM, 并在其中存放数列求和的指令序列, 然后通过PC寄存器取出指令. 你需要根据你的理解来确定ROM的规格.

搭建ROM,因为sCPU的PC位宽为4,字长为8,故ROM的深度为16,宽度为8,电路如下图所示:
F5_ROM模块.png

使用一个4位寄存器作为PC寄存器,与ROM连接形成取值模块,如下图所示:
F5_取指模块.png

实现GPR及其写入功能

题目

在寄存器的基础上搭建一个RAM, 从而实现GPR的写入功能. 你需要根据你的理解来确定RAM的规格.

RAM的规格为4x*8,电路如图所示:
F5_RAM.png

实现仅支持li指令的sCPU

题目

根据上文, 用数字电路实现li的指令周期涉及的各个部件, 并将它们连接起来. 实现后, 尝试让sCPU执行数列求和程序中的前几条li指令, 并观察电路中GPR的状态是否与ISA的状态一致.

将之前构造的部件按下图的形式连接起来,其中,RAM的高位四位输入与第3位保持相同:
F5_仅支持li指令的sCPU.png

添加add指令

题目

根据上文, 在sCPU中添加add指令. 实现后, 尝试让sCPU继续执行数列求和程序中的几条add指令, 并观察电路中GPR的状态是否与ISA的状态一致.

2读1写RAM如下所示:
F5_2R1W_RAM.png

添加加法电路后,sCPU如下图所示,为了避免连线杂乱,使用了Tunnel工具
F5_add_sCPU.png

添加bner0指令

题目

根据上文, 在sCPU中添加bner0指令. 实现后, 尝试让sCPU执行完整的数列求和程序, 如果你的实现正确, 你应该能看到PC最终为7, 且在某GPR中存放求和结果55.

添加bner0指令支持后的sCPU如下图所示:
F5_li_add_benr0_sCPU.png

其中运行程序后可以观察到最后的R2寄存器存储了最后结果55(0b00110111)
F5_数列求和结果1.png

计算10以内的奇数之和

题目

编写一段指令序列, 计算10以内的奇数之和, 即1+3+5+7+9. 然后尝试用你设计的sCPU指令这段指令序列, 检查运行结果是否符合预期.
完成后, 你对计算机的"存储程序"思想有什么认识?

程序如下:

1
2
3
4
5
6
7
8
9
0: li r0, 9
1: li r1, 1
2: li r2, 0
3: li r3, 2
4: add r2, r2, r1
5: add r1, r1, r3
6: add r2, r2, r1
7: bner0 r1, 5
8: bner0 r3, 8

指令序列如下:

Code
1
2
3
4
5
6
7
8
9
10 00 1001
10 01 0001
10 10 0000
10 11 0010
00 10 10 01
00 01 01 11
00 10 10 01
11 0101 01
11 1000 11

最终R2寄存器保存的值为25(0b00011001),如下图所示:
F5_数列求和结果2.png
存储使得用户可以方便修改cpu需要执行的任务。

添加新指令

题目

尝试为sISA添加一条新指令out rs, 执行该指令后, 会将R[rs]以十六进制的形式输出到七段数码管. 你可以自行决定这条指令的编码.然后, 在sCPU中实现out指令, 并修改数列求和程序, 使得在计算出结果后, 能在七段数码管中显示计算结果.

指令格式如下:

1
2
3
4
 7  6 5  4 3   2 1   0
+----+----+-----+-----+
| 01 | xxxx | rs | out rs
+----+----+-----+-----+

我们对上一问的程序稍作修改,如下:

1
2
3
4
5
6
7
8
9
10
0: li r0, 9
1: li r1, 1
2: li r2, 0
3: li r3, 2
4: add r2, r2, r1
5: add r1, r1, r3
6: add r2, r2, r1
7: bner0 r1, 5
8: out r2 #结果存放在r2寄存器,所以我们查看r2
9: bner0 r3, 9

指令序列如下:

Code
1
2
3
4
5
6
7
8
9
10
10 00 1001
10 01 0001
10 10 0000
10 11 0010
00 10 10 01
00 01 01 11
00 10 10 01
11 0101 01
01 0000 10
11 1001 11

电路图即仿真结果如下,可以看到正确显示求和结果的16进制数0x19,即十进制的25:
F5_out_sCPU.png