Skip to content

Latest commit

ย 

History

History
516 lines (444 loc) ยท 26.1 KB

File metadata and controls

516 lines (444 loc) ยท 26.1 KB

ScratchV Architecture โ€” ONNX โ†’ RISC-V ็ผ–่ฏ‘ๅ…จๆต็จ‹

็‰ˆๆœฌ: 0.3.0 | ๆ›ดๆ–ฐ: 2026-06-05

ๆœฌๆ–‡ๆกฃๅฎŒๆ•ด่ฏดๆ˜Ž ScratchV ๅฆ‚ไฝ•ๅฐ† ONNX CNN ๆจกๅž‹็ผ–่ฏ‘ไธบ RISC-V ๅฏๆ‰ง่กŒไปฃ็ ๏ผŒ่ฆ†็›– ScratchV ๅŽŸ็”Ÿ่ทฏๅพ„๏ผˆQ16.16 ๅฎš็‚น๏ผ‰ ๅ’Œ LLVM ่ทฏๅพ„๏ผˆfloat32๏ผ‰ ไธคๆก็ผ–่ฏ‘็ฎก็บฟใ€‚


็›ฎๅฝ•

  1. ้กน็›ฎๆ€ป่งˆ
  2. ScratchV ๅŽŸ็”Ÿ่ทฏๅพ„๏ผšONNX โ†’ RISC-V ๆœบๅ™จ็ 
  3. LLVM ่ทฏๅพ„๏ผšONNX โ†’ LLVM IR โ†’ RISC-V
  4. ๅŒ่ทฏๅพ„ๅฏนๆฏ”
  5. ๆจกๅ—ๅœฐๅ›พ
  6. ๆ•ฐๆฎๆตไธŽๆ–‡ไปถๆ ผๅผ

1. ้กน็›ฎๆ€ป่งˆ

ScratchV ๆ˜ฏไธ€ไธช Python ๅฎž็Žฐ็š„ AI ็ผ–่ฏ‘ๅ™จ๏ผŒๅฐ† ONNX ๆทฑๅบฆๅญฆไน ๆจกๅž‹็ผ–่ฏ‘ไธบ RISC-V ๆŒ‡ไปค้›†ใ€‚

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚    ONNX ๆจกๅž‹ (.onnx)  โ”‚
                    โ”‚  Conv, Gemm, ReLU,   โ”‚
                    โ”‚  MaxPool, Sigmoid... โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ–ผ                               โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  ScratchV ๅŽŸ็”Ÿ่ทฏๅพ„    โ”‚     โ”‚     LLVM ่ทฏๅพ„         โ”‚
   โ”‚  (Q16.16 ๅฎš็‚น)        โ”‚     โ”‚  (float32 ๆตฎ็‚น)       โ”‚
   โ”‚                      โ”‚     โ”‚                      โ”‚
   โ”‚  ONNX โ†’ IR โ†’ RISC-V  โ”‚     โ”‚  ONNX โ†’ IR โ†’ LLVM IR โ”‚
   โ”‚  ๅŽŸ็”Ÿๆœบๅ™จ็  (.bin)    โ”‚     โ”‚  โ†’ llc โ†’ RISC-V      โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚                               โ”‚
              โ–ผ                               โ–ผ
        RV32IM ๆœบๅ™จ็                    RV64FD ๆฑ‡็ผ– / LLVM IR
        (ๆ— ไพ่ต–, ้›ถ runtime)            (ๅฏๆŽฅ llc/opt/lli)

่ฎพ่ฎกๅ“ฒๅญฆ:

  • Python ๆ ‡ๅ‡†ๅบ“ๅณๅฏ่ฟ่กŒ๏ผˆๆ ธๅฟƒ็ผ–่ฏ‘ๅ™จ้›ถๅค–้ƒจไพ่ต–๏ผ‰
  • ไธคๆก่ทฏๅพ„ๅ…ฑไบซๅŒไธ€ไธช IR ๅ‰็ซฏ๏ผŒๅŽ็ซฏๅˆ†ๅ‰
  • ๅŒ่ทฏๅพ„ๅฏนๆฏ” โ†’ ๆŒ็ปญไผ˜ๅŒ– ScratchV ่ถ…่ถŠ LLVM

2. ScratchV ๅŽŸ็”Ÿ่ทฏๅพ„๏ผšONNX โ†’ RISC-V ๆœบๅ™จ็ 

2.1 ๆฆ‚่งˆ

ONNX ๆจกๅž‹ๆ–‡ไปถ (.onnx)
        โ”‚
        โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Stage 1: ONNX ่งฃๆž (ProtoReader)         โ”‚
