###### tags: `university note`
[TOC]
# 硬體描述語言
## CH1
___
```verilog=
module add_half_struct (a, b, sum, c_out);
input a, b;
output sum, c_out;
wire c_out_bar;
xor G1//取名(sum, a, b);
nand G2(c_out_bar, a, b);
not G3(c_out, c_out_bar);
xor #1(sum, a, b); //延遲1ms #表延遲
endmodule
```
___
### 0-1,1-0 delay轉換延遲
```verilog=
module nanf201 (A1, B1, O);
input A1, B1;
output O;
nand (O, A1, B1);
specify
specparam
Tpd_0_1 = 1.13:3.09:7.75, // rising delay (min-typical-max)
Tpd_1_0 = 0.93:2.50:7.34; // falling delay (min-typical-max)
(A1 => O) = (Tpd_0_1, Tpd_1_0);
(B1 => O) = (Tpd_0_1, Tpd_1_0);
endspecify
endmodul
```

___
### 一些基礎電路語法
`assign sum = a+b; //assign宣告讓sum在a,b之後改變時會同時改變`
#### MUX
```verilog=
input [1:0]select;
output y_out;
assign y_out = (a && !select[1] && !select[0]) ||(b && select[1] && !select[0])||....
```

___
### Module Function
要用幾次就寫幾次(電路角度思考)

```verilog=
module main_MOD();
MOD_A();
endmodule
module MOD_A();
....
endmodule
```
**Full adder with module**
Add_half是我們寫的一個module

___
### 宣告單變數多個值(類array)
`[x:y]variable;`
```verilog=
module bitArray(y, a, b);
input [7:0]a, b; //類似陣列宣告
output [7:0]y;
assign y = a|b;
```

___
### Port connection by name
`module(.modvariable(variable)...)`
```verilog=
module main;
wire [3:0] g;
mod(.a(g[0]), .b(g[1]), .c(g[2]), .c(g[3]));
endmodule
module mod(a,b,c,d);
output a,b;
input c,d;
endmodule
```
___
### bitArray自己操作
可讓bitArray內的值自行互相操作
```verilog=
//一般寫法
module and4_assign_1 (x_in1, x_in2, x_in3, x_in4, y_out);
input x_in1, x_in2, x_in3, x_in4;
output y_out;
assign y_out = x_in1 & x_in2 & x_in3 & x_in4;
endmodule
//更好的寫法
module and4_assign_2 (x_in, y_out);
input [3:0] x_in;
output y_out;
assign y_out = & x_in;
endmodule
```
___
### always語法
反覆執行always內的code
```verilog=
always
begin
...
end
always@(a or b) //a或b滿足觸發
always@(posedge clk) //上緣觸發
always@(negedge clk) //下緣觸發
```
:::danger
`always`宣告內的輸出要多加reg
```verilog=
output out;
reg out;
always@(a or b);
begin
out = ....;
end
```
:::
##### Always + bitArray
```verilog=
module and4_alg (y_out, x_in);
input [3:0] x_in;
output y_out;
reg y_out;
integer k;
always @ (x_in) // x_in[3] or x_in[2] or x_in[1] or x_in[0]
begin: and_loop
y_out = 1;
for (k=0; k <= 3; k = k+1)
if (x_in[k] == 0)
begin
y_out = 0;
disable and_loop;
end
end
endmodule
```
___
### bitArray減少code行數

:::danger
**必須要有一定規則**
EX:[24:0]output, 每小段都切5bit
:::

[bit數]'[base][val]
___
## CH2
### Inertial Delay
Due to propagation delay, the input signal pulse duration need to longer than **inertial delay time**

___
### Unit Test
思考需要甚麼輸入->設計code->設計輸出monitor->對拍測試
設計state diagram

