Skip to content

Instantly share code, notes, and snippets.

@mukheshpugal
Created October 3, 2020 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mukheshpugal/a8c2e9f022525649bc1c683f3c92e05c to your computer and use it in GitHub Desktop.
Save mukheshpugal/a8c2e9f022525649bc1c683f3c92e05c to your computer and use it in GitHub Desktop.
A partially implemented rv32i decoder.
import argparse
alu = {
'0000':'add', '1000':'sub',
'0001':'sll',
'0010':'slt',
'0011':'sltu',
'0100':'xor',
'0101':'srl', '1101':'sra',
'0110':'or',
'0111':'and'
}
alui = {
'0000':'addi', '1000':'addi',
'0001':'slli', '1001':'slli',
'0010':'slti', '1010':'slti',
'0011':'sltui', '1011':'sltui',
'0100':'xori', '1100':'xori',
'0101':'srli', '1101':'srai',
'0110':'ori', '1110':'ori',
'0111':'andi', '1111':'andi'
}
load = {
'000':'lb',
'001':'lh',
'010':'lw',
'100':'lbu',
'101':'lhu'
}
store = {
'000':'sb',
'001':'sh',
'010':'sw'
}
def decode(instr):
instr = format(int(instr, 16), '032b')[::-1]
opcode = instr[:7][::-1]
rd = instr[7:12][::-1]
funct3 = instr[12:15][::-1]
rs1 = instr[15:20][::-1]
rs2 = instr[20:25][::-1]
imm = instr[20:32][::-1]
if opcode == '0100011':
imm = imm[:7] + rd
rs1 = int(rs1, 2)
rs2 = int(rs2, 2)
rd = int(rd, 2)
imm = int(imm, 2)
if (imm & (1 << 11)) != 0:
imm = imm - (1 << 12)
# ALU
if opcode == '0010011': return f'{alui[instr[30]+funct3]}\tr{rd}, r{rs1}, {imm}'
elif opcode == '0110011': return f'{alu[instr[30]+funct3]}\tr{rd}, r{rs1}, {imm}'
# Load and Store
elif opcode == '0000011': return f'{load[funct3]}\t\tr{rd}, {imm}(r{rs1})'
elif opcode == '0100011': return f'{store[funct3]}\t\tr{rs2}, {imm}(r{rs1})'
else: return 'Invalid instruction'
parser = argparse.ArgumentParser(description='An rv32i decoder. Use as \'python3 rv32i.py INFILE -o OUTFILE\'')
parser.add_argument('file', action="store", help="File to read from")
parser.add_argument('-o', '--output', help='output filename')
args = parser.parse_args()
with open(args.file) as fp:
lines = fp.readlines()
outLines = []
for line in lines:
outLines.append(f'{line[:-2]}\t:\t{decode(line[:8])}\n')
if args.output:
with open(args.output, 'w') as fp:
fp.writelines(outLines)
print(f'Saved output to {args.output}')
exit(0)
for line in outLines:
print(line,end='')
@mukheshpugal
Copy link
Author

Please reply with any issues that you find.

@mukheshpugal
Copy link
Author

Refer to the below image for register nomenclature.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment