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