# FPGA 共筆 南大 [TOC] # 環境設定 > 使用 Windows 的同學請直接去安裝 Quartus II,因為 mac 和 linux 沒有與其相同版本的 Quartus II,所以可以採用以下方法 ## Verilog Linux ```bash sudo apt update sudo apt install iverilog gtkwave ``` macOS: (請事先安裝好 [brew](https://brew.sh) ) ```bash brew install icarus-verilog gtkwave ``` ## VHDL Linux ```bash sudo apt update sudo apt install ghdl gtkwave ``` macOS: (請事先安裝好 [brew](https://brew.sh) ) ```bash brew install ghdl brew install --cask gtkwave ``` # 語法 ## Cheatsheets * Verilog: https://marceluda.github.io/rp_dummy/EEOF2018/Verilog_Cheat_Sheet.pdf * VHDL: https://owd.tcnj.edu/~hernande/r/VHDL_QRC__01.pdf ## Comments Verilog ``` verilog // One line comment /* Two line comment just like C */ ``` VHDL ```vhdl -- This is the only way -- to comment in VHDL -- yeck! 🤮 ``` ## Modules ```verilog module name( // Input and output ); // your code here endmodule module name(); // no input, etc testbench endmodule ``` ```vhdl -- What on earth is this?? entity entity_name is port ( -- your input and output ); end entity_name; architecture arch_name is -- constants, variable, singals, components -- can be declared here begin -- your code here end arch_name; -- no input, etc testbench entity entity_name is port (); end entity_name; -- remain the same... ``` ## Input and Output Verilog ```verilog module main( // inputs input a, // one bit input input[0:3] b, // little endian input input[3:0] c, // big endian input // outputs output d, // one bit output output[0:3] e, // little endian output output[0:3] f, // big endian output // register (memorize your state) output reg g // register also as an output // no "," at the end ); reg h; // a register reg[0:7] i; // one byte register // your code here endmodule // also can written in module main(a,b,c,d,e,f,g); // inputs input a, // one bit input input[0:3] b, // little endian input input[3:0] c, // big endian input // outputs output d, // one bit output output[0:3] e, // little endian output output[0:3] f, // big endian output // register (memorize your state) output reg g // register also as an output reg h; reg[0:7] i; endmodule ``` VHDL ```vhdl entity example_entity is port( a: in std_logic; b: in std_logic_vector(0 to 3); c: in std_logic_vector(3 downto 0); d: out std_logic; e: out std_logic_vector(0 to 3); f: out std_logic_vector(3 downto 0); ); end example_entity; ``` # Testbench 撰寫 > 這裡假設你對 Verilog 的撰寫擁有一定的基礎 ## Verilog Testbench 的結構大致會呈現如下: 你一定會有一個 main module,這裡假設是 `main.v` 和 main: ```verilog module main( ... ); ... your code here ... endmodule ``` testbench 基本上就是一個程式測資,和任何程式的 unit test 一樣,他是一個可以運作的程式(在這裏是電路) 你一定會這幾個段落: 1. 測試的輸入和輸出 變數/wire/暫存器,偶爾可能還會有一些測試資料 2. 你需要在 tester 裡調用你自己的 main module(top level entry ) 3. 你需要 clock 和留有一些 delay 給你的程式,如下定義 main_test.v ```verilog `timescale 1ns/ 1ns `include "main.v" module tester(); // inputs for your main module reg clk; reg reset; reg start; reg din; // outputs for your main module // > outputs should always be "wire" wire count_out; wire[0:3] count_one; wire dout_valid; wire dout; // your constants data reg[0:7] data = 8'b01010010; // This part will // connect your main module into tester module main m( .reset(reset), .clk(clk), .start(start), .din(din), .count_out(count_out), .count_one(count_one), .dout_valid(dout_valid), .dout(dout) ); // maybe some integer to count on integer i; // the part of only run once initial begin // this part is very important! // this define the vvp (runtime) to output // the wave file result main_test.vcd // for later with the signals inside tester module $dumpfile("main_test.vcd"); $dumpvars(0, tester); clk = 0; reset = 0; start = 0; din = 0; // send a reset signal // this means waiting 2 unit of time // as well as defined in $timescale #2; reset = 1; #2; reset = 0; // ... for (i = 0; i < 8; i = i + 1) begin din = data[i]; #2; end // ... // This is also very important! // To stop the vvp simulation, // you'll need this line $finish; end // generate clock signal for every 1 unit of time // // why not #2? because one cycle of clock // required two changes, high and low, // so the program above will wait every 2 unit of time always #1 clk = ~clk; endmodule ``` 最後再執行這個 tester 就可以了。 vvp 是 iverilog 的模擬環境,用來模擬你編譯好的 verilog。 ``` iverilog -o main_test.vvp main_test.v vvp main_test.vvp ``` 模擬完後理論上會出現一個 main_test.vcd 1. 在你的資料夾內,用 GTKWave File > Open Tab 開啟這個檔案 2. 再SST裡選擇你的 module 3. 在下方選擇要觀測的訊號,按下最下面的 Insert 4. 然後就可以看到你的執行結果了。 如果你再次模擬了程式,只需要 File > Reload Waveform 或按下快捷鍵 Ctrl+Shift+R 即可載入最新結果 # 延深閱讀 ## 影片教學 用 GHDL + gtkwave 模擬 VHDL {%youtube j9hya97kRJA %} 用 iverilog + gtkwave 模擬 verilog {%youtube 3Xm6fgKAO94 %} ## Links * 如何寫 Testbench:https://ithelp.ithome.com.tw/articles/10192465