###### tags: `hdl` `hw` `thu` {%hackmd theme-dark %} # HDL-HW20221021 ## EX01 ![](https://i.imgur.com/tRnWNOY.png) Answer: 只是從常用的always block改成forever loop。 (Note: 不知道為什麼,平常放在上面的initial block裡的`$finish`在這個例子裡會被無視...要改放在下面他才會停下來,否則就真的會跑到forever...) ``` verilog module test1_tb; reg oscillate; //cmp cmp1 (out, i0, i1); initial begin oscillate = 1'b0; forever #20 oscillate = ~oscillate; //#100 $finish; end initial begin $display ("\t\tTIME\t|\toscillate"); $display ("\t\t------------------------------------------------------------"); $monitor ("%t\t|\t%b\n", $time, oscillate); #100 $finish; end endmodule ``` ![](https://i.imgur.com/OtnPYxl.png) ## EX02 ![](https://i.imgur.com/UheCfmy.png) Answer: 想法:利用`#(...)`裡可為變數,還可能可以是算式的特性設計: 1. 在clock = 1'b1的時候,每10個時間點就要toggle一次。 2. 在clock = 1'b0的時候,每40個時間點要toggle一次。 $\Rightarrow$ 把`40 - clock * 30`放在括號裡就可以表示出我們的意思了。 ``` verilog module test1_tb; reg clock; initial begin // dump for gtkwave $dumpfile("test1_tb.vcd"); $dumpvars(0,test1_tb); clock = 1'b1; #200 $finish; end // toggles clock always #(40 - ((clock)*30)) clock = ~clock; endmodule ``` ![](https://i.imgur.com/Zo2C7Nu.png) ## EX03 ![](https://i.imgur.com/YvuVRe8.png) ``` verilog initial begin a = 1'b1; b = #10 1'b0; c = #5 1'b0; d = #20 {a, b, c}; end ``` Answer: 因為他前面有指定從第零個時間點開始數,隔多少時間再把值給到等號左邊(但是他等號右邊的值都是在第0個時間點就取好的!), 1. 因此時間點分別為: - a: 第0個時間點 - b: 第10個時間點 - c: 第5個時間點 - d: 第20個時間點 2. a, b, c, d最終的值分別為: - a = `1'b1` - b = `1'b0` - c = `1'b0` - d = `1'b1` + b + c (此b, c為其它initial block在第0個時間點所給的值。但如果沒有,d的值就會變成未定義。) ## EX04 ![](https://i.imgur.com/VaXDAkY.png) ``` verilog initial begin a = 1'b0; #0 b = c; end initial begin b = 1'b1; #0 d = a; end ``` Answer: 並不會。 使用`#0 x = ... ;`的技巧被稱為***zero delay control***,被用來把該敘述放到指定時間點的最後一個來執行。因此: 1. 不會有誰先執行的問題 2. a, b, c, d的值分別為: - a = 1'b0 - b = c (如果c在其它block的第0時間點有定義的話,就沒問題。反之則未定義) - c = c (c保持不變) - d = 1'b0 ## EX05 ![](https://i.imgur.com/iACfqFd.png) 原始的code: ![](https://i.imgur.com/bIlZXGS.png) 可是這樣一來他的begin跟end就沒有對上了。 所以我認為他的意思會是: ``` verilog initial begin b = 1'b1; c = 1'b0; #10 b = 1'b0; end initial begin d = #25 (b | c); end ``` Answer: 照我的理解來回答的話,答案的d會是`1'b1`。 因為d的前面並沒有指定時間點,表示他是在第0時間點的時候就取好`(b | c)`的值了,只是在第25個時間點才把值給等號左邊的d。(在第10個時間點被改邊的b跟d在此是沒有產生關聯的)