EX: NAND-Latch test
```
```
___
### Variable
x: unknown
z: high impedence
**$\neg x$ is not exists**
___
#### Data types
* Structural Connectivity: **net**(wire, wand...)
* Data Storage: reg
* Procedural Computation: integer, real, time, realtime
:::info
reg(register)都是static
nets主要是線路設計出來連接(實際電路會做出來)
:::
___
#### Nets
主要是不同電路設計模組與閘之間的連接
##### wire
連接電路與訊號,不像邏輯閘本身有邏輯運算行為
* tri
same as wire, but with tri-stted(類似多工器控制是否input signal)

* supply0
gnd接地
* supply1
接電源

___
#### Regs
* use in flip-flop or latch stored
* stored in memory(不輸出電路)
* always use in prcedural statement
* initial value: "x"
:::danger
unsigned value(注意取補數時)
:::
___
#### module間net和reg限制

___
#### 2D-Array
電路中沒有真正的2d-array
對一個bitarray去開n個重複個bitarray
`reg [31:0] array[0:1023] -> array[1024][32] `
___
#### Module Hierarchical(模組間階層) Reference
父模組可透過identifier取子模組值

___
### Parameter(Const)
:::info
Verilog特殊用法

#**(4,5)代表size=4,delay=5**變成有點類似function的預設parameter值
:::
___
### 數學運算

sum,diff,neg由於上面是開5bit,所以會有5個bit
:::danger
**注意reg是unsigned value**
:::
#### Reduction
簡稱自己內部做bitwise

___
### Operators
* !num: 判斷是否為正數
* ===: 完全相等於(包括x,z都要依樣)
* 其餘大致跟C++差不多
設計輸入電路時,可以寫緩衝避免奇怪沒用到的資料混進去


___
#### 信號組合合成
使用`{}`
EX: `{10,01}=1001`
___
## CH3
電路行為描述
* 注重function化(注重function功能較不注重內部電路設計)
* 合成到ASIC, FPGAs
* 非所有電路都可組合輸出,也非所有組合輸出都合乎預期
### Behaviors
自己去查怎麼用
* initial
* initialize a simulation and create stimulus waveforms
* always

每一個behavior都是各自獨立同時執行的

___
### Procedural assignment
* Continuous Assigment:(static)
* 連續賦值語句總是處於激活狀態。只要任意一個操作數發生變化,表達式就會被立即重新計算。
* assign
* 只能用在NET
* Procedural Assigment:
* 阻塞賦值Blocking(=): 等這段跑完才跑後面
* 非阻塞賦值Non-blocking(<=): 併發執行,語句順序不影響
* 在always/initial內使用
* 只能用在reg
* Procedural Continuous Assigment:
* 在always/initial內使用
___
#### assign/deassign(PCA)
可用於reg的變數
* assign
* assign的优先级高于普通过程赋值语句
* 後一條assign賦值會覆蓋前一句
* 類似把變數進入static狀態
* deassign
* deassign後變數保持上一次賦值的內容
* 解除連續賦值狀態
EX:
* MUX:
若無使用assign則a,b,c,d更改時y_out不會更改可能不會是我們想要的

* SR latch:
注意紅框兩部分當有clear/preset指令時assign q 到指定值會覆蓋前段`q = data`的部分,而若要讓`q = data`則先deassign q

___
#### force/release(PCA)
可用於reg/wire變數,測試電路時感覺很實用(debug)
EX:
debug時不想管in1/2/3那邊直接測試可用force/release

___
**各種狀態適用Net,Reg表**

___
### Time Control
不同#的位置會在不同地方產生延遲

___
#### Event Control Operator(@)
`@(event)`當event產生變化,則進行下面的操作(常搭配always使用)
若@內還有其他@則有可能會依據目前狀態進行到哪邊而有無視事件


注意sig_B和sig_A變化的時間
EX:
* Flip-flop
:::danger
flip-flop值的更改需依照clk不可依set/reset...會造成值更改錯誤,跟預想不一樣
:::
#### Intra assignment delay
`a = @(enable) b+c //intra assigment delay`
`@(enable) a = b+c //inter assigment delay`
兩者是不同的,同理`#`
___
### Event
`event (variable_name)`宣告一個事件變數
```verilog=
event up_edge
always@(posedge clock)
->up_edge;
always@(up_edge)
begin
q = data;
end
```
clock觸發->up_edge->後續判斷到up_edge改變去對flip-flop做改變
EX:

