目录

CPU_Liet 指令集说明

基本算术运算指令

指令 操作码 代码长度 说明
ADD 0x00 4 寄存器加法
ADDii 0xC0 4 立即数加法
ADDix 0x80 4 寄存器+立即数
ADDxi 0x40 4 立即数+寄存器
SUB 0x01 4 寄存器减法
SUBii 0xC1 4 立即数减法
SUBix 0x81 4 寄存器-立即数
SUBxi 0x41 4 立即数-寄存器

逻辑运算指令

指令 操作码 代码长度 说明
AND 0x02 4 寄存器与运算
ANDii 0xC2 4 立即数与运算
ANDix 0x82 4 寄存器&立即数
ANDxi 0x42 4 立即数&寄存器
OR 0x03 4 寄存器或运算
ORii 0xC3 4 立即数或运算
ORix 0x83 4 寄存器
ORxi 0x43 4 立即数
NOT 0x04 4 寄存器取反
NOTii 0xC4 4 立即数取反
NOTix 0x84 4 寄存器取反
NOTxi 0x44 4 立即数取反
XOR 0x05 4 寄存器异或
XORii 0xC5 4 立即数异或
XORix 0x85 4 寄存器^立即数
XORxi 0x45 4 立即数^寄存器

乘除法运算指令

指令 操作码 代码长度 说明
MUL 0x06 4 寄存器乘法
MULii 0xC6 4 立即数乘法
MULix 0x86 4 寄存器*立即数
MULxi 0x46 4 立即数*寄存器
DIV 0x07 4 寄存器除法
DIVii 0xC7 4 立即数除法
DIVix 0x87 4 寄存器/立即数
DIVxi 0x47 4 立即数/寄存器
MOD 0x10 4 寄存器取模
MODii 0xD0 4 立即数取模
MODix 0x90 4 寄存器%立即数
MODxi 0x50 4 立即数%寄存器

移位运算指令

指令 操作码 代码长度 说明
SHL 0x11 4 寄存器左移
SHLii 0xD1 4 立即数左移
SHLix 0x91 4 寄存器<<立即数
SHLxi 0x51 4 立即数<<寄存器
SHR 0x12 4 寄存器右移
SHRii 0xD2 4 立即数右移
SHRix 0x92 4 寄存器>>立即数
SHRxi 0x52 4 立即数>>寄存器

控制流指令

指令 操作码 代码长度 说明
IF_EQUAL 0x20 4 相等跳转
IF_NOT_EQUAL 0x21 4 不等跳转
IF_LESS 0x22 4 小于跳转
IF_LESS_EQUAL 0x23 4 小于等于跳转
IF_GREATER 0x24 4 大于跳转
IF_GREATER_EQUAL 0x25 4 大于等于跳转
IFDELAY 0x26 2 延时跳转

特殊指令

指令 操作码 代码长度 说明
MOV 0x40(组合指令) 3 数据传送
REG_DELAY 0xC8 2 寄存器延时
PHSH 0x13 4 压栈操作
POP 0x14 4 弹栈操作
CALL 0x16 4 函数调用
RET 0x17 4 函数返回
END 0xE0000000(组合指令) 1 程序结束

后缀指令

指令 操作码
ii 0xC0
ix 0x80
xi 0x40

指令格式说明

  1. 基本格式:

    • 操作码(1字节) + 操作数(1-3字节)
  2. 寻址模式:

    • ii: 立即数寻址
    • ix: 寄存器+立即数
    • xi: 立即数+寄存器
    • 无后缀: 寄存器寻址
  3. 代码长度说明:

    • 2字节指令:操作码 + 1字节操作数
    • 3字节指令:操作码 + 2字节操作数
    • 4字节指令:操作码 + 3字节操作数
  4. 特殊说明:

    • 所有算术和逻辑运算都支持四种寻址模式
    • 控制流指令用于条件跳转
    • REG_DELAY和IFDELAY用于延时控制
    • PHSH和POP用于栈操作
    • CALL和RET用于函数调用和返回
    • END指令标志程序结束

系统总体架构

