Table of Contents
题目
这是关于 2024 春哈工大计组大作业的记录. 今年的题目是
题目并不困难, 而且也很自由, 虽然只占五分, 但如果认真做了, 还是会有收获的.
设计相当自由, 实现哪些指令, 控制器设计方法, 都可以自行决定. 据老师说, 其实大作业不是要处理器有多高的效率, 哪怕全是照书上做的, 也没有关系, 重在参与, 能把整个过程顺下来即可.
不知道大多数同学选择了什么方法. 由于 MIPS 指令集太流行了, 相关资源俯拾皆是, 有无数种现成的方法, 不局限于课上讲的, 任课老师说这样反而更好. 笔者是照谭志虎老师书里自动机和组合逻辑的方法设计的多周期处理器.
设计
设计几乎没有难度, 因为书上都有, 不只有方法, 连过程和结果都有. David Money Harris 的《数字逻辑和计算机体系结构》里, 甚至连 vhdl 和 verilog 的代码都给出来了.
我没有做微程序设计, 不知道其中辛酸, 但是做组合逻辑设计, 化简可能比较麻烦. 众所周知, 逻辑表达式化简是一个 NP-难问题, 因为一个不可满足的表达式必定化简为 false
, 这就解决了 SAT. 事实上这个问题甚至不在 NP 内. 因此, 如果你用到的输入信号少, 那可以画卡诺图, 或者有很多网站可以为你代劳. 笔者使用的是这个网站: http://www.32x8.com/index.html
如果多了, 比如说十来个, 那老天爷来也没有办法, 比如说
ALUCon(2:0) | 指令 | OP | funct |
000 | add | 000000 | 100000 |
000 | addi | 001000 | XXXXXX |
000 | lw | 100011 | XXXXXX |
就不要奢求最简, 写出来就得了. 非要化简, 也不要勉强自己, 有启发式的算法可以近似化简, 或者化到最简. 就笔者 16 个输入信号的例子而言, 可以立刻就出结果. 当然也没去验证它化出来的就是最简的, 希望是吧.
软件的名字叫 Espresso
, 命令格式: espresso -o eqntott (textfile)
. 如果想让它化到最简, 再加上 -Dexact
即可, 即 espresso -Dexact -o eqntott (textfile)
.
(textfile)
是一个文件, 这个文件怎么写? 简单说, 这么写, 对应的就是上面那个表.
# 输入数量, 如果乐意的话可以给输入起名, 否则默认叫v1, v2...
.i 12
# 如果起名, 加一行 .ilb 名 名 名 名
# 输出数量
.o 3
# 可以给输出起名
.ob s2 s1 s0
# 真值表, dont care用 - 表示
000000100000 000
001000------ 000
100011------ 000
......
# 可以显式标识EOF, 也可以不标
.e
默认输出到 stdout.
简单的文档:
http://bear.ces.cwru.edu/eecs_cad/man_octtools_espresso_inputs.html
实现与仿真
如果有同学想要去实现并仿真, 笔者也有一点点经验.
最正统的方法当然是用硬件描述语言 (VHDL, Verilog, …) 去做, 网上现成的实现很多, 书上也有.
如果想直观一些, 用 EDA 软件也可以, 比如 vivado? 有点杀鸡用牛刀的意思.
想要给生活增添趣味的同学可以用 oregano, 中文翻译叫牛至, 用牛至完成大作业多是一件美事.
可惜数字逻辑课 vivado 快给笔者整出 ptsd 了, 其实如果装了这只 200GB 的巨兽, 使用 vivado 大概会更方便一些.
另外如果你打算烧到板子上, 后面的几种方法或许不能直接做到.
有同学用《图灵完备》, 一个游戏去做, 似乎也可行. 笔者并不了解, 据评论区还有导出 verilog 的功能. 如果买了游戏的同学或许可以试试? 这是视频链接: https://www.bilibili.com/video/BV1xgTRegEiM
谭志虎老师的书后习题有的会用到 logisim, 这是一个教学软件. 谭志虎老师还有一个 gitee repository, https://gitee.com/totalcontrol/hustzc, 照着配置大概不难, 网上可参考的也很多.
logisim 本身已经停止开发了, 但还有一些 fork 还在开发. 笔者用的是 logisim-evolved, 不仅能够导出 verilog/VHDL, 也可以作为元件导入 verilog/VHDL, 前提是安装 modelsim, 大小 ’仅’ 4GB, 而且免费版的模拟速度相当不堪, 笔者的破笔记本上大概一秒只有二三拍. 其实有大小就不到 100MB 的开源替代 ghdl, 可惜 logisim 不支持. 对于英文苦手的同学, 软件有中文翻译, 质量尚可.
软件本身提供了加法器, 移位器, 比较器, 寄存器, RAM, ROM 等等元件, 可以说除了 CU 和 ALU, 其他都是现成的; 还可以自己放一些开关, 按钮, 灯或数码管来交互, 模拟过程中随时可以重新连线或者更改某个管脚的值, ram/rom/寄存器的值可以直接看到, 也可以随时修改. 这种交互性是类似的教学软件的强项, 笔者认为还是比较适合初学者的. 用软件还有一个好处, 就是可以画框图. 下面是一个实例:
![drawing](https://img-blog.csdnimg.cn/direct/4e1cd0d5137e43429aaa5e36809736ca.png#pic_center)
应用的界面还是相当直观的.
-
手形工具 (✋) 可以同元件交互, 比如拨时钟或者改管脚, 开关的值.
-
光标工具是用来编辑和修改连线的. 没啥好说的, 用一用就弄明白了. 中键拖拽可以移动视野, 中键单击的话和手形工具一样.
-
A 可以加文字, 起到注释的作用.
连线没啥说的, 注意的是如果线与元件伸出的管脚交叉就会自动连在上面, 布线的时候要注意.
如果有线宽不兼容的, 比如想取指令的 OP 部分 inst[31…26], 那就要用到分离器 splitter. 拖拽可以多选, ctrl 可以合并选.
- 左侧的加号可以添加电路
- VHDL 可以新建 VHDL 元件.
VHDL
关于 VHDL 元件, 笔者本来是因为犯懒, 想着 ALU, 自动机这些东西抄网上现成的就完了, 后来发现还是太天真了… 或许修改的成本没比自己写一个小多少.
首先配置环境, 先安装 modelsim, 然后填入对应路径即可, 安装位置不同路径就不同. 建议把第一个勾打上, 这样之后 validate VHDL 通过后一般仿真时就不会报错了.
如果实在配置不来, 那就不要勉强了, 老老实实用自带元件连线也不难.
点击 VHDL 那个按钮后, 会进入这个界面, ↓可以导入, ↑可以导出, ✅是验证/validate VHDL, 记得每次编辑完都要点击这个按钮.
VHDL 是一门类型严格的语言. 笔者半懂不懂, 下面是一些可能用到的语句:
运算: std_logic_vector
之间可以做 and, or 之类逻辑运算, 但不能做算术运算, 需要做类型转换, 比如想写有符号 SrcA + SrcB
, 就得写成
std_logic_vector(signed(SrcA) + signed(SrcB))
移位 SrcB << SrcA
运算:
std_logic_vector(
shift_left(
unsigned(SrcB),
natural(to_integer(unsigned(SrcA)))));
其他一些常用语法:
-- 起手
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- entity
entity <name> is
port (
A : in sth;
B : in sth;
C : out sth;
-- 最后一个不加分号!
D : out sth
-- 分号在这
);
end <name>;
-- if else
if <condition> then ...
elsif <condition> then ...
else ...
end if;
-- case when
case <signal> is
when <value> => ...;
when <value> => ...;
...;
when others => ...;
-- with select
with <signal> select
<out> <= ... when <value>,
... when <value>,
...,
... when others;
使用条件判断时候, 必须覆盖所有情况, 或者说必须有 else 或 others 那条语句才行.
下面只要按照书上的介绍接好线, 编好元件就可以仿真了!
写并运行程序
完成最后一步, 看着自己弄的依托神奇地跑起来, 还是很让人有满足感的. 虽然我们的设计十分简陋, 但是如果你选的指令不是太少, 也足够完成多数工作了! 事实上, 有编译器可以只使用 X86 的 MOV
指令编译 C89 程序. movfuscator 可惜我们没有 MOV
指令, 只好自己写汇编了, 好不好写这要看选的指令. 有加法 add, addi
; 条件跳转 beq
, 小于置数 slt
就能做很多事了, 至少排序没问题. 笔者写的汇编程序一塌糊涂, 就不献丑了.
在 https://alanhogan.com/asu/assembler.php 上进行汇编得到二进制机器码, 手动录入指令存储器. 注意网站生成的地址从 00400000 起始, 因此对于那些跳到绝对地址的 J 型指令, 需要手动修改. 改也非常简单, 笔者只设计了一条 J 型指令, 所以把形如 081...
这样的指令改成 080...
就完事了. 编辑 rom 内容就可以运行你的汇编程序了 — 按每秒 3 拍的速度.
图穷匕见
当然, 如果你觉得以上的都太麻烦了, 还可以使用 PPT. 请欣赏:
https://www.youtube.com/watch?v=LArkm4v5mWA
搬运:
[Tom Wildenhain] 精简指令集的PPT实现
![screenshot](https://img-blog.csdnimg.cn/direct/4523dd261f9044ef91fa03c6c8eacd0c.png)