parent
053aaf6edd
commit
cfef673b97
@ -0,0 +1,26 @@
|
|||||||
|
from hardware.hardware import Hardware
|
||||||
|
from execute.controller import Controller
|
||||||
|
from execute.debugger import Debugger
|
||||||
|
|
||||||
|
hw = Hardware()
|
||||||
|
ctrl = Controller(hw)
|
||||||
|
dbg = Debugger(hw)
|
||||||
|
prog = 'program/addiuTest.txt'
|
||||||
|
|
||||||
|
dbg.loadProgram(prog)
|
||||||
|
|
||||||
|
print('running...')
|
||||||
|
ctrl.run()
|
||||||
|
ctrl.run()
|
||||||
|
ctrl.run()
|
||||||
|
dbg.dumpGenReg()
|
||||||
|
|
||||||
|
print('running...')
|
||||||
|
ctrl.run()
|
||||||
|
ctrl.run()
|
||||||
|
ctrl.run()
|
||||||
|
dbg.dumpGenReg()
|
||||||
|
|
||||||
|
print('running...')
|
||||||
|
ctrl.run()
|
||||||
|
dbg.dumpGenReg()
|
@ -0,0 +1,27 @@
|
|||||||
|
## 已实现的指令
|
||||||
|
### 1 br型
|
||||||
|
#### 1.1 beq 相等时跳转
|
||||||
|
TODO
|
||||||
|
|
||||||
|
### 2 j型
|
||||||
|
#### 2.1 j 跳转
|
||||||
|
TODO
|
||||||
|
|
||||||
|
### 3 rr型
|
||||||
|
#### 3.1 addu 无符号加
|
||||||
|
TODO
|
||||||
|
|
||||||
|
### 4 ri型
|
||||||
|
#### 4.1 addiu 无符号加立即数
|
||||||
|
TODO
|
||||||
|
|
||||||
|
### 5 ldst型
|
||||||
|
#### 5.1 load 加载字节
|
||||||
|
TODO
|
||||||
|
|
||||||
|
#### 5.2 store 存储字节
|
||||||
|
TODO
|
||||||
|
|
||||||
|
### 6 其他
|
||||||
|
#### 6.1 nop 空指令
|
||||||
|
TODO
|
@ -0,0 +1,37 @@
|
|||||||
|
from instruction.instruction import Instruction
|
||||||
|
from hardware.hardware import Hardware
|
||||||
|
class Beq(Instruction):
|
||||||
|
def __init__(self, hw):
|
||||||
|
super().__init__(hw)
|
||||||
|
|
||||||
|
def instrDecode(self):
|
||||||
|
super().instrDecode()
|
||||||
|
instr = self.hw.pplReg[1][0].read()
|
||||||
|
mask1 = (1 << 5) - 1
|
||||||
|
rs = (instr >> 21) & mask1 # 这里的rs为base
|
||||||
|
rsData = self.hw.genReg[rs].read()
|
||||||
|
rt = (instr >> 16) & mask1
|
||||||
|
rtData = self.hw.genReg[rt].read()
|
||||||
|
mask2 = (1 << 16) - 1
|
||||||
|
offset = instr & mask2
|
||||||
|
|
||||||
|
self.hw.pplReg[2][0].write(rsData) # A <= Reg[base]
|
||||||
|
self.hw.pplReg[2][1].write(rtData) # B <= rt
|
||||||
|
self.hw.pplReg[2][2].write(offset) # C <= offset
|
||||||
|
def execute(self):
|
||||||
|
super().execute()
|
||||||
|
pc=self.hw.pc.read()
|
||||||
|
if self.hw.pplReg[2][0].read==self.hw.pplReg[2][1].read:
|
||||||
|
jpc=pc+4+self.hw.pplReg[2][2].read*4#offest后补两个0
|
||||||
|
else:
|
||||||
|
jpc=pc+4
|
||||||
|
self.hw.pplReg[3][0].write(jpc)
|
||||||
|
|
||||||
|
def memAccess(self):
|
||||||
|
super().memAccess()
|
||||||
|
|
||||||
|
Hardware.pc.write(self.hw.pplReg[3][0].read())
|
||||||
|
|
||||||
|
def writeBack(self):
|
||||||
|
super().writeBack()
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
#指令抽象类
|
||||||
|
# 一条指令的实现应当继承这个类,并重写四个方法
|
||||||
|
class Instruction:
|
||||||
|
#指令译码阶段
|
||||||
|
def instrDecode(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#运算阶段
|
||||||
|
def execute(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#访问存储器阶段
|
||||||
|
def memAccess(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#写回寄存器阶段
|
||||||
|
def writeBack(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init__(self, hw):
|
||||||
|
self.hw = hw #指令关联的硬件结构
|
||||||
|
self.stages = [
|
||||||
|
self.instrDecode,
|
||||||
|
self.execute,
|
||||||
|
self.memAccess,
|
||||||
|
self.writeBack
|
||||||
|
] #每条指令包含四个阶段
|
@ -0,0 +1,28 @@
|
|||||||
|
from instruction.instruction import Instruction
|
||||||
|
|
||||||
|
|
||||||
|
# 存取类指令
|
||||||
|
class Ldst(Instruction):
|
||||||
|
def __init__(self, hw):
|
||||||
|
super().__init__(hw)
|
||||||
|
|
||||||
|
def instrDecode(self):
|
||||||
|
super().instrDecode()
|
||||||
|
instr = self.hw.pplReg[1][0].read()
|
||||||
|
mask1 = (1 << 5) - 1
|
||||||
|
base = (instr >> 21) & mask1 # 这里的rs为base
|
||||||
|
baseData = self.hw.genReg[base].read()
|
||||||
|
rt = (instr >> 16) & mask1
|
||||||
|
mask2 = (1 << 16) - 1
|
||||||
|
offset = instr & mask2
|
||||||
|
|
||||||
|
self.hw.pplReg[2][0].write(baseData) # A <= Reg[base]
|
||||||
|
self.hw.pplReg[2][1].write(rt) # B <= rt
|
||||||
|
self.hw.pplReg[2][2].write(offset) # C <= offset
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
super().execute()
|
||||||
|
rt = self.hw.pplReg[2][1].read()
|
||||||
|
addr = self.hw.pplReg[2][0].read() + self.hw.pplReg[2][2].read() # 计算地址 = baseData+offset
|
||||||
|
self.hw.pplReg[3][0].write(addr)
|
||||||
|
self.hw.pplReg[3][1].write(rt)
|
@ -0,0 +1,20 @@
|
|||||||
|
from instruction.ldst.ldst import Ldst
|
||||||
|
|
||||||
|
|
||||||
|
class Load(Ldst):
|
||||||
|
def __init__(self, hw):
|
||||||
|
super().__init__(hw)
|
||||||
|
|
||||||
|
def memAccess(self):
|
||||||
|
super().memAccess()
|
||||||
|
addr = self.hw.pplReg[3][0].read()
|
||||||
|
memData = self.hw.dataMem.read(addr)
|
||||||
|
rt = self.hw.pplReg[3][1].read()
|
||||||
|
self.hw.pplReg[4][0].write(memData) # 取内存数据
|
||||||
|
self.hw.pplReg[4][1].write(rt)
|
||||||
|
|
||||||
|
def writeBack(self):
|
||||||
|
super().writeBack()
|
||||||
|
rt = self.hw.pplReg[4][1].read()
|
||||||
|
memData = self.hw.pplReg[4][0].read()
|
||||||
|
self.hw.genReg[rt].write(memData) # 数据写回目标寄存器
|
@ -0,0 +1,15 @@
|
|||||||
|
from instruction.ldst.ldst import Ldst
|
||||||
|
|
||||||
|
|
||||||
|
class Store(Ldst):
|
||||||
|
def __init__(self, hw):
|
||||||
|
super().__init__(hw)
|
||||||
|
|
||||||
|
def memAccess(self):
|
||||||
|
super().memAccess()
|
||||||
|
addr = self.hw.pplReg[3][0].read()
|
||||||
|
rt = self.hw.pplReg[3][1].read()
|
||||||
|
regData = self.hw.genReg[rt].read() # 取寄存器数据
|
||||||
|
self.hw.dataMem.write(addr, regData) # 写入存储器
|
||||||
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
from instruction.instruction import Instruction
|
||||||
|
|
||||||
|
#空指令
|
||||||
|
class Nop(Instruction):
|
||||||
|
#什么都不做
|
||||||
|
def instrDecode(self):
|
||||||
|
super().instrDecode()
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
super().execute()
|
||||||
|
|
||||||
|
def memAccess(self):
|
||||||
|
super().memAccess()
|
||||||
|
|
||||||
|
def writeBack(self):
|
||||||
|
super().writeBack()
|
@ -0,0 +1,16 @@
|
|||||||
|
from instruction.ri.riInstr import SignExtRegImmInstr
|
||||||
|
|
||||||
|
#无符号加立即数
|
||||||
|
class Addiu(SignExtRegImmInstr):
|
||||||
|
def execute(self):
|
||||||
|
super().execute()
|
||||||
|
|
||||||
|
op1 = self.hw.pplReg[2][0].read()
|
||||||
|
op2 = self.hw.pplReg[2][1].read()
|
||||||
|
rt = self.hw.pplReg[2][2].read()
|
||||||
|
|
||||||
|
mask = (1 << 32) - 1
|
||||||
|
res = (op1 + op2) & mask
|
||||||
|
|
||||||
|
self.hw.pplReg[3][0].write(res)
|
||||||
|
self.hw.pplReg[3][1].write(rt)
|
@ -0,0 +1,59 @@
|
|||||||
|
from instruction.instruction import Instruction
|
||||||
|
|
||||||
|
#RI类指令
|
||||||
|
class RegImmInstr(Instruction):
|
||||||
|
def instrDecode(self):
|
||||||
|
super().instrDecode()
|
||||||
|
|
||||||
|
instr = self.hw.pplReg[1][0].read()
|
||||||
|
mask = (1 << 5) - 1
|
||||||
|
|
||||||
|
rs = (instr >> 21) & mask
|
||||||
|
rsData = self.hw.genReg[rs].read()
|
||||||
|
rt = (instr >> 16) & mask
|
||||||
|
|
||||||
|
self.hw.pplReg[2][0].write(rsData)
|
||||||
|
self.hw.pplReg[2][2].write(rt)
|
||||||
|
|
||||||
|
def memAccess(self):
|
||||||
|
super().memAccess()
|
||||||
|
|
||||||
|
res = self.hw.pplReg[3][0].read()
|
||||||
|
rt = self.hw.pplReg[3][1].read()
|
||||||
|
|
||||||
|
self.hw.genReg[rt].write(res)
|
||||||
|
|
||||||
|
#进行零扩展的RI类指令
|
||||||
|
class ZeroExtRegImmInstr(RegImmInstr):
|
||||||
|
def instrDecode(self):
|
||||||
|
super().instrDecode()
|
||||||
|
|
||||||
|
instr = self.hw.pplReg[1][0].read()
|
||||||
|
mask = (1 << 16) - 1
|
||||||
|
|
||||||
|
imm = instr & mask
|
||||||
|
self.hw.pplReg[2][1].write(imm)
|
||||||
|
|
||||||
|
#进行符号扩展的RI类指令
|
||||||
|
class SignExtRegImmInstr(RegImmInstr):
|
||||||
|
#符号扩展
|
||||||
|
#输入:
|
||||||
|
# imm为16bit数据
|
||||||
|
#输出:
|
||||||
|
# imm的32bit符号扩展
|
||||||
|
def signedExtend(imm):
|
||||||
|
mask = (1 << 16) - 1 << 16
|
||||||
|
if (imm >> 15) & 1:
|
||||||
|
return imm | mask
|
||||||
|
else:
|
||||||
|
return imm
|
||||||
|
|
||||||
|
def instrDecode(self):
|
||||||
|
super().instrDecode()
|
||||||
|
|
||||||
|
instr = self.hw.pplReg[1][0].read()
|
||||||
|
mask = (1 << 16) - 1
|
||||||
|
|
||||||
|
imm = instr & mask
|
||||||
|
imm = SignExtRegImmInstr.signedExtend(imm)
|
||||||
|
self.hw.pplReg[2][1].write(imm)
|
@ -0,0 +1,50 @@
|
|||||||
|
from instruction.instruction import Instruction
|
||||||
|
#from hardware.hardware import Hardware
|
||||||
|
|
||||||
|
#RR类指令
|
||||||
|
class Addu(Instruction):
|
||||||
|
def __init__(self, hw):
|
||||||
|
super().__init__(hw)
|
||||||
|
|
||||||
|
def instrDecode(self):
|
||||||
|
super().instrDecode()
|
||||||
|
instr = self.hw.pplReg[1][0].read()
|
||||||
|
mask = (1 << 5) - 1
|
||||||
|
rs = (instr >> 21) & mask
|
||||||
|
rsData = self.hw.genReg[rs].read()
|
||||||
|
rt = (instr >> 16) & mask
|
||||||
|
rtData = self.hw.genReg[rs].read()
|
||||||
|
rd = (instr >> 11) & mask
|
||||||
|
|
||||||
|
self.hw.pplReg[2][0].write(rsData)
|
||||||
|
self.hw.pplReg[2][1].write(rtData)
|
||||||
|
self.hw.pplReg[2][3].write(rd)
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
super().execute()
|
||||||
|
|
||||||
|
op1 = self.hw.pplReg[2][0].read()
|
||||||
|
op2 = self.hw.pplReg[2][1].read()
|
||||||
|
rd = self.hw.pplReg[2][3].read()
|
||||||
|
|
||||||
|
mask = (1 << 32) - 1
|
||||||
|
res = (op1 + op2) & mask
|
||||||
|
|
||||||
|
self.hw.pplReg[3][0].write(res)
|
||||||
|
self.hw.pplReg[3][1].write(rd)
|
||||||
|
|
||||||
|
def memAccess(self):
|
||||||
|
super().memAccess()
|
||||||
|
|
||||||
|
addr = self.hw.pplReg[3][0].read()
|
||||||
|
memData = self.hw.dataMem.read(addr)
|
||||||
|
rd = self.hw.pplReg[3][1].read()
|
||||||
|
|
||||||
|
self.hw.pplReg[4][0].write(memData) # 取内存数据
|
||||||
|
self.hw.pplReg[4][1].write(rd)
|
||||||
|
|
||||||
|
def writeBack(self):
|
||||||
|
super().writeBack()
|
||||||
|
rd = self.hw.pplReg[4][1].read()
|
||||||
|
memData = self.hw.pplReg[4][0].read()
|
||||||
|
self.hw.genReg[rd].write(memData) # 数据写回目标寄存器
|
@ -0,0 +1,20 @@
|
|||||||
|
from hardware.hardware import Hardware
|
||||||
|
from execute.controller import Controller
|
||||||
|
from execute.debugger import Debugger
|
||||||
|
|
||||||
|
hw = Hardware()
|
||||||
|
ctrl = Controller(hw)
|
||||||
|
dbg = Debugger(hw)
|
||||||
|
prog = 'program/ldstTest.txt'
|
||||||
|
# Addiu r1,r1,3
|
||||||
|
# Store r1, 10(r0)
|
||||||
|
# Load r2, 10(r0)
|
||||||
|
|
||||||
|
dbg.loadProgram(prog)
|
||||||
|
|
||||||
|
ctrl.run()
|
||||||
|
ctrl.run()
|
||||||
|
ctrl.run()
|
||||||
|
dbg.dumpGenReg()
|
||||||
|
# dbg.dumpPplReg()
|
||||||
|
dbg.dumpDataMem(10)
|
@ -0,0 +1,7 @@
|
|||||||
|
24210001
|
||||||
|
24210001
|
||||||
|
24210001
|
||||||
|
2421ffff
|
||||||
|
2421ffff
|
||||||
|
2421ffff
|
||||||
|
2421ffff
|
@ -0,0 +1,3 @@
|
|||||||
|
24210003
|
||||||
|
A001000A
|
||||||
|
8002000A
|
@ -0,0 +1,3 @@
|
|||||||
|
00001000
|
||||||
|
00002000
|
||||||
|
00003000
|
@ -0,0 +1,28 @@
|
|||||||
|
from ir.ir import *
|
||||||
|
from ir.trans import ir2code
|
||||||
|
|
||||||
|
'''
|
||||||
|
beq r1, r2, out (1)
|
||||||
|
loop:
|
||||||
|
load r10, 0(r1) (2)
|
||||||
|
add r14, r10, r12 (3)
|
||||||
|
store r14, 0(r1) (4)
|
||||||
|
addi r1, r1, 1 (5)
|
||||||
|
bne r1, r2, loop (6)
|
||||||
|
out:
|
||||||
|
'''
|
||||||
|
|
||||||
|
prog = Program()
|
||||||
|
loop = Loop(1, 2)
|
||||||
|
|
||||||
|
loop.instrList.append(Beq(1, 2))
|
||||||
|
loop.instrList.append(Load(10, 0, 1))
|
||||||
|
loop.instrList.append(Add(14, 10, 12))
|
||||||
|
loop.instrList.append(Store(14, 0, 1))
|
||||||
|
loop.instrList.append(Addi(1, 1, 1))
|
||||||
|
loop.instrList.append(Bne(1, 2))
|
||||||
|
|
||||||
|
prog.instrList.append(loop)
|
||||||
|
|
||||||
|
fileName = 'program/irTest.txt'
|
||||||
|
ir2code(prog, fileName)
|
@ -0,0 +1,8 @@
|
|||||||
|
beq r1, r2, loop1
|
||||||
|
loop1:
|
||||||
|
load r10, 0(r1)
|
||||||
|
add r14, r10, 12
|
||||||
|
store r14, 0(r1)
|
||||||
|
addi r1, r1, 1
|
||||||
|
bne r1, r2, out1
|
||||||
|
out1:
|
@ -0,0 +1,95 @@
|
|||||||
|
from scoreboard import Scoreboard
|
||||||
|
|
||||||
|
class Runner:
|
||||||
|
#指令状态表项
|
||||||
|
class InstrItem:
|
||||||
|
def __init__(self):
|
||||||
|
self.issue = 0
|
||||||
|
self.read = 0
|
||||||
|
self.execute = 0
|
||||||
|
self.write = 0
|
||||||
|
|
||||||
|
#功能部件
|
||||||
|
class FuncUnit:
|
||||||
|
def __init__(self, num, execTime, instrStat, scoreboard):
|
||||||
|
self.num = num
|
||||||
|
self.execTime = execTime
|
||||||
|
self.instrStat = instrStat
|
||||||
|
self.scoreboard = scoreboard
|
||||||
|
|
||||||
|
self.clock = 0
|
||||||
|
self.localClock = 0
|
||||||
|
self.pc = 0
|
||||||
|
|
||||||
|
def issue(self, pc, clock):
|
||||||
|
self.clock = 1
|
||||||
|
self.pc = pc
|
||||||
|
instrItem = Runner.InstrItem()
|
||||||
|
instrItem.issue = clock
|
||||||
|
self.instrStat.append(instrItem)
|
||||||
|
|
||||||
|
def run(self, clock):
|
||||||
|
if self.clock == 1: #读操作数
|
||||||
|
if self.scoreboard.readControl(self.num):
|
||||||
|
self.instrStat[self.pc].read = clock
|
||||||
|
self.clock += 1
|
||||||
|
elif self.clock == 2: #执行
|
||||||
|
if self.localClock == 0: #未开始执行
|
||||||
|
if self.scoreboard.executeControl(self.num):
|
||||||
|
self.localClock = 1
|
||||||
|
else:
|
||||||
|
self.localClock += 1
|
||||||
|
|
||||||
|
if self.localClock == self.execTime:
|
||||||
|
self.localClock = 0
|
||||||
|
self.instrStat[self.pc].execute = clock
|
||||||
|
self.clock += 1
|
||||||
|
elif self.clock == 3: #写回结果
|
||||||
|
if self.scoreboard.writeControl(self.num):
|
||||||
|
self.instrStat[self.pc].write = clock
|
||||||
|
self.clock = 0
|
||||||
|
self.pc = 0
|
||||||
|
|
||||||
|
def __init__(self, program):
|
||||||
|
self.regCnt = 32
|
||||||
|
self.fuCnt = 4
|
||||||
|
self.scoreboard = Scoreboard(32, 4)
|
||||||
|
self.instrStat = []
|
||||||
|
|
||||||
|
self.clock = 0
|
||||||
|
self.fus = [
|
||||||
|
Runner.FuncUnit(0, 1, self.instrStat, self.scoreboard), #整数部件
|
||||||
|
Runner.FuncUnit(1, 10, self.instrStat, self.scoreboard), #乘法部件
|
||||||
|
Runner.FuncUnit(2, 2, self.instrStat, self.scoreboard), #加法部件
|
||||||
|
Runner.FuncUnit(3, 40, self.instrStat, self.scoreboard) #除法部件
|
||||||
|
]
|
||||||
|
|
||||||
|
self.program = program
|
||||||
|
self.pc = 0
|
||||||
|
|
||||||
|
def singleStepRun(self):
|
||||||
|
self.clock += 1
|
||||||
|
for i in range(4):
|
||||||
|
self.fus[i].run(self.clock)
|
||||||
|
if self.pc < len(self.program):
|
||||||
|
instr = self.program[self.pc]
|
||||||
|
if self.scoreboard.issueControl(instr):
|
||||||
|
self.fus[instr.fu].issue(self.pc, self.clock)
|
||||||
|
self.pc += 1
|
||||||
|
self.scoreboard.sync()
|
||||||
|
|
||||||
|
def run(self, circles):
|
||||||
|
for i in range(circles):
|
||||||
|
self.singleStepRun()
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
print('{:<10}{:<10}{:<10}{:<10}'.format('issue', 'read', 'execute', 'write'))
|
||||||
|
for item in self.instrStat:
|
||||||
|
print('{:<10}{:<10}{:<10}{:<10}'.format(
|
||||||
|
item.issue,
|
||||||
|
item.read,
|
||||||
|
item.execute,
|
||||||
|
item.write
|
||||||
|
))
|
||||||
|
print('')
|
||||||
|
self.scoreboard.dump()
|
@ -0,0 +1,236 @@
|
|||||||
|
from util import Register
|
||||||
|
|
||||||
|
#计分板
|
||||||
|
class Scoreboard:
|
||||||
|
#功能部件状态表项
|
||||||
|
class FuncUnitItem:
|
||||||
|
def __init__(self, fuCnt):
|
||||||
|
self.busy = Register(False)
|
||||||
|
self.op = Register('')
|
||||||
|
|
||||||
|
self.src1Valid = Register(False)
|
||||||
|
self.src1 = Register(0)
|
||||||
|
self.fu1 = Register(fuCnt)
|
||||||
|
self.ready1 = Register(False)
|
||||||
|
|
||||||
|
self.src2Valid = Register(False)
|
||||||
|
self.src2 = Register(0)
|
||||||
|
self.fu2 = Register(fuCnt)
|
||||||
|
self.ready2 = Register(False)
|
||||||
|
|
||||||
|
self.destValid = Register(False)
|
||||||
|
self.dest = Register(0)
|
||||||
|
|
||||||
|
#同步
|
||||||
|
def sync(self):
|
||||||
|
self.busy.sync()
|
||||||
|
self.op.sync()
|
||||||
|
self.src1Valid.sync()
|
||||||
|
self.src1.sync()
|
||||||
|
self.fu1.sync()
|
||||||
|
self.ready1.sync()
|
||||||
|
self.src2Valid.sync()
|
||||||
|
self.src2.sync()
|
||||||
|
self.fu2.sync()
|
||||||
|
self.ready2.sync()
|
||||||
|
self.destValid.sync()
|
||||||
|
self.dest.sync()
|
||||||
|
|
||||||
|
def __init__(self, regCnt, fuCnt):
|
||||||
|
self.regCnt = regCnt
|
||||||
|
self.fuCnt = fuCnt
|
||||||
|
self.regResStat = [Register(fuCnt) for i in range(regCnt)] #寄存器结果状态表
|
||||||
|
self.funcUnitStat = [Scoreboard.FuncUnitItem(fuCnt) for i in range(fuCnt)] #功能部件状态表
|
||||||
|
|
||||||
|
#同步
|
||||||
|
def sync(self):
|
||||||
|
for item in self.regResStat:
|
||||||
|
item.sync()
|
||||||
|
for item in self.funcUnitStat:
|
||||||
|
item.sync()
|
||||||
|
|
||||||
|
#检查功能部件号是否有效
|
||||||
|
#约定:功能部件号为功能部件总数表示无效
|
||||||
|
def fuValid(self, fu):
|
||||||
|
return fu < self.fuCnt
|
||||||
|
|
||||||
|
def issueControl(self, instr):
|
||||||
|
fuItem = self.funcUnitStat[instr.fu]
|
||||||
|
|
||||||
|
#检查功能部件忙碌
|
||||||
|
busy = fuItem.busy.read()
|
||||||
|
|
||||||
|
#检查写后写
|
||||||
|
waw = False
|
||||||
|
if instr.destValid:
|
||||||
|
waw |= self.fuValid(self.regResStat[instr.dest].read())
|
||||||
|
|
||||||
|
if busy or waw: #阻塞
|
||||||
|
return False
|
||||||
|
|
||||||
|
fuItem.busy.write(True) #占用功能部件
|
||||||
|
fuItem.op.write(instr.op) #记录操作
|
||||||
|
|
||||||
|
#记录操作数信息
|
||||||
|
fuItem.src1Valid.write(instr.src1Valid)
|
||||||
|
if instr.src1Valid:
|
||||||
|
fuItem.src1.write(instr.src1)
|
||||||
|
fu1 = self.regResStat[instr.src1].read()
|
||||||
|
fuItem.fu1.write(fu1)
|
||||||
|
fuItem.ready1.write(not self.fuValid(fu1))
|
||||||
|
fuItem.src2Valid.write(instr.src2Valid)
|
||||||
|
if instr.src2Valid:
|
||||||
|
fuItem.src2.write(instr.src2)
|
||||||
|
fu2 = self.regResStat[instr.src2].read()
|
||||||
|
fuItem.fu2.write(fu2)
|
||||||
|
fuItem.ready2.write(not self.fuValid(fu2))
|
||||||
|
|
||||||
|
#记录结果信息
|
||||||
|
fuItem.destValid.write(instr.destValid)
|
||||||
|
if instr.destValid:
|
||||||
|
fuItem.dest.write(instr.dest)
|
||||||
|
self.regResStat[instr.dest].write(instr.fu)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def readControl(self, fu):
|
||||||
|
fuItem = self.funcUnitStat[fu]
|
||||||
|
src1Valid = fuItem.src1Valid.read()
|
||||||
|
src2Valid = fuItem.src2Valid.read()
|
||||||
|
|
||||||
|
#检查指令未发出
|
||||||
|
unissued = not fuItem.busy.read()
|
||||||
|
|
||||||
|
#检查写后读
|
||||||
|
raw = False
|
||||||
|
if src1Valid:
|
||||||
|
raw |= not fuItem.ready1.read()
|
||||||
|
if src2Valid:
|
||||||
|
raw |= not fuItem.ready2.read()
|
||||||
|
|
||||||
|
if unissued or raw: #阻塞
|
||||||
|
return False
|
||||||
|
|
||||||
|
#操作数已读取
|
||||||
|
if src1Valid:
|
||||||
|
fuItem.fu1.write(self.fuCnt)
|
||||||
|
fuItem.ready1.write(False)
|
||||||
|
if src2Valid:
|
||||||
|
fuItem.fu2.write(self.fuCnt)
|
||||||
|
fuItem.ready2.write(False)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def executeControl(self, fu):
|
||||||
|
fuItem = self.funcUnitStat[fu]
|
||||||
|
|
||||||
|
#检查指令未发出
|
||||||
|
unissued = not fuItem.busy.read()
|
||||||
|
|
||||||
|
if unissued: #阻塞
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def writeControl(self, fu):
|
||||||
|
fuItem = self.funcUnitStat[fu]
|
||||||
|
destValid = fuItem.destValid.read()
|
||||||
|
|
||||||
|
#检查指令未发出
|
||||||
|
unissued = not fuItem.busy.read()
|
||||||
|
|
||||||
|
#检查读后写
|
||||||
|
war = False
|
||||||
|
if destValid:
|
||||||
|
dest = fuItem.dest.read()
|
||||||
|
for f in self.funcUnitStat:
|
||||||
|
if f.src1Valid.read():
|
||||||
|
war |= (f.src1.read() == dest) and f.ready1.read()
|
||||||
|
if f.src2Valid.read():
|
||||||
|
war |= (f.src2.read() == dest) and f.ready2.read()
|
||||||
|
|
||||||
|
if unissued or war: #阻塞
|
||||||
|
return False
|
||||||
|
|
||||||
|
if destValid:
|
||||||
|
#所有依赖该结果的指令可以读操作数
|
||||||
|
for f in self.funcUnitStat:
|
||||||
|
if f.src1Valid.read() and f.fu1.read() == fu:
|
||||||
|
f.ready1.write(True)
|
||||||
|
if f.src2Valid.read() and f.fu2.read() == fu:
|
||||||
|
f.ready2.write(True)
|
||||||
|
|
||||||
|
#结果已写回
|
||||||
|
self.regResStat[fuItem.dest.read()].write(self.fuCnt)
|
||||||
|
|
||||||
|
#功能部件不再被占用
|
||||||
|
fuItem.busy.write(False)
|
||||||
|
fuItem.src1Valid.write(False)
|
||||||
|
fuItem.src2Valid.write(False)
|
||||||
|
fuItem.destValid.write(False)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
#打印
|
||||||
|
def dump(self):
|
||||||
|
#打印功能部件状态表
|
||||||
|
print('{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}'.format(
|
||||||
|
'busy',
|
||||||
|
'dest',
|
||||||
|
'src1',
|
||||||
|
'src2',
|
||||||
|
'fu1',
|
||||||
|
'fu2',
|
||||||
|
'ready1',
|
||||||
|
'ready2'
|
||||||
|
))
|
||||||
|
for item in self.funcUnitStat:
|
||||||
|
busy = item.busy.read()
|
||||||
|
if item.destValid.read():
|
||||||
|
dest = item.dest.read()
|
||||||
|
else:
|
||||||
|
dest = ''
|
||||||
|
|
||||||
|
src1 = item.src1.read()
|
||||||
|
fu1 = item.fu1.read()
|
||||||
|
if not self.fuValid(fu1):
|
||||||
|
fu1 = ''
|
||||||
|
ready1 = item.ready1.read()
|
||||||
|
if not item.src1Valid.read():
|
||||||
|
src1 = ''
|
||||||
|
fu1 = ''
|
||||||
|
ready1 = ''
|
||||||
|
|
||||||
|
src2 = item.src2.read()
|
||||||
|
fu2 = item.fu2.read()
|
||||||
|
if not self.fuValid(fu2):
|
||||||
|
fu2 = ''
|
||||||
|
ready2 = item.ready2.read()
|
||||||
|
if not item.src2Valid.read():
|
||||||
|
src2 = ''
|
||||||
|
fu2 = ''
|
||||||
|
ready2 = ''
|
||||||
|
|
||||||
|
print('{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}'.format(
|
||||||
|
busy,
|
||||||
|
dest,
|
||||||
|
src1,
|
||||||
|
src2,
|
||||||
|
fu1,
|
||||||
|
fu2,
|
||||||
|
ready1,
|
||||||
|
ready2
|
||||||
|
))
|
||||||
|
print('')
|
||||||
|
|
||||||
|
#打印寄存器结果状态表
|
||||||
|
for i in range(self.regCnt):
|
||||||
|
if i % 2 == 0:
|
||||||
|
print('F{:<3}'.format(i), end = ' ')
|
||||||
|
print('')
|
||||||
|
for i in range(self.regCnt):
|
||||||
|
if i % 2 == 0:
|
||||||
|
fu = self.regResStat[i].read()
|
||||||
|
if not self.fuValid(fu):
|
||||||
|
fu = ''
|
||||||
|
print('{:<4}'.format(fu), end = ' ')
|
||||||
|
print('')
|
@ -0,0 +1,16 @@
|
|||||||
|
from run import Runner
|
||||||
|
from util import Instruction
|
||||||
|
|
||||||
|
program = []
|
||||||
|
program.append(Instruction('load', 0, True, 6, False, 0, True, 2))
|
||||||
|
program.append(Instruction('load', 0, True, 2, False, 0, True, 3))
|
||||||
|
program.append(Instruction('mult', 1, True, 0, True, 2, True, 4))
|
||||||
|
program.append(Instruction('sub', 2, True, 8, True, 6, True, 2))
|
||||||
|
program.append(Instruction('div', 3, True, 10, True, 0, True, 6))
|
||||||
|
program.append(Instruction('add', 2, True, 6, True, 8, True, 2))
|
||||||
|
|
||||||
|
runner = Runner(program)
|
||||||
|
runner.run(70)
|
||||||
|
runner.dump()
|
||||||
|
print('')
|
||||||
|
print('clk: {}'.format(runner.clock))
|
@ -0,0 +1,39 @@
|
|||||||
|
#寄存器
|
||||||
|
class Register:
|
||||||
|
def __init__(self, initValue):
|
||||||
|
self.data = initValue
|
||||||
|
self.buff = None
|
||||||
|
|
||||||
|
#读数据
|
||||||
|
#输出:
|
||||||
|
# 寄存器中的数据
|
||||||
|
def read(self):
|
||||||
|
return self.data
|
||||||
|
|
||||||
|
#写数据
|
||||||
|
#输入:
|
||||||
|
# data为写入的数据
|
||||||
|
#效果:
|
||||||
|
# 将data写入缓冲区
|
||||||
|
def write(self, data):
|
||||||
|
self.buff = data
|
||||||
|
|
||||||
|
#同步
|
||||||
|
#效果:
|
||||||
|
# 将缓冲区中的数据写入寄存器
|
||||||
|
def sync(self):
|
||||||
|
if self.buff is not None:
|
||||||
|
self.data = self.buff
|
||||||
|
self.buff = None
|
||||||
|
|
||||||
|
#指令
|
||||||
|
class Instruction:
|
||||||
|
def __init__(self, op, fu, destValid, dest, src1Valid, src1, src2Valid, src2):
|
||||||
|
self.op = op #操作
|
||||||
|
self.fu = fu #所需的功能部件
|
||||||
|
self.destValid = destValid #目的寄存器是否有效
|
||||||
|
self.dest = dest #目的寄存器号
|
||||||
|
self.src1Valid = src1Valid #源寄存器1是否有效
|
||||||
|
self.src1 = src1 #源寄存器号1
|
||||||
|
self.src2Valid = src2Valid #源寄存器2是否有效
|
||||||
|
self.src2 = src2 #源寄存器号2
|
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
# IS表中的元素
|
||||||
|
class Ins_Status:
|
||||||
|
def __init__(self):
|
||||||
|
self.issue = 'None'
|
||||||
|
self.oper = 'None'
|
||||||
|
self.comp = 'None'
|
||||||
|
self.result = 'None'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
print_str = 'issue=' + str(self.issue) + ' '
|
||||||
|
print_str += 'oper=' + str(self.oper) + ' '
|
||||||
|
print_str += 'comp=' + str(self.comp) + ' '
|
||||||
|
print_str += 'result=' + str(self.result)
|
||||||
|
return print_str
|
||||||
|
|
||||||
|
|
||||||
|
# FUS表的元素
|
||||||
|
class FU_Status:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.busy = 'No'
|
||||||
|
self.op = 'None'
|
||||||
|
self.fi = 'None'
|
||||||
|
self.fj = 'None'
|
||||||
|
self.fk = 'None'
|
||||||
|
self.qj = 'None'
|
||||||
|
self.qk = 'None'
|
||||||
|
self.rj = 'None'
|
||||||
|
self.rk = 'None'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
print_str = 'busy=' + self.busy + ' '
|
||||||
|
print_str += 'op=' + str(self.op) + ' '
|
||||||
|
print_str += 'fi=' + self.fi + ' '
|
||||||
|
print_str += 'fj=' + self.fj + ' '
|
||||||
|
print_str += 'fk=' + self.fk + ' '
|
||||||
|
print_str += 'qj=' + str(self.qj) + ' '
|
||||||
|
print_str += 'qk=' + str(self.qk) + ' '
|
||||||
|
print_str += 'rj=' + self.rj + ' '
|
||||||
|
print_str += 'rk=' + self.rk
|
||||||
|
return print_str
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.busy = 'No'
|
||||||
|
self.op = 'None'
|
||||||
|
self.fi = 'None'
|
||||||
|
self.fj = 'None'
|
||||||
|
self.fk = 'None'
|
||||||
|
self.qj = 'None'
|
||||||
|
self.qk = 'None'
|
||||||
|
self.rj = 'None'
|
||||||
|
self.rk = 'None'
|
@ -0,0 +1,130 @@
|
|||||||
|
INT_REG_SIZE = 32 #整数寄存器数
|
||||||
|
FP_REG_SIZE = 32 #浮点寄存器数
|
||||||
|
PC_REG_SIZE = 1
|
||||||
|
BUF_REG_SIZE = 6
|
||||||
|
REG_SIZE = INT_REG_SIZE + FP_REG_SIZE + PC_REG_SIZE + BUF_REG_SIZE
|
||||||
|
REG_OFF = 0
|
||||||
|
INT_REG_OFF = REG_OFF
|
||||||
|
FP_REG_OFF = INT_REG_OFF + INT_REG_SIZE
|
||||||
|
PC_REG_OFF = FP_REG_OFF + FP_REG_SIZE
|
||||||
|
BUF_REG_OFF = PC_REG_OFF + PC_REG_SIZE
|
||||||
|
|
||||||
|
INSTR_MEM_SIZE = 32
|
||||||
|
DATA_MEM_SIZE = 32
|
||||||
|
MEM_SIZE = INSTR_MEM_SIZE + DATA_MEM_SIZE
|
||||||
|
MEM_OFF = 0
|
||||||
|
INSTR_MEM_OFF = MEM_OFF
|
||||||
|
DATA_MEM_OFF = INSTR_MEM_OFF + INSTR_MEM_SIZE
|
||||||
|
|
||||||
|
FU_SIZE = 4 #功能部件数
|
||||||
|
FU_OFF = 0
|
||||||
|
INT_FU_OFF = FU_OFF
|
||||||
|
ADD_FU_OFF = INT_FU_OFF + 1
|
||||||
|
MUL_FU_OFF = ADD_FU_OFF + 1
|
||||||
|
MEM_FU_OFF = MUL_FU_OFF + 1
|
||||||
|
|
||||||
|
INT_RS_SIZE = 1
|
||||||
|
ADD_RS_SIZE = 3 #浮点加法部件保留站数量
|
||||||
|
MUL_RS_SIZE = 2 #浮点乘法部件保留站数量
|
||||||
|
MEM_RS_SIZE = BUF_REG_SIZE
|
||||||
|
RS_SIZE = INT_RS_SIZE + ADD_RS_SIZE + MUL_RS_SIZE + MEM_RS_SIZE
|
||||||
|
RS_OFF = 1
|
||||||
|
INT_RS_OFF = RS_OFF
|
||||||
|
ADD_RS_OFF = INT_RS_OFF + INT_RS_SIZE
|
||||||
|
MUL_RS_OFF = ADD_RS_OFF + ADD_RS_SIZE
|
||||||
|
MEM_RS_OFF = MUL_RS_OFF + MUL_RS_SIZE
|
||||||
|
|
||||||
|
#寄存器
|
||||||
|
class Register:
|
||||||
|
def __init__(self):
|
||||||
|
self.val = 0
|
||||||
|
self.src = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
reg = Register()
|
||||||
|
reg.val = self.val
|
||||||
|
reg.src = self.src
|
||||||
|
return reg
|
||||||
|
|
||||||
|
#功能部件
|
||||||
|
class FuncUnit:
|
||||||
|
def __init__(self):
|
||||||
|
self.clk = 0
|
||||||
|
self.op = ''
|
||||||
|
self.res = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
fu = FuncUnit()
|
||||||
|
fu.clk = self.clk
|
||||||
|
fu.op = self.op
|
||||||
|
fu.res = self.res
|
||||||
|
return fu
|
||||||
|
|
||||||
|
#保留站
|
||||||
|
class ReservStation:
|
||||||
|
def __init__(self):
|
||||||
|
self.busy = False
|
||||||
|
self.op = ''
|
||||||
|
self.val1 = 0
|
||||||
|
self.src1 = 0
|
||||||
|
self.val2 = 0
|
||||||
|
self.src2 = 0
|
||||||
|
self.addr = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
rs = ReservStation()
|
||||||
|
rs.busy = self.busy
|
||||||
|
rs.op = self.op
|
||||||
|
rs.val1 = self.val1
|
||||||
|
rs.src1 = self.src1
|
||||||
|
rs.val2 = self.val2
|
||||||
|
rs.src2 = self.src2
|
||||||
|
rs.addr = self.addr
|
||||||
|
return rs
|
||||||
|
|
||||||
|
#指令
|
||||||
|
class Instruction:
|
||||||
|
def __init__(self):
|
||||||
|
self.op = ''
|
||||||
|
self.dest = 0
|
||||||
|
self.op1 = 0
|
||||||
|
self.op2 = 0
|
||||||
|
self.imm = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
instr = Instruction()
|
||||||
|
instr.op = self.op
|
||||||
|
instr.dest = self.dest
|
||||||
|
instr.op1 = self.op1
|
||||||
|
instr.op2 = self.op2
|
||||||
|
instr.imm = self.imm
|
||||||
|
return instr
|
||||||
|
|
||||||
|
#架构
|
||||||
|
class Architecture:
|
||||||
|
def __init__(self):
|
||||||
|
self.reg = [Register() for i in range(REG_OFF + REG_SIZE)]
|
||||||
|
self.mem = [0 for i in range(MEM_OFF + MEM_SIZE)]
|
||||||
|
self.fu = [FuncUnit() for i in range(FU_OFF + FU_SIZE)]
|
||||||
|
self.rs = [ReservStation() for i in range(RS_OFF + RS_SIZE)]
|
||||||
|
self.clk = 0 #时钟
|
||||||
|
self.bus = 0 #总线
|
||||||
|
return
|
||||||
|
|
||||||
|
def copy(self):
|
||||||
|
arch = Architecture()
|
||||||
|
for i in range(REG_SIZE):
|
||||||
|
arch.reg[i] = self.reg[i].copy()
|
||||||
|
for i in range(MEM_SIZE):
|
||||||
|
arch.mem[i] = self.mem[i]
|
||||||
|
for i in range(FU_SIZE):
|
||||||
|
arch.fu[i] = self.fu[i].copy()
|
||||||
|
for i in range(RS_SIZE):
|
||||||
|
arch.rs[i] = self.rs[i].copy()
|
||||||
|
arch.clk = self.clk
|
||||||
|
arch.bus = self.bus
|
||||||
|
return arch
|
@ -0,0 +1,176 @@
|
|||||||
|
from architecture import *
|
||||||
|
|
||||||
|
def dump(arch):
|
||||||
|
dumpClk(arch)
|
||||||
|
print('')
|
||||||
|
dumpPC(arch)
|
||||||
|
print('')
|
||||||
|
dumpIntReg(arch)
|
||||||
|
print('')
|
||||||
|
dumpFpReg(arch)
|
||||||
|
print('')
|
||||||
|
dumpIntUnit(arch)
|
||||||
|
print('')
|
||||||
|
dumpAddUnit(arch)
|
||||||
|
print('')
|
||||||
|
dumpMulUnit(arch)
|
||||||
|
print('')
|
||||||
|
dumpMemUnit(arch)
|
||||||
|
print('')
|
||||||
|
dumpDataMem(arch)
|
||||||
|
return
|
||||||
|
|
||||||
|
def getInstr(op, dest, op1, op2, imm):
|
||||||
|
instr = Instruction()
|
||||||
|
instr.op = op
|
||||||
|
instr.dest = dest
|
||||||
|
instr.op1 = op1
|
||||||
|
instr.op2 = op2
|
||||||
|
instr.imm = imm
|
||||||
|
return instr
|
||||||
|
|
||||||
|
def program(arch, program):
|
||||||
|
arch1 = arch.copy()
|
||||||
|
print('{:<6}{:<6}{:<6}{:<6}{:<6}'.format(
|
||||||
|
'op',
|
||||||
|
'dest',
|
||||||
|
'op1',
|
||||||
|
'op2',
|
||||||
|
'imm'
|
||||||
|
))
|
||||||
|
for i in range(len(program)):
|
||||||
|
instr = program[i]
|
||||||
|
print('{:<6}{:<6}{:<6}{:<6}{:<6}'.format(
|
||||||
|
instr.op,
|
||||||
|
instr.dest,
|
||||||
|
instr.op1,
|
||||||
|
instr.op2,
|
||||||
|
instr.imm
|
||||||
|
))
|
||||||
|
arch1.mem[INSTR_MEM_OFF + i] = instr
|
||||||
|
return arch1
|
||||||
|
|
||||||
|
def valid(check, data):
|
||||||
|
if check:
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
def dumpClk(arch):
|
||||||
|
print('{:<6}{:<6}'.format('clk', 'bus'))
|
||||||
|
print('{:<6}{:<6}'.format(arch.clk, arch.bus))
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpPC(arch):
|
||||||
|
print('pc:\n{:<6}{:<6}'.format('value', arch.reg[PC_REG_OFF].val), end = '')
|
||||||
|
src = arch.reg[PC_REG_OFF].src
|
||||||
|
src = valid(src, src)
|
||||||
|
print('\n{:<6}{:<6}'.format('Qi', src), end = '')
|
||||||
|
print('')
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpReg(arch, offset, size):
|
||||||
|
print('{:<6}'.format(''), end = '')
|
||||||
|
for i in range(size):
|
||||||
|
print('{:<4}'.format(i), end = '')
|
||||||
|
print('\n{:<6}'.format('value'), end = '')
|
||||||
|
for i in range(size):
|
||||||
|
print('{:<4}'.format(arch.reg[offset + i].val), end = '')
|
||||||
|
print('\n{:<6}'.format('Qi'), end = '')
|
||||||
|
for i in range(size):
|
||||||
|
src = arch.reg[offset + i].src
|
||||||
|
src = valid(src, src)
|
||||||
|
print('{:<4}'.format(src), end = '')
|
||||||
|
print('')
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpIntReg(arch):
|
||||||
|
print('integer registers:')
|
||||||
|
dumpReg(arch, INT_REG_OFF, INT_REG_SIZE)
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpFpReg(arch):
|
||||||
|
print('floating point registers:')
|
||||||
|
dumpReg(arch, FP_REG_OFF, FP_REG_SIZE)
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpRS(arch, offset):
|
||||||
|
busy = arch.rs[offset].busy
|
||||||
|
op = valid(busy, arch.rs[offset].op)
|
||||||
|
val1 = valid(busy, arch.rs[offset].val1)
|
||||||
|
val2 = valid(busy, arch.rs[offset].val2)
|
||||||
|
src1 = valid(busy, arch.rs[offset].src1)
|
||||||
|
src2 = valid(busy, arch.rs[offset].src2)
|
||||||
|
addr = valid(busy, arch.rs[offset].addr)
|
||||||
|
src1 = valid(src1, src1)
|
||||||
|
src2 = valid(src2, src2)
|
||||||
|
addr = valid(addr, addr)
|
||||||
|
print('{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}'.format(
|
||||||
|
busy,
|
||||||
|
op,
|
||||||
|
val1,
|
||||||
|
val2,
|
||||||
|
src1,
|
||||||
|
src2,
|
||||||
|
addr))
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpFU(arch, fuOff, rsOff, rsSize):
|
||||||
|
print('{:<6}{:<6}{:<6}'.format('clk', 'op', 'res'))
|
||||||
|
print('{:<6}{:<6}{:<6}'.format(
|
||||||
|
arch.fu[fuOff].clk,
|
||||||
|
arch.fu[fuOff].op,
|
||||||
|
arch.fu[fuOff].res))
|
||||||
|
print('{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}'.format(
|
||||||
|
'busy',
|
||||||
|
'op',
|
||||||
|
'Vj',
|
||||||
|
'Vk',
|
||||||
|
'Qj',
|
||||||
|
'Qk',
|
||||||
|
'A'))
|
||||||
|
for i in range(rsSize):
|
||||||
|
dumpRS(arch, rsOff + i)
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpIntUnit(arch):
|
||||||
|
print('integer unit:')
|
||||||
|
dumpFU(arch, INT_FU_OFF, INT_RS_OFF, INT_RS_SIZE)
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpAddUnit(arch):
|
||||||
|
print('add unit:')
|
||||||
|
dumpFU(arch, ADD_FU_OFF, ADD_RS_OFF, ADD_RS_SIZE)
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpMulUnit(arch):
|
||||||
|
print('multiply unit:')
|
||||||
|
dumpFU(arch, MUL_FU_OFF, MUL_RS_OFF, MUL_RS_SIZE)
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpMemUnit(arch):
|
||||||
|
print('memory access unit:')
|
||||||
|
dumpFU(arch, MEM_FU_OFF, MEM_RS_OFF, MEM_RS_SIZE)
|
||||||
|
print('memory access buffer:')
|
||||||
|
print('{:<6}'.format('A'), end = '')
|
||||||
|
for i in range(BUF_REG_SIZE):
|
||||||
|
src = arch.reg[BUF_REG_OFF + i].src
|
||||||
|
addr = valid(src, arch.reg[BUF_REG_OFF + i].val)
|
||||||
|
print('{:<6}'.format(addr), end = '')
|
||||||
|
print('\n{:<6}'.format('Qi'), end = '')
|
||||||
|
for i in range(BUF_REG_SIZE):
|
||||||
|
src = arch.reg[BUF_REG_OFF + i].src
|
||||||
|
src = valid(src, src)
|
||||||
|
print('{:<6}'.format(src), end = '')
|
||||||
|
print('')
|
||||||
|
return
|
||||||
|
|
||||||
|
def dumpDataMem(arch):
|
||||||
|
print('data memory:')
|
||||||
|
for i in range(DATA_MEM_SIZE):
|
||||||
|
print('{:<4}'.format(i), end = '')
|
||||||
|
print('')
|
||||||
|
for i in range(DATA_MEM_SIZE):
|
||||||
|
print('{:<4}'.format(arch.mem[DATA_MEM_OFF + i]), end = '')
|
||||||
|
print('')
|
||||||
|
return
|
@ -0,0 +1,149 @@
|
|||||||
|
from architecture import *
|
||||||
|
|
||||||
|
#执行一个周期
|
||||||
|
def run(arch):
|
||||||
|
arch1 = Architecture()
|
||||||
|
|
||||||
|
for i in range(INSTR_MEM_SIZE):
|
||||||
|
arch1.mem[INSTR_MEM_OFF + i] = arch.mem[INSTR_MEM_OFF + i]
|
||||||
|
|
||||||
|
arch1.clk = arch.clk + 1
|
||||||
|
|
||||||
|
arch1.reg[PC_REG_OFF] = runPC(arch)
|
||||||
|
'''
|
||||||
|
for i in range(INT_REG_SIZE):
|
||||||
|
arch1.reg[INT_REG_OFF + i] = runIntReg(arch, i)
|
||||||
|
for i in range(FP_REG_SIZE):
|
||||||
|
arch1.reg[FP_REG_OFF + i] = runFpReg(arch, i)
|
||||||
|
|
||||||
|
for i in range(DATA_MEM_SIZE):
|
||||||
|
arch1.mem[DATA_MEM_OFF + i] = runMem(arch, i)
|
||||||
|
arch1.fu[INT_FU_OFF] = runIntFU(arch)
|
||||||
|
arch1.fu[ADD_FU_OFF] = runAddFU(arch)
|
||||||
|
arch1.fu[MUL_FU_OFF] = runMulFU(arch)
|
||||||
|
arch1.fu[MEM_FU_OFF] = runMemFU(arch)
|
||||||
|
|
||||||
|
arch1.rs[INT_RS_OFF] = runIntRS(arch)
|
||||||
|
for i in range(ADD_RS_SIZE):
|
||||||
|
arch1.rs[ADD_RS_OFF + i] = runAddRS(arch, i)
|
||||||
|
for i in range(MUL_RS_SIZE):
|
||||||
|
arch1.rs[MUL_RS_OFF + i] = runMulRS(arch, i)
|
||||||
|
for i in range(MEM_RS_SIZE):
|
||||||
|
arch1.rs[MEM_RS_OFF + i] = runMemRS(arch, i)
|
||||||
|
for i in range(BUF_REG_SIZE):
|
||||||
|
arch1.reg[BUF_REG_OFF + i] = runBufReg(arch, i)
|
||||||
|
|
||||||
|
arch1.bus = runBus(arch)
|
||||||
|
'''
|
||||||
|
|
||||||
|
return arch1
|
||||||
|
|
||||||
|
def runPC(arch):
|
||||||
|
pc = Register()
|
||||||
|
|
||||||
|
if issue(arch):
|
||||||
|
pc.val = arch.reg[PC_REG_OFF].val + 1
|
||||||
|
|
||||||
|
instr = fetch(arch)
|
||||||
|
if instr.op == 'jump':
|
||||||
|
pc.src = INT_RS_OFF
|
||||||
|
else:
|
||||||
|
pc.src = arch.reg[PC_REG_OFF].src
|
||||||
|
elif arch.reg[PC_REG_OFF].src and not arch.fu[INT_FU_OFF].clk:
|
||||||
|
pc.val = arch.fu[INT_FU_OFF].res
|
||||||
|
pc.src = 0
|
||||||
|
else:
|
||||||
|
pc.val = arch.reg[PC_REG_OFF].val
|
||||||
|
pc.src = arch.reg[PC_REG_OFF].src
|
||||||
|
|
||||||
|
return pc
|
||||||
|
|
||||||
|
def runIntReg(arch, i):
|
||||||
|
reg = Register()
|
||||||
|
|
||||||
|
fuOff = writeReg(arch, INT_REG_OFF + i)
|
||||||
|
if fuOff:
|
||||||
|
reg.val = arch.fu[fuOff].res
|
||||||
|
else:
|
||||||
|
reg.val = arch.reg[INT_REG_OFF + i].val
|
||||||
|
|
||||||
|
rsOff = issue(arch)
|
||||||
|
if rsOff:
|
||||||
|
instr = fetch(arch)
|
||||||
|
|
||||||
|
if instr.op == 'addi':
|
||||||
|
#TODO
|
||||||
|
|
||||||
|
def runFpReg(arch, i):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runMem(arch, i):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runIntFU(arch):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runAddFU(arch):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runMulFU(arch):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runMemFU(arch):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runIntRS(arch):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runAddRS(arch, i):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runMulRS(arch, i):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runMemRS(arch, i):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runBufReg(arch, i):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def runBus(arch, i):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def issue(arch):
|
||||||
|
if not arch.reg[PC_REG_OFF].src:
|
||||||
|
instr = fetch(arch)
|
||||||
|
if instr:
|
||||||
|
rsMap = {
|
||||||
|
'addi': (INT_RS_OFF, INT_RS_SIZE),
|
||||||
|
'jump': (INT_RS_OFF, INT_RS_SIZE),
|
||||||
|
'fadd': (ADD_RS_OFF, ADD_RS_SIZE),
|
||||||
|
'fmul': (MUL_RS_OFF, MUL_RS_SIZE),
|
||||||
|
'load': (MEM_RS_OFF, MEM_RS_SIZE),
|
||||||
|
'store': (MEM_RS_OFF, MEM_RS_SIZE)
|
||||||
|
}
|
||||||
|
offset, size = rsMap[instr.op]
|
||||||
|
return first(arch, offset, size):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def fetch(arch):
|
||||||
|
return arch.mem[INSTR_MEM_OFF + arch.reg[PC_REG_OFF].val]
|
||||||
|
|
||||||
|
def first(arch, offset, size):
|
||||||
|
for i in range(size):
|
||||||
|
if not arch.rs[offset + i].busy:
|
||||||
|
return offset + i
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def writeReg(arch, i):
|
||||||
|
src = arch.reg[i].src
|
||||||
|
if src == INT_RS_OFF:
|
||||||
|
return INT_FU_OFF
|
||||||
|
elif src >= ADD_RS_OFF and src < ADD_RS_OFF + ADD_RS_SIZE:
|
||||||
|
return ADD_FU_OFF
|
||||||
|
elif src >= MUL_RS_OFF and src < MUL_RS_OFF + MUL_RS_SIZE:
|
||||||
|
return MUL_FU_OFF
|
||||||
|
elif src >= MEM_RS_OFF and src < MEM_RS_OFF + MEM_RS_SIZE:
|
||||||
|
return MEM_FU_OFF
|
||||||
|
else:
|
||||||
|
return 0
|
@ -0,0 +1,19 @@
|
|||||||
|
from architecture import *
|
||||||
|
from debug import *
|
||||||
|
from run import run
|
||||||
|
|
||||||
|
arch = Architecture()
|
||||||
|
prog = [
|
||||||
|
getInstr('load', 0, 1, 0, 0),
|
||||||
|
getInstr('fmul', 4, 0, 2, 0),
|
||||||
|
getInstr('store', 0, 4, 1, 0),
|
||||||
|
getInstr('addi', 1, 1, 0, -8),
|
||||||
|
getInstr('jump', 0, 0, 0, -4)
|
||||||
|
]
|
||||||
|
arch = program(arch, prog)
|
||||||
|
print('')
|
||||||
|
for i in range(6):
|
||||||
|
arch = run(arch)
|
||||||
|
dumpClk(arch)
|
||||||
|
print('')
|
||||||
|
dumpPC(arch)
|
Loading…
Reference in new issue