You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
6.8 KiB

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('')