下面的代码用python实现了for循环语句
for (int i = 999; i >= 0; i--)
x[i] = x[i] + s
#RISC-V
#小端模式
# 寄存器类
Register = {
0b00000: 0x00000000,
0b00001: 0xf2345678,
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
# 储存器类
Memory = {
0x00000000: 0b01000001
}
# 初始化内存,大小为1KB
def init_Mem():
for i in range(2**20):
Memory[0x00000000 + i] = 0x00
# 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):
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):
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):
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 * 4
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):
global pc
if (Register[rs1] != Register[rs2]):
pc += (imm * 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
#指令集
class ISA:
def __init__(self):
instruction = self.defInstr()
self.tellFormat(instruction)
def defInstr(self): # 传入参数为指令在内存的地址
instru = 0x00000000
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
}
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
}
Format = switch.get(opcode, 'Invalid')
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):
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)
return False
def decodeIFormat(self, instruction):
imm = instruction >> 20
immTemp = 0b000000000000
# 这里的imm是十二位的二进制补码,需要将其转换为机器数
if (imm >> 11 == 1):
for i in range(11):
immTemp += (1 - (imm >> i & 1)) * (2 ** i)
immTemp += 1
imm = 0 - immTemp
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)
return False
def decodeSFormat(self, instruction):
imm = (instruction >> 7) & 0b11111 + (instruction >> 25) * 0b100000
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)
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
if opcode == 0b0110111:
return lui(rd, imm)
elif opcode == 0b0010111:
return auipc(rd, imm)
return False
def decodeUJFormat(self, instruction):
return False
def main():
init_Mem()
#load word指令
#imm[11:0] rs1 010 rd 0000011
#000000010100 00001 010 00010 0000011
#0x014 0A 10 3
#0x01 40 A1 03
#小端模式为0x 03 A1 00 00
Memory[0x00000000] = 0x03
Memory[0x00000001] = 0xA1
Memory[0x00000002] = 0x40
Memory[0x00000003] = 0x01
# add r3, r1, r2
#这里应该进行浮点数的运算,所以要改
# 这里r3的地址为:0b00101,r1的地址为:0b00010,r2的地址为:0b00100
# funct7 rs2 rs1 funct3 rd opcode
# 0000000 00011 00010 000 00100 0110011
# 其中funct7和funct3的组合表示加法运算
# 16进制表示为0x 00 31 02 33小端模式表示为0x33 02 31 00
Memory[0x00000004] = 0x33
Memory[0x00000005] = 0x02
Memory[0x00000006] = 0x31
Memory[0x00000007] = 0x00
# store r3, #3
# r3为0b00101,#3采用基址寻址+间接寻址,内存起始地址为0x00000019,基址寄存器为0b00110,offset为0
# rs2需要存储的数据
# rs1基址寄存器
# imm[11:5] rs2 rs1 func3 imm[4:0] opcode
# 0000000 00100 00001 010 10100 0100011
# 这里的立即数和load指令中的立即数具有相同的作用,即数组在内存中的开始地址
# 0000000 10100
# 其十六进制表示为0x00 40 AA 23
Memory[0x00000008] = 0x23
Memory[0x00000009] = 0xAA
Memory[0x0000000A] = 0x40
Memory[0x0000000B] = 0x00
#addi x1,x1,8
#这里用了4,哭唧唧,8B太复杂了
#x1是存储在第一条load指令的基址寄存器和imm产生的内存地址,每次减一
#imm为-1
#imm[11:0] rs1 111 rd 0010011
#111111111111 00001 111 00001 0010011
#十六进制表示为0x FF F0 F0 93
#小端模式表示为0x 93 F0 F0 FE
Memory[0x0000000C] = 0x93
Memory[0x0000000D] = 0xF0
Memory[0x0000000E] = 0xF0
Memory[0x0000000F] = 0xFF
#bne x1,x2,loop
#若x1和x2里面的内容不相等则进行分支转移
#imm[12|10:5] rs2 rs1 func3 imm[4:1|11] opcode
# x1 x2
#1111111 00001 00110 001 11011 1100011
#16进制表示为0x FE 13 1D E3
Memory[0x00000010] = 0xE3
Memory[0x00000011] = 0x1D
Memory[0x00000012] = 0x13
Memory[0x00000013] = 0xFE
#定义数组x,用来存储1000个float类型的数字
for i in range(1000):
Memory[0x00000014 + i * 4] = 0x01
Memory[0x00000014 + i * 4 + 1] = 0x01
Memory[0x00000014 + i * 4 + 2] = 0x01
Memory[0x00000014 + i * 4 + 3] = 0x01
# 寄存器
Register[0b00001] = 0x00000F9C # 第一条load指令的变址寄存器,用来存储x1,即数组地址的偏移量,初始x1为999,由于每个元素占有四个存储空间,因此这里是999*4
Register[0b00010] = 0x00000000 # 第一条load指令的目的寄存器
Register[0b00011] = 0x00000001 # 用来存放add指令中加的常数s,令其为1
Register[0b00100] = 0x00000000 # 用来存放add指令产生的结果,也用来存放即将store的数字
# Register[0b00101] = 0x00000000 # 基址寄存器,用来存放store的内存地址
Register[0b00110] = 0x00000000 # 用来存放x2,即0
while (1):
ISA()
print("Memory 4019 is: ", Memory[4019])
print("Memory 4018 is: ", Memory[4018])
print("Memory 4017 is: ", Memory[4017])
print("Memory 4016 is: ", Memory[4016])
print("Memory 4015 is: ",Memory[4015])
print("Memory 4014 is: ",Memory[4014])
print("Memory 4013 is: ", Memory[4013])
print("Memory 4012 is: ", Memory[4012])
if Register[0b00001] == 0x00000000:
break
pass
main()