event可以跨模組使用,方便!
___
#### Wait
[wait和@的差別](https://blog.csdn.net/qq_41894346/article/details/104964478)
`wait(enable) `
wait中的值為TRUE時,觸發wait後的描述
EX:
latch


有多種寫法,此為用wait之寫法
___
#### Event with non-blocking

:::danger


:::
___
#### Non-blocking運作
:::info
1. The non-blocking statements are encountered first in the sequential activity flow, and sample the values of
c and d (x).
2. The blocking assignments at the same time step then execute in order, setting c to 0 and d to 1.
3. Then the non-blocking assignments execute, setting c to x and d to x.
4. Thus, the non-blocking assignments overwrite the blocked assignments at the same time step.
取樣RHS->執行同時間的blocking->執行non-blocking
:::
___
#### display&monitor

* **Montitor和display同時出現時,display會優先執行**
* display遇到non-blocking會印non-blocking前的值
* monitor會印non-blocking後的值
___
### LFSR
產生一長周期的數字排列(偽隨機數)


___
### Repeat Intra-assignment Delay
`repeat(count)`:條件重複5次後才執行
* if count it x/z -> 0
* use`disable` to stop count repeat

reg_b會在經過5次正緣後=10時間單位時reg_a的值
___
### 模糊賦值(同時間對值有不同賦值)
可能會造成不確定賦值
___
### Activity Flow Control
* 三元運算子
* case
* if/else
* repeat
* Loop
* fork...join
#### case
* case
* 嚴格比較
* casex
* x,z可為任何可能
* casez
* z可為任何可能

___
#### Loop
* for
* 需要注意條件判斷bits數
* while
* forever
* 無限執行
皆可透過`disable`強制中斷
:::danger
**always v.s. foerever**
* always
* concurrent behavior
* can't be nested
* forever
* computational activty flow
* can be nested
:::
##### disable

___
#### fork/join
Create parallel threads of activity
常用於信號分配
```verilog=
fork
statement1
statement2
join
```

___
##### Race
同時賦值和被賦值->模糊賦值

___
### Task and Function

Function need LHS `() = func()`,預設返回為RHS之type
___
Task EX:

___
Function EX:

___
### State Chart
有state的電路可分為兩部分
1. state
2. combinational outputs
根據不同狀態和我們所期望的output訊號可以畫出狀態機
狀態機設計可主要分成三步驟:
1. clk觸發傳遞狀態(non-blocking)
2. 根據目前狀態和輸入確定下一狀態(blockin)
3. 根據目前狀態和輸入確定輸出(non-blocking)

有$n$個狀態時需要$ln(n)$個bits去儲存狀態
___
#### Mealy machine with registered outputs
目的在於同步state和output不要在非需要時輸出output訊號(change output when clk edge)

___
## CH4
### Synthesis of Combinational Logic(組合電路合成)
* 移除多餘電路
* 自動調整成多層組合電路
* 整合成黏在一起(?(找適合的電路組合)
___
### Cyclic Behavior(always) Synthesis
* 所有output都必須在行為中被賦值,否則可能會自動生成latch
* 要有狀態控制訊號/事件


___
### Function/Task Synthesis

電路基本上長一樣(?
___
#### Simulation Efficiency


___
### Unexpected Latches
不完全敘述的if/case(缺少else敘述、case缺default或沒寫所有可能case),此時組合電路可能會自動**添加latch表示使訊號保持訊號不變**


___
### Priortiy Structure
case/if在較前的敘述對電路來說優先級會更高

if(a)->直接跑完
if(c)->if(b)->if(a)->done
EX:

___
### 7-Segment Display


___
### Some Technology
#### Mapping
可以把相關電路但不同訊號整合在一起,之後使用做mapping即可
EX:
Adder的Carry和out

___
#### Use Special Synthesis or Technology
用各種方法減少電路數量(省成本)


下面的寫法只會有一次算data_a+其中一個
而原寫法會把data_a+accum和data_a+data_b都算過之後丟mux看選哪個信號
___
#### 3-State Buffer
控制多個信號的傳輸
EX:
bus

___
___
## CH5(序向電路-儲存元件)
https://blog.csdn.net/weixin_37728585/article/details/120185758
### Synthesis of Latch
latch在enable時值會持續改變(level-sensitive)
1. 可能多次改變,或no debounce增加下一層級電路不正確性
2. 不完全的電路設計造成電路增加latch複雜化(i.e. self-feedback)
___
#### Self-Feedback
:::info
示意圖

:::
此種電路非組合電路,且會**自動加上mux**(根據模擬軟體決定)

___
#### if/case寫不完全造成的預設latch/flip-flop
[verilog避免latch](https://www.runoob.com/w3cnote/verilog-latch.html)
**if**
* else不寫明
* 不同值賦值未寫明

避免方式
1. 補上else敘述
2. 對信號賦予初值

___
**case**


沒有列出所有Case又沒寫default,則某些合成軟體會預設default為原本值而自動添加latch
___
#### always內判斷信號不完整
always內的敏感信號有寫錯或不符合預期,该触发的时候没有触发,那么相关寄存器还是会保存之前的输出结果,因而会生成锁存器。

缺少`x_in[0]`判斷

___
### JK-FlipFlop
直接上扣

case.ver

#### JK-FlipFlop內部電路

:::info
由j,k決定q值
j,k值不同->q必定同為j,k值
j,k值相同->根據q決定next_q之值
:::
___
### Clk時間
* Clk開關時間必須確保能夠讓input訊號能送進來
* 資料必須在Clk正/負緣觸發前穩定
___
### 各種Register
#### Shift Register
多register

單register,因為blocking賦予

等於`Data_reg[0]=Data_in`
___
#### Parallel Load Register

code:

___
#### Barrel Shifter


MSB回到LSB
```verilog=
Data_out <= {Data_out[6:0], Data_out[7]};
```
___
#### Ripple Counter
前項從1變成0時,此項下一clk會變成1


```verilog=
always @(negedge c0 or posedge reset)
if(reset == 1'b1) count[1] <= 1'b0;
else if(toggle == 1'b1) count[1] <= ~count[1];
...
```
**並非只有clk訊號可以當作觸發clk**
___
#### Shift Register+Combinational Logic
在begin end內的組合電路敘述會被自動加上flip-flop,因此要善用assign


new_signal使用到flip-flop中的sig_a/sig_b
___
#### Accumulator
累加器,可以使用`{}`把sum加上一個overflow來判斷說是否有溢位

___
### Data Flow Graph(重要)
資料間運算關係的圖

___
#### Synthesis of Non-blocking
```verilog=
//dataB會為上一周期的dataA
always@(posedge clk)
dataA = data_in;
always@(posedge clk)
dataB <= dataA;
_____________________________________________
//dataB會和dataA一樣是正緣時的data_in
always@(posedge clk)
dataA = data_in;
dataB <= dataA;
```

___
### Synthesis of Multi-Cycle

兩個clk,裡面的clk等收到一次外面的clk
___
### Flip-Flop Timing(超重要)
$t_{cd}$:
$t_{pd}$:
$t_{setup}$:
$t_{hold}$:
___
### More about Synthesis
目的要讓最後output一定要是Wire(善用assign)
#### Memory Synthesis

___
#### Synthesis of Equality Operation

當我們寫判斷兩signal是否相同時,合成軟體可能會合成以下電路

___
#### Synthesis of Reduction Operator(自己對自己做bit operation)

會生成以下電路

___
___
## ModelSim
電路模擬
module+testbench(測試檔)
