---
# System prepended metadata

title: HDLBits Notes

---

# HDLBits Notes

## AlwaysBlock

```verilog
always @(posedge clk) begin
    LHS <= RHS;
    ME <= (A&B);
end
assign ME2 = ME;
```
在CLK 正緣的時候，根據觀看變數的角色，時間關係會變化。

在同一個CLK 更新的變數。
例如說ME 是LHS（輸出）的變數看過去，LHS 就是 RHS_OLD，RHS（輸入）就是 LHS_NEXT。

不同CLK 更新的變數。
例如說ME2 是assign 的變數的時候，ME 就是 ME2_NEW，因為ME 是RHS 並且是任何時候都更新。

## AlwaysBlock

https://hdlbits.01xz.net/wiki/Alwaysblock2
Continuous assignments (`assign x = y;`). 
Can only be used when not inside a procedure ("always block").

Procedural blocking assignment: (`x = y;`). 
Can only be used inside a procedure.

Procedural non-blocking assignment: (`x <= y;`). 
Can only be used inside a procedure.


## JK Filp Flop

1. **Start with the JK flip-flop truth table** (first table).
2. **Expand it** to include the current state $Q_{\text{old}}$ (second table).
3. **Replace Q with D($Q_{\text{next}}$)** — because for a D flip-flop,

最簡單的描述方式
| J(In) | K(In) |      Q(Out)       |
|:-----:|:-----:|:-----------------:|
|   0   |   0   | $Q_{\text{old}}$  |
|   0   |   1   |         0         |
|   1   |   0   |         1         |
|   1   |   1   | ~$Q_{\text{old}}$ |

把結果都寫出來
| J(In) | K(In) | $Q_{\text{old}}$(In) | Q(Out) |
|:-----:|:-----:|:--------------------:|:------:|
|   0   |   0   |          0           |   0    |
|   0   |   0   |          1           |   1    |
|   0   |   1   |          0           |   0    |
|   0   |   1   |          1           |   0    |
|   1   |   0   |          0           |   1    |
|   1   |   0   |          1           |   1    |
|   1   |   1   |          0           |   1    |
|   1   |   1   |          1           |   0    |

**Flip Flop is Update Q with Q next**

> 在推理JK Filp Flop 的時候有使用到Q_OLD 的概念。
原本預期直覺去想會是 Q <= Q_OLD。 但是不能放在Always Block 當中。

> 目標是 Q 是每一個CLK 才更新，需要放在Always Block 當中，Q 必須要成為 LHS。
又根據Always Block 的邏輯，只能在(輸入)右邊放NEXT，（輸出)左邊放OLD (NEW)。

>然後Q 跟 Q_OLD 是接在一起只是中間多了REG，所以Q 的時間角色因為其實可以交換去看，原本是OLD(In) 的人變成NOW(Out)，原本NOW(Out) 的人變成NEXT(In)。

**嘗試把表格交換個時間的角度去看，看看能不能解決問題。**

> 因為 J 與 K 跟時間沒關係，所以不用改變。
> 因為 J K 會決定 Q ，所以用 Assign 的方式把 J K 輸入到Q_NEXT 當中。
> 在Always Block 當中 Q <= Q_NEXT 符合預期，也合理。
> 然後 J K 跟時間沒關係，指定給Q 效果不正確，所以指定給Q_NEXT。


| J(In) | K(In) | Q(Out) | D($Q_{\text{next}}$)(In) |
|:-----:|:-----:|:------:|:------------------------:|
|   0   |   0   |   0    |            0             |
|   0   |   0   |   1    |            1             |
|   0   |   1   |   0    |            0             |
|   0   |   1   |   1    |            0             |
|   1   |   0   |   0    |            1             |
|   1   |   0   |   1    |            1             |
|   1   |   1   |   0    |            1             |
|   1   |   1   |   1    |            0             |

### Sum of product

Each minterm is **AND** of all variables (negating if `0` in the row):

**Row 2** $(J=0, K=0, Q=1)$: $\overline{J} \cdot \overline{K} \cdot Q$
**Row 5** $(J=1, K=0, Q=0)$: $J \cdot \overline{K} \cdot \overline{Q}$
**Row 6** $(J=1, K=0, Q=1)$: $J \cdot \overline{K} \cdot Q$
**Row 7** $(J=1, K=1, Q=0)$: $J \cdot K \cdot \overline{Q}$

$$
D = (\overline{J} \cdot \overline{K} \cdot Q) + (J \cdot \overline{K} \cdot \overline{Q}) + (J \cdot \overline{K} \cdot Q) + (J \cdot K \cdot \overline{Q})
$$

**Group terms with** $\overline{Q}$:

