|
這幾天為了測試 non-blocking 的用法,寫了底下的範例,卻發現 compiler 一直過不了... |
---|
module func1(clk, Input1, Output1, Output2); input clk; input [15:0] Input1; output [15:0] Output1, Output2; always@(posedge clk) begin Output1 <= Input1 + 1; Output2 <= Output1; end endmodule
出現的錯誤訊息如下:
Output1 <= Input1 + 1; | ncvlog: *E,WANOTL (func1.v,10|8): a net is not a legal lvalue in this context [9.3.1(IEEE)]. Output2 <= Output1; | ncvlog: *E,WANOTL (func1.v,11|8): a net is not a legal lvalue in this context [9.3.1(IEEE)]. module worklib.func1:v errors: 2, warnings: 0
一時之間毫無頭緒,只好找同事協助,後來才發現,在 always 裡面的 noblocking assignment 不能單單宣告為 output 屬性,需要賦予 reg 屬性,才可以正確動作,範例修正如下:
module func1( clk, Input1, Output1, Output2 ); input clk; input [15:0] Input1; output [15:0] Output1, Output2; reg [15:0] Output1, Output2; always @ (posedge clk) begin Output1 <= Input1+1; Output2 <= Output1; end endmodule
修改後便可以正常 compiler 了,再寫個 test bench 去確認執行結果:
`define cycle 4 module func1_test(); reg [15:0] a; wire [15:0] b, c; reg clk; initial clk = 0; always #(`cycle/2) clk = ~clk; func1 func1_te( .clk(clk), .Input1(a), .Output1(b), .Output2(c) ); initial begin @(posedge clk) a = 16'b0000000000000001; @(posedge clk) a = 16'b0000000000000010; @(posedge clk) a = 16'b0000000000000011; @(posedge clk) a = 16'b0000000000000100; @(posedge clk) a = 16'b0000000000001000; #100 $finish; end initial begin $monitor($time, " a=%d, b=%d, c=%d", a, b, c); end initial begin $fsdbDumpfile("func1.fsdb"); $fsdbDumpvars; end endmodule
compiler 後將訊息打在螢幕,發現有趣的現象:
0 a= x, b= x, c= x
2 a= 1, b= 2, c= x
6 a= 2, b= 3, c= 2
10 a= 3, b= 4, c= 3
14 a= 4, b= 5, c= 4
18 a= 8, b= 9, c= 5
22 a= 8, b= 9, c= 9
變數 c 在 time 2 的時後,也就是第一次 clk 拉起時並沒有被賦值,而是延遲到了下次 clk rising 才會進行賦值,並賦予上個 clk 變數 b 的值,即變數 c 的賦值被延遲了一個 clock。為了確認這件事情,將程式改成底下的寫法,並觀察結果:
module func1( clk, Input1, Output1, Output2 ); input clk; input [15:0] Input1; output [15:0] Output1, Output2; reg [15:0] wInput; reg [15:0] Output1, Output2; always @ (posedge clk) begin wInput <= Input1; Output1 <= wInput+1; Output2 <= Output1; end endmodule
額外宣告了一個 reg wInput,並將 Input1 先賦予 wInput,發現:
0 a= x, b= x, c= x
2 a= 1, b= x, c= x
6 a= 2, b= 2, c= x
10 a= 3, b= 3, c= 2
14 a= 4, b= 4, c= 3
18 a= 8, b= 5, c= 4
22 a= 8, b= 9, c= 5
26 a= 8, b= 9, c= 9
變數 b 的賦直延遲了一個 clock 並且 c 延遲兩個 clock 後始有動作。
Taiwan is an independent country.
No comments:
Post a Comment