โ”‚  ๆ–‡ไปถ: scratchv/standalone/               โ”‚
โ”‚        onnx_to_riscv_standalone.py        โ”‚
โ”‚                                          โ”‚
โ”‚  ๆ‰‹ๅทฅ่งฃๆž protobuf wire format            โ”‚
โ”‚  โ†’ ๆๅ– graph nodes, initializers,        โ”‚
โ”‚     tensor shapes, weights, biases        โ”‚
โ”‚  โ†’ ๆž„ๅปบ ONNXModel ๅฏน่ฑก                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Stage 2: ๅ†…ๅญ˜่ง„ๅˆ’ (MemoryPlan)            โ”‚
โ”‚                                          โ”‚
โ”‚  ไธบๆƒ้‡/ๅ็ฝฎ/่พ“ๅ…ฅ/่พ“ๅ‡บๅˆ†้…ๅœฐๅ€็ฉบ้—ด          โ”‚
โ”‚  ๅฐ† float32 ๆƒ้‡่ฝฌไธบ Q16.16 ๅฎš็‚นๆ ผๅผ       โ”‚
โ”‚  โ†’ Q16.16: ้ซ˜ 16 ไฝๆ•ดๆ•ฐ, ไฝŽ 16 ไฝๅฐๆ•ฐ     โ”‚
โ”‚  โ†’ ๅ€ผๅŸŸ: [-32768, 32767.99998]           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Stage 3: RISC-V ไปฃ็ ็”Ÿๆˆ                   โ”‚
โ”‚  (CNNRISCVGenerator)                     โ”‚
โ”‚                                          โ”‚
โ”‚  ้€็ฎ—ๅญ็”Ÿๆˆๅ†…่” RISC-V ๆœบๅ™จ็ :              โ”‚
โ”‚                                          โ”‚
โ”‚  Conv2D:  6 ๅฑ‚ๅตŒๅฅ—ๅพช็Žฏ                      โ”‚
โ”‚    for oh in 0..OH:                      โ”‚
โ”‚      for ow in 0..OW:                    โ”‚
โ”‚        for oc in 0..OC:                  โ”‚
โ”‚          for kh in 0..KH:                โ”‚
โ”‚            for kw in 0..KW:              โ”‚
โ”‚              for ic in 0..IC:            โ”‚
โ”‚                load input[ic][h][w]       โ”‚
โ”‚                load weight[oc][ic][kh][kw]โ”‚
โ”‚                mul (Q16.16)              โ”‚
โ”‚                add (accumulate)          โ”‚
โ”‚              srai 16 (Q16.16 ๅฎš็‚น่ฟ˜ๅŽŸ)     โ”‚
โ”‚          + bias[oc]                      โ”‚
โ”‚          store output[oc][oh][ow]         โ”‚
โ”‚                                          โ”‚
โ”‚  Gemm:    3 ๅฑ‚ๅตŒๅฅ—ๅพช็Žฏ (ๆ”ฏๆŒ transB)       โ”‚
โ”‚  MaxPool: 5 ๅฑ‚ๅตŒๅฅ—ๅพช็Žฏ + ่พน็•Œๆฃ€ๆŸฅ           โ”‚
โ”‚  ReLU:    max(a0, zero)                  โ”‚
โ”‚  Sigmoid: ๆŸฅ่กจๆณ• + ็บฟๆ€งๆ’ๅ€ผ                โ”‚
โ”‚  Reshape: ็›ดๆŽฅๆ‹ท่ด                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Stage 4: ๆœบๅ™จ็ ็ผ–็  + ้“พๆŽฅ                  โ”‚
โ”‚  (RISCVEmitter)                          โ”‚
โ”‚                                          โ”‚
โ”‚  ๅฐ† RV32IM ๆŒ‡ไปค็ผ–็ ไธบ 32-bit ๆœบๅ™จ็           โ”‚
โ”‚  ไธค้ๆ‰ซๆ:                                 โ”‚
โ”‚    ็ฌฌไธ€้: emit ๆ‰€ๆœ‰ๆŒ‡ไปค, ่ฎฐๅฝ• label ไฝ็ฝฎ     โ”‚
โ”‚    ็ฌฌไบŒ้: ๅ›žๅกซๅˆ†ๆ”ฏ/่ทณ่ฝฌๅ็งป้‡ (fixup)        โ”‚
โ”‚  โ†’ ่พ“ๅ‡บ flat binary (.bin), position-     โ”‚
โ”‚    independent, ๅฏ็›ดๆŽฅๅŠ ่ฝฝๅˆฐๅ†…ๅญ˜ๆ‰ง่กŒ          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
            โ”‚  output.bin   โ”‚  โ† RV32IM flat binary
            โ”‚  output.s     โ”‚  โ† (ๅฏ้€‰) ไบบ็ฑปๅฏ่ฏปๆฑ‡็ผ–
            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