$$
J \cdot \overline{K} \cdot \overline{Q} + J \cdot K \cdot \overline{Q} 
= J \cdot \overline{Q} \cdot (\overline{K} + K) 
= J \cdot \overline{Q}
$$

**Group terms with** $Q$:

$$
\overline{J} \cdot \overline{K} \cdot Q + J \cdot \overline{K} \cdot Q 
= \overline{K} \cdot Q \cdot (\overline{J} + J) 
= \overline{K} \cdot Q
$$

---

**Final simplified SOP equation:**

$$
D = (J \cdot \overline{Q}) + (\overline{K} \cdot Q)
$$

---

**Verilog**

```verilog
wire D;
// Combinational logic for JK → D mapping
assign D = (J & ~Q) | (~K & Q);
// D flip-flop
always @(posedge clk) begin
    Q <= D;
end
```

## https://hdlbits.01xz.net/wiki/Edgedetect

| $\text{in}$ | $\text{in}_\text{old}$ | $\text{pedge}$ |
|:-----------:|:----------------------:|:--------------:|
|      0      |           0            |       0        |
|      0      |           1            |       0        |
|      1      |           0            |       1        |
|      1      |           1            |       0        |

因為從 pedge 要在這一個clk 更新，pedge 要放在LHS。
從LHS 的角度去看時間關係的話。LHS 是reg，會儲存上一次的 RHS 數值。
所以對於pedge 來講同一個CLK，LHS 對他來講是old，RHS 是new。
LHS <= RHS

### Sum of product

$$
\text{pedge} = (\text{in}) \cdot  (\overline{\text{in}_\text{old}})
$$

```verilog
reg [7:0] old_in;
always @(posedge clk) begin
    old_in <= in;
    pedge <= in & ~old_in;
end
```

## https://hdlbits.01xz.net/wiki/Edgedetect2

| $\text{in}$ | $\text{in}_\text{old}$ | $\text{anyedge}$ |
|:-----------:|:----------------------:|:----------------:|
|      0      |           0            |        0         |
|      0      |           1            |        1         |
|      1      |           0            |        1         |
|      1      |           1            |        0         |

### Sum of product

**Row 1** $\text{anyedge} = (\text{in}) \cdot  (\overline{\text{in}_\text{old}})$
**Row 2** $\text{anyedge} = (\overline{\text{in}}) \cdot  (\text{in}_\text{old})$

```verilog
reg [7:0] old_in;
always @(posedge clk) begin
    old_in <= in;
    anyedge <= (in & ~old_in) | (~in & old_in);
end
```

https://hdlbits.01xz.net/wiki/Edgecapture

| in  | $\text{in}_\text{old}$ | $\text{out}_\text{old}$ | reset | out |
|:---:|:----------------------:|:-----------------------:|:-----:|:---:|
|  0  |           0            |            0            |   0   |  0  |
|  0  |           0            |            1            |   0   |  1  |
|  0  |           1            |            0            |   0   |  1  |
|  0  |           1            |            1            |   0   |  1  |
|  1  |           0            |            0            |   0   |  0  |
|  1  |           0            |            1            |   0   |  1  |
|  1  |           1            |            0            |   0   |  0  |
|  1  |           1            |            1            |   0   |  1  |
|  x  |           x            |            x            |   1   |  0  |

| in  | $\text{in}_\text{old}$ | out | reset | $\text{out}_\text{next}$ |
|:---:|:----------------------:|:---:|:-----:|:------------------------:|
|  0  |           0            |  0  |   0   |            0             |
|  0  |           0            |  1  |   0   |            1             |
|  0  |           1            |  0  |   0   |            1             |
|  0  |           1            |  1  |   0   |            1             |
|  1  |           0            |  0  |   0   |            0             |
|  1  |           0            |  1  |   0   |            1             |
|  1  |           1            |  0  |   0   |            0             |
|  1  |           1            |  1  |   0   |            1             |
|  x  |           x            |  x  |   1   |            0             |


### Product of Sum

**Row 0** $\text{out}_\text{next} = (\text{in}) +  (\text{in}_\text{old}) + (\text{out})$
**Row 4** $\text{out}_\text{next} = (\overline{\text{in}}) +  (\text{in}_\text{old}) + (\text{out})$
**Row 6** $\text{out}_\text{next} = (\overline{\text{in}}) +  (\overline{\text{in}_\text{old}}) + (\text{out})$
**Row 6** $\text{out}_\text{next} = (\overline{\text{reset}})$

:::spoiler Ans
```verilog
reg [31:0] in_old;
wire [31:0] out_next;
assign out_next = (in | in_old | out) & (~in | in_old | out) & (~in | ~in_old | out) & {32{~reset}};
always @(posedge clk) begin
    old_in <= in;
    out <= out_next;
end
```
:::spoiler

