推しミネラルウォーターはありますか?

Verilogの文法について、教えてください。
下のリストのように、if文をネストして2つのカウンタを作っています。
reg1が特定の値になったらreg2をカウントアップするという動作です。

ここで、リスト真ん中当たりの、reg2がカウントアップされるところで、
ネストしたif文(※1の箇所)のelseを入れると、そのif文の上(※2)が
実行されません。

Verilogの場合、elseは直前のif文に対応するはずなので、
影響してしまう理由が分かりません。

どなたか教えてください。

reg [9:0] reg1; // 水平レジスタ
reg [9:0] reg2; // 垂直レジスタ

always @(posedge clk25m or negedge rst_n) begin
if(rst_n == 1'b0) begin // リセット
reg1 <= 10'h000;
reg2 <= 10'h000;
end
else if(clk25m == 1'b1) begin
if(10'd800 < reg1) begin
reg1 <= 10'h000;
reg2 <= reg2 + 10'h001; // ※2
if(10'd600 < reg2) // ※1
reg2 <= 10'h000;
// else
// reg2 <= reg2;
// コメントアウトしないと reg2 <= reg2 + 10'h001;(※2)が実行されない  
end
else
reg1 <= reg1 + 10'h001;
end
else
reg1 <= reg1;
end

A 回答 (2件)

基本的に#1さんの書いている通りC言語の感覚で書くとダメです。


しかし他にも突っ込み所が満載です・・・・。
特にこの行
else if(clk25m == 1'b1) begin
・・・・ありえません。

同期回路には決まった書き方があります。
たぶん投稿者さんが書きたいのは

always @(posedge clk25m or negedge rst_n)
 begin
  if(!rst_n)
   begin
    reg1 <= 10'h000;
    reg2 <= 10'h000;
   end
  else if(10'd800 < reg1)
   begin
    reg1 <= 10'h000;
    if(10'd600 < reg2 + 10'h001)
     begin
      reg2 <= 10'h000;
     end
    else
     begin
      reg2 <= reg2 + 10'h001;
     end
   end
  else
   begin
    reg1 <= reg1 + 10'h001;
    reg2 <= reg2;
   end
 end

これでも、まだありえません。ちゃんとしたlintを適用するとはじかれます。
こんな感じですかね。


wire [9:0] reg2inc;
assign reg2inc = reg2 + 10'h001; //Wrap

always @(posedge clk25m or negedge rst_n)
 begin
  if(!rst_n)
   begin
    reg1 <= 10'h000;
   end
  else if(10'd800 < reg1)
   begin
    reg1 <= 10'h000;
   end
  else
   begin
    reg1 <= reg1 + 10'h001;
   end
 end
always @(posedge clk25m or negedge rst_n)
 begin
  if(!rst_n)
   begin
    reg2 <= 10'h000;
   end
  else if(10'd800 < reg1)
   begin
    if(10'd600 < reg2inc)
     begin
      reg2 <= 10'h000;
     end
    else
     begin
      reg2 <= reg2inc;
     end
   end
  else
   begin
    reg2 <= reg2;
   end
 end
    • good
    • 0

ノンブロッキング代入(<=)を使用していることが原因.


else節のコメントを解除した場合, 回路のアウトプットには※2が接続されずに"reg2 <= reg2"が接続されるため, インクリメントは行われません.
※1下の"reg2 <= 10'h000;"も同様. インクリメントが行われた後リセットされているのではない.

ノンブロッキング代入では同時処理される並列な回路が用意され, if文に応じてアウトプットに接続される回路が切り替わっているイメージを持つと良いと思います.

手続き型言語(C言語など)の様な動作を期待するのであれば, ブロッキング代入(=)を利用.
ただし同一ブロック内での併用は不可.
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報