graph TB
    subgraph "外部接口"
        CLK[时钟输入 clk]
        RST[复位输入 rst]
        IO_IN[8位并行输入 io_in]
        IO_OUT[8位并行输出 io_out]
        TX[UART串口发送 tx]
    end

    subgraph "时钟管理"
        PLL[Gowin_PLL
锁相环] end subgraph "CPU核心 - LEG顶层" LEG[LEG.v] end subgraph "CPU核心组件" PC[Program.v
程序计数器] REGS[REGS.v
寄存器文件] ALU[ALU.v
算术逻辑单元] STACK[Stack.v
硬件堆栈] end subgraph "存储资源" PROM[Gowin_pROM
256x32bit] RAM[ramREGS
64x8bit] REGFILE[regfile
7x8bit] PTRREG[pointer_reg
8x8bit] end subgraph "外设接口" UART[uart_fifo_tx] end CLK --> PLL PLL -->|系统时钟| LEG RST --> LEG IO_IN --> REGS LEG --> PC LEG --> REGS LEG --> ALU LEG --> UART PC --> PROM REGS --> RAM REGS --> REGFILE REGS --> PTRREG ALU --> STACK UART --> TX REGS -->|操作数A/B| ALU ALU -->|运算结果| REGS ALU -->|跳转控制| PC PC -->|指令| REGS

CPU数据通路

graph LR
    subgraph "取指阶段"
        PC_ADDR[程序计数器]
        PROM_MEM[程序ROM]
        INSTR[32位指令]
        PC_ADDR -->|地址| PROM_MEM
        PROM_MEM --> INSTR
    end

    subgraph "译码阶段"
        DIR[操作码 dir]
        DATA_A[操作数A]
        DATA_B[操作数B]
        ADDR[地址/立即数]
        INSTR --> DIR
        INSTR --> DATA_A
        INSTR --> DATA_B
        INSTR --> ADDR
    end

    subgraph "执行阶段"
        REGFILE_REG[寄存器组]
        ALU_CORE[ALU核心]
        RESULT[运算结果]
        SKIP[跳转信号]
        DATA_A --> REGFILE_REG
        DATA_B --> REGFILE_REG
        REGFILE_REG -->|out_a| ALU_CORE
        REGFILE_REG -->|out_b| ALU_CORE
        DIR -->|控制| ALU_CORE
        ALU_CORE --> RESULT
        ALU_CORE --> SKIP
    end

    subgraph "写回阶段"
        WRITE_BACK[写回逻辑]
        RESULT --> WRITE_BACK
        WRITE_BACK --> REGFILE_REG
    end

    subgraph "跳转控制"
        PC_UPDATE[PC更新]
        SKIP --> PC_UPDATE
        ADDR --> PC_UPDATE
        PC_UPDATE --> PC_ADDR
    end

模块接口关系

graph TB
    subgraph "LEG.v 顶层"
        LEG_IN[输入: clk, rst, io_in]
        LEG_OUT[输出: io_out, tx]
    end

    subgraph "Program.v"
        PC_IN[输入: clk, rst_n, skip, skip_data]
        PC_OUT[输出: dir, data_a, data_b, address, addr_pc]
    end

    subgraph "REGS.v"
        REGS_IN[输入: clk, skip, imm_a, imm_b, data_a/b, in, io_in, delay...]
        REGS_OUT[输出: io_out, out_a/b, skip_data, delay_reg...]
    end

    subgraph "ALU.v"
        ALU_IN[输入: dir, data_a/b, address, clk, pc, indelay_data]
        ALU_OUT[输出: out, skip, delay, POP, PHSH, func_skip, tx_en...]
    end

    subgraph "Stack.v"
        STACK_IN[输入: clk, POP, PHSH, input_Stack]
        STACK_OUT[输出: output_Stack]
    end

    LEG_IN --> PC_IN
    LEG_IN --> REGS_IN
    LEG_IN --> ALU_IN
    PC_OUT --> REGS_IN
    PC_OUT --> ALU_IN
    REGS_OUT --> ALU_IN
    REGS_OUT --> PC_IN
    ALU_OUT --> REGS_IN
    ALU_OUT --> PC_IN
    ALU_OUT --> STACK_IN
    STACK_OUT --> ALU_IN
    ALU_OUT --> UART
    UART --> LEG_OUT
    REGS_OUT --> LEG_OUT

指令执行流程