## https://hdlbits.01xz.net/wiki/Dualedge

### MY_ANS

:::spoiler Ans
```verilog
reg new_pos;
reg new_neg;  
always @(posedge clk)begin
   new_pos <= d;
end
always @(negedge clk)begin
   new_neg <= d;
end
always @(*)begin
    case(clk)
        1'b1: q = new_pos;
        1'b0: q = new_neg;
    endcase
end
```
:::

原理上可行，但不推薦用 case(clk) combinational 判斷，因為 clk 是連續波形，可能造成 latch inference。

:::spoiler Ans
```verilog
// A positive-edge triggered flip-flop
always @(posedge clk)
    p <= d ^ n;
// A negative-edge triggered flip-flop
always @(negedge clk)
    n <= d ^ p;
// Why does this work? 
// After posedge clk, p changes to d^n. Thus q = (p^n) = (d^n^n) = d.
// After negedge clk, n changes to d^p. Thus q = (p^n) = (p^d^p) = d.
// At each (positive or negative) clock edge, p and n FFs alternately
// load a value that will cancel out the other and cause the new value of d to remain.
assign q = p ^ n;
```
:::

所以設計電路的時候要先從輸出去思考，都要從LHS 的角度去思考，這樣子才可以把時間因素一起考慮進去。
難怪大家都說寫Verilog 都要先思考Output 是什麼。
所以根據以上的推論試著把更新時間也考慮進去推導，從LHS 的角度去思考

1. 把需求拆成「每個 edge 要達到的 q 值」
    posedge clk → 需要 q = d
    negedge clk → 需要 q = d
2. 分配兩個單邊 FF（p/n）分別捕捉正/負緣
    posedge clk → 需要 p = d
    negedge clk → 需要 n = d
3. 想辦法讓每個 edge 更新能「抵消另一個 FF 的舊值」
4. XOR 是一個自然方法，因為 A ^ A = 0 , A is 0 or A is 1.
   q = (p) ^ (n) 是一個自然的方法

#### 先假設 posedge 去思考
p 就是new ，n 會變成 OLD，通常new 就不會寫，因為現在是posedge
q = p ^ n_old 
現在 p <= d，然後要把 n_old 消除的話就會是 n_old ^ n_old 先把q 假設出來

第一種假設 p <= d | n_old : q = d | n_old ^ n_old
第二種架設 p <= d ^ n_old : q = d ^ n_old ^ n_old
第二種假設 p <= d & n_old : q = d & n_old ^ n_old

目標truth table
d(in) x_old(in) q(out)
0     0         0       只有第二種符合
0     1         0       都符合
1     0         1       都符合
1     1         1       都符合

#### 假設 negedge 去思考

也是只有第二種合理
n <= d ^ p_old : q = p_old ^ d ^ p_old

#### 所以要在Always 當中都變成

:::spoiler Ans

```verilog
// A positive-edge triggered flip-flop
always @(posedge clk)
    p <= d ^ n;
// A negative-edge triggered flip-flop
always @(negedge clk)
    n <= d ^ p;
````
:::

## https://hdlbits.01xz.net/wiki/Count_clock

:::spoiler Ans
```verilog
module bcd_counter(
    input clk,
    input reset,
    input ena,
    input [3:0] reset_value,
    input [3:0] max_value,
    output reg [3:0] bcd);
    
    always @(posedge clk) begin
        if (reset || (ena && (bcd == max_value))) begin
            bcd <= reset_value;
        end else if (ena) begin
            bcd <= bcd + 1'b1;
        end
    end
endmodule