2.2 ๅ…ณ้”ฎ่ฎพ่ฎกๅ†ณ็ญ–

Q16.16 ๅฎš็‚น่ฟ็ฎ—:

  • ไน˜ๆณ•: MUL a, b โ†’ 64 ไฝ็ป“ๆžœ โ†’ SRAI 16 ๆˆชๆ–ญๅ›ž 32 ไฝ
  • ๅŠ ๆณ•: ็›ดๆŽฅ ADD๏ผˆๅฐๆ•ฐ็‚นๅฏน้ฝ๏ผ‰
  • ็ฒพๅบฆๆŸๅคฑ: ~1.5e-5 ็›ธๅฏน่ฏฏๅทฎ๏ผŒCNN ๆŽจ็†่ถณๅคŸ
  • ไปฃไปท: ๆฏไธช MAC ้œ€ ~30 ๆกๆŒ‡ไปค๏ผˆๅซๅœฐๅ€่ฎก็ฎ—ใ€ๅŠ ่ฝฝใ€ไน˜ๆณ•ใ€ๅฎš็‚น่ฟ˜ๅŽŸ๏ผ‰

ๆ—  Runtime ไพ่ต–:

  • ๆ‰€ๆœ‰็ฎ—ๅญ้€š่ฟ‡ๅ†…่”ๅพช็Žฏๅฎž็Žฐ๏ผŒไธไพ่ต–ๅค–้ƒจๅบ“
  • Flat binary ๅฏ็›ดๆŽฅๅŠ ่ฝฝๅˆฐ FPGA/ASIC ็š„ RISC-V ๆ ธๆ‰ง่กŒ
  • ๆƒ้‡ๅตŒๅ…ฅไบŒ่ฟ›ๅˆถๆ–‡ไปถไธญ

Q16.16 ๅฎš็‚น่ฝฌๆข:

def float32_to_q16(value: float) -> int:
    """ๅฐ† float32 ่ฝฌไธบ Q16.16 ๅฎš็‚นๆ•ดๆ•ฐ"""
    # ไน˜ไปฅ 2^16 = 65536๏ผŒๅ–ๆ•ด
    return int(value * 65536.0) & 0xFFFFFFFF  # 32-bit ๆˆชๆ–ญ

2.3 ๅ‘ฝไปค่กŒ

# ScratchV ๅŽŸ็”Ÿ็ผ–่ฏ‘
python scratchv/standalone/onnx_to_riscv_standalone.py models/graph/cnn.onnx \
    -o output.bin          # ่พ“ๅ‡บ flat binary
    --asm output.s         # ๅŒๆ—ถ่พ“ๅ‡บๆฑ‡็ผ–
    --estimate             # ๆ€ง่ƒฝไผฐ็ฎ— (ๅŠจๆ€ๆŒ‡ไปคๆ•ฐ)
    --report               # ็”Ÿๆˆ่ฏฆ็ป†ๆŠฅๅ‘Š

3. LLVM ่ทฏๅพ„๏ผšONNX โ†’ LLVM IR โ†’ RISC-V

3.1 ๆฆ‚่งˆ

ONNX ๆจกๅž‹ๆ–‡ไปถ (.onnx)
        โ”‚
        โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Stage 1: ONNX ่งฃๆž                        โ”‚