flowchart TD
    START["开始"] --> FETCH["取指: 从PROM读32位指令"]
    FETCH --> DECODE["译码: 解析dir, data_a, data_b, address"]
    DECODE --> MODE{"dir[5]模式?"}
    MODE -->|0运算| EXEC["执行ALU运算"]
    MODE -->|1判断| CMP["条件比较"]
    EXEC --> OP_TYPE{"dir[4:3]类型?"}
    OP_TYPE -->|00| BASIC["ADD/SUB/AND/OR/XOR/MUL/DIV"]
    OP_TYPE -->|01| DELAY["REG_DELAY延迟"]
    OP_TYPE -->|10| SPEC["MOD/SHL/SHR/PHSH/POP/CALL/RET"]
    OP_TYPE -->|11| UART["串口发送"]
    SPEC --> STACK_OP{"栈操作?"}
    STACK_OP -->|PHSH| PUSH["压栈"]
    STACK_OP -->|POP| POP_E["弹栈"]
    STACK_OP -->|CALL| CALL_F["保存返回地址+跳转"]
    STACK_OP -->|RET| RET_F["恢复返回地址"]
    CMP --> RESULT["比较结果"]
    RESULT --> CONDITION{"条件满足?"}
    CONDITION -->|是| SET_SKIP["skip=1"]
    CONDITION -->|否| NO_SKIP["skip=0"]
    BASIC --> WRITEBACK["写回结果到寄存器"]
    DELAY --> WRITEBACK
    PUSH --> WRITEBACK
    POP_E --> WRITEBACK
    UART --> WRITEBACK
    SET_SKIP --> PC_JUMP["更新PC跳转"]
    NO_SKIP --> PC_NEXT["PC+1"]
    CALL_F --> PC_JUMP
    RET_F --> PC_JUMP
    WRITEBACK --> PC_NEXT
    PC_JUMP --> NEXT["下一条指令"]
    PC_NEXT --> NEXT
    NEXT --> FETCH

ALU详细结构

