• 締切済み

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 ------------------------------------ 宜しくお願い致します。

みんなの回答

  • P0O9I
  • ベストアンサー率32% (693/2146)
回答No.1

最大シフト数までのシフト回路をつくり、それをマルチプレクサで切り替える、という方法はどうでしょう。

tk_1980024
質問者

お礼

ありがとうございます。いや、もっと汎用的な方法がを望んでいました。 ちょっと考えてみましたが、sig_aとそれを遅らせるsig_b、同じモジュールで生成するのなら容易ですね。 逆に別のモジュールで遅らせるのは難しい。。。 ということで、「根元で遅らせる」というのがおそらく正解なのかな?という気がしています。   +根元で遅らせる例 initial begin  fork   begin   while(1) begin   sig_a <= 0;   repeat(N) @(posedge CLK);   sig_a <= 1;   repeat(N) @(posedge CLK);   end  end  begin   while(1) begin   repeat(M) @(posedge CLK); <-- M遅れ   sig_b <= 0;   repeat(N) @(posedge CLK);   sig_b <= 1;   repeat(N-M) @(posedge CLK);   end  join_none end

関連するQ&A

  • 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での記述、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記述方法に関して

    以下のVerilog記述についてどの様な記述が一般的か教えてほしい のですが? QuartusIIにて合成を行っているのですが、 「Can't resolve multiple constant drive for net ****」の エラーメッセージが発生します。 記述は以下の様なもので、別々のクロックでalways内から同じ変数 に代入しています。これが問題の様ですが、これを回避するための 一般的な処理方法はどの様にすればよいのでしょうか? Verilog初心者で、この様な処理自体がナンセンスなのかもしれません が、どなたか分かる方御願い致します。 【抜粋のため分かり難いですが記述内容は以下の様なもの】 always@(posedge clkB) begin : ClrV<= 1'b1; : end always@(posedge clkA) begin : if(ClrV) ClrV<= 1'b0; : end 以上

  • 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でのプログラミングですが,まず入力クロック(clk1)を適当に分周したクロック(clk2)を生成し,そのクロック(clk2)を遅延させたクロック(clk3)を生成したいのですが,どのようなプログラムを作成すれば良いのでしょうか? clk1からclk2を生成するところまでのプログラムは作成できているのですが,clk3の生成がうまくできません. 図で示すと以下のような信号を生成したいです. clk1 _「L_「L_「L_「L_「L_「L_「L_「L_「L_「L_「L_「L_「L  clk2 _「  L _ _ _「  L _ _ _「  L _ _ _「  L _ _ clk3 _ _ _  _ _ _ _ _ _ _ _ 「  L _ _ _「  L _ 「  L みたいな感じです. 宜しくお願いします.

  • 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で動的なモジュールを作る方法

    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でメモリの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を使って制御する必要があるのでしょうか?すいませんが、どなたか教えていただけないでしょうか?

  • 秀丸での正規表現:複雑な条件を指定する場合 続き

    この質問は、 http://okwave.jp/qa/q8757880.html の続きです。 具体的な事を全然書いてませんでした。すみません。 Verilog-HDLというハードウェア記述言語での話です。 上記であげたパターンは、サブモジュールのインスタンス記述 (プログラムで言うサブルーチン呼び出しのようなもの)です。 サブモジュールのインスタンス記述を強調したいと思っていますが、それ以外にも always @(posedge clk)begin  if(xxx)begin   ...  end  else if(yyy)begin //←ここで誤検出   ...  end end というサブモジュールでない記述で誤マッチしてしまうのです。 話それてしまいますが always @(posedge clk)begin  if(xxx)begin   ...  end  else begin   if(yyy)begin    ...   end  end end とかけばよい、という手もあるのですが、他者のコードも受け入れる関係上、その手も難しいのが実情です。 話が前後してしまいましたがサブモジュールインスタンス記述は、 sub_mod_name instance_name ( .... のようになっており、1語目、2語目ともに任意の文字列となっています。 else ifともに言語上の予約語であり、これはインスタンス記述にはなり得ません。 『これにマッチする正規表現」かつ『else if(』にはマッチしないというのは、そもそも『ひとつの正規表現』では表せないのかと悩んでおります。 長くなりすみません。 なにか抜けている点などありましたらご指摘頂けると助かります。

専門家に質問してみよう