# 程式風格 ###### 參考資料:[Coding Style](https://hackmd.io/@derek8955/BJB9M33yo) > [!Tip] **目的** > - **可讀性 ==(Readable)==** > - **可合成的代碼 ==(Synthesizable Code)==** > - **減少 ==電路面積==** > - **縮短 ==電路時間==** ## 1. 可讀性 (Readable) ### (1) 一些好的習慣 - **`always block` 中 ==邊緣觸發==、==準位觸發== 不要混用** ```verilog= always@(posedge clk or a) begin /* ... */end ``` - **設計==組合邏輯==時,`always block` 使用 ==`*`(全域觸發)==** ```verilog= always@(*) begin /* ... */ end ``` - **==組合邏輯==電路使用 ==`blocking assignment (=)`==** ```verilog= always@(*) begin out = (out == 1'd0)? in1:in2; end ``` - **==循序邏輯==電路使用 ==`non-blocking assignment (<=)`==** ```verilog= always@(posedge clk) begin out <= (out == 1'd0)? in1:in2; end ``` - **電路的 ==input==、==output== 先用 ==FF== 存起來,避免取出訊號為 ==`X`==、==`Z`== 的狀態** ```verilog= input a; reg a_buffer; always@(posedge clk) begin if (a) b <= a; else b <= 1'b0; end ``` - **多使用 ==FSM (Finite State Machine)==** ### (2) 明確區塊分工 > [!Note] **說明** > - **在設計電路時,==不要==把所有變數==寫入同一個程式區塊中==** > - **建議==分散==成不同的電路區塊,每個區塊有==不同==的主要==功能==** > - **ex: ==FSM== 中,把 ==CS==、==NS==、==OL==分開撰寫** > ```verilog= > always@(posedge clk) begin > if (reset) CS <= S0; > else CS <= NS; > end > always@(*) begin > case(CS) > S0: NS <= /*...*/ > S1: NS <= /*...*/ > default: NS <= /*...*/ > endcase > end > always@(*) begin > case(CS) > S0: OL <= /*...*/ > S1: OL <= /*...*/ > default: OL <= /*...*/ > endcase > end > ``` > [!Tip] **優點** > - **==邏輯分清楚==,debug 比較輕鬆** > - **==電路合成==會比較接近預期結果** ## 2. 避免在組合邏輯中產生 ==Latch== ### (1) 不要沒寫完組合邏輯的 ==條件表達式== > [!Caution] **注意:** > - **ex1:`CASE` ==狀態沒列完==** > ```verilog= > always@(*) begin > case(sel) > 2'd0: out = in1; > 2'd1: out = in2; > endcase > end > ``` > - **ex2:`IF` ==沒有接`ELSE`==** > ```verilog > always@(*) begin > if(en) out = in; > end > ``` > [!Tip] **原因** > - **組合邏輯的 ==訊號== 在電路中只是 ==一條帶有標籤的線路(`wire`)==** > - **所以 ==`wire` 不會儲存訊號狀態==** > - **因此當條件表達式遇到 ==未定義的條件==時,需要先將 ==原本的訊號保存==下來** > **直到遇到 ==已定義的條件==** ### (2) 不要在組合邏輯電路中產生 ==回授電路== > [!Caution] **注意:** > - **ex:`a = ~c;` `b = ~a;` `c = ~b;`** >  > - **ex:把輸出透過==組合邏輯電路==、==直接連線==送到輸入** > ```verilog= > wire sel; > wire [3:0] a; > assign a = b ? a : a + 1; > ``` > [!Tip] **原因** > - **一樣是 ==`wire` 不會儲存訊號狀態== 的問題** > - **要把==原始的訊號==送回輸入端,產出==新的訊號==,** > **需要先把==原始的訊號==保存起來,才能送回輸入端** ### (3) 循序邏輯電路不會產生 ==Latch== > [!Tip] **原因** > - **循序邏輯的 ==訊號== 在電路中是==DFF 的輸出(`reg`)==** > - **所以 ==`reg`== 本身具有 ==栓鎖功能==** > - **且 ==觸發源== 來自程式中的 ==`always@()` block==** > - **==Latch== 沒有跟著 ==`always@()` block== 的觸發源** > - **ex:以下電路==不會產生 Latch==** > ```verilog= > reg [3:0] a; > always@(posege clk) begin > if(flag) a <= 3; > end > ``` ---
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up