โ”‚  ๆ–‡ไปถ: scratchv/standalone/               โ”‚
โ”‚        onnx_to_llvm_standalone.py         โ”‚
โ”‚                                          โ”‚
โ”‚  ๅค็”จ ONNXModel (ๅŒๅŽŸ็”Ÿ่ทฏๅพ„)                โ”‚
โ”‚  ๆๅ–่Š‚็‚นไฟกๆฏใ€ๆƒ้‡ใ€tensor ๅฝข็Šถ             โ”‚
โ”‚  โ†’ ๆƒ้‡ไฟๆŒ float32 (ไธ่ฝฌ Q16.16)          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Stage 2: LLVM IR ็”Ÿๆˆ                      โ”‚
โ”‚  (LLVMCNNGenerator + LLVMIRBuilder)       โ”‚
โ”‚                                          โ”‚
โ”‚  ้€็ฎ—ๅญ็”Ÿๆˆ float32 LLVM IR:               โ”‚
โ”‚                                          โ”‚
โ”‚  ; ็คบไพ‹: Conv2D ๅ†…ๅฑ‚ๅพช็Žฏ็š„ LLVM IR ็‰‡ๆฎต       โ”‚
โ”‚  %idx = getelementptr float, float** %w, โ”‚
โ”‚         i32 %w_offset                     โ”‚
โ”‚  %w_val = load float, float* %idx         โ”‚
โ”‚  %in_val = load float, float* %in_ptr     โ”‚
โ”‚  %mul = fmul float %in_val, %w_val        โ”‚
โ”‚  %acc = fadd float %acc, %mul             โ”‚
โ”‚                                          โ”‚
โ”‚  ็‰นๆ€ง:                                    โ”‚
โ”‚  - ็œŸๆญฃ็š„ float32 ่ฟ็ฎ— (fmul, fadd, fdiv)  โ”‚
โ”‚  - GEP ๅœฐๅ€่ฎก็ฎ— (ๆ›ฟไปฃๆ‰‹ๅŠจ MUL+ADD)          โ”‚
โ”‚  - ๅตŒๅฅ—ๅพช็Žฏ + padding ่พน็•Œๆฃ€ๆŸฅ              โ”‚
โ”‚  - ๅ‡ฝๆ•ฐ็ญพๅ: float* (ๆŒ‡้’ˆไผ ้€’ tensor)        โ”‚
โ”‚  - target triple: riscv64-unknown-elf     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Stage 3: LLVM ไผ˜ๅŒ– + ็›ฎๆ ‡ไปฃ็ ็”Ÿๆˆ (ๅค–้ƒจ)      โ”‚
โ”‚                                          โ”‚
โ”‚  ้€‰้กน A: llc (้™ๆ€็ผ–่ฏ‘)                      โ”‚
โ”‚    $ llc output.ll -o output.s           โ”‚
โ”‚       -O3 -march=rv64fd                   โ”‚
โ”‚    โ†’ RISC-V 64-bit float ๆฑ‡็ผ–              โ”‚
โ”‚                                          โ”‚
โ”‚  ้€‰้กน B: opt + llc (่‡ชๅฎšไน‰ไผ˜ๅŒ–)              โ”‚
โ”‚    $ opt -O3 output.ll | llc -O3 -o out.s โ”‚
โ”‚    โ†’ LLVM ๅ…จๅฅ—ไผ˜ๅŒ– pass                    โ”‚
โ”‚                                          โ”‚
โ”‚  ้€‰้กน C: lli (JIT ๆ‰ง่กŒ)                     โ”‚
โ”‚    $ lli output.ll                        โ”‚
โ”‚    โ†’ ็›ดๆŽฅๅœจไธปๆœบไธŠ JIT ่ฟ่กŒ (่ฐƒ่ฏ•/้ชŒ่ฏ)        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚  output.ll          โ”‚  โ† LLVM IR ๆ–‡ๆœฌ
        โ”‚  output.s (via llc) โ”‚  โ† RISC-V ๆฑ‡็ผ–
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

3.2 ๅ…ณ้”ฎ่ฎพ่ฎกๅ†ณ็ญ–

Float32 ๅŽŸ็”Ÿ่ฟ็ฎ—:

  • ๆฏๆก MAC = fmul + fadd โ‰ˆ 2 ๆกๆŒ‡ไปค๏ผˆvs Q16.16 ็š„ ~30 ๆก๏ผ‰
  • ๆ— ้œ€ๅฎš็‚น่ฝฌๆขๅผ€้”€
  • ไธŽ ONNX ๅŽŸๅง‹็ฒพๅบฆไธ€่‡ด๏ผŒๆ•ฐๅ€ผ้ชŒ่ฏๆ›ด็ฎ€ๅ•

LLVM IR ไฝœไธบไธญ้—ดไบง็‰ฉ:

  • ๅฏๆŽฅ LLVM ๅ…จๅฅ—ไผ˜ๅŒ– pass (-O3: ๅพช็Žฏๅฑ•ๅผ€ใ€ๅ‘้‡ๅŒ–ใ€ๆŒ‡ไปคๅˆๅนถ...)
  • ๅฏๅคš็›ฎๆ ‡็ผ–่ฏ‘๏ผˆRV64, x86-64, ARM๏ผ‰
  • ไบบ็ฑปๅฏ่ฏป็š„ SSA ๆ–‡ๆœฌๆ ผๅผ๏ผŒไพฟไบŽๅˆ†ๆžๅ’Œ่ฐƒ่ฏ•

GEP ๅœฐๅ€่ฎก็ฎ—:

  • LLVM ็š„ getelementptr ๆŒ‡ไปคๅ•ๆกๅฎŒๆˆๅคš็ปดๆ•ฐ็ป„ๅœฐๅ€่ฎก็ฎ—
  • ๆ›ฟไปฃ ScratchV ๅŽŸ็”Ÿ่ทฏๅพ„ไธญๆ‰‹ๅŠจ็š„ ~5 ๆก MUL + ADD ้“พ