flowchart TB
    subgraph "ALU输入"
        DIR["dir[7:0]"]
        DATA_A["data_a[7:0]"]
        DATA_B["data_b[7:0]"]
        ADDR["address[7:0]"]
    end

    MODE_SEL{"dir[5]模式"}

    subgraph "运算模式 dir[5]=0"
        OP_TYPE{"dir[4:3]类型"}
        OP_TYPE -->|00基本| BASIC{"dir[2:0]"}
        BASIC -->|000| ADD["data_a+data_b"]
        BASIC -->|001| SUB["data_a-data_b"]
        BASIC -->|010| AND["data_a&data_b"]
        BASIC -->|011| OR["data_a|data_b"]
        BASIC -->|100| NOT["~data_a"]
        BASIC -->|101| XOR["data_a^data_b"]
        BASIC -->|110| MUL["data_a*data_b"]
        BASIC -->|111| DIV["data_a/data_b"]
        OP_TYPE -->|01延迟| DELAY["REG_DELAY"]
        OP_TYPE -->|10特殊| SPEC{"dir[2:0]"}
        SPEC -->|000| MOD["data_a%data_b"]
        SPEC -->|001| SHL["data_a<|010| SHR["data_a>>data_b"]
        SPEC -->|011| PHSH["压栈PHSH=1"]
        SPEC -->|100| POP["弹栈POP=1"]
        SPEC -->|101| CALL["函数调用"]
        SPEC -->|111| RET["函数返回"]
        OP_TYPE -->|11UART| TX["UART发送tx_en=1"]
    end

    subgraph "判断模式 dir[5]=1"
        CMP_TYPE{"dir[2:0]比较"}
        CMP_TYPE -->|000| EQ["data_a==data_b"]
        CMP_TYPE -->|001| NE["data_a!=data_b"]
        CMP_TYPE -->|010| LT["data_a|011| LE["data_a<=data_b"]
        CMP_TYPE -->|100| GT["data_a>data_b"]
        CMP_TYPE -->|101| GE["data_a>=data_b"]
        CMP_TYPE -->|110| DELAY_CHK["indelay_data>0"]
    end

    DIR --> MODE_SEL
    DATA_A --> MODE_SEL
    DATA_B --> MODE_SEL
    MODE_SEL -->|0| OP_TYPE
    MODE_SEL -->|1| CMP_TYPE
    ADD --> OUT["out[7:0]"]
    SUB --> OUT
    AND --> OUT
    OR --> OUT
    NOT --> OUT
    XOR --> OUT
    MUL --> OUT
    DIV --> OUT
    MOD --> OUT
    SHL --> OUT
    SHR --> OUT
    EQ --> SKIP["skip信号"]
    NE --> SKIP
    LT --> SKIP
    LE --> SKIP
    GT --> SKIP
    GE --> SKIP
    DELAY_CHK --> SKIP
    CALL --> FUNC["func_skip,skipfunc"]
    RET --> FUNC
    PHSH --> STACK_CTRL["PHSH,POP信号"]
    POP --> STACK_CTRL
    DELAY --> DELAY_OUT["delay,delay_data"]
    TX --> UART_OUT["tx_en,txout"]

堆栈操作时序

sequenceDiagram
    participant CPU as CPU核心
    participant ALU as ALU
    participant STACK as Stack
    participant REGS as REGS
    Note over CPU, REGS: CALL指令执行
    CPU ->> ALU: CALL指令 dir=0xD6
    ALU ->> ALU: 计算PC+1
    ALU ->> STACK: PHSH=1, 压入(PC+1,程序页)
    STACK ->> STACK: stack_pointer++
    ALU ->> REGS: skip=1
    REGS ->> CPU: 跳转到函数地址
    Note over CPU, REGS: 函数执行中...
    CPU ->> CPU: 执行函数体
    Note over CPU, REGS: RET指令执行
    CPU ->> ALU: RET指令 dir=0xD7
    ALU ->> STACK: POP=1
    STACK ->> ALU: 返回地址
    ALU ->> REGS: func_skip=1, skip=1
    REGS ->> CPU: 返回调用地址

存储层次结构

graph TB
    subgraph "L1: 寄存器级 最快"
        L1_REG[通用寄存器 7x8bit]
        L1_PTR[指针寄存器 8x8bit]
    end

    subgraph "L2: 片上RAM 快速"
        L2_RAM[数据RAM 64x8bit]
        L2_DELAY[延迟寄存器 24bit]
    end

    subgraph "L3: 堆栈 中等"
        L3_STACK[堆栈 256x16bit]
    end

    subgraph "L4: 程序ROM"
        L4_PROM[程序ROM 256x32bit]
    end

    subgraph "L5: 外部IO 最慢"
        L5_IO[并行IO 8bit]
        L5_UART[UART串口]
    end

    CPU[CPU核心] <--> L1_REG
    CPU <--> L1_PTR
    L1_PTR <--> L2_RAM
    CPU <--> L2_DELAY
    CPU <--> L3_STACK
    CPU <--> L4_PROM
    CPU <--> L5_IO
    CPU --> L5_UART

指令编码结构

graph TB
    subgraph "32位指令格式"
        B31_24[31:24 操作码dir]
        B23_16[23:16 操作数A]
        B15_8[15:8 操作数B]
        B7_0[7:0 地址/立即数]
    end

    subgraph "操作码dir[7:0]结构"
        D7[bit7: imm_a标志]
        D6[bit6: imm_b标志]
        D5[bit5: 0=运算 1=判断]
        D4_3[bit4-3: 运算类型]
        D2_0[bit2-0: 具体操作]
    end

    32位指令 --> B31_24
    32位指令 --> B23_16
    32位指令 --> B15_8
    32位指令 --> B7_0
    B31_24 --> D7
    B31_24 --> D6
    B31_24 --> D5
    B31_24 --> D4_3
    B31_24 --> D2_0
    D5 -->|0| ALU_OP[运算模式]
    D5 -->|1| CMP_OP[判断模式]
    D4_3 -->|00| BASIC[ADD/SUB/AND/OR/MUL/DIV]
    D4_3 -->|01| DELAY_C[REG_DELAY]
    D4_3 -->|10| SPEC_C[MOD/SHL/SHR/PHSH/POP/CALL/RET]
    D4_3 -->|11| UART_C[UART发送]

技术规格

项目 规格
数据宽度 8位
地址空间 256字节
指令长度 32位固定
通用寄存器 7个
指针寄存器 8个
数据RAM 64字节
硬件堆栈 256层×16位
程序ROM 256条指令
目标器件 GW5AST-LV138PG484
IO标准 LVCMOS33 3.3V
关于

简单处理器

117.6 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802032778号