FPGA筆記[2]-撥碼開關控制LED燈

qsBye發表於2024-05-19

摘要

使用四個撥碼開關的異或邏輯亮燈控制LED燈亮滅.

關鍵資訊

  • 系統macOS 14.4.1,Apple Silicon M2
  • 開發板:Sipeed-Tang-Primer-20k
  • FPGA晶片:GW2A-LV18PG256C8/I7(GW2A-18C-PBGA256)
  • 工具鏈:YosysHQ/oss-cad-suite

原理簡介

LUT4簡介

[https://wiki.sipeed.com/hardware/zh/tang/tang-primer-20k/examples/xor_led_on.html]
Tang Primer 20K 的主控晶片 GW2A-LV18PG256C8/I7 內部基本邏輯單元為 LUT4。LUT 即為查詢表(Look-Up-Table),本質上就是一個 RAM。它將資料事先寫入 RAM 後,每個輸入訊號就相當於目標內容地址,找出地址對應的內容,然後輸出。LUT4 指的是 4 個輸入訊號的查詢表。
如下程式碼中,我們恰好 使用4 個輸入和 1 個輸出。所以使用 1 個 lut4 就夠了。

實現

檔案結構

key.v
build.sh
tangprimer20k.cst

核心程式碼

key.v

module xor_led_on(
  input [5:2] dip_switch,
  output led
);
  assign led = dip_switch[5] ^ dip_switch[4] ^dip_switch[3] ^ dip_switch[2] ;
endmodule

(tips:VSCODE中cst檔案預設可能會使用Lushy Code開啟,右鍵檔案可以選擇以文字編輯器開啟檔案)
tangprimer20k.cst

IO_LOC "led" C13;
IO_LOC "dip_switch[5]" T5;
IO_LOC "dip_switch[4]" T4;
IO_LOC "dip_switch[3]" E8;
IO_LOC "dip_switch[2]" E9;
IO_PORT "led" PULL_MODE=UP DRIVE=8;
IO_PORT "dip_switch[5]" PULL_MODE=DOWN;
IO_PORT "dip_switch[4]" PULL_MODE=DOWN;
IO_PORT "dip_switch[3]" PULL_MODE=DOWN;
IO_PORT "dip_switch[2]" PULL_MODE=DOWN;

build.sh

export PATH=$PATH:/Applications/oss-cad-suite/bin
NAME="key"
yosys -p "read_verilog key.v; synth_gowin -json $NAME.json"
# 透過設定裝置名、CST檔案和剛才生成的 JSON 檔案來生成 FPGA 佈局和佈線資訊,並且放入 test_led_pnr.json 中。
nextpnr-gowin --device GW2A-LV18PG256C8/I7 --cst tangprimer20k.cst --json $NAME.json --write test_${NAME}_pnr.json
# 生成碼流
gowin_pack -d "GW2A-18" -o $NAME.fs test_${NAME}_pnr.json
# 燒錄
openFPGALoader -b tangprimer20k $NAME.fs

構建

chmod +x ./build.sh
./build.sh

輸出:

2.30. Printing statistics.

=== xor_led_on ===

   Number of wires:                  4
   Number of wire bits:             10
   Number of public wires:           4
   Number of public wire bits:      10
   Number of ports:                  2
   Number of port bits:              5
   Number of memories:               0
   Number of memory bits:            0
   Number of processes:              0
   Number of cells:                  6
     IBUF                            4
     LUT4                            1
     OBUF                            1

2.31. Executing CHECK pass (checking for obvious problems).
Checking module xor_led_on...
Found and reported 0 problems.

2.32. Executing JSON backend.

End of script. Logfile hash: 711b6756e0, CPU: user 0.23s system 0.02s
Yosys 0.41+69 (git sha1 07ac4c2fa, aarch64-apple-darwin21.4-clang++ 14.0.0-1ubuntu1.1 -fPIC -Os)
Time spent: 29% 19x read_verilog (0 sec), 13% 1x abc9_exe (0 sec), ...
Info: Series:GW2A-18 Device:GW2A-18 Package:PBGA256 Speed:C8/I7

Info: Packing constants..
Info: Packing Shadow RAM..
Info: Packing GSR..
Info: No GSR in the chip base
Info: Packing IOs..
Info: Packing diff IOs..
Info: Packing IO logic..
Info: Packing wide LUTs..
Info: Packing LUT5s..
Info: Packing LUT6s..
Info: Packing LUT7s..
Info: Packing LUT8s..
Info: Packing ALUs..
Info: Packing LUT-FFs..
Info: Packing non-LUT FFs..
Info: Packing PLLs..
Info: Checksum: 0x7495f0c9

Info: Device utilisation:
Info:                    VCC:       1/      1   100%
Info:                  SLICE:       1/  20736     0%
Info:                    IOB:       5/    383     1%
Info:                IOLOGIC:       0/    408     0%
Info:              MUX2_LUT5:       0/  10368     0%
Info:              MUX2_LUT6:       0/   5184     0%
Info:              MUX2_LUT7:       0/   2592     0%
Info:              MUX2_LUT8:       0/   2544     0%
Info:                    GND:       1/      1   100%
Info:                   RAMW:       0/    648     0%
Info:                    OSC:       0/      1     0%
Info:                   rPLL:       0/      4     0%

Info: Placed 5 cells based on constraints.
Info: Creating initial analytic placement for 1 cells, random placement wirelen = 192.
Info:     at initial placer iter 0, wirelen = 181
Info:     at initial placer iter 1, wirelen = 161
Info:     at initial placer iter 2, wirelen = 150
Info:     at initial placer iter 3, wirelen = 150
Info: Running main analytical placer, max placement attempts per cell = 10000.
Info:     at iteration #1, type SLICE: wirelen solved = 150, spread = 150, legal = 150; time = 0.00s
Info: HeAP Placer Time: 0.01s
Info:   of which solving equations: 0.00s
Info:   of which spreading cells: 0.00s
Info:   of which strict legalisation: 0.00s

Info: Running simulated annealing placer for refinement.
Info:   at iteration #1: temp = 0.000000, timing cost = 0, wirelen = 150
Info:   at iteration #2: temp = 0.000000, timing cost = 0, wirelen = 149 
Info: SA placement time 0.00s

Info: No Fmax available; no interior timing paths found in design.
Info: Checksum: 0x586e3d35

Info: Routing..
Info: Setting up routing queue.
Info: Routing 5 arcs.
Info:            |   (re-)routed arcs  |   delta    | remaining|       time spent     |
Info:    IterCnt |  w/ripup   wo/ripup |  w/r  wo/r |      arcs| batch(sec) total(sec)|
Info:          5 |        0          5 |    0     5 |         0|       0.01       0.01|
Info: Routing complete.
Info: Router1 time 0.01s
Info: Checksum: 0x35124c9c

Info: Critical path report for cross-domain path '<async>' -> '<async>':
Info: curr total
Info:  0.0  0.0  Source dip_switch_IBUF_I_3$iob.O
Info:  6.5  6.5    Net dip_switch_IBUF_I_O[3] (0,37) -> (45,44)
Info:                Sink led_OBUF_O_I_LUT4_F_LC.D
Info:                Defined in:
Info:                  /Applications/oss-cad-suite/libexec/../share/yosys/gowin/cells_map.v:130.20-130.21
Info:  0.4  6.8  Source led_OBUF_O_I_LUT4_F_LC.F
Info:  3.0  9.9    Net led_OBUF_O_I (45,44) -> (55,31)
Info:                Sink led_OBUF_O$iob.I
Info: 0.4 ns logic, 9.5 ns routing

Info: No Fmax available; no interior timing paths found in design.

Info: Program finished normally.
empty
Jtag frequency : requested 6.00MHz   -> real 6.00MHz  
Parse file Parse key.fs: 
Done
DONE
Load SRAM: [==================================================] 100.00%
Done
DONE

效果

四個撥碼開關 2、3、4、5 位有奇數個開關撥下是;LED0 熄滅,偶數個開關撥下時,LED0 點亮。

偶數個開關撥下 奇數個開關撥下

相關文章