3.3 ๅ‘ฝไปค่กŒ

# LLVM IR ็”Ÿๆˆ
python scratchv/standalone/onnx_to_llvm_standalone.py models/graph/cnn.onnx \
    -o output.ll           # ่พ“ๅ‡บ LLVM IR
    --compare              # ไธŽ ScratchV ๅฏนๆฏ”ไผฐ็ฎ—

# ็”จ llc ็ผ–่ฏ‘ไธบ RISC-V ๆฑ‡็ผ–
llc -O3 -march=rv64fd -mattr=+d output.ll -o output.s

# LLVM vs ScratchV ็ผ“ๅญ˜ๅฏนๆฏ”ๅˆ†ๆž
python scratchv/standalone/llvm_cache_compare.py \
    --json-output output/llvm_vs_scratchv.json

4. ๅŒ่ทฏๅพ„ๅฏนๆฏ”

4.1 ๆžถๆž„ๅทฎๅผ‚

็ปดๅบฆ ScratchV ๅŽŸ็”Ÿ LLVM
ๆ•ฐๅ€ผๆ ผๅผ Q16.16 ๅฎš็‚น (int32) IEEE 754 float32
็›ฎๆ ‡ ISA RV32IM (ๆ•ดๆ•ฐ) RV64FD (ๆตฎ็‚น)
่พ“ๅ‡บๆ ผๅผ Flat binary (.bin) LLVM IR (.ll)
ๆฏๆก MAC ๆŒ‡ไปคๆ•ฐ ~30 ๆก ~2 ๆก
ไพ่ต– Python stdlib ้œ€่ฆ llvmlite / llc
่ฟ่กŒๆ—ถ ้›ถไพ่ต–, ็›ดๆŽฅๆ‰ง่กŒ ้œ€่ฆ C runtime (printf ็ญ‰)
ๅฏ็งปๆคๆ€ง RV32IM ้€š็”จ ไพ่ต– LLVM ๅทฅๅ…ท้“พ
ไผ˜ๅŒ–่ƒฝๅŠ› ๆ‰‹ๅŠจๅ†…่”ๅพช็Žฏ LLVM ๅ…จๅฅ—ไผ˜ๅŒ– pass
ๆ•ฐๅ€ผ็ฒพๅบฆ ~1.5e-5 ็›ธๅฏน่ฏฏๅทฎ ๅŽŸ็”Ÿ float32

4.2 ๆ€ง่ƒฝๆ•ฐๆฎ (cnn.onnx: 3ร—Conv + 3ร—MaxPool + 2ร—FC)

ๆŒ‡ๆ ‡ LLVM (RV64FD) ScratchV (RV32IM) ๆฏ”ๅ€ผ
้™ๆ€ๆŒ‡ไปคๆ•ฐ 1,059 785 0.74x
ๅŠจๆ€ๆŒ‡ไปคๆ•ฐ 18.5 ไบฟ 77.7 ไบฟ 4.2x
ๅŠจๆ€ Load 5.27 ไบฟ (28.6%) 15.6 ไบฟ (20.1%) 0.34x
ๅŠจๆ€ Store 0.03 ไบฟ (0.2%) 5.19 ไบฟ (6.7%) 0.01x
ๅŠจๆ€ FP/ALU 5.25 ไบฟ (28.4%) 46.6 ไบฟ (60.0%) 0.14x
ๅŠจๆ€ Branch 0.81 ไบฟ (4.4%) 5.20 ไบฟ (6.7%) 0.16x
D$ ๅ‘ฝไธญ็އ 88.75% 88.75% 1:1
D$ ็ผบๅคฑๅญ—่Š‚ 19.1 ไบฟ 74.8 ไบฟ 3.9x
็ปผๅˆๅŠ ้€Ÿๆฏ” 1x (baseline) 0.23x LLVM 4.4x ๅฟซ

