Re: [問題] 關於verilog signal&varieble問題
※ 引述《zxvc (修行)》之銘言:
: 我是習慣這種coding style。
: 或許你以為這樣就是分開sequential circuit與combinational circuit,
: module Test(c, d, Clock, Reset1);
: output reg [2:0] c;
: output reg d;
: input Clock, Reset1;
: reg d2;
: always@(posedge Clock)
: if(Reset1)
: c = 0;
: else
: begin
: c = c+1;
: d = d2;
: end
: always@(*)
: if(c == 2)
: d2 = 1;
: else
: d2 = 0;
: endmodule
: 但其實c = c+1;會合出加法器(combinational circuit)。
: 所以這種敘述也是bad style!?:
: always@(posedge Clock)
: if(Reset1)
: a = 0;
: else
: begin
: if(b)
: a = 1;
: else
: a = 0;
: end
: 因為if(b)會合出多工器。
: 如果這真是你們實驗室的coding style,我也認了。
: 不過我沒有輕視任何coding style的意思,只是習慣的差異。
: 至於debug的容易與否我想跟你自己習慣的coding style有關。
: 你自己習慣哪種coding style,你就覺得它容易debug。
: 不過如果大多數人的coding style跟我不一樣,
: 我想我也只好習慣別人的coding style。
: 題外話:這個世界不是最好的東西就是最好,還要大家說最好才算數。
我的習慣也是不會刻意去分開成兩個 always,但是
仔細想一想吧,多寫一些code就會體會把
always @(*) , always @(posedge ...) 分開的好處
最明顯的是用在 FSM 上, 雖然也可以都寫在一塊...
例,
always @(*) begin
a = 1; b = 0; c =1;
if ( S == 1 ) a = 0;
if ( S == 2 ) b = 1;
if ( S == 3 ) c = 0;
end
always @( posedge clk ) begin
a_r <= a;
b_r <= b;
c_r <= c;
end
你可以試著把他寫成一個 always @( posedge ... ) 看看, 會不會比較好閱讀
這個例子的電路有點簡單, 直接分開成 三個 always @( posedge ... ) 反而更好,
當然我的用意不是這樣,希望你可以理解
如果舉的例子是 a~z 呢? 那每個 if 都要連貫, if 內要有 a~z 的描述...
應該會亂掉吧
=====================================================================
另外,如果今天我要改設計,想拿掉 c_r register呢? 變 wire out 呢?
: initial
: begin
: a = 0; (1)
: a <= 1; (2)
: b = 0; (3)
: c <= a; (4)
: end
: (2)跟(4)如果視為同時動作,所以最後a = 1, c = 0!?就錯了。
: 硬要用"同時"、"不同時"去解釋也解釋不通這initial怎麼跑。
: blocking assignment中block作動詞解釋為"阻擋",不是"方塊"。
: 阻擋什麼?答案是執行的控制權。
: 也就是當assignment的update動作還沒完成,它是不會執行下一行的。
: begin...end在Verilog中叫sequential block,
: 也就它裡面的敘述是一行一行(sequential)執行的(IEEE 1364-2005 Sec. 9.8.1)。
: fork...join在Verilog中叫parallel block,
: 它裡面的各敘述才是同時(concurrent)執行的(IEEE 1364-2005 Sec. 9.8.2)。
: 所以上面的initial要怎麼跑?答案就是,initial後面接sequential block,
: 所以它會先執行(1)。(1)是blocking assignment,
: 所以它會先對等號右手端求值(evaluation),然後更新(update)完a才繼續執行下一行。
: 所以現在a = 0,然後執行(2)。(2)是non-blocking assignment,它會先evaluation,
: 但不會立即update就執行下一行(3)。
: non-blocking assignment update的動作是當
: 遇到blocking assignment或sequential block的end才會update。
: (3)是blocking assignment,所以a會被強制update。所以(3)執行完後
: a = 1, b = 0。
: 接著執行(4),但a此時=1,所以最後a = 1, b = 0, c = 1。
: 有興趣可以用ModelSim驗證看看。
: 另外請勿使用parallel block(fork...join)設計硬體,
: 因為大多合成器不能合成。
基本上你initial, fork join都是simulation的用法,是不能合成的
還有 non-blocking, blocking 最好不要一起用,很有趣,但沒多少人看的懂,
連simulator都可能有不同解釋
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.64.79.59
※ 編輯: pierreqq 來自: 61.64.79.59 (04/14 23:17)
推
04/15 06:29, , 1F
04/15 06:29, 1F
→
04/15 06:33, , 2F
04/15 06:33, 2F
→
04/15 06:34, , 3F
04/15 06:34, 3F
→
04/15 06:37, , 4F
04/15 06:37, 4F
→
04/15 06:39, , 5F
04/15 06:39, 5F
→
04/15 06:40, , 6F
04/15 06:40, 6F
→
04/15 06:41, , 7F
04/15 06:41, 7F
→
04/15 06:43, , 8F
04/15 06:43, 8F
→
04/15 06:43, , 9F
04/15 06:43, 9F
我的建議也是搞懂,但是不要刻意用,
HDL 愈簡單愈好, 因為flow的不同, 用的tool不盡相同, 會出什麼問題也不知道
Verilog雖然長的像C, 但是其實精神還是 HDL, 而編譯器(synthesizer?)也不單純
所以我是不太會去挑戰tool的極限的
(有興趣研究的人例外...)
推
04/15 08:40, , 10F
04/15 08:40, 10F
我好像打漏了 @, 補一下
推
04/15 09:15, , 11F
04/15 09:15, 11F
推
04/15 09:16, , 12F
04/15 09:16, 12F
→
04/15 09:16, , 13F
04/15 09:16, 13F
→
04/15 09:17, , 14F
04/15 09:17, 14F
→
04/15 09:18, , 15F
04/15 09:18, 15F
→
04/15 09:18, , 16F
04/15 09:18, 16F
推
04/15 09:23, , 17F
04/15 09:23, 17F
→
04/15 09:24, , 18F
04/15 09:24, 18F
→
04/15 09:25, , 19F
04/15 09:25, 19F
推
04/15 09:51, , 20F
04/15 09:51, 20F
※ 編輯: pierreqq 來自: 211.78.167.166 (04/15 10:43)
推
04/15 12:45, , 21F
04/15 12:45, 21F
→
04/15 12:47, , 22F
04/15 12:47, 22F
推
04/15 12:52, , 23F
04/15 12:52, 23F
嗯,當然, 隨著tools的更新,對scheduling的解讀應該會趨向一致,這東西會愈用愈明白
只是之前遇上了, 而且這也不是正規寫法,只好避開不用,對我之後的coding也沒影響
因為寫 HDL 重點不在這,就算我在 test bench 可以這樣用, 但是為了別人閱讀上的
方便,我也會儘量去寫穩定不會出錯的code
這就跟有人可以去參加比賽,寫出最怪異的C,而且是有功能的,贏得冠軍
但是教科書上絕對不會教你有這種寫法的道理一樣
※ 編輯: pierreqq 來自: 211.78.167.166 (04/15 14:51)
→
11/11 15:04, , 24F
11/11 15:04, 24F
→
01/04 21:55,
7年前
, 25F
01/04 21:55, 25F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 8 之 10 篇):