verilogのwhile文についての質問

このQ&Aのポイント
  • verilog初心者です。while文での処理を記述していたのですが、なんとか出来る方法はないでしょうか?
  • TESTモジュール内でのwhile文の利用について、変更するとエラーとなってしまいます。
  • 合成やシミュレーションでは期待する値を得ることができましたが、while文の変更でエラーが発生します。
回答を見る
  • ベストアンサー

verilogでのwhile文について質問

verilog初心者です。 while文での処理を記述していたのですが、 下記のように変更するとエラーとなってしまいます。 なんとか出来る方法はないでしょうか? module TEST(in_data, state, clock, reset, out); input [9:0] in_data; input [5:0] state; input clock; input reset; output [5:0] out; reg [5:0] out; always@(posedge clock or negedge reset) begin if(reset == 0) begin out = 0; end else begin out = in_data; while(out > 7)begin out = out >> 1; end end end // always@ (posedge clock or negedge reset) endmodule // TEST 上のように書くと、合成でき、シミュレーションでも期待する値は得ることが出来ました。 以下のようにwhile文を変更するとエラーとなってしまいます。 while(out > state)begin out = out >> 1; end よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Werner
  • ベストアンサー率53% (395/735)
回答No.2

複数クロックサイクルかかっても良いなら、そういう順序回路を組めば良いだけです。 1クロックサイクルでループを1つ進める感じにすれば、サイクル数は必要ですがループで出来ることは実現できるでしょう。 組み合わせ回路でやりたいなら、 if文やcase文などで構成することになります もっともforやwhileが必要になるという時点で設計方針が怪しいので、 最初から考え直すのが一番お勧めかもしれません。 (論理回路を作っていると認識があればforやwhileは普通出てこないはずなので。) 例えば提示されているソースは、 in_dataの値を条件が満たされるまで1つずつ右シフトしてますが、 条件を満たすにはどれだけ右シフトすればよいか求める回路を作って その出力を右シフト量として与えるというやり方の方がまだあり得ると思います。 (念のため、この方法が最善というわけではないです。 やりたい処理内容によってはもっと根本から再設計した方が良いかもしれません。)

pokopoko09
質問者

お礼

遅くなってしまいましたが、回答ありがとうございました。 あれから少し勉強し、論理回路を作っていると認識があればforやwhileは出てこない、の意味が分かりました。 問題の回路は設計方針から見直し、使わないように直しました。

その他の回答 (1)

  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

forやwhileは条件次第では一応合成できますが、 基本的には合成できないと思ってください。 初心者なら論理合成対象にforやwhileは使わない方が良いですよ。 (シミュレーション記述に使うのは問題ないです。) 普通に論理設計してるだけなら 使う必要性があることはまず無いはずです。

pokopoko09
質問者

お礼

回答ありがとうございます。 参考にしている本何冊かでも同じように論理合成対象にforやwhileは使わないほうが良いと書かれてありました。 しかし、自分の中でこのような処理をしたい、と思ったとき forやwhileを使用しないと出来ないのでは?と思うことが多々あります。 そのような場合、どのように解決するものなのでしょうか?

