Files
BSI-901-fpga-software/tmp/fpga_doc2/make_submodule_diagrams.py
T

51 lines
2.3 KiB
Python

from pathlib import Path
from PIL import Image, ImageDraw, ImageFont
OUT = Path(r"D:\Project\spinal_stim\pl\spinal_stim_v2\tmp\fpga_doc2\submodule_diagrams")
OUT.mkdir(parents=True, exist_ok=True)
try:
FONT = ImageFont.truetype(r"C:\Windows\Fonts\msyh.ttc", 24)
SMALL = ImageFont.truetype(r"C:\Windows\Fonts\msyh.ttc", 19)
except Exception:
FONT = SMALL = ImageFont.load_default()
def diagram(name, title, boxes, suffix):
im = Image.new("RGB", (1400, 520), "white")
d = ImageDraw.Draw(im)
d.text((30, 20), title, fill="black", font=FONT)
y = 180
w, h, gap = 235, 100, 45
total = len(boxes)*w + (len(boxes)-1)*gap
x = (1400-total)//2
for i, b in enumerate(boxes):
d.rounded_rectangle((x,y,x+w,y+h), radius=8, outline="#1f4e79", width=3, fill="#d9eaf7")
lines = b.split("\n")
yy = y + 20
for line in lines:
bb = d.textbbox((0,0), line, font=SMALL)
d.text((x+(w-(bb[2]-bb[0]))//2, yy), line, fill="black", font=SMALL)
yy += 28
if i < len(boxes)-1:
x2 = x+w+gap
d.line((x+w+5,y+h//2,x2-10,y+h//2), fill="#c00000", width=4)
d.polygon([(x2-10,y+h//2),(x2-25,y+h//2-10),(x2-25,y+h//2+10)], fill="#c00000")
x += w+gap
p = OUT / f"{name}_{suffix}.png"
im.save(p)
mods = {
"eeg_top": ["BRAM config", "SPI init\nstate machine", "DRDY sample\n24-bit x 8", "AXIS record"],
"emg_top": ["BRAM config", "ADS1299 reset\n/start", "DRDY sample\n8 channels", "AXIS EMG"],
"upload_top": ["Input packet", "Header + ID", "Channel map\n/filter", "CRC + TLAST"],
"eeg_emg_upload": ["EEG FIFO", "Select mode", "Drop head/tail\nmerge", "CRC + output"],
"cur_mon_top": ["CNV trigger", "SPI capture\nAD7689", "Map/filter\nstatistics", "Threshold\nfault latch"],
"rhs2116_top": ["Stim config", "DDS/timer", "SPI distribute", "Monitor/event"],
"channel_switch": ["PS GPIO/SPI", "Decode select", "ADG1414\nshift", "Switch state"],
"trigger_top": ["Input trigger", "Synchronize", "Detect edge\n/code", "Interrupt/stream"],
}
for name, boxes in mods.items():
diagram(name, f"{name} 状态/处理流程图", boxes, "flow")
diagram(name, f"{name} 数据流图", [boxes[0], boxes[1], boxes[2], boxes[3]], "data")
diagram(name, f"{name} 时序处理图", ["IDLE", "CONFIG", "RUN", "END"], "state")