2015-08-25 18 views
0

我弄不明白,這個errors.Invalid use of input signal <ck> as target錯誤是從哪裏來的?Verilog:errors.Invalid使用輸入信號<ck>作爲目標

module register 
    #(parameter Width = 8) 
    (output reg [Width-1:0] out, 
    input  [Width-1:0] in, 
    input     clear, load, clock); 

always @(posedge clock) 
    if (~clear) 
    out<= 0; 
    else if (~load) 
    out<=in; 
endmodule 

module adder 
    #(parameter Width = 8) 
    (input [Width-1:0] a,b, 
    output [Width-1:0] sum); 
    assign sum = a + b; 
endmodule 


module compareLT // compares a < b 
    #(parameter Width = 8) 
    (input [Width-1:0] a, b, 
    output    out); 
    assign out = a < b; 
endmodule 

module compareLEQ // compares a <= b 
    #(parameter Width = 8) 
    (input [Width-1:0] a, b, 
    output   out); 
    assign out = a <= b; 
endmodule 


module roshanpoop 
    #(parameter Width = 8) 
    (input    ck, reset, 
    input [Width-1:0] yln, 
    output [Width-1:0] y, x); 

    wire [Width-1:0] i, addiOut, addxOut; 
    wire yLoad, yClear, xLoad, xClear, iLoad,iClear; 

    register #(Width) I (i, addiOut, iClear, iLoad, ck); 
    register #(Width) Y (y, yIn, yClear, yLoad, ck); 
    register #(Width) X (x, addxOut, xClear, xLoad, ck); 

    adder #(Width) addI (addiOut, 'b1, i), 
    addX (x, y, addxOut); 
    compareLT #(Width) cmpX (x, 'b0, xLT0); 
    compareLEQ #(Width) cmpI (i, 'd10, iLEQ10); 
    fsm ctl  (xLT0,iLEQ10 ,yLoad, yClear, xLoad, xClear, iLoad,iClear, ck, reset); 
endmodule 


module fsm 
(input LT,LEQ, ck, reset, 
    output reg yLoad, yClear, xLoad, xClear, iLoad, iClear); 
    reg [2:0] cState, nState; 

    always @(posedge ck,negedge reset) 
    if (~reset) 
     cState <= 0; 
    else 
     cState <= nState; 

    [email protected](cState, LT,LEQ) 
    case (cState) 
     3'b00: begin //stateA 
     yLoad = 1; yClear = 1; xLoad = 1; xClear = 0; 
     iLoad = 1; iClear = 0; nState = 3'b001; 
     end 
     3'b001: begin // state B 
     yLoad = 1; yClear = 1; xLoad = 0; xClear = 1; 
     iLoad = 0; iClear = 1; nState = 3'b010; 
     end 
     3'b010: begin //state C 
     yLoad = 1; yClear = 1; xLoad = 1; xClear = 1; 
     iLoad = 1; iClear = 1; 
     if(LEQ)   nState = 3'b001; 
     if(~LEQ & LT) nState = 3'b011; 
     if (~LEQ & ~LT) nState = 3'b100; 
     end 
     3'b011: begin //state D 
     yLoad = 1; yClear = 0; xLoad = 1; xClear = 1; 
     iLoad = 1; iClear = 1; nState = 3'b101; 
     end 
     3'b100: begin //state E 
     yLoad = 1; yClear = 1; xLoad = 1; xClear = 0; 
     iLoad = 1; iClear = 1; nState = 3'b101; 
     end 
     default: begin // required to satisfy combinational synthesis rules 
     yLoad = 1; yClear = 1; xLoad = 1; xClear = 1; 
     iLoad = 1; iClear = 1;nState = 3'b000; 
     $display("Oops, unknown state: %b", cState); 
     end 
    endcase 
endmodule 

錯誤:

line no:70 
Invalid use of input signal ck as target, 
Invalid use of input signal target as target. 

在模塊roshanpoop上述誤差來了。可能是什麼問題?

+0

您正在使用哪種工具進行仿真? – Emman

回答

2

錯誤是由該實例導致

module fsm 
(input LT,LEQ, ck, reset, 
    output reg yLoad, yClear, xLoad, xClear, iLoad, iClear); 

您使用的位置實例,這是不推薦,因爲它使維護你的模塊的任務比較困難(例如,如果你想給你的模塊添加信號:如果你在模塊定義的中間添加它,所有剩餘的信號將被錯誤連接)。

