本程序在上一个tomasulo算法的基础上添加了btb分支预测
代码实现如下
# RISC-V
# 小端模式
# 硬件
Hardware = {
# tag:还剩多久执行完毕; busy:0空闲,1不空闲; op:'lw' 'sw' 'mul' 'addi' 'bne'五条指令
# 'addi'指令:'imm'用来存立即数
# s1_vj和s2_vk:直接存数; rs_qj和rs_qk:存 'load1' 'mult2' 'add3'等
# rs_qj和rs_qk:如果有数据,不需要指针,则这两个指针置为数字0
# 寄存器中,如果有结果直接存数,如果是指针,则同rs_qj和rs_qk存 'load1' 'mult2' 'add3'等
# isinstance()函数可以判断数据类型是不是指定类型,例如isinstance(Hardware['load1']['busy'],int)==True/False
'load1': {
'tag': 0,
'busy': 0,
'address': 0,
'data': 0,
'op' : 0
},
'load2': {
'tag': 0,
'busy': 0,
'address': 0,
'data': 0,
'op' : 0
},
'load3': {
'tag': 0,
'busy': 0,
'address': 0,
'data': 0,
'op' : 0
},
'store1': {
'tag': 0,
'busy': 0,
'address': 0,
'data': 0,
's1_vj': 0,
'rs_qj': 0,
'op' : 0
},
'store2': {
'tag': 0,
'busy': 0,
'address': 0,
'data': 0,
's1_vj': 0,
'rs_qj': 0,
'op' : 0
},
'store3': {
'tag': 0,
'busy': 0,
'address': 0,
'data': 0,
's1_vj': 0,
'rs_qj': 0,
'op' : 0
},
'add1': {
'tag': 0,
'busy': 0,
'op': 0,
's1_vj': 0,
's2_vk': 0,
'rs_qj': 0,
'rs_qk': 0,
'imm': 0,
'data': 0
},
'add2': {
'tag': 0,
'busy': 0,
'op': 0,
's1_vj': 0,
's2_vk': 0,
'rs_qj': 0,
'rs_qk': 0,
'imm': 0,
'data': 0
},
'add3': {
'tag': 0,
'busy': 0,
'op': 0,
's1_vj': 0,
's2_vk': 0,
'rs_qj': 0,
'rs_qk': 0,
'imm': 0,
'data': 0
},
'mult1': {
'tag': 0,
'busy': 0,
'op': 0,
's1_vj': 0,
's2_vk': 0,
'rs_qj': 0,
'rs_qk': 0,
'data': 0
},
'mult2': {
'tag': 0,
'busy': 0,
'op': 0,
's1_vj': 0,
's2_vk': 0,
'rs_qj': 0,
'rs_qk': 0,
'data': 0
}
}
# 调用方式
# Hardware['load1']['busy']='6'
# print(Hardware['load1']['busy'])
# print(isinstance(Hardware['load1']['busy'],int))
'''for key in Hardware:
print(Hardware[key]['tag'])
pass'''
# 寄存器类
X_ = 0x00000033
Register = {
0b00000: 0x00000000,
0b00001: 0x00000000,
0b00010: 0x00000008,
0b00011: 0x00000000,
0b00100: 0x00000000,
0b00101: 0x00000000,
0b00110: 0x00000000,
0b00111: 0x00000000,
0b01000: 0x00000000,
0b01001: 0x00000000,
0b01010: 0x00000000,
0b01011: 0x00000000,
0b01100: 0x00000000,
0b01101: 0x00000000,
0b01110: 0x00000000,
0b01111: 0x00000000,
0b10000: 0x00000000,
0b10001: 0x00000000,
0b10010: 0x00000000,
0b10011: 0x00000000,
0b10100: 0x00000000,
0b10101: 0x00000000,
0b10110: 0x00000000,
0b10111: 0x00000000,
0b11000: 0x00000000,
0b11001: 0x00000000,
0b11010: 0x00000000,
0b11011: 0x00000000,
0b11100: 0x00000000,
0b11101: 0x00000000,
0b11110: 0x00000000,
0b11111: 0x00000000
}
pc = 0x00000000
'''Register[0]=0
if(isinstance(Register[0],str)):
print(type(Register[0]),'class')
print('ss')
elif(isinstance(Register[0],int)):
print(type(Register[0]), 'int')
print('ii')'''
# 储存器类
Memory = {
0x00000000: 0x00
}
# 控制BTB的执行
BTB={
0x00000000:[0x00000000,0,0], #PC:[PC_predict,tag1,tag2];tag1为第一次判断结果(yes:1/no:0),tag2为第二次判断结果
}
PC_Control = [0,0,0,0]#[PC,PC_IF,PC_ID,PC_EX],分阶段存下该阶段所执行指令对应的PC值
# 初始化内存,大小为16KB
def init_Mem():
for i in range(2 ** 14):
Memory[0x00000000 + i] = 0x00
# *****************Tomasulo**************
def Refresh(a): # 如果得到了某个数据,则利用这个函数,刷新需要这个数据的所有buffer和寄存器
a1 = list(a)
a1.pop()
a1 = ''.join(a1)
if a1 == 'store':
Memory[Hardware[a]['address']] = Hardware[a]['data']
return
for key in Register: # 刷新寄存器
if Register[key] == a:
Register[key] = Hardware[a]['data']
pass
pass
for key in Hardware: # 刷新buffer
key1 = list(key)
key1.pop()
key1 = ''.join(key1)
if key1 == 'load':
continue
if key1 == 'store':
if Hardware[key]['rs_qj'] == a:
Hardware[key]['s1_vj'] = Hardware[a]['data']
Hardware[key]['rs_qj'] = 0
Hardware[key]['tag'] = 2
continue
if Hardware[key]['rs_qj'] == a or Hardware[key]['rs_qk'] == a:
if Hardware[key]['rs_qj'] == a:
Hardware[key]['s1_vj'] = Hardware[a]['data']
Hardware[key]['rs_qj'] = 0
if Hardware[key]['rs_qk'] == a:
Hardware[key]['s2_vk'] = Hardware[a]['data']
Hardware[key]['rs_qk'] = 0
if Hardware[key]['rs_qj'] == 0 and Hardware[key]['rs_qk'] == 0: # 所需数据准备完毕,则进入执行阶段
if Hardware[key]['op'] == 'addi' or Hardware[key]['op'] == 'bne':
Hardware[key]['tag'] = 2
elif Hardware[key]['op'] == 'mul':
Hardware[key]['tag'] = 10
pass
pass
pass
IF_Found = False
ID_Branch = False
def IF():
global IF_Found
# IF阶段
# 第一次判断,PC_Control是否在BTB中
global pc
if pc== 64:
print(pc)
PC_Control[0] = pc
# PC_Control[0] = PC_Control[0] + 1 # PC_Control[0]表示PC_Control值
PC_Control[1] = PC_Control[0] + 1 # PC_Control_IF,IF阶段的PC_Control
if PC_Control[0] in BTB:
#BTB[PC_Control[1]][1] = 1
IF_Found = True
else:
#BTB[PC_Control[0]] = [0, 0, 0] # 如果没有命中BTB,插入一条item方便后续操作
IF_Found = False
pass
def ID():
global IF_Found
global ID_Branch
global BTB
# ID阶段
PC_Control[2] = PC_Control[1] # PC_Control_ID,ID阶段指令对应的PC_Control
#opcode = Memory[PC_Control[0]] & 0b1111111
instru = 0x00000000
for i in range(4):
instru += Memory[PC_Control[0] + i] * (256 ** i)
opcode = instru & 0b1111111
if (IF_Found == False):
if opcode == 0b1100011: # 如果是分支指令
#这里需要知道当前正在执行的指令的下一条语句,稍后处理这一段
ID_Branch = True
# BTB[PC_Control[0]] = [48,1,0]
else:
ID_Branch = False
return
else:
pass
"""
if BTB[PC_Control[2]][1] == 1 and BTB[PC_Control[2]][2] == 1: # 是分支指令,并且命中BTB时,将预测地址赋值给PC_Control,因为PC_Control会自增,这里提前-1
PC_Control[0] = BTB[PC_Control[2]][0]
"""
"""
if opcode == 0b1100011: # 如果是分支指令
BTB[PC_Control[2]][2] = 1
else:
BTB[PC_Control[2]][2] = 0
if BTB[PC_Control[2]][1] == 1 and BTB[PC_Control[2]][2] == 1: # 是分支指令,并且命中BTB时,将预测地址赋值给PC_Control,因为PC_Control会自增,这里提前-1
PC_Control[0] = BTB[ PC_Control[2]][0]
"""
pass
def Issue(): # 指令流出
# 1 首先检查是否可进行指令流出
# 2 若可以进行指令流出则设置对应硬件的状态
# 3 若流出则安排pc加四的位置
global IF_Found
global ID_Branch
IF_Found = False
ID_Branch = False
IF()
ID()
ISA()
# 只修改了这次用到的几个函数,将函数的实现改完,硬件状态的改变以及是否流出
pass
def BTB_Exec():
global IF_Found
global ID_Branch
global pc
if IF_Found == False and ID_Branch == False:
return
elif IF_Found == False and ID_Branch == True:
BTB[PC_Control[0]] = [pc, 1, 0]
elif IF_Found == True:
if BTB[PC_Control[0]][0] == pc:
pass
else:
BTB.pop(PC_Control[0])
"""
# EX阶段
PC_Control[3] = PC_Control[2] # PC_Control_EX,EX阶段指令对应的PC_Control
if BTB[PC_Control[3]][2] == 0: # 若不是分支指令,则删除该PC_Control在BTB中的item
BTB.pop(PC_Control[3])
elif BTB[PC_Control[3]][1] == 0: # 是分支指令,但没有在BTB中时,将该PC_Control放入到BTB中
# branch为该指令跳转的地址,需要针对指令设置;
branch = 0 # 该指令跳转的地址,需要针对指令设置;
BTB[PC_Control[3]][0] == branch
print(PC_Control)
print(BTB)
"""
pass
def Exec(): # 指令执行
for key in Hardware:
if Hardware[key]['busy'] == 1 and Hardware[key]['tag'] > 0:
Hardware[key]['tag'] -= 1
if Hardware[key]['tag'] == 0: # 执行结束,得到结果存到data
if Hardware[key]['op'] == 'lw': # 'sw' 'mul' 'addi' 'bne'
Hardware[key]['data'] = Memory[Hardware[key]['address']] + (Memory[Hardware[key]['address'] + 1] << 8) + (
Memory[Hardware[key]['address'] + 2] << 16) + (Memory[Hardware[key]['address'] + 3] << 24)
pass
if Hardware[key]['op'] == 'sw': # 'sw' 'mul' 'addi' 'bne'
#Memory[Hardware[key]['address']] = Hardware[key]['s1_vj']
#Memory[Hardware[key]['address']] = Hardware[key]['s1_vj']
Hardware[key]['data'] = Hardware[key]['s1_vj']
pass
if Hardware[key]['op'] == 'mul': # 'sw' 'mul' 'addi' 'bne'
if Hardware[key]['s1_vj'] < 2 ** 31:
tag1 = Hardware[key]['s1_vj']
else:
tag1 = Hardware[key]['s1_vj'] - 2 ** 32
if Hardware[key]['s2_vk'] < 2 ** 31:
tag2 = Hardware[key]['s2_vk']
else:
tag2 = Hardware[key]['s2_vk'] - 2 ** 32
tag3 = tag1 * tag2
if tag3 < 2 ** 31:
Hardware[key]['data'] = tag3
elif tag3 < 2 ** 32:
Hardware[key]['data'] = tag3 - 2 ** 32
else:
return False
pass
if Hardware[key]['op'] == 'addi': # 'sw' 'mul' 'addi' 'bne'
imm = Hardware[key]['imm']
if Hardware[key]['imm'] & 0b100000000000 == 0b100000000000:
imm = Hardware[key]['imm'] + 0b11111111111111111111000000000000
Hardware[key]['data'] = (Hardware[key]['s2_vk'] + imm) & 0xffffffff
pass
if Hardware[key]['op'] == 'bne': # 'sw' 'mul' 'addi' 'bne'
if Hardware[key]['s1_vj'] != Hardware[key]['s2_vk']:
global pc
pc += (Hardware[key]['imm'] * 4) - 4
BTB_Exec()
pass
pass
pass
pass
def Write(): # 数据写回
for key in Hardware:
if Hardware[key]['busy'] == 1 and Hardware[key]['tag'] == 0: # 如果该数据可以写回
Refresh(key) # 刷新需要这个数据的所有buffer和寄存器
Hardware[key]['busy'] = 0
pass
pass
pass
# ISA指令
# ***************************Loads***************************
# 字节加载指令
def lb(rd, rs1, imm):
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
a = Memory[Register[rs1] + imm]
if a & 0b10000000 == 0b10000000:
a = a + 0b11111111111111111111111100000000
Register[rd] = a
pass
# 半字加载指令
def lh(rd, rs1, imm):
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
a = Memory[Register[rs1] + imm] + (Memory[Register[rs1] + imm + 1] << 8)
if a & 0b1000000000000000 == 0b1000000000000000:
a = a + 0b11111111111111110000000000000000
Register[rd] = a
pass
# 字加载指令
def lw(rd, rs1, imm):
# 将原来的实现修改为硬件状态的检查和修改以及是否流出
# 1 检查是否有空闲的硬件,若没有则停止流出
# 2 若有则修改硬件状态
List = ['load1', 'load2', 'load3']
for i in List:
if Hardware[i]['busy'] == 0:
# 若存在硬件是空闲的,则修改硬件状态,然后返回
Hardware[i]['tag'] = 2
Hardware[i]['busy'] = 1
Hardware[i]['op'] = 'lw'
Hardware[i]['address'] = Register[rs1] + imm
Register[rd] = i
return
# 若不存在空闲硬件,则停止流出
global pc
pc -= 4
"""if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
a = Memory[Register[rs1] + imm] + (Memory[Register[rs1] + imm + 1] << 8) + (
Memory[Register[rs1] + imm + 2] << 16) + (Memory[Register[rs1] + imm + 3] << 24)
Register[rd] = a
"""
pass
# 无符号字节加载指令
def lbu(rd, rs1, imm):
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
a = Memory[Register[rs1] + imm]
Register[rd] = a
pass
# 无符号半字加载指令
def lhu(rd, rs1, imm):
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
a = Memory[Register[rs1] + imm] + (Memory[Register[rs1] + imm + 1] << 8)
Register[rd] = a
pass
# ***************************Stores***************************
# 存字节指令
def sb(rs1, rs2, imm):
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
Memory[Register[rs1] + imm] = Register[rs2] & 0b11111111
pass
# 存半字指令
def sh(rs1, rs2, imm):
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
Memory[Register[rs1] + imm] = Register[rs2] & 0b11111111
Memory[Register[rs1] + imm + 1] = (Register[rs2] >> 8) & 0b11111111
pass
# 存字指令
# 存字指令
def sw(rs1, rs2, imm):
# rs1表示内存地址,rs2表示存入寄存器
List = ['store1', 'store2', 'store3']
for i in List:
if Hardware[i]['busy'] == 0:
# 若存在硬件是空闲的,则修改硬件状态,然后返回
Hardware[i]['tag'] = 2
Hardware[i]['busy'] = 1
Hardware[i]['op'] = 'sw'
Hardware[i]['address'] = Register[rs1] + imm
if isinstance(Register[rs2], int):
Hardware[i]['s1_vj'] = Register[rs2]
else:
Hardware[i]['rs_qj'] = Register[rs2]
Register[rs2] = Hardware[i]
return
# 若不存在空闲硬件,则停止流出
global pc
pc -= 4
"""
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
Memory[Register[rs1] + imm] = Register[rs2] & 0b11111111
Memory[Register[rs1] + imm + 1] = (Register[rs2] >> 8) & 0b11111111
Memory[Register[rs1] + imm + 2] = (Register[rs2] >> 16) & 0b11111111
Memory[Register[rs1] + imm + 3] = Register[rs2] >> 24
"""
pass
# ***************************Shifts***************************
# 逻辑左移指令
def sll(rd, rs1, rs2):
Register[rd] = (Register[rs1] << (Register[rs2] & 0b11111)) & 0xffffffff
pass
# 立即数逻辑左移
def slli(rd, rs1, shamt):
if shamt < 0b100000:
Register[rd] = (Register[rs1] << shamt) & 0xffffffff
pass
# 逻辑右移指令
def srl(rd, rs1, rs2):
Register[rd] = Register[rs1] >> (Register[rs2] & 0b11111)
pass
# 立即数逻辑右移
def srli(rd, rs1, shamt):
if shamt < 0b100000:
Register[rd] = Register[rs1] >> shamt
pass
# 算数右移指令
def sra(rd, rs1, rs2):
Register[rd] = Register[rs1] >> (Register[rs2] & 0b11111)
if (Register[rs1] >> 31) == 1:
for i in range(0, Register[rs2] & 0b11111):
Register[rd] = Register[rd] + 2 ** (31 - i)
pass
# 立即数算数右移指令
def srai(rd, rs1, shamt):
Register[rd] = Register[rs1] >> (shamt & 0b11111)
if (Register[rs1] >> 31) == 1:
for i in range(0, shamt & 0b11111):
Register[rd] = Register[rd] + 2 ** (31 - i)
pass
# ***************************Arithmetic***************************
# 加指令
def add(rd, rs1, rs2):
Register[rd] = Register[rs1] + Register[rs2]
pass
# 加立即数指令
def addi(rd, rs1, imm):
List = ['add1', 'add2', 'add3']
for i in List:
if Hardware[i]['busy'] == 0:
# 若存在硬件是空闲的,则修改硬件状态,然后返回
Hardware[i]['tag'] = 2
Hardware[i]['busy'] = 1
Hardware[i]['op'] = 'addi'
if isinstance(Register[rs1], int):
Hardware[i]['s1_vj'] = Register[rs1]
else:
Hardware[i]['rs_qj'] = Register[rs1]
Hardware[i]['imm'] = imm
Register[rd] = Hardware[i]
return
# 若不存在空闲硬件,则停止流出
global pc
pc -= 4
"""
# print(Register[rd],Register[rs1],imm)
print('指令addi')
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
Register[rd] = (Register[rs1] + imm) & 0xffffffff
print('x1:')
print(Register[rd])
"""
pass
# 减指令
def sub(rd, rs1, rs2):
pass
# 高位立即数加载指令
def lui(rd, imm):
pass
# PC加立即数指令
def auipc(rd, imm):
pass
# ***************************Logical***************************
# 异或指令
def xor(rd, rs1, rs2):
pass
# 立即数异或指令
def xori(rd, rs1, imm):
pass
# 取或指令
def or_(rd, rs1, rs2):
pass
# 立即数取或指令
def ori(rd, rs1, imm):
pass
# 与指令
def and_(rd, rs1, rs2):
pass
# 与立即数指令
def andi(rd, rs1, imm):
Register[rd] = Register[rs1] + imm
pass
def mul(rd, rs1, rs2):
List = ['mult1', 'mult2']
for i in List:
if Hardware[i]['busy'] == 0:
# 若存在硬件是空闲的,则修改硬件状态,然后返回
Hardware[i]['tag'] = 10
Hardware[i]['busy'] = 1
Hardware[i]['op'] = 'mul'
if isinstance(Register[rs1], int):
Hardware[i]['s1_vj'] = Register[rs1]
else:
Hardware[i]['rs_qj'] = Register[rs1]
if isinstance(Register[rs2], int):
Hardware[i]['s2_vk'] = Register[rs2]
else:
Hardware[i]['rs_qk'] = Register[rs2]
Register[rd] = Hardware[i]
return
# 若不存在空闲硬件,则停止流出
global pc
pc -= 4
"""
if Register[rs1] < 2 ** 31:
tag1 = Register[rs1]
else:
tag1 = Register[rs1] - 2 ** 32
if Register[rs2] < 2 ** 31:
tag2 = Register[rs2]
else:
tag2 = Register[rs2] - 2 ** 32
tag3 = tag1 * tag2
if tag3 < 2 ** 31:
Register[rd] = tag3
elif tag3 < 2 ** 32:
Register[rd] = tag3 - 2 ** 32
else:
return False
"""
pass
# ***************************Compare***************************
# 小于则置位指令
def slt(rd, rs1, rs2):
pass
# 小于立即数则置位指令
def slti(rd, rs1, imm):
pass
# 无符号小于则置位指令
def sltu(rd, rs1, rs2):
pass
# 无符号小于立即数则置位指令
def sltiu(rd, rs1, imm):
pass
# ***************************Branches***************************
# 相等时分支指令
def beq(rs1, rs2, imm):
pass
# 不等式分支指令
def bne(rs1, rs2, imm):
List = ['add1', 'add2', 'add3']
for i in List:
if Hardware[i]['busy'] == 0:
# 若存在硬件是空闲的,则修改硬件状态,然后返回
Hardware[i]['tag'] = 1
Hardware[i]['busy'] = 1
Hardware[i]['op'] = 'bne'
Hardware[i]['s1_vj'] = Register[rs1]
Hardware[i]['s2_vk'] = Register[rs2]
Hardware[i]['imm'] = imm
return
# 若不存在空闲硬件,则停止流出
global pc
pc -= 4
"""
print('指令bne')
global pc
if (Register[rs1] != Register[rs2]):
pc += (imm * 4) - 4
"""
pass
# 小于时分支指令
def blt(rs1, rs2, imm):
pass
# 大于等于时分支指令
def bge(rs1, rs2, imm):
pass
# 无符号小于时分支指令
def bltu(rs1, rs2, imm):
pass
# 无符号大于等于时分支指令
def bgeu(rs1, rs2, imm):
pass
def jalr(rd, rs1, imm):
pass
def ecall(rd, rs1, imm):
pass
def ebreak(rd, rs1, imm):
pass
# ***************************Supplement***************************
# 浮点加载双字
def fld(rd, rs1, imm):
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
# print(Register[rs1], imm)
# mout(Register[rs1] + imm)
a = Memory[Register[rs1] + imm] + (Memory[Register[rs1] + imm + 1] << 8) + (
Memory[Register[rs1] + imm + 2] << 16) + (Memory[Register[rs1] + imm + 3] << 24)
Register[rd] = a
imm = imm + 4
a = Memory[Register[rs1] + imm] + (Memory[Register[rs1] + imm + 1] << 8) + (
Memory[Register[rs1] + imm + 2] << 16) + (Memory[Register[rs1] + imm + 3] << 24)
Register[rd + 1] = a
print('指令fld')
print('内存:')
print(((Register[rs1] + imm - 4) - 56) / 8)
print('取数:')
rout(rd)
pass
# 双精度浮点加
def fadd_d(rd, rs1, rs2):
tag1 = Register[rs1 + 1] >> 31
index1 = ((Register[rs1 + 1] >> 20) & 0b11111111111) - 1023
mantissa1 = 1 + ((Register[rs1 + 1] & 0xfffff) * (2 ** 32) + Register[rs1]) * (2 ** (-52))
tag2 = Register[rs2 + 1] >> 31
index2 = ((Register[rs2 + 1] >> 20) & 0b11111111111) - 1023
mantissa2 = 1 + ((Register[rs2 + 1] & 0xfffff) * (2 ** 32) + Register[rs2]) * (2 ** (-52))
a = ((-1) ** tag1) * mantissa1 * (2 ** index1) + ((-1) ** tag2) * mantissa2 * (2 ** index2)
# print(a)
if a >= 0:
tag3 = 0
else:
tag3 = 1
a = a * (-1)
# print(a)
index3 = 1023
while a >= 2:
a = a / 2
index3 = index3 + 1
mantissa3 = (int)((a - 1) * (2 ** 52))
# print(bin(tag3),bin(index3),bin(mantissa3))
Register[rd] = mantissa3 & 0xffffffff
# print(bin(Register[rd]))
Register[rd + 1] = tag3 * (2 ** 31) + index3 * (2 ** 20) + (mantissa3 >> 32)
# print(bin(Register[rd]+1))
print('指令fadd_d')
rout(rs1)
rout(rs2)
rout(rd)
pass
'''Register[0]=0
Register[1]=0b01000000000010110110000000000000
Register[2]=0
Register[3]=0b11000000001001011000000000000000
Register[4]=0
Register[5]=0
fadd_d(4,0,2)
print(bin(Register[4]),bin(Register[5]))
print((0b11011011-0b1010110000)/(2**6),(0b111010101)/64)'''
# 双精度浮点存储
def fsd(rs1, rs2, imm):
if imm & 0b100000000000 == 0b100000000000:
imm = imm + 0b11111111111111111111000000000000
Memory[Register[rs1] + imm] = Register[rs2] & 0b11111111
Memory[Register[rs1] + imm + 1] = (Register[rs2] >> 8) & 0b11111111
Memory[Register[rs1] + imm + 2] = (Register[rs2] >> 16) & 0b11111111
Memory[Register[rs1] + imm + 3] = Register[rs2] >> 24
rs2 = rs2 + 1
imm = imm + 4
Memory[Register[rs1] + imm] = Register[rs2] & 0b11111111
Memory[Register[rs1] + imm + 1] = (Register[rs2] >> 8) & 0b11111111
Memory[Register[rs1] + imm + 2] = (Register[rs2] >> 16) & 0b11111111
Memory[Register[rs1] + imm + 3] = Register[rs2] >> 24
print('指令fsd')
# rout(rs2-1)
print('存入内存:')
print(((Register[rs1] + imm - 4) - 56) / 8)
print('存入数:')
mout(Register[rs1] + imm - 4)
pass
def mout(addr):
a = Memory[addr] + (Memory[addr + 1] << 8) + (
Memory[addr + 2] << 16) + (Memory[addr + 3] << 24)
addr = addr + 4
b = Memory[addr] + (Memory[addr + 1] << 8) + (
Memory[addr + 2] << 16) + (Memory[addr + 3] << 24)
tag = b >> 31
index = ((b >> 20) & 0b11111111111) - 1023
mantissa = 1 + ((b & 0xfffff) * (2 ** 32) + a) * (2 ** (-52))
flo = mantissa * (2 ** index) * ((-1) ** tag)
print(flo)
def rout(addr):
a = Register[addr]
addr = addr + 1
b = Register[addr]
tag = b >> 31
index = ((b >> 20) & 0b11111111111) - 1023
mantissa = 1 + ((b & 0xfffff) * (2 ** 32) + a) * (2 ** (-52))
flo = mantissa * (2 ** index) * ((-1) ** tag)
print(flo)
# 指令集
class ISA:
def __init__(self):
instruction = self.defInstr()
self.tellFormat(instruction)
def defInstr(self): # 传入参数为指令在内存的地址
instru = 0x00000000
if (pc == 68):
print("breakpoint")
for i in range(4):
# print(hex(addr + i))
# print(hex(Memory[addr + i]))
instru += Memory[pc + i] * (256 ** i)
# print(hex(instru))
return instru
instruFormat = {
0b0110011: 'RFormat', # 运算
0b0010011: 'IFormat', # 运算
0b0000011: 'IFormat', # load
0b0100011: 'SFormat', # store
0b1100011: 'SBFormat', # branch
0b1101111: 'UJFormat', # jump(大立即数跳转)
0b1100111: 'IFormat', # jump
0b0110111: 'UFormat', # rd = imm << 12
0b0010111: 'UFormat', # rd = pc + (imm << 12)
0b1110011: 'IFormat', # transfer control
0b0100111: 'SFormat', # fsd
0b0000111: 'IFormat', # fld
0b1010011: 'RFormat', # fadd_d
}
def getopfromins(self, instruction):
return instruction & 0b1111111
def tellFormat(self, instruction):
opcode = self.getopfromins(instruction)
switch = {
0b0110011: 'RFormat', # 运算
0b0010011: 'IFormat', # 运算
0b0000011: 'IFormat', # load
0b0100011: 'SFormat', # store
0b1100011: 'SBFormat', # branch
0b1101111: 'UJFormat', # jump(大立即数跳转)
0b1100111: 'IFormat', # jump
0b0110111: 'UFormat', # rd = imm << 12
0b0010111: 'UFormat', # rd = pc + (imm << 12)
0b1110011: 'IFormat', # transfer control
0b0100111: 'SFormat', # fsd
0b0000111: 'IFormat', # fld
0b1010011: 'RFormat', # fadd_d
}
Format = switch.get(opcode, 'Invalid')
# 这里pc加四,如果后面检测到不可以流出,再进行减四
global pc
pc += 4
if (Format == 'Invalid'):
return False
elif (Format == 'RFormat'):
return self.decodeRFormat(instruction)
elif (Format == 'IFormat'):
return self.decodeIFormat(instruction)
elif (Format == 'SFormat'):
return self.decodeSFormat(instruction)
elif (Format == 'SBFormat'):
return self.decodeSBFormat(instruction)
elif (Format == 'UFormat'):
return self.decodeUFormat(instruction)
elif (Format == 'UJFormat'):
return self.decodeUJFormat(instruction)
return False
def decodeRFormat(self, instruction):
opcode = instruction & 0b1111111
funct7 = instruction >> 25
rs2 = instruction >> 20 & 0b11111
rs1 = instruction >> 15 & 0b11111
funct3 = instruction >> 12 & 0b111
rd = instruction >> 7 & 0b11111
if (funct7 == 0x00):
if (funct3 == 0x0):
return add(rd, rs1, rs2)
elif (funct3 == 0x4):
return xor(rd, rs1, rs2)
elif (funct3 == 0x6):
return or_(rd, rs1, rs2)
elif (funct3 == 0x7):
return and_(rd, rs1, rs2)
elif (funct3 == 0x1):
return sll(rd, rs1, rs2)
elif (funct3 == 0x5):
return srl(rd, rs1, rs2)
elif (funct3 == 0x2):
return slt(rd, rs1, rs2)
elif (funct3 == 0x3):
return sltu(rd, rs1, rs2)
elif (funct7 == 0x20):
if (funct3 == 0x0):
return sub(rd, rs1, rs2)
elif (funct3 == 0x5):
return sra(rd, rs1, rs2)
elif (funct7 == 0x01):
if (opcode == 0b1010011):
return fadd_d(rd, rs1, rs2)
elif (funct3 == 0x0 and opcode == 0b0110011):
return mul(rd, rs1, rs2)
return False
def decodeIFormat(self, instruction):
imm = instruction >> 20
rs1 = instruction >> 15 & 0b11111
funct3 = instruction >> 12 & 0b111
rd = instruction >> 7 & 0b11111
opcode = instruction & 0b1111111
if (opcode == 0b0010011):
if (funct3 == 0x0):
return addi(rd, rs1, imm)
elif (funct3 == 0x4):
return xori(rd, rs1, imm)
elif (funct3 == 0x6):
return ori(rd, rs1, imm)
elif (funct3 == 0x7):
return andi(rd, rs1, imm)
elif (funct3 == 0x1):
return slti(rd, rs1, imm)
elif (funct3 == 0x5):
if (instruction >> 25 == 0b0000000):
return srli(rd, rs1, imm)
elif (instruction >> 25 == 0b0100000):
return srai(rd, rs1, imm)
elif (funct3 == 0x2):
return slti(rd, rs1, imm)
elif (funct3 == 0x3):
return sltiu(rd, rs1, imm)
elif (opcode == 0b0000011):
if (funct3 == 0x0):
return lb(rd, rs1, imm)
elif (funct3 == 0x1):
return lh(rd, rs1, imm)
elif (funct3 == 0x2):
return lw(rd, rs1, imm)
elif (funct3 == 0x4):
return lbu(rd, rs1, imm)
elif (funct3 == 0x5):
return lhu(rd, rs1, imm)
elif (opcode == 0b1100111):
if (funct3 == 0x0):
return jalr(rd, rs1, imm)
elif (opcode == 0b1110011):
if (funct3 == 0x0 and imm == 0x0):
return ecall(rd, rs1, imm)
elif (funct3 == 0x0 and imm == 0x1):
return ebreak(rd, rs1, imm)
elif (opcode == 0b0000111):
if (funct3 == 0b011):
return fld(rd, rs1, imm)
return False
def decodeSFormat(self, instruction):
imm = (instruction >> 7) & 0b11111 + (instruction >> 25) * 0b100000
immTemp = 0b000000000000
# 这里的imm是十二位的二进制补码,需要将其转换为机器数
if (imm >> 11 == 1):
for i in range(11):
immTemp += (1 - (imm >> i & 1)) * (2 ** i)
immTemp += 1
imm = 0 - immTemp
funct3 = (instruction >> 12) & 0b111
rs1 = (instruction >> 15) & 0b11111
rs2 = (instruction >> 20) & 0b11111
if funct3 == 0x0:
return sb(rs1, rs2, imm)
elif funct3 == 0x1:
return sh(rs1, rs2, imm)
elif funct3 == 0x2:
return sw(rs1, rs2, imm)
elif funct3 == 0x3:
return fsd(rs1, rs2, imm)
return False
def decodeSBFormat(self, instruction):
a = (instruction >> 7) & 0b11111
c = ((instruction >> 25) & 0b1111111) << 5
imm = a + c
immTemp = 0b000000000000
# 这里的imm是十二位的二进制补码,需要将其转换为机器数
if (imm >> 11 == 1):
for i in range(11):
immTemp += (1 - (imm >> i & 1)) * (2 ** i)
immTemp += 1
imm = 0 - immTemp
funct3 = (instruction >> 12) & 0b111
rs1 = (instruction >> 15) & 0b11111
rs2 = (instruction >> 20) & 0b11111
if funct3 == 0x0:
return beq(rs1, rs2, imm)
elif funct3 == 0x1:
return bne(rs1, rs2, imm)
elif funct3 == 0x4:
return blt(rs1, rs2, imm)
elif funct3 == 0x5:
return bge(rs1, rs2, imm)
elif funct3 == 0x6:
return bltu(rs1, rs2, imm)
elif funct3 == 0x7:
return bgeu(rs1, rs2, imm)
return False
def decodeUFormat(self, instruction):
opcode = instruction & 0b1111111
rd = (instruction >> 7) & 0b11111
imm = instruction >> 12
immTemp = 0b000000000000
# 这里的imm是十二位的二进制补码,需要将其转换为机器数
if (imm >> 11 == 1):
for i in range(11):
immTemp += (1 - (imm >> i & 1)) * (2 ** i)
immTemp += 1
imm = 0 - immTemp
if opcode == 0b0110111:
return lui(rd, imm)
elif opcode == 0b0010111:
return auipc(rd, imm)
return False
def decodeUJFormat(self, instruction):
return False
def main():
global Register
global Memory
# 初始化寄存器
Register[0b00001] = 0x00000000 # 1,2寄存器用来存储常量s
Register[0b00010] = 0x40180000 # s=6
# Register[0b00011] = 0x00000300 # 用来存储x1,即99,这里令其为96*8=768=0x300
Register[0b00100] = 0x00000318 # 用来存储x2,即99 * 8 =
# 需要变址寄存器用来找到load和store指令中的内存地址,每四条指令使用同一个变址寄存器,通过改变立即数的大小来决定内存地址的变换
Register[0b00101] = 0x00000000 # 用来存储x1=0,用来表示load或者store指令的变址寄存器
# 其余的寄存器用来存储加载的数字以及计算结果,其初始值都是零
# l1 fld
# 内存中的指令数据
# 1 fld f6 0x38()
# load two word指令,立即数为0x38,转化为二进制为0011 1000
# imm[11:0] rs1 011 rd 0000111
# 0000 0011 1000 0010 1 011 0011 0 000 0111
# EA = A + (rs1)
# 0x 03 82 B3 07
Memory[0x00000030] = 0x07
Memory[0x00000031] = 0xB3
Memory[0x00000032] = 0x82
Memory[0x00000033] = 0x03
# l2 fadd
# 这里rd(14\15)的地址为:0b01110,rs1(6、7数组中的元素)的地址为:0b00110,r2(1/2,常量s)的地址为:0b00001
# funct7 rs2 rs1 funct3 rd opcode
# 0000001 00001 00110 001 01110 1010011
# 其中funct7和funct3的组合表示浮点加法运算
# 16进制表示为0x 02 13 17 53
Memory[0x00000034] = 0x53
Memory[0x00000035] = 0x17
Memory[0x00000036] = 0x13
Memory[0x00000037] = 0x02
# l3 fsd
# 和第一条load指令相对应
# 内存中的指令数据
# 1 fld
# load two word指令,立即数为0x38,转化为二进制为0011 1000
# imm[11:0] rs1 110 rd 0000011
# 000000111000 00101 110 00110 0000011
# rs2需要存储的数据
# rs1基址寄存器
# imm[11:5] rs2 rs1 func3 imm[4:0] opcode
# 0000001 01110 00101 011 11000 0100011
# 这里的立即数和load指令中的立即数具有相同的作用,即数组在内存中的开始地址
# 其十六进制表示为0x02 E2 BC 23
Memory[0x00000038] = 0x23
Memory[0x00000039] = 0xBC
Memory[0x0000003A] = 0xE2
Memory[0x0000003B] = 0x02
# l4 addi
# x1是存储在第一条load指令的基址寄存器和imm产生的内存地址,初始值为96*4,最后的值为0
# imm为8
# imm[11:0] rs1 111 rd 0010011
# 0000 0000 1000 0010 1 000 0010 1 001 0011
# 十六进制表示为0x 00 82 82 93
Memory[0x0000003C] = 0x93
Memory[0x0000003D] = 0x82
Memory[0x0000003E] = 0x82
Memory[0x0000003F] = 0x00
"""
# l5 bne
# 若x1和x2里面的内容不相等则进行分支转移
# 分支转移中的立即数,令其为-6
# imm[12|10:5] rs2 rs1 func3 imm[4:1|11] opcode
# x1 x2
# 1111111 00101 00100 001 11010 1100011
# 16进制表示为0x FE 52 1D 63
Memory[0x00000040] = 0x63
Memory[0x00000041] = 0x1D
Memory[0x00000042] = 0x52
Memory[0x00000043] = 0xFE
"""
# l5 bne
# 若x1和x2里面的内容不相等则进行分支转移
# 分支转移中的立即数,令其为-4
# imm[12|10:5] rs2 rs1 func3 imm[4:1|11] opcode
# x1 x2
# 1111111 00101 00100 001 11100 1100011
# 16进制表示为0x FE 52 1E 63
Memory[0x00000040] = 0x63
Memory[0x00000041] = 0x1E
Memory[0x00000042] = 0x52
Memory[0x00000043] = 0xFE
# 指令后面的位置用来存储数组数据,从十进制56开始即0x38
for i in range(100):
Memory[0x00000044 + i * 8] = 0x00
Memory[0x00000044 + i * 8 + 1] = 0x00
Memory[0x00000044 + i * 8 + 2] = 0x00
Memory[0x00000044 + i * 8 + 3] = 0x00
m = (i + 1023) * 16
Memory[0x00000044 + i * 8 + 4] = 0x00
Memory[0x00000044 + i * 8 + 5] = 0x00
Memory[0x00000044 + i * 8 + 6] = m & 0xff
Memory[0x00000044 + i * 8 + 7] = (m >> 8) & 0xff
"""
for i in range(100):
print('运行前内存%d:' % i)
mout(0x00000044 + i * 8)
"""
global pc
pc = 0x00000030
clock = 0
for clock in range(10000):
print(pc)
Issue()
Exec()
Write()
clock += 1
if pc == 0x00000044:
pass
"""
for i in range(100):
print('运行后内存%d:' % i)
mout(0x00000038 + i * 8)
"""
main()