简单CPU模拟器的设计与实现

一、设计内容

简单CPU模拟器的设计与实现

二、设计要求

计算机组成原理这门课程主要是告诉我们在硬件上计算机是如何工作的,如何实现我们的操作的,即让我们了解计算机的基本组成结构以及数据和命令在计算机的物理层面上如何运行的。在学习完这门课程后,我们应该能够运用该课程的基本原理和基本方法,对有关计算机硬件系统中的理论和实际问题进行计算和分析,并能对一些基本部件进行简单设计。因此在本次计算机原理设计中,我运用了所学的知识,对计算机CPU运行的过程进行了一次模拟。

1.模拟CPU基本组成

本次模拟的CPU由指令寄存器IR、数据寄存器、PC寄存器、程序状态寄存器SR、16个通用寄存器组成。指令寄存器地址总线和数据总线宽度为16位,数据总线的地址宽度为16位,数据总线的宽度为8位。指令寄存器IR、PC寄存器宽度为16位,16个通用寄存器组R0-R15, 对应的宽度为8位,对应的地址为0—15。通用寄存器、程序状态寄存器和数据存储器统一编址,通用寄存器既可以用寄存器号访问,也可以用地址空间的地址访问。

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

img

如果有参考价值麻烦采纳一下,谢谢啦!!_

// 定义CPU的寄存器和总线
var IR: 16位指令寄存器
var DR: 8位数据寄存器
var PC: 16位PC寄存器
var SR: 程序状态寄存器
var Registers: 168位通用寄存器
var AddressBus: 16位地址总线
var DataBus: 8位数据总线

// 定义指令集
var MOV = 0x01
var ADD = 0x02
var SUB = 0x03
var CMP = 0x04
var JMP = 0x05
var JZ = 0x06
var JNZ = 0x07
var LD = 0x08
var ST = 0x09

// 定义辅助函数
function readMemory(address: 16位地址) -> 8位数据 {
    AddressBus.write(address)
    DataBus.read()
    return DataBus.value
}

function writeMemory(address: 16位地址, data: 8位数据) {
    AddressBus.write(address)
    DataBus.write(data)
}

function updateFlags(value: 8位数据) {
    SR.zero = (value == 0)
    SR.negative = (value < 0)
}

// 定义主程序
while (true) {
    // 读取指令
    IR = readMemory(PC)
    PC = PC + 1

    // 解码指令并执行
    switch(IR) {
        case MOV: {
            var source: 8位数据
            var destination: 8位数据

            // 读取操作数
            source = readMemory(PC)
            PC = PC + 1
            destination = readMemory(PC)
            PC = PC + 1

            // 执行指令
            if (destination < 16) {
                Registers[destination] = source
            } else {
                writeMemory(destination, source)
            }
            break
        }
        case ADD: {
            var source: 8位数据
            var destination: 8位数据

            // 读取操作数
            source = readMemory(PC)
            PC = PC + 1
            destination = readMemory(PC)
            PC = PC + 1

            // 执行指令
            if (destination < 16) {
                Registers[destination] = Registers[destination] + source
            } else {
                var value = readMemory(destination) + source
                writeMemory(destination, value)
            }
            updateFlags(value)
            break
        }
        case SUB: {
            var source: 8位数据
            var destination: 8位数据

            // 读取操作数
            source = readMemory(PC)
            PC = PC + 1
            destination = readMemory(PC)
            PC = PC + 1

            // 执行指令
            if (destination < 16) {
                Registers[destination] = Registers[destination] - source
            } else {
                var value = readMemory(destination) - source
                writeMemory(destination, value)
            }
            updateFlags(value)
            break
        }
        case CMP: {
            var value1:8位数据
            var value2: 8位数据

            // 读取操作数
            value1 = readMemory(PC)
            PC = PC + 1
            value2 = readMemory(PC)
            PC = PC + 1

            // 执行指令
            if (value1 == value2) {
                SR.zero = true
                SR.negative = false
            } else if (value1 < value2) {
                SR.zero = false
                SR.negative = true
            } else {
                SR.zero = false
                SR.negative = false
            }
            break
        }
        case JMP: {
            var address: 16位地址

            // 读取操作数
            address = readMemory(PC)
            PC = address
            break
        }
        case JZ: {
            var address: 16位地址

            // 读取操作数
            address = readMemory(PC)
            PC = PC + 1

            // 执行指令
            if (SR.zero) {
                PC = address
            }
            break
        }
        case JNZ: {
            var address: 16位地址

            // 读取操作数
            address = readMemory(PC)
            PC = PC + 1

            // 执行指令
            if (!SR.zero) {
                PC = address
            }
            break
        }
        case LD: {
            var address: 16位地址
            var destination: 8位数据

            // 读取操作数
            address = readMemory(PC)
            PC = PC + 1
            destination = readMemory(PC)
            PC = PC + 1

            // 执行指令
            if (address < 16) {
                Registers[destination] = Registers[address]
            } else {
                var value = readMemory(address)
                Registers[destination] = value
            }
            break
        }
        case ST: {
            var source: 8位数据
            var address: 16位地址

            // 读取操作数
            source = readMemory(PC)
            PC = PC + 1
            address = readMemory(PC)
            PC = PC + 1

            // 执行指令
            if (address < 16) {
                Registers[address] = source
            } else {
                writeMemory(address, source)
            }
            break
        }
        default: {
            // 未知指令,抛出异常
            throw new Error("Unknown instruction code: " + IR)
        }
    }
}

要求使用visual studio中的C#窗体应用程序完成上述设计。

简易CPU的设计和实现
现成的,可以看看

这需求很明确了,CPU设计IR、DR、PC、SR、GR1到GR16,总线16位、程序状态寄存器和数据存储器统一编址,外加一定量的memory,把这些通过总线管理起来,一个cpu就ok了

CPU模拟器的设计需要使用到:加法指令;格式为(Add Rd , Rr),减法指令:格式为(Sub Rd , Rr),无符号乘法指令:格式为(Mul Rd, Rr),无条件相对跳转指令:格式为(RJMP K),有条件相对跳转指令:格式为(BRMI K),数据传送指令:格式为(mov Rd, Rr),载入立即数指令: 格式为(ldi Rd, K),装载指令:格式为(ld Rd, X),存储指令:格式为(st X, Rr)。
具体的操作方法和实验过程可以参考:https://blog.csdn.net/qq_39988217/article/details/81138814

将指令集、内存模型、CPU指令解码器、指令执行器等统一编址,通过总线管理起来