Verilog:errors。无效使用输入信号<ck>作为目标

时间:2015-08-25 13:23:18

标签: verilog hardware system-verilog xilinx fsm

我无法弄清楚,这个errors.Invalid use of input signal <ck> as target错误来自哪里?

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;

  always@(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上面提到的错误即将到来。可能是什么问题?

2 个答案:

答案 0 :(得分:2)

错误是由此实例化引起的:

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

模块:

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,它都将始终连接到模块内的正确信号。

答案 1 :(得分:0)

不是答案,而是一些可能使代码更容易理解的提示。我会发表评论,但代码示例在评论中效果不佳。

1)使用现代工具集时,可以[应该]避免使用手动灵敏度列表。

always@(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;

FSM结构可能看起来像:

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

随着可读性的提高,通常更容易发现错误使用的信号。