Fix
This commit is contained in:
@@ -7,29 +7,28 @@ LA32R Simple Assembler
|
||||
- Supports all 14 instructions required by the course design.
|
||||
- Handles register names like '$r4', '$r12' and immediate values.
|
||||
- Outputs a 'program.hex' file suitable for Verilog's $readmemh.
|
||||
- [FIXED] Corrected the encoding for ADDI.W to match the ISA specification
|
||||
(opcode 000000 + func4).
|
||||
- [FINAL FIX] Corrected the string formatting for 3R-type instructions, which
|
||||
was scrambling the register and function fields.
|
||||
"""
|
||||
|
||||
# 指令编码定义
|
||||
# Instruction encoding definitions
|
||||
OPCODES = {
|
||||
'add.w': '000000', 'sub.w': '000000', 'slt': '000000', 'sltu': '000000',
|
||||
'add.w': '000000', 'sub.w': '000000', 'slt': '000000', 'sltu': '000000',
|
||||
'nor': '000000', 'and': '000000', 'or': '000000',
|
||||
'addi.w': '000010', 'lu12i.w': '000101', 'ld.w': '001010', 'st.w': '001010',
|
||||
'b': '010100', 'beq': '010110', 'blt': '011000'
|
||||
'addi.w': '000000', 'lu12i.w': '000101', 'ld.w': '001010', 'st.w': '001010',
|
||||
'b': '010100', 'beq': '010110', 'blt': '011000'
|
||||
}
|
||||
|
||||
FUNC_3R = {
|
||||
# 'opcode': ('func2', 'func5')
|
||||
'add.w': ('01', '00000'), 'sub.w': ('01', '00010'), 'slt': ('01', '00100'),
|
||||
'sltu': ('01', '00101'), 'nor': ('01', '01000'), 'and': ('01', '01001'),
|
||||
'or': ('01', '01010')
|
||||
'add.w': ('01', '00000'), 'sub.w': ('01', '00010'), 'slt': ('01', '00100'),
|
||||
'sltu': ('01', '00101'), 'nor': ('01', '01000'), 'and': ('01', '01001'),
|
||||
'or': ('01', '01010')
|
||||
}
|
||||
|
||||
FUNC_2RI12 = {
|
||||
# 'opcode': 'func4'
|
||||
'addi.w': '1010',
|
||||
'ld.w': '0010',
|
||||
'st.w': '0110'
|
||||
'addi.w': '1010', 'ld.w': '0010', 'st.w': '0110'
|
||||
}
|
||||
|
||||
|
||||
@@ -52,42 +51,39 @@ def assemble_line(line):
|
||||
parts = re.split(r'[\s,]+', line)
|
||||
op = parts[0]
|
||||
|
||||
if op in FUNC_3R: # 3R-type: add.w $r3, $r1, $r2
|
||||
if op in FUNC_3R: # 3R-type
|
||||
rd, rj, rk = parse_register(parts[1]), parse_register(parts[2]), parse_register(parts[3])
|
||||
opcode = OPCODES[op]
|
||||
func2, func5 = FUNC_3R[op]
|
||||
# [THE FIX] Removed the erroneous hardcoded '00000' field.
|
||||
# The correct format for these 3R instructions is opcode | 0000 | func2 | func5 | rk | rj | rd
|
||||
return f"{opcode}0000{func2}{func5}{rk}{rj}{rd}"
|
||||
|
||||
elif op in ['addi.w', 'ld.w', 'st.w']: # 2RI12-type
|
||||
rd = parse_register(parts[1])
|
||||
rj = parse_register(parts[2])
|
||||
# FIX: Use int(str, 0) to auto-detect base (e.g., '0x' for hex)
|
||||
imm = to_binary(int(parts[3], 0), 12)
|
||||
opcode = OPCODES[op]
|
||||
func4 = FUNC_2RI12[op]
|
||||
return f"{opcode}{func4}{imm}{rj}{rd}"
|
||||
|
||||
elif op == 'lu12i.w': # 1RI20-type: lu12i.w $r1, 0x12345
|
||||
elif op == 'lu12i.w': # 1RI20-type
|
||||
rd = parse_register(parts[1])
|
||||
imm = to_binary(int(parts[2], 0), 20) # Support hex (0x) and dec
|
||||
imm = to_binary(int(parts[2], 0), 20)
|
||||
opcode = OPCODES[op]
|
||||
return f"{opcode}0{imm}{rd}"
|
||||
|
||||
elif op in ['beq', 'blt']: # 2RI16-type: beq $r1, $r2, -4
|
||||
rj = parse_register(parts[1])
|
||||
rd = parse_register(parts[2])
|
||||
# FIX: Use int(str, 0) to auto-detect base
|
||||
offset = int(parts[3], 0) >> 2 # Offset is in bytes, convert to word offset for encoding
|
||||
elif op in ['beq', 'blt']: # 2RI16-type
|
||||
rj, rd = parse_register(parts[1]), parse_register(parts[2])
|
||||
offset = int(parts[3], 0) >> 2
|
||||
imm = to_binary(offset, 16)
|
||||
opcode = OPCODES[op]
|
||||
return f"{opcode}{imm}{rj}{rd}"
|
||||
|
||||
elif op == 'b': # I26-type: b -8
|
||||
# FIX: Use int(str, 0) to auto-detect base
|
||||
offset = int(parts[1], 0) >> 2 # Convert to word offset
|
||||
elif op == 'b': # I26-type
|
||||
offset = int(parts[1], 0) >> 2
|
||||
imm = to_binary(offset, 26)
|
||||
offs_25_16 = imm[0:10]
|
||||
offs_15_0 = imm[10:26]
|
||||
offs_25_16, offs_15_0 = imm[0:10], imm[10:26]
|
||||
opcode = OPCODES[op]
|
||||
return f"{opcode}{offs_15_0}{offs_25_16}"
|
||||
|
||||
@@ -110,7 +106,6 @@ def main():
|
||||
# Ignore comments and empty lines
|
||||
if not line or line.startswith('//'):
|
||||
continue
|
||||
|
||||
try:
|
||||
# 移除行内注释
|
||||
# Remove inline comments
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
14246004
|
||||
0a915884
|
||||
02915884
|
||||
15110005
|
||||
0abffca5
|
||||
02bffca5
|
||||
00101486
|
||||
00111487
|
||||
00121488
|
||||
@@ -9,13 +9,13 @@
|
||||
0014948a
|
||||
0015148b
|
||||
00142d4c
|
||||
0a819001
|
||||
02819001
|
||||
29800024
|
||||
29801025
|
||||
2880002d
|
||||
2880102e
|
||||
580009a4
|
||||
0a80040f
|
||||
0280040f
|
||||
600008e6
|
||||
0a800410
|
||||
02800410
|
||||
53ffffff
|
||||
|
||||
Reference in New Issue
Block a user