在此,使用位置實例化已造成信號ck從頂部模塊將被連接到iLoad,這是從fsm的輸出信號,所以你正試圖把一個值到一個輸入信號僅ck

的方式是不是正確的方法是使用顯式實例,其中從模塊的每個信號被明確命名並從頂層模塊分配給一個信號,就像這樣:

fsm ctl  (.LT(xLT0), 
      .LEQ(iLEQ10), 
      .yLoad(yLoad), 
      .yClear(yClear), 
      .xLoad(xLoad), 
      .xClear(xClear), 
      .iLoad(iLoad), 
      .iClear(iClear), 
      .ck(ck), 
      .reset(reset) 
     ); 

所以,無論在哪裏在參數列表中,您輸入信號clk它將始終連接到模塊內的正確信號。

+0

fsm也可以實例化爲'fsm ctrl(.LT(xLT0),.LEQ(iLEQ10),。*);',其中'。*'將自動連接同名的網絡。如果存在位寬不匹配的情況,某些模擬器會發生錯誤(這是一個很好的錯誤);別人會發出警告(檢查你的日誌文件並解決)。 – Greg

+0

這僅適用於System Verilog。標籤顯示了它,但問題標題顯示爲「Verilog」,所以我堅持使用適用於Verilog和SVerilog的首選實例化方法。 –

+0

你是對的@mcleod_ideafix,我的錯。我認爲它是IEEE Std 1364-2001的一部分。我打開了我的LRM副本,並找不到任何IEEE 1364中的參考文獻。 – Greg

0

不是一個答案,而是一些可能使代碼更容易理解的提示。我會發表評論,但代碼示例在評論中效果不好。

1)使用現代工具集時應避免手動靈敏度列表。

[email protected](cState, LT,LEQ) 

隨着自動靈敏度列表將只是:

always @(*) 
// Or 
always @* 

如果能夠使用的SystemVerilog(如問題標籤指示),則優選的方法是:

always_comb 

2 )代替:

yLoad = 1; yClear = 1; xLoad = 1; xClear = 0; 
iLoad = 1; iClear = 0; 

對於每一種情況下,我們可以有

reg [5:0] temp_control; 
assign {yLoad, yClear xLoad, xClear, iLoad, iClear} = temp_control; 
//... 
always @* 
    case(cState) 
    3'b000: begin //stateA 
     temp_control = 6'b111010; nState = 3'b001; 
     end 
     3'b001: begin // state B 
     temp_control = 6'b110101; nState = 3'b010; 
     end 
     3'b010: begin //state C 
     temp_control = 6'b111111; 
     if(LEQ)   nState = 3'b001; 
     if(~LEQ & LT) nState = 3'b011; 
     if (~LEQ & ~LT) nState = 3'b100; 
     end 
//... 

更好的是創造了temp_controls助記符。

localparam [5:0] CTRL_LOAD = 6'b111010; 
localparam [5:0] CTRL_CLEAR = 6'b111010; 

助記符的狀態也非常有幫助:

localparam [2:0] STATE_INIT = 3'b000; 
localparam [2:0] STATE_START = 3'b001; 
localparam [2:0] STATE_STOP = 3'b010; 

的密克羅尼西亞聯邦結構可能看起來像一些事情:

always @* 
    case(cState) 
     STATE_INIT: begin //stateA 
     temp_control = CTRL_LOAD; nState = STATE_START; 
     end 
     STATE_START: begin // state B 
     temp_control = CTRL_CLEAR; nState = STATE_STOP; 
     end 
     STATE_STOP: begin //state C 
     temp_control = CTRL_HALT; 
     if(LEQ)   nState = STATE_START; 
     if(~LEQ & LT) nState = STATE_RECYCLE; 
     if (~LEQ & ~LT) nState = STATE_CRUSH; 
     end 

由於可讀性提高它往往是容易被發現一個錯誤使用的信號。

fsm ctl  (xLT0,iLEQ10 ,yLoad, yClear, xLoad, xClear, iLoad,iClear, ck, reset); 
模塊

+2

由於OP使用SystemVerilog標記問題,因此應該使用'always_comb'而不是'always @ *'。 always_comb保證在時間0(當某些塊的輸入是常量時需要)執行,並執行規則檢查以保證組合邏輯的執行。 –

+0

真正的dave_59,因爲我沒有看到任何SystemVerilog構造認爲他們只是想要簡單的verilog,將編輯答案。 – Morgan