- 締切済み
「入門Verilog HDL記述」 の 一例について
「入門Verilog HDL記述」を読みながらVerilog を勉強中なのですが、周りに聞ける人がいないので、質問させてください。 (ちなみに VHDL は習得しているつもりです。) いろいろ疑問点があるので、分けて何点か質問させていただきました。 改訂版 入門Verilog HDL記述の240ページのリスト II.5に generate ブロックと if 分についての以下のようなコードがありますが、 これは期待通りには動かないと思うのですが。。。 module sel2to1_2( input sel, input [3:0] d0, d1, output [3:0] dout ); parameter sel_type = 1; generate if(sel_type == 1) begin: sel_always reg [3:0] dout; always @* begin if(sel) dout <= d1; else dout <= d0; end end else if(sel_type == 2) begin: sel_cond wire [3:0] dout; assign dout = (sel == 1) ? d1 : d0; end endgenerate endmodule ModelSimでシミュレーションしてみましたが、generate文の中の reg [3:0] dout は generate 文の中のスコープでのみ定義されているらしく、 output [3:0] dout とは別の信号らしいです。よってoutputには何も代入されず。 試しに、xilinx の ISE でコンパイルしてみたが、やっぱり output には なにも接続されず、セレクタなんて生成されませんでした。 そもそも module sel2to1_2( input sel, input [3:0] d0, d1, output [3:0] dout ); reg [3:0] dout; みたいに書くと、2回宣言されているとなってエラーになります。 よって、参照ソースコードみたいに reg と wire を切り替えるような書き方はそもそもできないのでは? 皆さんどう思われますか? (インデントがうまくいかず、読みづらくてすいません。)
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- nanako_
- ベストアンサー率0% (0/0)
veritak でトップモジュールを付加してやってみました。構文は通るので 文法的には間違いではないようですが、多分意図したようにはうごかないでしょうね。 まず、generate ですが、初心者は避けた方がよい、難しい構文です。 実行時ではなく、コンパイル時の条件動作文だと思ってください。 上では、parameter sel_type = 1; なので、SIM実行時には、 begin: sel_always reg [3:0] dout; always @* begin if(sel) dout <= d1; else dout <= d0; end end のみが残ります。(勿論これだけを取りだすことは、構文不備になりますが、説明の都合上こうしています。)さらにSCOPEの指定を外すと、 reg [3:0] dout; always @* begin if(sel) dout <= d1; else dout <= d0; end となり見慣れた構文になりますね。しかし、SCOPEラベルがあるために、 このregは、 sel2to1_2.sel_always.dout と言うインスタンス名になります。一方ポートの方は、 sel2to1_2.dout ですから、別な信号になります。従って、regの方のdoutは、ポートに接続されることはありません。 >よってoutputには何も代入されず。 >試しに、xilinx の ISE でコンパイルしてみたが、やっぱり output には >なにも接続されず、セレクタなんて生成されませんでした。 従い、上の現象になります。 > >module sel2to1_2( >input sel, >input [3:0] d0, d1, >output [3:0] dout >); reg [3:0] dout; >みたいに書くと、2回宣言されているとなってエラーになります。 これは、verilog2001 の記法の問題と1995スタイルの混在が問題です。 generate でreg/wire を切り替えるなら、多分1995スタイルでないと無理です。 1995では、 module xx sel, d0,d1, dout); input d0,d1; output [3:0] dout; //generate if 文 reg [3:0] dout; //else wire.. //endgenerate と書けます。 >よって、参照ソースコードみたいに reg と wire を切り替えるような書き>方はそもそもできないのでは? 上のようにSCOPE指定を外せば文法上は、書けます。しかしXILINXのツールでは、なぜか(本来必要のないIF文に)SCOPEラベルがないとエラーになったりすので、余計にわけ分からないことになってしまいますね。
お礼
詳しいご回答ありがとうございました。 > まず、generate ですが、初心者は避けた方がよい、難しい構文です。 > 実行時ではなく、コンパイル時の条件動作文だと思ってください。 はい、理解しております。 普段 VHDL で仕事しているときはgenerate文 (特にfor~generate)を多用してますが。 同じことを何度も書かなくていいのはもちろんですが、ビット幅をパラメータで可変にしたいときは、generate文がないと書けないときがあるので。。 (VHDL を見ていると、Verilog1995だけだとほんと不便に感じます。 generate文がない、wire は宣言なしで使えるので信号名のミスタイプでもコンパイル通ってしまうなどなど。) > 上のようにSCOPE指定を外せば文法上は、書けます。しかしXILINXのツールでは、なぜか(本来必要のないIF文に)SCOPEラベルがないとエラーになったりすので、余計にわけ分からないことになってしまいますね。 確かに、Xilinxのツールではラベルをつけないとエラーになってしまいます。 Model Simでもやってみたところ、ラベルなしでコンパイルは通るんですが、「genblk1」みたいなラベル名を勝手につけてくれたりするので、やはり別スコープの信号になりますね。ということで私の手元にあるツールではgenerate文を使った段階で別スコープになるので多分無理かも。(Alteraもコンパイルは通るがdoutにはGND直結だけ。) この件に関する限り、筆者が動作確認とっているとは考えにくいですよね。 (他のページでも明らかなミスも見つけてしまったし。) とにかくありがとうございました。