4.3 ไธบไป€ไนˆ ScratchV ๆ…ข 4.4x๏ผŸ

  1. Q16.16 ๅฎš็‚นๅผ€้”€ (ไธปๅ› ): ๆฏไธช MAC ้œ€่ฆ ~15 ๆกๆ•ดๆ•ฐๆŒ‡ไปค๏ผˆMUL โ†’ SRAI 16 โ†’ ADD + ๆบขๅ‡บๅค„็†๏ผ‰๏ผŒ่€Œ LLVM float32 ๅช้œ€ fmul + fadd โ‰ˆ 2 ๆก
  2. ๅœฐๅ€่ฎก็ฎ—ๅผ€้”€: ๆ—  getelementptr๏ผŒๆ‰‹ๅŠจ MUL + ADD ้“พ ~5 ๆก/ๆฌก
  3. Store ๅทฎ่ท: ScratchV ๆฏไธช่พ“ๅ‡บๅ…ƒ็ด ้ƒฝ้œ€่ฆ SW ๅ†™ๅ›ž๏ผŒLLVM ๅฏๅฐ†ไธญ้—ด็ป“ๆžœไฟ็•™ๅœจๆตฎ็‚นๅฏ„ๅญ˜ๅ™จไธญ
  4. ๅพช็Žฏๅ˜ๆข: LLVM -O3 ่‡ชๅŠจๅš loop unrolling / interchange / vectorization๏ผŒScratchV ๆ— ไปปไฝ•ๅพช็Žฏไผ˜ๅŒ–

4.4 ่ถ…่ถŠ่ทฏ็บฟ

ScratchV ็š„ไผ˜ๅŠฟไธๅœจไบŽ้€š็”จ็ผ–่ฏ‘๏ผŒ่€ŒๅœจไบŽ CNN ไธ“็”จไผ˜ๅŒ–:

  1. ็ฎ—ๅญ่žๅˆ: Conv+ReLU ็ซฏๅˆฐ็ซฏ่žๅˆ๏ผŒๆถˆ้™คไธญ้—ด store/load
  2. ๅ†…ๅญ˜ๅธƒๅฑ€ๅฎšๅˆถ: CHWโ†’HWC ๅ˜ๆขๆๅ‡ cache ๅฑ€้ƒจๆ€ง
  3. ไธ“็”จๆŒ‡ไปค: ๅฆ‚ๆžœ็กฌไปถๆ”ฏๆŒ SIMD/P ๆ‰ฉๅฑ•๏ผŒLLVM ไธไธ€ๅฎš่ƒฝ่‡ชๅŠจๅˆฉ็”จ
  4. ็ฒพๅบฆ/้€ŸๅบฆๆŠ˜ไธญ: Q16.16 ๅœจๆŽจ็†ๅœบๆ™ฏ่ถณๅคŸ๏ผŒๅฏๅฐ่ฏ• Q8.8 ่ฟ›ไธ€ๆญฅๅ‡ๅฐ‘ๆŒ‡ไปค

5. ๆจกๅ—ๅœฐๅ›พ

ScratchV ้กน็›ฎ โ€” ๅฎŒๆ•ดๆจกๅ—ๅœฐๅ›พ
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        ๅ‰็ซฏ (Frontend)                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  scratchv/frontend/onnx_parser.py     ONNX ๆจกๅž‹่งฃๆž           โ”‚
โ”‚  scratchv/frontend/dsl_parser.py      DSL ่งฃๆž (ๆ—  ONNX ไพ่ต–) โ”‚
โ”‚  scratchv/frontend/dsl_extended.py    ๆ‰ฉๅฑ• DSL (if/while)     โ”‚
โ”‚  scratchv/frontend/dsl_errors.py      DSL ้”™่ฏฏๆ็คบ            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      ไธญ้—ด่กจ็คบ (IR)                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  scratchv/ir/types.py        OpCode, Value, DataType ๅฎšไน‰     โ”‚
โ”‚  scratchv/ir/builder.py      IRBuilder (ไธ‰ๅœฐๅ€็ ๆž„้€ ๅ™จ)       โ”‚
โ”‚  scratchv/ir/printer.py      IRPrinter (ๆ–‡ๆœฌ่พ“ๅ‡บ)            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ–ผ                               โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   ไผ˜ๅŒ–ๅ™จ (Optimizer)        โ”‚   โ”‚   ๅˆ†ๆž (Analysis)          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ constant_folding.py       โ”‚   โ”‚ cfg_builder.py             โ”‚
โ”‚ dead_code.py              โ”‚   โ”‚ ir_verifier.py             โ”‚
โ”‚ peephole.py               โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ muladd_fusion.py          โ”‚
โ”‚ licm.py (ๅพช็Žฏไธๅ˜้‡ๅค–ๆ)    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚
              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    ๅŽ็ซฏ (Backend) โ€” ไธคๆก่ทฏๅพ„                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                             โ”‚
