wire型とalways文
// 誤った記述
wire x;
always @(a) x <= a;
wire型の変数(信号)は、always文の中で値を代入(<=)することはできません。
Error (10137): Verilog HDL Procedural Assignment error at sample.v(7): object "x" on left-hand side of assignment must have a variable data type
(対策)always文の中で値を代入する変数はreg型(variable data type)で宣言します。
// 正しい記述
reg x;
always @(a) x <= a;
reg型とassign文
// 誤った記述
reg x;
assign x = a;
reg型の変数(信号)は、assign文の中で値を代入することはできません。
(assign文は、あくまでも配線で両者を「つなぐ」こと)
Error (10219): Verilog HDL Continuous Assignment error at sample.v(5): object "x" on left-hand side of assignment must have a net type
(対策)assign文の左辺にくる信号はwire型(net type)で宣言します。
// 正しい記述
wire x;
assign x = a;
ビット幅の異なる代入・割り当て
// 誤った記述
wire [1:0] a;
wire x;
assign x = a;
左辺と右辺の変数(信号)のビット幅が異なります。
(truncated: 短縮する/2ビット幅を1ビット幅に縮めたよ、というWarning)
Warning (10230): Verilog HDL assignment warning at sample.v(6): truncated value with size 2 to match size of target (1)
(対策)左辺と右辺のビット幅をあわせます。
// 正しい記述
wire [1:0] a;
wire [1:0] x;
assign x = a;
begin-endの対応
// 誤った記述
always @(a) begin
if (a == 1'b0)
x <= a;
end
end
endmodule
beginとendの対応がとれていません。
(インデントをそろえるとこの間違いを発見しやすい)
このミスは、Errorメッセージからは推測がしにくいですが、
「ここにくるべきendがないよ」という類のエラーメッセージのことが多い。
Error (10170): Verilog HDL syntax error at sample.v(9) near text "end"; "end" without "begin"
(対策)
begin-endの対応をそろえる。
それを見つけやすくするためにも、ちゃんとインデントをしたほうがよい。
// 正しい記述
always @(a) begin
if (a == 1'b0) begin
x <= a;
end
end
endmodule
always文内のクロックと信号
// 誤った記述
always @(posedge clk or posedge rst or posedge a) begin
if (clk == 1'b1) x <= a;
if (rst == 1'b1) x <= 0;
end
always文内でposedge clkを使った記述をすると、論理合成時に同期式回路であると判定され、それにあわせた回路(D-FFを使った回路)が生成される。
このようにQuartusIIでは、HDL記述から回路を推測することを行ってくれる(しまう)が、この例の記述では、clkとrstのどちらがクロックでどちらがリセットかが区別できず、見かけ以上clkとrstの両者の立ち上がりでxが変化するため、どちらもクロック信号に見えてしまう。
(さらにこの例ではalways @の中にposedge aもあるが、これが使われていない。これがリセット信号のように使われていればこのエラーは出ない。つまり"rst"のように「リセット信号っぽい名前」かどうかはこの判断に関係ない)
Error (10200): Verilog HDL Conditional Statement error at sample.v(8): cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct
(対策)
明示的に同期回路の記述をする。
// 正しい記述(clkの立ち上がりでリセットがかかる同期リセットの例)
always @(posedge clk or posedge rst or posedge a) begin
if (clk == 1'b1) begin
if (rst == 1'b1) x <= 0;
else x <= a;
end
end
// 正しい記述(clkの立ち上がりとは無関係にリセットがかかる非同期リセットの例)
always @(posedge clk or posedge rst or posedge a) begin
if (rst == 1'b1) x <= 0;
else if (clk == 1'b1) begin
x <= a;
end
end