Skip to content

Instantly share code, notes, and snippets.

@mukheshpugal
Created October 3, 2020 15:04
Show Gist options
  • Select an option

  • Save mukheshpugal/a8c2e9f022525649bc1c683f3c92e05c to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
Author

Please reply with any issues that you find.

@mukheshpugal

Copy link
Copy Markdown
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