โ”‚  RISC-V ไปฃ็ ็”Ÿๆˆ:                   LLVM ไปฃ็ ็”Ÿๆˆ:              โ”‚
โ”‚  โ”œ instruction_select.py            โ”” llvm_codegen.py        โ”‚
โ”‚  โ”œ inst_select_ext.py                   (IR โ†’ LLVM IR)       โ”‚
โ”‚  โ”œ register_alloc.py                                          โ”‚
โ”‚  โ”œ regalloc_linear.py                                        โ”‚
โ”‚  โ”œ asm_emit.py                                               โ”‚
โ”‚  โ”œ asm_peephole.py    (ๅŽไผ˜ๅŒ–)                                 โ”‚
โ”‚  โ”œ const_merge.py     (ๅธธ้‡ๅˆๅนถ)                                โ”‚
โ”‚  โ”œ asm_beautifier.py  (ๆ ผๅผๅŒ–)                                 โ”‚
โ”‚  โ”œ inst_scheduler.py  (ๆŒ‡ไปค่ฐƒๅบฆ)                                โ”‚
โ”‚  โ”œ inst_counter.py    (ๆŒ‡ไปค็ปŸ่ฎก)                                โ”‚
โ”‚  โ”œ cycle_estimator.py (ๆตๆฐด็บฟๆจกๆ‹Ÿ)                               โ”‚
โ”‚  โ”œ riscv_encoder.py   (ๆฑ‡็ผ–โ†’ๆœบๅ™จ็ )                              โ”‚
โ”‚  โ”” machine_types.py   (็ฑปๅž‹ๅฎšไน‰)                                โ”‚
โ”‚                                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 ็‹ฌ็ซ‹ๅทฅๅ…ท (Standalone)                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  onnx_to_riscv_standalone.py  ONNX โ†’ RV32IM ๅŽŸ็”Ÿ็ผ–่ฏ‘ๅ™จ         โ”‚
โ”‚  onnx_to_llvm_standalone.py   ONNX โ†’ LLVM IR ็ผ–่ฏ‘ๅ™จ           โ”‚
โ”‚  benchmark.py                 RV32IM ไปฟ็œŸๅ™จ + ๆ€ง่ƒฝ่ฎกๆ•ฐๅ™จ       โ”‚
โ”‚  cache_model.py               Set-associative cache ๆจกๅž‹      โ”‚
โ”‚  spike_sim.py                 Spike ไปฟ็œŸๅ™จๅŒ…่ฃ…                 โ”‚
โ”‚  run_spike_bench.py           ๅธฆ cache ็š„ๅฎŒๆ•ดไปฟ็œŸๅ™จ            โ”‚
โ”‚  llvm_cache_compare.py        LLVM vs ScratchV ็ผ“ๅญ˜ๅฏนๆฏ”       โ”‚
โ”‚  tinyfive_compare.py          TinyFive ้™ๆ€ๅฏนๆฏ”               โ”‚
โ”‚  compare_codegen.py           ไปฃ็ ็”Ÿๆˆ่ดจ้‡ๅฏนๆฏ”                  โ”‚
โ”‚  rv32_bench.py                RV32 ๅ…จ้‡ Benchmark             โ”‚
โ”‚  bench_report.py              HTML/JSON/MD ๆŠฅๅ‘Š็”Ÿๆˆ           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    CI / Dashboard                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  scratchv/ci/ci_benchmark.py   CI ๅŸบๅ‡†ๆต‹่ฏ•็ผ–ๆŽ’ๅ™จ               โ”‚
โ”‚  scratchv/ci/dashboard.py     ๆ€ง่ƒฝๅฏนๆฏ”ไปช่กจ็›˜ (็บฏ้™ๆ€ HTML)      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              ๆจกๆ‹Ÿๅ™จ / ้ชŒ่ฏ (Simulator / Verification)          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  scratchv/simulator/tinyfive.py   TinyFive ้€‚้…ๅ™จ             โ”‚
โ”‚  scratchv/simulator/rv32_emulator.py  RV32IM ๅ…จๅŠŸ่ƒฝไปฟ็œŸๅ™จ     โ”‚
โ”‚  scratchv/verification/verifier.py  ONNX Runtime / numpy ้ชŒ่ฏ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

6. ๆ•ฐๆฎๆตไธŽๆ–‡ไปถๆ ผๅผ

6.1 ScratchV ๅŽŸ็”Ÿ่ทฏๅพ„ๆ–‡ไปถ่ฝฌๆข้“พ

models/graph/cnn.onnx               โ† ่พ“ๅ…ฅ: ONNX protobuf
       โ”‚
       โ”‚  onnx_to_riscv_standalone.py
       โ–ผ
output.bin                          โ† RV32IM flat binary (position-independent)
output.s                            โ† (ๅฏ้€‰) GAS ๆฑ‡็ผ–
benchmark_reports/cnn_scratchv.s    โ† CI ไบง็‰ฉ

6.2 LLVM ่ทฏๅพ„ๆ–‡ไปถ่ฝฌๆข้“พ

