- 締切済み
Verilogの文法
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
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- ICE_FALCON
- ベストアンサー率56% (63/111)
基本的に#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
- bug_bug
- ベストアンサー率78% (36/46)
ノンブロッキング代入(<=)を使用していることが原因. else節のコメントを解除した場合, 回路のアウトプットには※2が接続されずに"reg2 <= reg2"が接続されるため, インクリメントは行われません. ※1下の"reg2 <= 10'h000;"も同様. インクリメントが行われた後リセットされているのではない. ノンブロッキング代入では同時処理される並列な回路が用意され, if文に応じてアウトプットに接続される回路が切り替わっているイメージを持つと良いと思います. 手続き型言語(C言語など)の様な動作を期待するのであれば, ブロッキング代入(=)を利用. ただし同一ブロック内での併用は不可.