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