models/graph/cnn.onnx               โ† ่พ“ๅ…ฅ: ONNX protobuf
       โ”‚
       โ”‚  onnx_to_llvm_standalone.py
       โ–ผ
benchmark_reports/cnn.onnx_llvm.ll  โ† LLVM IR ๆ–‡ๆœฌ
       โ”‚
       โ”‚  llc -O3 -march=rv64fd
       โ–ผ
output.s                            โ† RISC-V 64 ๆฑ‡็ผ–

6.3 CI ไบง็‰ฉๆ•ฐๆฎๆต

models/graph/cnn.onnx
       โ”‚
       โ”œโ”€โ”€โ†’ onnx_to_riscv_standalone.py โ†’ cnn_scratchv.s โ†’ tinyfive_compare.py
       โ”‚                                                          โ”‚
       โ””โ”€โ”€โ†’ onnx_to_llvm_standalone.py  โ†’ cnn.onnx_llvm.ll        โ”‚
                     โ”‚                                            โ”‚
                     โ””โ”€โ”€โ†’ llvm_cache_compare.py โ†โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ”œโ”€โ”€ benchmark_reports/llvm_vs_scratchv.json
                              โ”œโ”€โ”€ benchmark_reports/llvm_vs_scratchv.md
                              โ””โ”€โ”€โ†’ dashboard.py
                                       โ”‚
                                       โ–ผ
                              benchmark_reports/dashboard.html
                                       โ”‚
                                       โ”‚  upload-pages-artifact
                                       โ–ผ
                              https://scratchv-compiler.github.io/ScratchV/

6.4 Q16.16 ๅฎš็‚นๆ ผๅผ

32-bit ๆ•ดๆ•ฐ็š„้ซ˜ 16 ไฝ = ๆ•ดๆ•ฐ้ƒจๅˆ†
32-bit ๆ•ดๆ•ฐ็š„ไฝŽ 16 ไฝ = ๅฐๆ•ฐ้ƒจๅˆ†

ไพ‹: 3.14159 โ†’ int(3.14159 ร— 65536) = 205887
     205887 = 0x0003243F
     ้ซ˜ 16 ไฝ: 0x0003 = 3 (ๆ•ดๆ•ฐ้ƒจๅˆ†)
     ไฝŽ 16 ไฝ: 0x243F โ‰ˆ 0.14159 (ๅฐๆ•ฐ้ƒจๅˆ†, ็ฒพๅบฆ 1/65536 โ‰ˆ 1.5e-5)

ไน˜ๆณ•: MUL a, b โ†’ 64-bit โ†’ SRAI 16 (ๅณ็งป 16 ไฝๆˆชๆ–ญ)
     ๅ› ไธบ (a ร— 2^16) ร— (b ร— 2^16) = (a ร— b) ร— 2^32
     ้œ€่ฆๅณ็งป 16 ไฝ่ฟ˜ๅŽŸไธบ Q16.16 โ†’ ็ป“ๆžœ ร— 2^16

ๅŠ ๆณ•: ADD a, b  (็›ดๆŽฅๅŠ ๏ผŒๅฐๆ•ฐ็‚นๅทฒๅฏน้ฝ)

้™„ๅฝ•: ๅ…ณ้”ฎๅ‘ฝไปค้€ŸๆŸฅ

# ScratchV ๅŽŸ็”Ÿ็ผ–่ฏ‘ + ไผฐ็ฎ—
python scratchv/standalone/onnx_to_riscv_standalone.py models/graph/cnn.onnx \
    -o output.bin --asm output.s --estimate --report

# LLVM IR ็”Ÿๆˆ + ๅฏนๆฏ”
python scratchv/standalone/onnx_to_llvm_standalone.py models/graph/cnn.onnx \
    -o output.ll --compare

# LLVM vs ScratchV ็ผ“ๅญ˜ๅฏนๆฏ”
python scratchv/standalone/llvm_cache_compare.py \
    --json-output output/llvm_vs_scratchv.json

# TinyFive ้™ๆ€ๅˆ†ๆž
python scratchv/standalone/tinyfive_compare.py \
    --json output/tinyfive_compare.json

# Dashboard ็”Ÿๆˆ
python scratchv/ci/dashboard.py \
    --llvm-json output/llvm_vs_scratchv.json \
    --tinyfive-json output/tinyfive_compare.json \
    -o dashboard.html

# ไธ€้”ฎ CI ๅ…จ้ƒจ
make bench-ci

# Harness ้ชŒ่ฏ
python .claude/harness/verify/run.py --level L2

็›ธๅ…ณๆ–‡ๆกฃ