関連するQ&A

  • Verilog-HDLのFF記述について

    先程アップしたのは、図が変になってしまいました。 改めて質問します。 1つのFF(非同期リセット)をVerilog-HDLで記述すると、以下のように記述出来ますよね? always @ ( posedge CLK or negedge RESET ) begin if ( !RESET ) begin Q <= 1'b0 ; xQ <= 1'b1 ; end else begin Q <= D ; xQ <= ~D ; end end この1つのFFをalways文を2つ使って記述出来るんですか? ご回答宜しくお願いします。

  • Verilogで動的なモジュールを作る方法

    Verilogで動的なモジュールを作る方法 たとえば、どのような周波数であっても 1秒のウェイトをする回路を作りたいと思っています。 試験的に、 `define time (1) //1S `define tCK (20) //周期20nS module wait( input iCLOCK, input inRESET, output reg oWAITEND); localparam = loop_end (1/(`time * 1000000000))/`tCK; reg [31 : 0] loop; always@(posedge iCLOCK or negedge inRESET)begin if(inRESET == 1'b0)begin loop <= 32'h00000000; end else begin if(loop < loop_end)begin loop <= loop + 32'h00000001; oWAITEND <= 1'b0; end else begin oWAITEND <= 1'b0; loop <= loop; end end end //always endmodule というものを作って、defineの値(このdefineは別ヘッダファイルからincludeしてやりました)を変えてやれば目的の周波数で動き、目的のウェイト作るモジュールををソース自体を変えずに得られると思いましたが、 シミュレーションではうまくいったものの、QuartusIIではうまく論理合成されませんでした。 もし、他に方法がありましたら教えていただけないでしょうか? よろしくおねがいします。

  • Verilog HDLについて質問

    以下のプログラムを入力し、試してもうまくいきません。どこがいけないのでしょうか。 しようとおもっていることを大まかにいうと、 ・x1の立ち上がりに、money1に1を足す ・x2の立ち上がりに、money2に2を足す ・クロックの立ち上がりに、sumにmoney1とmoney2を足したものを入れて、 sumが3だったら、z1に割り当てたLEDを光らせる sumが4だったら、z2に割り当てたLEDを光らせる というものです。 試してみると結果はz1,z2両方のLEDが、x1,x2を立ち上げなくても最初から光ってしまいます。 module vendmachine(x1,x2,z1,z2,clk); input x1,x2,clk; output z1,z2; reg [2:0] money1; reg [2:0] money2; reg [2:0] sum; reg ledz1,ledz2; always@(posedge x1) begin money1=money1+3'd1; end always@(posedge x2) begin    money2=money2+3'd2; end always@(posedge clk) begin sum=money1+money2; if(sum==3'd3)begin ledz1=1'b1; end if(sum==3'd4)begin ledz1=1'b1; ledz2=1'b1; end end assign z1=ledz1; assign z2=ledz2; endmodule

  • verilog HDLについての質問

    verilogで以下のようなコードだと、エラーが起こります。 何故起こるのか、対処法はどのようにすればよいか教えてください。 //-----ソースコード---------------------------- modele Test(CLK1,CLK2,PG1); input CLK1; input CLK2; output PG1; reg dmy; always @(posedge CLK) begin dmy = 1; end always @(posedge CS) begin dmy = 0; end assign PG1 = dmy; //-----エラー内容------------------------------- Only one always block may assign a given variable dmy //-----以上---------------------------------------- regは複数のalwaysで変化させることはできませんということでしょうが、なぜでしょうか。

  • Verilogでメモリのmoduleと演算のmoduleを組み合わせたい

    module spram_sr(clk, we, address, data_i, data_o); input clk; input we; input [7:0] address; input [2:0] data_i; output [2:0] data_o; reg [6:0] ram [15:0]; reg [6:0] read_a; always @(posedge clk) begin if (we) begin ram[address] <= data_i; end read_a <= address; end assign data_o = ram[read_a]; endmodule を使って、メモリから8bitの整数を取り出して、0~15個の数値をたすような計算をさせたいと思って別に計算させるmoduleを作りました。これに計算をさせるスタート信号と計算終了を知らせるフィニッシュ信号を加えています。 module sigma(clk,x,sum,start,finish); input clk; input[7:0] x, start; output[7:0] sum; output finish; reg[7:0] sum,start,write_add; reg finish; integer i; always@(posedge clk) begin if(start) for(i=0;i<=15;i=i+1) sum<=sum+x[i]; write_add<=sum; finish<=1'b1; end endmodule この二つを使いたいのですが、メモリから演算のモジュールに整数を渡すやりかたがわかりません。もう一つmoduleを使って制御する必要があるのでしょうか?すいませんが、どなたか教えていただけないでしょうか?

  • verilogでの記述、always@の使い方

    verilogでの記述の仕方について質問です。 画像のようなタイミングチャートを考えています。 clkとplsは入力、dataが出力です。 構成は、  pls↑の次のclk↑で、dataをアサートする。 というのを考えています。 pls↑やclk↑は、posedgeを使えばよいと思うのですが、 私の考え通りに記述すると always @(posedge pls)begin @(posedge clk)begin data <= 1; end end こんな感じになるのか?となってしまいます。 @()begin end の中に@()beginを記述することが出来るのか というところから疑問です。 出来たとしても、これが私が意図したとおりに動作するのかがよくわかりません。 ネットで、 always @() @() と記述すると順序回路ができるとあったのですが、いまいち動作が分かりません。 どなたか、動作を教えていただけないでしょうか。 また、pls↑の次のclk↑で、dataをアサートする方法を教えていただけないでしょうか。 よろしくお願い致します。

  • verilog HDL のレジスタ記述について

    こんにちは verilog初心者です。論理合成をしていて気になる点があったので質問させていただきました。 二つのクロックの立ち上がりで書き込むレジスタを記述していて、 (全て1bit、clkはクロック) always @(posedge clk1 or posedge clk2) begin q <= d; end としたところ、シミュレーションはできますが論理合成はできませんでした。 自分の持っている参考書に「複数の書き込み信号があるレジスタはない」という記述があったので一応納得しました。 ところが、 always @(posedge clk1 or posedge clk2) begin if (clk1==1) q <= d; else if (clk2==1) q <= d; end と記述すると論理合成できてしまいます。 両者の書き込み信号に対する振る舞いは同じように思うのですが、一体何が違うのでしょうか。 わかる方いましたら是非ご教示下さい。よろしくお願いします。

  • Verilog-HDLによる設計において

    現在Z8085のCPUを設計しており、テンポラリレジスタにラッチする部分でなかなか上手くいきませんので質問させていただきます。 always文を使用したステートマシンにより制御しようとしているのですが次のようなWarningが出ます。 Warning: Latch IR[0]$latch has unsafe behavior Warning: Latch IR[1]$latch has unsafe behavior            : Warning: Latch IR[7]$latch has unsafe behavior Warning: Latch TMP1[0]$latch has unsafe behavior Warning: Latch TMP1[1]$latch has unsafe behavior            : Warning: Latch TMP1[7]$latch has unsafe behavior Warning: Latch TMP2[0]$latch has unsafe behavior Warning: Latch TMP2[1]$latch has unsafe behavior            : Warning: Latch TMP2[7]$latch has unsafe behavior Warning: Latch NEXT_STATE[0]$latch has unsafe behavior Warning: Latch NEXT_STATE[1]$latch has unsafe behavior <ソース> module CPU_TMP( CLK, nRST, FROM_DCD, IR, TMP1, TMP2, STATE, NEXT_STATE ); input CLK;//クロック input nRST;//リセット input [7:0] FROM_DCD;//入力命令 output [7:0] IR;//命令レジスタ output [7:0] TMP1;//テンポラリレジスタ1 output [7:0] TMP2;//テンポラリレジスタ2 output [1:0] STATE;//現在のステート output [1:0] NEXT_STATE;//次のステート reg [7:0] IR; reg [7:0] TMP1; reg [7:0] TMP2; reg [1:0] STATE; reg [1:0] NEXT_STATE; //状態 parameter S0 = 2'b00; parameter S1 = 2'b01; parameter S2 = 2'b10; parameter SD = 2'b11; //命令 parameter INRA = 8'h11; parameter MVIA = 8'h22; parameter JMP = 8'h33; always @( posedge CLK ) begin     if( nRST == 0 )       STATE <= SD;     else       STATE <= NEXT_STATE; end always @( STATE ) begin    case( STATE )      SD : begin            IR <= 0;            TMP1 <= 0;            TMP2 <= 0;            NEXT_STATE <= S0;          end      S0 : begin            IR <= FROM_DCD;            case( FROM_DCD )              INRA : NEXT_STATE <= S0;              MVIA : NEXT_STATE <= S1;              JMP : NEXT_STATE <= S2;            endcase          end      S1 : begin              TMP1 <= FROM_DCD;              NEXT_STATE <= S0;          end      S2 : begin              TMP2 <= FROM_DCD;              NEXT_STATE <= S0;          end endcase end endmodule どのようにしたらこのWarningを消すことができるでしょうか。

  • verilogである信号の数クロック遅れの信号を生成させる記述方法をお

    verilogである信号の数クロック遅れの信号を生成させる記述方法をお伺いします。 動作記述でOKです。 通常、「sig_a」 から2クロック遅れの「sig_b」を生成させるのなら: > sig_a - 2clockおくれ -> sig_b ----------------------------------- reg [2:0] regs; assign sig_b = regs[2]; asisgn regs[0] = sig_a; always @(posedge CLK) regs[2:0] <= {regs[1:0], sig_a}; ----------------------------------- のように、パイプラインに信号を通すことで実現できるですが、 何クロック遅れるかを可変(動的に設定する)としたいのです。 動作モデル的な記述で簡単にかけないのでしょうか? ------------------------------------ [NGの例]: これだとNcycle_delayがSIM途中で更新されたとき、反映できない。。。 initial begin  sig_b <= #D 1'b0;   while(1) begin   repeat(Ncycyle_delay) @(posedge CLK);    while(1) begin     sig_b <= sig_a;     repeat(1) @(posedge CLK);    end   end end ------------------------------------ 宜しくお願い致します。

  • Verilog HDL で 74165 相当の機能

    Verilog HDL で非同期のパラレル入力をシフトレジスタで取り出したいので、SN74165 相当の機能を次の式のように考えました。 always @(negedge clk or load or indt) begin if (load) begin sftdt <= indt; end else if (!load) begin sftdt <= {sftdt[6:0], 1'b0}; end end SILOS でシュミレートしたところ、思ったように動作しましたが、 Quatus IIでは、次のエラーが出てしまいます。 single- and double-edge expressions are not supported 良い方法は無いでしょうか。

専門家に質問してみよう