系统设计Retro8的完整指令集架构(ISA),定义每条指令的编码、功能、标志位影响和执行时序。ISA是硬件和软件之间的契约——一个好的ISA让编程高效,也让硬件实现简洁。
指令集架构(Instruction Set Architecture, ISA)是CPU对外暴露的编程接口。它定义了:
ISA是计算机科学中最重要的抽象之一——同一个ISA可以有不同的硬件实现(如Intel和AMD都实现x86),同一个硬件也可以模拟不同的ISA(如QEMU)。
| 操作码 | 助记符 | 格式 | 功能 | 标志位 |
|---|---|---|---|---|
| 0x00 | NOP | 1字节 | 无操作 | — |
| 0x04 | LDI Rd, #imm | 2字节 | Rd ← imm | — |
| 0x08 | LDA Rd, [addr] | 2-3字节 | Rd ← [addr] | — |
| 0x0C | STA Rs, [addr] | 2-3字节 | [addr] ← Rs | — |
| 0x10 | MOV Rd, Rs | 1字节 | Rd ← Rs | — |
| 0x14 | LDX Rd, [Rs+X] | 2字节 | Rd ← [Rs+R3] | — |
| 0x18 | STX Rs, [Rd+X] | 2字节 | [Rd+R3] ← Rs | — |
| 0x1C | LEA Rd, addr | 2-3字节 | Rd ← addr | — |
| 操作码 | 助记符 | 格式 | 功能 | 标志位 |
|---|---|---|---|---|
| 0x20 | ADD Rd, Rs | 1字节 | Rd ← Rd + Rs | Z,N,C,V |
| 0x24 | ADC Rd, Rs | 1字节 | Rd ← Rd + Rs + C | Z,N,C,V |
| 0x28 | SUB Rd, Rs | 1字节 | Rd ← Rd - Rs | Z,N,C,V |
| 0x2C | SBC Rd, Rs | 1字节 | Rd ← Rd - Rs - C | Z,N,C,V |
| 0x30 | INC Rd | 1字节 | Rd ← Rd + 1 | Z,N,V |
| 0x34 | DEC Rd | 1字节 | Rd ← Rd - 1 | Z,N,V |
| 0x38 | CMP Rd, Rs | 1字节 | Rd - Rs (不存) | Z,N,C,V |
| 0x3C | MUL Rd, Rs | 1字节 | Rd:Rd+1 ← Rd × Rs | Z,N |
| 操作码 | 助记符 | 格式 | 功能 | 标志位 |
|---|---|---|---|---|
| 0x40 | AND Rd, Rs | 1字节 | Rd ← Rd & Rs | Z,N |
| 0x44 | OR Rd, Rs | 1字节 | Rd ← Rd | Rs | Z,N |
| 0x48 | XOR Rd, Rs | 1字节 | Rd ← Rd ^ Rs | Z,N |
| 0x4C | NOT Rd | 1字节 | Rd ← ~Rd | Z,N |
| 0x50 | SHL Rd | 1字节 | Rd ← Rd << 1 | Z,N,C |
| 0x54 | SHR Rd | 1字节 | Rd ← Rd >> 1 | Z,N,C |
| 0x58 | ROL Rd | 1字节 | Rd ← 循环左移 | Z,N,C |
| 0x5C | ROR Rd | 1字节 | Rd ← 循环右移 | Z,N,C |
| 操作码 | 助记符 | 格式 | 功能 | 标志位 |
|---|---|---|---|---|
| 0x60 | JMP addr | 3字节 | PC ← addr | — |
| 0x64 | JZ offset | 2字节 | Z=1: PC←PC+offset | — |
| 0x68 | JNZ offset | 2字节 | Z=0: PC←PC+offset | — |
| 0x6C | JC offset | 2字节 | C=1: PC←PC+offset | — |
| 0x70 | JNC offset | 2字节 | C=0: PC←PC+offset | — |
| 0x74 | JN offset | 2字节 | N=1: PC←PC+offset | — |
| 0x78 | JNN offset | 2字节 | N=0: PC←PC+offset | — |
| 0x7C | CALL addr | 3字节 | PUSH PC; PC←addr | — |
| 0x80 | RET | 1字节 | PC ← POP | — |
| 0x84 | SEI | 1字节 | I ← 1 (开中断) | I |
| 0x88 | CLI | 1字节 | I ← 0 (关中断) | I |
| 0x8C | RTI | 1字节 | POP FLAGS; POP PC | ALL |
| 操作码 | 助记符 | 格式 | 功能 | 标志位 |
|---|---|---|---|---|
| 0x90 | PUSH Rs | 1字节 | [SP]←Rs; SP-- | — |
| 0x94 | POP Rd | 1字节 | SP++; Rd←[SP] | — |
| 0x98 | PHF | 1字节 | PUSH FLAGS | — |
| 0x9C | PLF | 1字节 | POP FLAGS | ALL |
| 0xA0 | IN Rd, port | 2字节 | Rd ← IO[port] | — |
| 0xA4 | OUT Rs, port | 2字节 | IO[port] ← Rs | — |
| 0xA8 | HLT | 1字节 | 停机 | — |
| 0xAC | NMI | 1字节 | 软件中断 | — |
// ========================================
// retro8_isa.v - Retro8指令集常量定义
// ✅Verilator验证通过
// ========================================
// 数据传送指令
localparam [5:0] OP_NOP = 6'h00;
localparam [5:0] OP_LDI = 6'h01;
localparam [5:0] OP_LDA = 6'h02;
localparam [5:0] OP_STA = 6'h03;
localparam [5:0] OP_MOV = 6'h04;
localparam [5:0] OP_LDX = 6'h05;
localparam [5:0] OP_STX = 6'h06;
localparam [5:0] OP_LEA = 6'h07;
// 算术指令
localparam [5:0] OP_ADD = 6'h08;
localparam [5:0] OP_ADC = 6'h09;
localparam [5:0] OP_SUB = 6'h0A;
localparam [5:0] OP_SBC = 6'h0B;
localparam [5:0] OP_INC = 6'h0C;
localparam [5:0] OP_DEC = 6'h0D;
localparam [5:0] OP_CMP = 6'h0E;
localparam [5:0] OP_MUL = 6'h0F;
// 逻辑与移位指令
localparam [5:0] OP_AND = 6'h10;
localparam [5:0] OP_OR = 6'h11;
localparam [5:0] OP_XOR = 6'h12;
localparam [5:0] OP_NOT = 6'h13;
localparam [5:0] OP_SHL = 6'h14;
localparam [5:0] OP_SHR = 6'h15;
localparam [5:0] OP_ROL = 6'h16;
localparam [5:0] OP_ROR = 6'h17;
// 分支与控制指令
localparam [5:0] OP_JMP = 6'h18;
localparam [5:0] OP_JZ = 6'h19;
localparam [5:0] OP_JNZ = 6'h1A;
localparam [5:0] OP_JC = 6'h1B;
localparam [5:0] OP_JNC = 6'h1C;
localparam [5:0] OP_JN = 6'h1D;
localparam [5:0] OP_JNN = 6'h1E;
localparam [5:0] OP_CALL = 6'h1F;
localparam [5:0] OP_RET = 6'h20;
localparam [5:0] OP_SEI = 6'h21;
localparam [5:0] OP_CLI = 6'h22;
localparam [5:0] OP_RTI = 6'h23;
// 堆栈与I/O指令
localparam [5:0] OP_PUSH = 6'h24;
localparam [5:0] OP_POP = 6'h25;
localparam [5:0] OP_PHF = 6'h26;
localparam [5:0] OP_PLF = 6'h27;
localparam [5:0] OP_IN = 6'h28;
localparam [5:0] OP_OUT = 6'h29;
localparam [5:0] OP_HLT = 6'h2A;
localparam [5:0] OP_NMI = 6'h2B;
我们的ISA遵循正交性:每条算术/逻辑指令都可以和任何寻址模式组合。例如:
这种设计让编译器的工作更简单——不需要为特殊情况进行特殊处理。6502 ISA就缺乏正交性,很多操作只能在特定寻址模式下使用,这是它被批评最多的地方。
| 特性 | 6502 | Z80 | Retro8 |
|---|---|---|---|
| 寄存器数 | 3(A,X,Y) | 7(A,B,C,D,E,H,L) | 8(R0-R7) |
| 指令数 | 56 | 158 | 44 |
| 寻址模式 | 13 | 10 | 8 |
| 正交性 | 低 | 中 | 高 |
| 编码效率 | 高 | 中 | 中 |
将以下汇编指令手工编码为机器码:
如果要添加以下指令,设计操作码和编码格式:
用Python写一个简单的Retro8 ISA仿真器,能执行LDI、ADD、SUB、CMP、JZ、JNZ、HLT指令。不需要实现内存,用数组模拟寄存器即可。
达成条件:
奖励:你定义了硬件和软件的契约。ISA是计算机科学中最持久的接口之一——x86 ISA已经存在了40多年!