module top_module(
    input clk,
    input reset,
    input ena,
    output reg pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    // 秒
    bcd_counter s1(clk, reset, ena, 4'd0, 4'd9, ss[3:0]);
    wire s2_ena = (ena && ss[3:0] == 4'd9);
    bcd_counter s2(clk, reset, s2_ena, 4'd0, 4'd5, ss[7:4]);
    
    // 分
    wire m1_ena = (s2_ena && ss[7:4] == 4'd5);
    bcd_counter m1(clk, reset, m1_ena, 4'd0, 4'd9, mm[3:0]);
    
    wire m2_ena = (m1_ena && mm[3:0] == 4'd9);
    bcd_counter m2(clk, reset, m2_ena, 4'd0, 4'd5, mm[7:4]);
    
    // 小時：先處理個位數
    wire h1_ena = (m2_ena && mm[7:4] == 4'd5);
    bcd_counter h1(
        clk, reset, h1_ena,
        (reset ? 2'd2 : (hh == 8'h12 ? 4'd1 : 4'd0)),        // 如果是12，下一個小時要回 01
        (hh[7:4] == 1 ? 4'd2 : 4'd9),       // 如果是 1x，max=2，否則 max=9
        hh[3:0]
    );
    
    // 小時：十位數 (0~1)
    wire h2_ena = (h1_ena && ((hh[7:4] == 0 && hh[3:0] == 9) || (hh[7:4] == 1 && hh[3:0] == 2)));
    bcd_counter h2(
        clk, reset, h2_ena,
        (reset ? 1'd1 : (hh == 8'h12 ? 4'd0 : hh[7:4])),     // 12 → 01
        4'd1,
        hh[7:4]
    );
    
    // AM/PM 切換
    always @(posedge clk) begin
        if (reset) begin
            pm <= 0; // AM
        end else if (h1_ena && hh == 8'h11 && mm == 8'h59 && ss == 8'h59) begin
            pm <= ~pm; // 在 11:59:59 翻轉
        end
    end
endmodule
```
:::

## https://hdlbits.01xz.net/wiki/Shift18

:::spoiler Ans
```verilog
module top_module(
    input clk,
    input load,
    input ena,
    input [1:0] amount,
    input [63:0] data,
    output reg [63:0] q); 
    always @(posedge clk) begin
        if(load) begin
            q <= data;
        end 
        else if(ena) begin
            if (amount == 2'b00) begin //shift left by 1 bit.
                q[63:1] <= q[62:0];
                q[0] <= 0;
            end
            else if (amount == 2'b01) begin //shift left by 8 bits.
                q[63:8] <= q[55:0];
                q[7:0] <= 0;
            end
            else if (amount == 2'b10) begin //shift right by 1 bit.
                q[62:0] <= q[63:1];
            end
            else if (amount == 2'b11) begin //shift right by 8 bits.
                // First Version
                // if(q[63] == 1'b1) begin
                //     q[63:0] <= {{8{1'b1}}, q[63:8]};
                // end
                // else begin
                //     q[62:0] <= q[63:8];
                // end
                // Second Version
                q[62:0] <= {{7{q[63]}}, q[63:8]};
            end
        end
    end
endmodule
```
:::

## https://hdlbits.01xz.net/wiki/Shift18

:::spoiler Ans
```verilog
module dff_module(
    input clk,
    input d,
    input reset,
    input reset_value,
    output q
);
    always @ (posedge clk) begin
        if(reset) begin
            q <= reset_value;
        end else begin
            q <= d; 
        end
    end
endmodule

module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output [4:0] q
); 
    dff_module dff1(clk, q[1], reset, 1, q[0]);
    dff_module dff2(clk, q[2], reset, 0, q[1]);
    dff_module dff3(clk, q[3]^q[0], reset, 0, q[2]);
    dff_module dff4(clk, q[4], reset, 0, q[3]);
    dff_module dff5(clk, q[0], reset, 0, q[4]);
        
endmodule
```
:::

## https://hdlbits.01xz.net/wiki/Lfsr5

:::spoiler ANS1
直覺解法1
```verilog
module dff_module(
    input clk,
    input d,
    input reset,
    input reset_value,
    output q
);
    always @ (posedge clk) begin
        if(reset) begin
            q <= reset_value;
        end else begin
            q <= d; 
        end
    end
endmodule
```
```verilog    
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output [4:0] q
); 
    dff_module dff1(clk, q[1], reset, 1, q[0]);
    dff_module dff2(clk, q[2], reset, 0, q[1]);
    dff_module dff3(clk, q[3]^q[0], reset, 0, q[2]);
    dff_module dff4(clk, q[4], reset, 0, q[3]);
    dff_module dff5(clk, q[0], reset, 0, q[4]);
endmodule
```
:::

:::spoiler 換成Vector 寫法
Step1
```verilog
dff_module dff1(clk, {q[2],q[1]}, reset, 2'b01, {q[1],q[0]});
dff_module dff3(clk, q[3]^q[0], reset, 0, q[2]);
dff_module dff4(clk, {q[0], q[4]}, reset, 2'b00, {q[4], q[3]});
```

記得要把dff_module 改成5bit
```verilog
module dff_module(
    input clk,
    input [4:0]d,
    input reset,
    input [4:0]reset_value,
    output [4:0]q
);
    always @ (posedge clk) begin
        if(reset) begin
            q <= reset_value;
        end else begin
            q <= d; 
        end
    end
endmodule
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output [4:0] q
); 
    wire [4:0] d = {q[0]^0, q[4]^0, (q[3]^q[0]), q[2]^0, q[1]^0};
    dff_module dff1(clk, d, reset, 5'b00001, q[4:0]);
endmodule
```

可以把`wire [4:0] d`這一段在寫成更 Gernal 步驟如下

Step0
```verilog
wire [4:0] d = {q[0]^0, q[4]^0, (q[3]^q[0]), q[2]^0, q[1]^0};
```
step1
```verilog
wire [4:0] d = {(q[0]^1'b0), (q[4]^1'b0), (q[3]^q[0]), (q[2]^1'b0), (q[1]^1'b0)};
```

step2
```verilog
wire [4:0] d = {q[0], q[4], q[3], q[2], q[1]} ^ {1'b0, 1'b0, q[0], 1'b0, 1'b0};
```

step3
```verilog
wire [4:0] d = {q[0], q[4:1]} ^ {1'b0, 1'b0, q[0], 1'b0, 1'b0};
```

step4
> taps at bit positions **5** and **3**. (Tap positions are usually numbered starting from 1)
```verilog
wire [4:0] d = {1'b0, q[4:1]} ^ {q[0], 1'b0, q[0], 1'b0, 1'b0};
                               //   5,    4,    3,    2,    1
```

:::

## https://hdlbits.01xz.net/wiki/Lfsr32

思考步驟是觀察Lfsr5 發現可以換成Vector 的方式實現，先回去實驗小題目的規則，這樣子必較好寫。

dff_module 就改成32 Bits的版本就可以了，上面的是5 Bits 版本
:::spoiler ANS1
```verilog
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 32'h1
    output [31:0] q5
); 
    wire [31:0] d = {1'b0, q[31:1]} ^ {q[0], {9{1'b0}} , q[0], {18{1'b0}}, 1'b0, q[0], q[0]};
                                     //  32,         23,   22,       21-4,    3,    2,    1
    //taps at bit positions 32, 22, 2, and 1.
    dff_module dff1(clk, d, reset, 32'h1, q[31:0]);
```
:::

## [m2014 q4k](https://hdlbits.01xz.net/wiki/Exams/m2014_q4k)

:::spoiler ANS
```verilog
module top_module (
    input clk,
    input resetn,   // synchronous reset
    input in,
    output out);
    reg [3:0] q;
    always @ (posedge clk) begin
        if(resetn == 1'b0) begin
            q <= 4'b0;
        end else begin
            q[3] <= in;
            q[2:0] <= q[3:1];
        end
    end
    assign out = q[0];
endmodule
```
:::

## [Exams/2014 q4b](https://hdlbits.01xz.net/wiki/Exams/2014_q4b)

:::spoiler ANS
```verilog
module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //    
    MUXDFF MUXDFF3(KEY[0],KEY[3],SW[3],KEY[1],KEY[2],LEDR[3]);
    MUXDFF MUXDFF2(KEY[0],LEDR[3],SW[2],KEY[1],KEY[2],LEDR[2]);
    MUXDFF MUXDFF1(KEY[0],LEDR[2],SW[1],KEY[1],KEY[2],LEDR[1]);
    MUXDFF MUXDFF0(KEY[0],LEDR[1],SW[0],KEY[1],KEY[2],LEDR[0]);
endmodule

module MUXDFF (
    input clk,
    input w, R, E, L,
    output Q
);
    wire mux1, mux2;
    assign mux1 = E ? w : Q;
    assign mux2 = L ? R : mux1;
    always @(posedge clk)begin
        Q <= mux2;
    end
endmodule
```
:::

## https://hdlbits.01xz.net/wiki/Fsm3onehot

What does "derive equations by inspection" mean?

One-hot state machine encoding guarantees that exactly one state bit is 1.
Although knowing this algorithm isn't necessary for RTL-level design (the logic synthesizer handles this), 
it is illustrative of why one-hot FSMs often have simpler logic (at the expense of more state bit storage), 
and this topic frequently shows up on exams in digital logic courses.

## [ece241_2013_q4](https://hdlbits.01xz.net/wiki/Exams/ece241_2013_q4)

| State | Next State |      |      |      | Output |     |     |     |
| ----- | ---------- | ---- | ---- | ---- | ------ | --- | --- | --- |
|       | None=1     | S1=1 | S2=1 | S3=1 | FR1    | FR2 | FR3 | DFR |
| None  | None       | S1   | S2   | S3   | 1      | 1   | 1   | 1   |
| S1    | None       | S1   | S2   | S3   | 1      | 1   | 0   | 0   |
| S2    | None       | S1_D | S2   | S3   | 1      | 0   | 0   | 0   |
| S3    | None       | S1_D | S2_D | S3   | 0      | 0   | 0   | 0   |
| S2_D  | None       | S1_D | S2_D | S3   | 1      | 0   | 0   | 1   |
| S1_D  | None       | S1_D | S2   | S3   | 1      | 1   | 0   | 1   |

```
// State transition logic
// State flip-flops with synchronous reset
// Output logic
```

:::spoiler ans
```verilog
module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 
    parameter NONE=3'd0, S1=3'd1, S2=3'd2, S3=3'd3, S2_D=3'd4, S1_D=3'd5;
    reg [2:0] state, next_state;    
    
// State transition logic
    always @(*) begin
        case (state)
            default: next_state = 'x; //Synthesis Determine
            NONE: next_state = s[3] ? S3 : (s[2] ? S2   : (s[1] ? S1   : NONE));
            S1  : next_state = s[3] ? S3 : (s[2] ? S2   : (s[1] ? S1   : NONE));
            S2  : next_state = s[3] ? S3 : (s[2] ? S2   : (s[1] ? S1_D : NONE));
            S3  : next_state = s[3] ? S3 : (s[2] ? S2_D : (s[1] ? S1_D : NONE));
            S2_D: next_state = s[3] ? S3 : (s[2] ? S2_D : (s[1] ? S1_D : NONE));
            S1_D: next_state = s[3] ? S3 : (s[2] ? S2   : (s[1] ? S1_D : NONE));
        endcase
    end
// State flip-flops with synchronous reset
    always @ (posedge clk) begin
        if(reset) begin
            state <= NONE;
        end else begin
            state <= next_state;
        end
    end
// Output logic
    always @ (*) begin
        case (state)
            default: {fr3,fr2,fr1,dfr} = 'x;
            NONE   : {fr3,fr2,fr1,dfr} = 4'b1111;
            S1     : {fr3,fr2,fr1,dfr} = 4'b0110;
            S2     : {fr3,fr2,fr1,dfr} = 4'b0010;
            S3     : {fr3,fr2,fr1,dfr} = 4'b0000;
            S2_D   : {fr3,fr2,fr1,dfr} = 4'b0011;
            S1_D   : {fr3,fr2,fr1,dfr} = 4'b0111;
        endcase
    end
endmodule
```
:::

## [Tb/clock](https://hdlbits.01xz.net/wiki/Tb/clock)

:::spoiler ans
```verilog
module top_module ( );
    
  reg clk;           // testbench clock
  dut uut (          // instance of dut
    .clk(clk)
  );

  initial begin
    clk = 0;         // initialize to zero
    forever #5 clk = ~clk;  // toggle every 5 ps -> 10 ps period
  end

endmodule
```
:::

## [Tb/tb2](https://hdlbits.01xz.net/wiki/Tb/tb2)

:::spoiler ans
```verilog
module top_module();
    reg clk, in, out;
    reg [2:0] s;
    q7 q7_inst(clk, in, s, out);
    
    initial begin
        clk = 0;
        forever #5 clk = ~clk; 
    end
    
    initial begin
        in = 0;
        #20 in = 1;
        #10 in = 0;
        #10 in = 1;
        #30 in = 0;
    end
    
    initial begin
        s = 3'd2;
        #10 s = 3'd6;
        #10 s = 3'd2;
        #10 s = 3'd7;
        #10 s = 3'd0;
    end
endmodule

```
:::

## [Lemmings4](https://hdlbits.01xz.net/wiki/Lemmings4)

:::spoiler ans
```verilog
module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    input dig,
    output walk_left,
    output walk_right,
    output aaah,
    output digging ); 

    parameter LEFT=3'd0, RIGHT=3'd1, FALL_LEFT=3'd2, FALL_RIGHT=3'd3, DIG_L=3'd4, DIG_R=3'd5, SPLAT=3'd6;
    reg [2:0] state, next_state;
    reg [4:0] fall_cycles;
    
    always @(*) begin
        case (state)
            default : next_state = 'x;
            LEFT       : next_state = ground ? (dig ? DIG_L : (bump_left ? RIGHT : LEFT))  : FALL_LEFT;
            RIGHT      : next_state = ground ? (dig ? DIG_R : (bump_right ? LEFT : RIGHT)) : FALL_RIGHT;
            FALL_LEFT  : next_state = ground ? ((fall_cycles == 5'd20) ? SPLAT : LEFT): FALL_LEFT;
            FALL_RIGHT : next_state = ground ? ((fall_cycles == 5'd20) ? SPLAT : RIGHT) : FALL_RIGHT;
            DIG_L      : next_state = ground ? DIG_L : FALL_LEFT;
            DIG_R      : next_state = ground ? DIG_R : FALL_RIGHT;
            SPLAT      : next_state = SPLAT;
        endcase
    end
    
    always @(posedge clk, posedge areset) begin
        if(areset) begin
        	state <= LEFT;
        end else begin
            state <= next_state;
        end
    end
    
    always @(posedge clk, posedge areset) begin
        if(areset) begin
            fall_cycles <= 0;
        end else if((state == FALL_LEFT) || (state == FALL_RIGHT))begin
            if(fall_cycles < 5'd20) begin
                fall_cycles <= fall_cycles + 1'd1;
            end
        end else begin
           fall_cycles <= 0;
        end
    end
    // Output logic
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign aaah = ((state == FALL_LEFT) || (state == FALL_RIGHT));
    assign digging = (state == DIG_L) || (state == DIG_R);
    
endmodule
```
:::

## [Fsm serial](https://hdlbits.01xz.net/wiki/Fsm_serial)

one start bit (0), 8 data bits, and 1 stop bit (1)

觀察發現Before Start Bit(0), 要先等到Stop bit(1)

```graphviz
digraph FSM {
    rankdir=LR;
    node [shape = circle];

    INIT [label="",shape=plaintext];

    INIT -> START [label="reset"];

    START -> DATA  [label="in == 1"];
    START -> START [label="in == 0"];

    DATA  -> STOP;
    DATA  -> DATA [label="bits < 8"];

    STOP  -> DONE [label="in == 1"];
    STOP  -> WAIT [label="in == 0"];

    WAIT  -> START [label="in == 1"];
    WAIT  -> WAIT  [label="in == 0"];

    DONE  -> DATA  [label="in == 0"];
    DONE  -> START [label="in == 1"];
}
```

::: spoiler ANS
```verilog
module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    parameter START=3'd0, DATA=3'd1, STOP=3'd2, DONE=3'd3, WAIT=3'd4;
    reg [2:0] state, count;
    wire [2:0] next_state;
    
    // State transition logic (combinational)
    always @ (*) begin
        case (state)
            START : next_state = (in == 0) ? DATA : START;
            DATA  : next_state = (count == 7) ? STOP : DATA;
            STOP  : next_state = (in == 1) ? DONE : WAIT;
            WAIT  : next_state = (in == 0) ? WAIT : START;
            DONE  : next_state = (in == 0) ? DATA : START;
        endcase
    end
    // State flip-flops (sequential)
    always @ (posedge clk) begin
        if(reset) begin
            state <= START;
            count <= 0;
        end else begin
            state <= next_state;
            if(state == DATA) begin
            	count <= count + 1'd1;
            end else begin
                count <= 0;
            end
        end
    end
    // Output logic
    assign done = (state == DONE);
endmodule
```
:::


## [Fsm_serialdata](https://hdlbits.01xz.net/wiki/Fsm_serialdata)

assign out_byte = data[0:7];

out_byte[7] 會對應到 data[0]
out_byte[6] 會對應到 data[1]
...
out_byte[0] 會對應到 data[7]

:::spoiler ANS
```verilog
module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
    parameter START=3'd0, DATA=3'd1, STOP=3'd2, DONE=3'd3, WAIT=3'd4;
    reg [2:0] state, count;
    wire [2:0] next_state;
    reg [0:7] data;
    // State transition logic (combinational)
    always @ (*) begin
        case (state)
            START : next_state = (in == 0) ? DATA : START;
            DATA  : next_state = (count == 7) ? STOP : DATA;
            STOP  : next_state = (in == 1) ? DONE : WAIT;
            WAIT  : next_state = (in == 0) ? WAIT : START;
            DONE  : next_state = (in == 0) ? DATA : START;
        endcase
    end
    // State flip-flops (sequential)
    always @ (posedge clk) begin
        if(reset) begin
            state <= START;
            count <= 0;
        end else begin
            state <= next_state;
            if(state == DATA) begin
                data[0:7] <= {in, data[0:6]};
            	count <= count + 1'd1;
            end else begin
                count <= 0;
            end
        end
    end
    // Output logic
    assign done = (state == DONE);
    // New: Datapath to latch input bits.
    assign out_byte = data[0:7];
endmodule
```
:::

## [Fsm_serialdp](https://hdlbits.01xz.net/wiki/Fsm_serialdp)

```graphviz
digraph FSM {
    rankdir=LR;
    node [shape = circle];

    INIT [label="",shape=plaintext];
    DATA [label="DATA"]
    
    INIT -> START [label="reset"];

    START -> DATA  [label="in == 1"];
    START -> START [label="in == 0"];

    DATA  -> DATA [label="bits < 8"];
    DATA  -> ODD;
    
    ODD   -> STOP;
    
    STOP  -> DONE [label="in == 1"];
    STOP  -> WAIT [label="in == 0"];

    WAIT  -> START [label="in == 1"];
    WAIT  -> WAIT  [label="in == 0"];

    DONE  -> DATA  [label="in == 0"];
    DONE  -> START [label="in == 1"];
}
```

```graphviz

```

```verilog
parity parity_inst(clk, parity_reset, parity_in, odd);
```

| STATE | parity_reset | parity_in |
|:-----:|:------------:|:---------:|
| START |      1       |     0     |
| DATA  |      0       |     1     |
|  ODD  |      0       |     1     |
| STOP  |      0       |     0     |
| WAIT  |      0       |     0     |
| DONE  |      1       |     0     |

:::spoiler ANS
```verilog
module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
    parameter START=3'd0, DATA=3'd1, STOP=3'd2, DONE=3'd3, WAIT=3'd4;
    parameter ODD=3'd5; //NEW
    reg [2:0] state, count;
    wire [2:0] next_state;
    reg [0:7] data;
    // State transition logic (combinational)
    always @ (*) begin
        case (state)
            START : next_state = (in == 0) ? DATA : START;
            DATA  : next_state = (count == 7) ? ODD : DATA; //NEW
            ODD   : next_state = STOP;                      //NEW
            STOP  : next_state = (in == 1) ? DONE : WAIT;
            WAIT  : next_state = (in == 0) ? WAIT : START;
            DONE  : next_state = (in == 0) ? DATA : START;
        endcase
    end
    // State flip-flops (sequential)
    always @ (posedge clk) begin
        if(reset) begin
            state <= START;
            count <= 0;
        end else begin
            state <= next_state;
            if(state == DATA) begin
                data[0:7] <= {in, data[0:6]};
            	count <= count + 1'd1;
            end else begin
                count <= 0;
            end
        end
    end
    assign out_byte = data[0:7];
    // New: Add parity checking.
    wire parity_reset, parity_in, odd;
    parity parity_inst(clk, parity_reset, parity_in, odd);
    always @(*) begin
        case (state)
            START : begin parity_reset = 1; parity_in = 0 ; end //Done == START
            DATA  : begin parity_reset = 0; parity_in = in; end
            ODD   : begin parity_reset = 0; parity_in = in; end
            STOP  : begin parity_reset = 0; parity_in = 0 ; end
            WAIT  : begin parity_reset = 0; parity_in = 0 ; end
            DONE  : begin parity_reset = 1; parity_in = 0 ; end //Done == START
        endcase
    end
    assign done = ((state == DONE) && (odd == 1'b1));
endmodule
```
:::

## [Fsm_hdlc](https://hdlbits.01xz.net/wiki/Fsm_hdlc)

:::spoiler ANS
```graphviz
digraph FSM {
    rankdir=LR
    node [shape = circle]
    INIT [label="",shape=plaintext]
    
    INIT -> NONE [label="reset"]
    NONE -> NONE [label="0"]
    NONE -> ONE  [label="1"]
    ONE  -> NONE [label="0"]
    ONE  -> TWO  [label="1"]
    TWO  -> THREE[label="1"]
    TWO  -> NONE [label="0"]
    THREE-> FOUR [label="1"]
    THREE-> NONE [label="0"]
    FOUR -> FIVE [label="1"]
    FOUR -> NONE [label="0"]
    FIVE -> DISC [label="0"]
    FIVE -> SIX  [label="1"]
    DISC -> NONE [label="0"]
    DISC -> ONE  [label="1"]
    SIX  -> ERR  [label="1"]
    SIX  -> FLAG [label="0"]
    FLAG -> NONE [label="0"]
    FLAG -> ONE  [label="1"]
    ERR  -> NONE [label="0"]
    ERR  -> ERR  [label="1"]
}
```
:::spoiler

## [ece241_2013_q8](https://hdlbits.01xz.net/wiki/Exams/ece241_2013_q8)

Mealy-type finite state machine
```graphviz
digraph FSM {
    rankdir=LR;
    node [shape = circle];

    // States
    S0 [label="S0\n(no history)"];
    S1 [label="S1\n(seen '1')"];
    S2 [label="S2\n(seen '10')"];

    // Transitions
    S0 -> S1 [label="x=1 / z=0"];
    S0 -> S0 [label="x=0 / z=0"];

    S1 -> S1 [label="x=1 / z=0"];
    S1 -> S2 [label="x=0 / z=0"];

    S2 -> S1 [label="x=1 / z=1"]; // detection here
    S2 -> S0 [label="x=0 / z=0"];

    // Initial state
    INIT [shape=plaintext, label="reset"];
    INIT -> S0;
}
```