免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Verilog非阻塞賦值的仿真/綜合問題(二)
From:http://blog.eccn.com/space.php?uid=121854&do=blog&id=1432

8.0
流水線建模

圖二示意了一個簡單的時序(sequential流水線寄存器。

               

                

 

從例5到例8列舉了一個工程師可能選用的4種使用阻塞賦值為它建模的方案。

 

module pipeb1 (q3, d, clk);

output [7:0] q3;

input [7:0] d;                                      

input clk;

reg [7:0] q3, q2, q1;

always @(posedge clk) begin

q1 = d;

q2 = q1;

q3 = q2;

end

endmodule

Example 5 - Bad blocking-assignment sequential coding style #1

                                                                   

   

 

(外注:綜合報告:WARNING: Signal <q1> is assigned but never used.

WARNING:Signal <q2> is assigned but never used.

在例5里面,接連的“阻塞賦值”命令將使得輸入D連續(xù)地覆蓋所有寄存器輸出(在下一個posedge clk到來時)。即在每一個clk邊沿,輸入值被無延遲地傳到q3的輸出。這很明顯并沒有建立一個流水線而只是為一個寄存器建模------實際綜合結(jié)果將是上面的圖3。

 

module pipeb2 (q3, d, clk);

output [7:0] q3;

input [7:0] d;

input clk;

reg [7:0] q3, q2, q1;

 

always @(posedge clk) begin  //注意次序的更改!

q3 = q2;               

q2 = q1;               

q1 = d;                

end

endmodule

Example 6 - Bad blocking-assignment sequential coding style #2 - but it works!

上面的pipeb2里面,阻塞賦值被仔細地安排了次序以使得行為仿真正確。這種建模同樣也可以得到正確的綜合結(jié)果。(外注:Found 3-bit shift register for signal <q3>.

    Summary: inferred   8 Shift register(s).  

 

在下面的例3里,“阻塞賦值”被安排在不同的always塊里面。這樣Verilog標準允許以任意的次序 來仿真執(zhí)行3always-------這也許會使得該流水線仿真結(jié)果產(chǎn)生錯誤,因為這產(chǎn)生了Verilog競爭條件。由不同的always塊執(zhí)行順序會產(chǎn)生不同的結(jié)果。盡管這樣,它的綜合結(jié)果將是正確的!   這就意味著綜合前仿真和綜合后仿真不匹配。Pipeb4或者其它的類似always塊同樣也許會產(chǎn)生仿真與綜合不匹配的結(jié)果------綜合結(jié)果是對的,但是仿真結(jié)果也許不正確。(外注:pipeb4只是又顛倒了一下次序,對實際仿真次序卻不產(chǎn)生決定作用.

 

module pipeb3 (q3, d, clk);

output [7:0] q3;

input [7:0] d;

input clk;

reg [7:0] q3, q2, q1;

always @(posedge clk) q1=d;

always @(posedge clk) q2=q1;

always @(posedge clk) q3=q2;

endmodule

Example 7 - Bad blocking-assignment sequential coding style #3

 

module pipeb4 (q3, d, clk);

output [7:0] q3;

input [7:0] d;

input clk;

reg [7:0] q3, q2, q1;

always @(posedge clk) q2=q1;

always @(posedge clk) q3=q2;

always @(posedge clk) q1=d;

endmodule

Example 8 - Bad blocking-assignment sequential coding style #4

 

假如每一個上面的例子都改用“非阻塞賦值”那么將會都能得到正確的仿真結(jié)果,并綜合出想要的流水線邏輯。

 

module pipen1 (q3, d, clk);

output [7:0] q3;

input [7:0] d;

input clk;

reg [7:0] q3, q2, q1;

always @(posedge clk) begin

q1 <= d;

q2 <= q1;

q3 <= q2;

end

endmodule

Example 9 - Good nonblocking-assignment sequential coding style #1

 

module pipen2 (q3, d, clk);

output [7:0] q3;

input [7:0] d;

input clk;

reg [7:0] q3, q2, q1;

always @(posedge clk) begin

q3 <= q2;

q2 <= q1;

q1 <= d;

end

endmodule

Example 10 - Good nonblocking-assignment sequential coding style #2

 

module pipen3 (q3, d, clk);

output [7:0] q3;

input [7:0] d;

input clk;

reg [7:0] q3, q2, q1;

always @(posedge clk) q1<=d;

always @(posedge clk) q2<=q1;

always @(posedge clk) q3<=q2;

endmodule

Example 11 - Good nonblocking-assignment sequential coding style #3

 

module pipen4 (q3, d, clk);

output [7:0] q3;

input [7:0] d;

input clk;

reg [7:0] q3, q2, q1;

always @(posedge clk) q2<=q1;

always @(posedge clk) q3<=q2;

always @(posedge clk) q1<=d;

endmodule

Example 12 - Good nonblocking-assignment sequential coding style #4

 

從上面的流水線編碼風(fēng)格例子可以看出:

 僅一個“阻塞賦值”的描述可以保證仿真正確。

 三個“阻塞賦值”的描述可以得到正確綜合結(jié)果。

 四個“非阻塞賦值”描述都可以保證仿真結(jié)果正確。

 四個“非阻塞賦值”描述都可以得到正確綜合結(jié)果。(原文這一條是“阻塞賦值”大概是有誤?)

雖然,如果限制在一個always塊里面,并小心地組織好一個always塊里面阻塞賦值的次序(外注:一個always塊里面的幾個“阻塞賦值”是按照陳述的次序串行仿真執(zhí)行的,綜合執(zhí)行次序也是?)同樣可能會正確地為流水線建模;但是另一方面,我們可以很容易地使用“非阻塞賦值”來為上面的流水線建模------它們既可以正確仿真也可以正確綜合。

 

9.0 阻塞賦值 & 簡單例子

 

有許多將VerilogVerilog綜合的書,它們舉了很多成功地利用“阻塞賦值”為一些簡單的時序電路建模的小例子。例13是一個在大多數(shù)Verilog書本里用來為一個觸發(fā)器(flip-flop)建模的例子(這是簡單而有缺陷的阻塞賦值建模,但是它確實可以工作):

 

module dffb (q, d, clk, rst);

output q;

input d, clk, rst;

reg q;

always @(posedge clk)

if (rst) q = 1'b0;

else q = d;

endmodule

Example 13 - Simple flawed blocking-assignment D-flipflop model - but it works!

 

如果工程師們想把所有的模塊(module)都集中到一個always里面描述,“阻塞賦值”可以用來正確地為所需要的邏輯建模、仿真和綜合。但是不幸的是這個原因?qū)е铝讼矚g在其它情況下也使用“阻塞賦值”的習(xí)慣,并且更復(fù)雜的時序always塊將會產(chǎn)生競爭條件------在前面已經(jīng)詳細闡述過。

 

module dffx (q, d, clk, rst);

output q;

input d, clk, rst;

reg q;

always @(posedge clk)

if (rst) q <= 1'b0;

else q <= d;

endmodule

Example 14 - Preferred D-flipflop coding style with nonblocking assignments

 

應(yīng)該努力養(yǎng)成使用“非阻塞賦值”為 所有的 時序邏輯建模的習(xí)慣------象上面的例14一樣------即使是為了對付任何一個簡單的模塊。

 

下面考慮一下一個稍微復(fù)雜的時序邏輯,一個線性反饋移位寄存器(Linear Feedback shift-Register)或稱之為LFSR。

 

10.0 為時序反饋建模 Sequential feedback modeling

 

一個LFSR是一種帶反饋環(huán)路(feedback loop)的時序邏輯。反饋環(huán)路(feedback loop)為工程師們帶來了一個難題使得他們試圖使用細心組織次序的“阻塞賦值”來為它正確建模,如下面的例子:

 

 

module lfsrb1 (q3, clk, pre_n);

output q3;

input clk, pre_n;

reg q3, q2, q1;

wire n1;

assign n1 = q1 ^ q3;

always @(posedge clk or negedge pre_n)

if (!pre_n) begin

q3 = 1'b1;

q2 = 1'b1;

q1 = 1'b1;

end

else begin

q3 = q2;

q2 = n1;

q1 = q3;

end

endmodule

Example 15 - Non-functional LFSR with blocking assignments(外注:綜合報告―――>

Register <q1> equivalent to <q3> has been removed

    Found 1-bit register for signal <q3>.

    Found 1-bit xor2 for signal <n1>.

Found 1-bit register for signal <q2>.

Summary:

inferred   2 D-type flip-flop(s).

沒有辦法通過調(diào)整描述次序的方法來正確建模除非引入一個臨時的變量(

外注:例如引入“wire n2――>

module xxxxx (q3, clk, pre_n);

output q3;

input clk, pre_n;

reg q3, q2, q1;

wire n1,n2;

assign n1 = q1 ^ q3;

assign n2 = q3;

always @(posedge clk or negedge pre_n)

if (!pre_n) begin

q3 = 1'b1;

q2 = 1'b1;

q1 = 1'b1;

end

else begin

q3 = q2;

q2 = n1;

q1 = n2;

end

endmodule

 

這樣可以得到正確的綜合結(jié)果:

    Found 1-bit register for signal <q3>.

    Found 1-bit xor2 for signal <n1>.

    Found 1-bit register for signal <q1>.

    Found 1-bit register for signal <q2>.

    Summary:

  inferred   3 D-type flip-flop(s).)。

可以通過把所有賦值弄到一個等式的方式(one-line equations)來避免使用臨時變量,例如下面的例16所示。但是現(xiàn)在編碼顯得更難于理解尤其當涉及的表達式更大更長時,編寫代碼和調(diào)試都變得比較困難,因此不鼓勵使用這種風(fēng)格。

 

module lfsrb2 (q3, clk, pre_n);

output q3;

input clk, pre_n;

reg q3, q2, q1;

always @(posedge clk or negedge pre_n)

if (!pre_n) {q3,q2,q1} = 3'b111;

else {q3,q2,q1} = {q2,(q1^q3),q3};

endmodule

Example 16 - Functional but cryptic LFSR with blocking assignments

 

 

 如果把例15和例16的阻塞賦值(blocking assignment)都替換為非阻塞賦值(nonblocking assignment),如下面例1718所示,那么所有的仿真都將如我們對一個LFSR所期望的那樣。

module lfsrn1 (q3, clk, pre_n);

output q3;

input clk, pre_n;

reg q3, q2, q1;

wire n1;

assign n1 = q1 ^ q3;

always @(posedge clk or negedge pre_n)

if (!pre_n) begin

q3 <= 1'b1;

q2 <= 1'b1;

q1 <= 1'b1;

end

else begin

q3 <= q2;

q2 <= n1;

q1 <= q3;

end

endmodule

Example 17 - Functional LFSR with nonblocking assignments

 

module lfsrn2 (q3, clk, pre_n);

output q3;

input clk, pre_n;

reg q3, q2, q1;

always @(posedge clk or negedge pre_n)

if (!pre_n) {q3,q2,q1} <= 3'b111;

else {q3,q2,q1} <= {q2,(q1^q3),q3};

endmodule

Example 18 - Functional but cryptic LFSR with nonblocking assignments

      

                 根據(jù)8.0段例子pipeline10.0段例子LFSR,我們推薦對所有時序邏輯建模時使用非阻塞賦值(nonblocking assignment)。相似的分析也將顯示出對latch建模時使用非阻塞賦值(nonblocking assignment)是最安全的。

 

1: 當為時序邏輯建模,使用“非阻塞賦值”。

2: 當為鎖存器(latch)建模,使用“非阻塞賦值”。

 

11.0  組合邏輯―使用阻塞賦值(blocking assignment

 

Verilog可以有很多種方法為組合邏輯建模,但是當使用always塊來為組合邏輯建模時,應(yīng)該使用阻塞賦值(blocking assignment)。

 

如果在某個always塊里面只有一個賦值(表達),那么使用阻塞或者非阻塞賦值都可以正確工作。但是如果您對養(yǎng)成好的編碼習(xí)慣有興趣的話,還是要“總是用阻塞賦值對組合邏輯建模”。

 

一些設(shè)計師建議非阻塞賦值不應(yīng)該只為編寫時序邏輯,它也可以用來編寫組合邏輯。當然對于簡單的組合邏輯always塊這是可以的,但是對于在一個always塊里面含有多個賦值陳述,例如例19含有and-or的陳述,使用了不含延遲(delay)的非阻塞賦值會造成仿真不正確,或者要使仿真正確您需要另外的添加敏感事件列表(sensitivity list entries),和“多登入路徑”multiple passes)來貫穿always 塊以使得仿真正確。接下來的問題是從仿真需要多長時間來看,這是低效率的(外注:即降低仿真的performance)。

 

19y輸出建立在3個依次執(zhí)行的陳述上(外注:tmp1 <= a & b;   tmp2 <= c & d;   y <= tmp1 | tmp2;。由于非阻塞賦值的LHS變量值更新是在對RHS表達式估值之后,所以tmp1tmp2的值仍然是該always塊上一個登入口的值而不是在這一個仿真時間步(simulation time step)結(jié)束時被更新的值。因此y的值將受舊的tmp1tmp2影響,而不是這次掃描過的always塊內(nèi)被更新的值。

 

module ao4 (y, a, b, c, d);

output y;

input a, b, c, d;

reg y, tmp1, tmp2;

always @(a or b or c or d) begin

tmp1 <= a & b;

tmp2 <= c & d;

y <= tmp1 | tmp2;

end

endmodule

Example 19 - Bad combinational logic coding style using nonblocking assignments

 

20與例19是一樣的,不同之處在于tmp1tmp2被添加到事件列表中去了。如第7段(section 7.0)中所述,在“非阻塞賦值更新事件隊列”中當非阻塞賦值更新LHS變量時,always塊將會“自觸發(fā)”并使用最新的tmp1tmp2來更新y輸出?,F(xiàn)在y輸出值正確了因為增加使用了兩條“登入路徑”(two passes)貫穿整個always塊。使用更多的“登入路徑”來貫穿always塊等于降低仿真器的性能,因此如果可以有合理的一些代碼變化可以取代這種用法的話,就盡量避免這種用法。

 

module ao5 (y, a, b, c, d);

output y;

input a, b, c, d;

reg y, tmp1, tmp2;

always @(a or b or c or d or tmp1 or tmp2) begin

tmp1 <= a & b;

tmp2 <= c & d;

y <= tmp1 | tmp2;

end

endmodule

Example 20 - Inefficient multi-pass combinational logic coding style with nonblocking assignments

 

發(fā)展一個好的習(xí)慣可以避免使用“多登入路徑”(multiple passes)貫穿always塊,即使用阻塞賦值為組合邏輯建模。

 

module ao2 (y, a, b, c, d);

output y;

input a, b, c, d;

reg y, tmp1, tmp2;

always @(a or b or c or d) begin

tmp1 = a & b;

tmp2 = c & d;

y = tmp1 | tmp2;

end

endmodule

Example 21 - Efficient combinational logic coding style using blocking assignments

 

21與例19一樣,不同之處只在于用阻塞賦值替代了非阻塞賦值。這保證了在一個“登入路徑”貫穿alwaysy輸出的正確(guarantee that the y-output assumes the correct value after only one pass through the always block?)。因此有下面的編碼方針:

 

 3 當用always塊為組合邏輯建模,使用“阻塞賦值

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
筆試題(觸發(fā)器)
Verilog的135個經(jīng)典設(shè)計實例
Verilog常見必備面試題
流水線技術(shù)原理和Verilog HDL實現(xiàn)
大神教你DIY | 如何用一塊FPGA開發(fā)板制作音樂盒?
Verilog中阻塞和非阻塞賦值原則
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服