# Verilog 基本語法整理與心得
## 常用指令
```verilog=
// run testbench
$ ncverilog filename +access+r
$ vcs +v2k -f sim.f -R -full64 -debug_acc
// run .f file(將hdl、testbench、+access+r寫在.f檔)
$ ncverilog -f filelist(.f)
// copy file
$ cp test.log ../result/
// copy all folder
$ cp -r lab1/ ~/Backup/
// 常用軟體
//// 文字編輯器
$ gedit filename &
$ verdi &
$ nWave &
// run spyglass (to get spyglass report)
$ sg_shell < spy.tcl
// 合成電路
$ dc_shell –f synthesis.tcl | tee da.log
// open LEC GUI
$ lec -xl -gui &
// run .bat (LEC)
$ sh run_lec.bat
// run primetime
$ pt_shell -f pt_px.tcl
//***********************//
// innovus //
//***********************//
// DRC
$ verify_drc -report fir_DRC.log
// LVS
$ verifyConnectivity -type all -noAntenna -error 1000 -warning 50 -report fir_LVS.log
// get core area
$ dbGet top.fplan.coreBox_area
// get die area
$ dbGet top.fplan.box_area
```
## 技巧與心得
優化:
1. parallel case
![](https://i.imgur.com/zCgoxlG.png)
or
```verilog =
(* synthesis, parallel_case *)
```
2. 想辦法共用同一塊硬體(寫成module,利用更改input來得到想要的output)
3. 將所有input都接到D filp-flop後再使用,就可以避免timing產生input_external_delay
![](https://i.imgur.com/AAMn0gg.png)
4. output都是以D filp-flop輸出,就可以避免timing產生output_external_delay
寫code:
1. default 只要再 case上面寫就不會有latch
EX:
![](https://i.imgur.com/qd1H9r8.png)
## Verilog 基礎語法
[他人筆記](http://hydai.logdown.com/snippets/205768-verilog-stepped-on-thunder-force-a-computer-test-on-compiling-my-notes)
[verilog 教學講義](https://hom-wang.gitbooks.io/verilog-hdl/content/Chapter_01.html)
### 宣告
```verilog =
module (
input [3:0] a, e, f, // 括號裡只有input output
output reg [3:0] b
);
reg [3:0] c; // register 用於 procedural block 接線
wire [3:0] d; // net 用於 continuous assignment 接線(接module一律用wire)
integer i; // 單純的變數(例如用於for迴圈)
// 未宣告default: wire
```
### 描述module方式
```verilog =
assign d = 2; // continuous assignment
always @(*) begin // procedural block (RTL 使用)
c = 1; // 只要有參數變動就執行
end
initial begin // procedural block (Testbench 使用)
a = 1; // 只跑一次
end
```
## Creating hierarchy
```verilog =
module halfadd(input a, b, output sum, carry); // 可重複使用module
assign sum = a ^ b;
assign carry = a & b;
endmodule
module fulladd (input a, b, cin, output sum, carry);
wire n_sum, n_carry1, n_carry2; // (接module一律用wire)
halfadd U1(.a(a), .b(b), .sum(n_sum), .carry(n_carry1));
halfadd U2(.a(n_sum), .b(cin), .sum(sum), .carry(n_carry2));
or U3(carry, n_carry2, n_carry1);
endmodule
// Note:.該module內部腳位名稱(外面接線腳位名稱)
```
## 特殊宣告
```verilog =
index = 4;
slice = vect[index -: 2] // same as slice = vect[4:3]
reg [7:0] reg_a [0:99]; // array of 100 8-bit vectors
reg [7:0] word, array[0:255];
word = array[10]; // access address 10
bit = word[7]; // access bit 7 of extracted word
bit = array[10][7] // 和上面一樣
```
## 使用 parameter 宣告
```verilog =
module us_mult (a, b ,product);
parameter width_a = 5 // 可以被外面修改(習慣放最前面)
parameter width_b = 5
localparam op_width = width_a + width_b; // 不可被外面修改
input [width_a-1 : 0] a; // 建議用此方式定義宣告長度,遇到不同長度的input可重複使用
input [width_b-1 : 0] b;
output [op_width-1 : 0] product;
assign product = a * b;
endmodule
```
## Operators
&& -> logical AND
& -> bit-wise AND
盡量不要用 除(/)、取餘數(%)、指數次方power(**) -> 會增加很多面積
== -> RTL使用
=== -> Testbench 使用
```verilog =
assign y = en ? a : 1'b0; // conditional operator (較為簡潔)
new = {a[6:5], b[4:3], c[3:0]} // concatenation operater (好用)
bus = {8{a}} // peplication operator
```
## 選bit技巧
![](https://i.imgur.com/BnRw65b.png)
## 讀寫檔案
[verilog系統任務讀寫檔案$ fopen和$ fdisplay的使用](https://www.itread01.com/content/1549321208.html)
## 觀念補充
[timing 觀念](https://www.cnblogs.com/oomusou/archive/2010/08/04/timing_slack.html)
[power 觀念](https://www.tutortecho.com/post/ic-design-%E6%B7%BA%E8%AB%87power-analysis%EF%BC%8Cleakage-power%E3%80%81internal-power%E3%80%81switching-power)
![](https://i.imgur.com/FEvMr5m.png)
![](https://i.imgur.com/vyKHJgq.png)