generated from chipsalliance/chisel-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathload_program.py
More file actions
83 lines (70 loc) · 2.95 KB
/
load_program.py
File metadata and controls
83 lines (70 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env python3
"""
RISC-V program loader for Basys3
Sends a .hex file over UART to the uart_program_loader module.
Usage:
python3 load_program.py program.hex
python3 load_program.py program.hex --port /dev/ttyUSB1
python3 load_program.py program.hex --port COM3 --baud 115200
"""
import serial
import time
import sys
import argparse
# -------------------------------------------------------
# Argument parsing
# -------------------------------------------------------
parser = argparse.ArgumentParser(description="Load a RISC-V hex program onto Basys3 over UART")
parser.add_argument("hex_file", help="Path to the .hex program file")
parser.add_argument("--port", default="/dev/ttyUSB1", help="Serial port (default: /dev/ttyUSB0)")
parser.add_argument("--baud", default=115200, type=int, help="Baud rate (default: 115200)")
parser.add_argument("--delay", default=0.01, type=float, help="Delay between words in seconds (default: 0.01)")
args = parser.parse_args()
# -------------------------------------------------------
# Read hex file
# -------------------------------------------------------
words = []
try:
with open(args.hex_file, 'r') as f:
for lineno, line in enumerate(f, 1):
line = line.strip()
if not line or line.startswith("//") or line.startswith("#"):
continue
try:
word = int(line, 16)
words.append(word)
except ValueError:
print(f"Warning: skipping invalid line {lineno}: '{line}'")
except FileNotFoundError:
print(f"Error: file '{args.hex_file}' not found")
sys.exit(1)
if not words:
print("Error: no valid words found in hex file")
sys.exit(1)
print(f"Loaded {len(words)} words ({len(words) * 4} bytes) from '{args.hex_file}'")
# -------------------------------------------------------
# Send over UART
# -------------------------------------------------------
try:
with serial.Serial(args.port, args.baud, timeout=2) as ser:
print(f"Opened {args.port} at {args.baud} baud")
print("Sending program...")
for i, word in enumerate(words):
# Little-endian: LSB first
data = word.to_bytes(4, byteorder='little')
ser.write(data)
time.sleep(args.delay)
# Progress bar
pct = (i + 1) / len(words) * 100
bar = '█' * int(pct / 2) + '░' * (50 - int(pct / 2))
print(f"\r[{bar}] {pct:.1f}% ({i+1}/{len(words)} words)", end='', flush=True)
print() # newline after progress bar
# Send end sequence: 4x 0xFF
print("Sending end sequence (0xFF 0xFF 0xFF 0xFF)...")
ser.write(bytes([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]))
time.sleep(0.1)
print("Done! CPU should now be running your program.")
except serial.SerialException as e:
print(f"Serial error: {e}")
print(f"Make sure the board is connected and '{args.port}' is correct")
sys.exit(1)