我无法弄清楚,这个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上面提到的错误即将到来。可能是什么问题?
答案 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
随着可读性的提高,通常更容易发现错误使用的信号。