您的位置:首页 > 编程语言 > Python开发

硬件设计测试中,MIPS汇编指令翻译成二进制编码的Python实现

2011-04-18 23:43 621 查看
最近在做计算机体系结构与组成原理的实验,需要写MIPS指令系统的CPU。在测试时,人工将需要测试的指令翻译成二进制的编码实在有些繁琐,而且极易出错,正好最近在学习python,就写了一个实用的脚本,来完成这个工作。

由于我们实现的CPU暂时只实现了16条指令,分别是:

add rd,rs,rt

addu rd,rs,rt

addi rt,rs,imm

addiu rt,rs,imm

sub rd,rs,rt

subu rd,rs,rt

nor rd,rs,rt

xori rt,rs,imm

clo rd, rs

clz rs,rs

slt rd,rs,rt

sltu rd,rs,rt

slti rt,rs,imm

sltiu rt,rs imm

blez rs,imm

j target

因此这个脚本只涉及了这些指令的内容,以后再扩展吧。

下面说一下实现思路:

1、从一个文件中读取MIPS的汇编指令;

2、通过字符串处理,然后将其各个部分进行匹配;

3、将生成的二进制编码写到一个文件中。

需要注意的是,指令应该向上边的示例一样,在操作符和操作数之间应该有个空格,操作数之间以逗号和若干(最好0)个空格分隔,每行写一条指令,指令前最好没有空字符。由于这个脚本主要是自己用,鲁棒性不是很好,见谅。

下面直接上代码:

import os
def readfile(filename):
"""read and store test file"""
try:
fobj = open(filename, 'r')
except IOError, e:
print "*** file open error:", e
else:
lines = []
for eachLine in fobj:
lines.append(eachLine)
fobj.close()
return lines
def writefile(filename, l):
"""write the file with the binary"""
ls = os.linesep
fobj = open(filename, 'w')
fobj.writelines(['%s%s' % (x, ls) for x in l])
fobj.close()
print 'DONE!'
def splitOandD(inst):
"""split the op and data"""
sinst = []
for x in inst:
z = x.rstrip()
y = z.split(' ', 1)
sinst.append(y);
return sinst
def numtobin(num, count):
"""tran a num to binary"""
s = (bin(num))[2:]
ss = ((count - len(s)) * '0') + s
return ss
def regtobin(reg):
"""make a regs to binary"""
regs = reg.lstrip()
regnum = regs[1:]
if((int)(regnum) <= 31 and (int)(regnum) >= 0):
regb = numtobin((int)(regnum), 5)
return regb
else:
print "***no regs: ", regs
return regb
def handle(ins):
"""handle the strings to regular binary code"""
op = (str)(ins[0])
data = (str)(ins[1])
sdata = data.lstrip()
dl = sdata.split(',')
if op == "add":
opcode = "000000"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
rt = regtobin(dl[2])
func = "100000"
incode = opcode+rs+rt+rd+"00000"+func
elif op == "addu":
opcode = "000000"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
rt = regtobin(dl[2])
func = "100001"
incode = opcode+rs+rt+rd+"00000"+func
elif op == "addi":
opcode = "001000"
rt = regtobin(dl[0])
rs = regtobin(dl[1])
imm = numtobin((int)(dl[2]), 16)
incode = opcode + rs + rt + imm
elif op == "addiu":
opcode = "001001"
rt = regtobin(dl[0])
rs = regtobin(dl[1])
imm = numtobin((int)(dl[2]), 16)
incode = opcode + rs + rt + imm
elif op == "sub":
opcode = "000000"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
rt = regtobin(dl[2])
func = "100010"
incode = opcode+rs+rt+rd+"00000"+func
elif op == "subu":
opcode = "000000"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
rt = regtobin(dl[2])
func = "100011"
incode = opcode+rs+rt+rd+"00000"+func
elif op == "nor":
opcode = "000000"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
rt = regtobin(dl[2])
func = "100111"
incode = opcode+rs+rt+rd+"00000"+func
elif op == "xori":
opcode = "001110"
rt = regtobin(dl[0])
rs = regtobin(dl[1])
imm = numtobin((int)(dl[2]), 16)
incode = opcode + rs + rt + imm
elif op == "clo":
opcode = "011100"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
func = "100001"
incode = opcode + rs + "00000" + rd + "00000" + func
elif op == "clz":
opcode = "011100"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
func = "100000"
incode = opcode + rs + "00000" + rd + "00000" + func
elif op == "slt":
opcode = "000000"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
rt = regtobin(dl[2])
func = "101010"
incode = opcode+rs+rt+rd+"00000"+func
elif op == "sltu":
opcode = "000000"
rd = regtobin(dl[0])
rs = regtobin(dl[1])
rt = regtobin(dl[2])
func = "101011"
incode = opcode+rs+rt+rd+"00000"+func
elif op == "slti":
opcode = "001010"
rt = regtobin(dl[0])
rs = regtobin(dl[1])
imm = numtobin((int)(dl[2]), 16)
incode = opcode + rs + rt + imm
elif op == "sltiu":
opcode = "001011"
rt = regtobin(dl[0])
rs = regtobin(dl[1])
imm = numtobin((int)(dl[2]), 16)
incode = opcode + rs + rt + imm
elif op == "blez":
opcode = "000110"
rs = regtobin(dl[0])
imm = numtobin((int)(dl[1]), 16)
incode = opcode + rs + "00000" + imm
elif op == "j":
opcode = "000010"
imm = numtobin((int)(dl[0]), 26)
incode = opcode + imm
else:
print "***Not Define: ", op
return incode

def main():
l = readfile("i.txt")
s = splitOandD(l)
b = []
print s
for m in s:
if m != ['']:
print m
b.append(handle(m))

writefile("o.txt", b)
if __name__ == "__main__":
main()


Reference:

《Mips instruction Reference》

http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: