Verilog :errors.Invalid 使用输入信号 <ck> 作为目标

Verilog :errors.Invalid use of input signal <ck> as target

我不知道这个 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 中出现上述错误。可能是什么问题?

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

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

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

错误是由这个实例化引起的:

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 放在参数列表的哪个位置,它都将始终连接到模块内的正确信号。