Verilog HDLで非同期のパラレル入力をシフトレジスタで取り出す方法

このQ&Aのポイント
  • Verilog HDLを使用して非同期のパラレル入力をシフトレジスタで取り出す方法を考えました。
  • SN74165相当の機能を使用し、次の式を実装しました。
  • SILOSでシミュレートしたところ正常に動作しましたが、Quatus IIではエラーが発生します。より良い方法はあるでしょうか?
回答を見る
  • ベストアンサー

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 良い方法は無いでしょうか。

  • P0O9I
  • お礼率58% (7/12)

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

  • ベストアンサー
  • JYUZA
  • ベストアンサー率29% (54/184)
回答No.1

もしかしたらalways文のclk以外の信号にも()でくくってedgeを指示すればいいんじゃないですか? というかalways @(negedge clk or posedge load)だけで良いような気がしますが。。。その場合はelse ifの!loadは外します。

P0O9I
質問者

お礼

動きました。ありがとうございます。 実は最初これでやったのですが、SILOS ではラッチしてくれなく、ラッチ回路の式を思い出し、上の式を編み出したのですが、Quatus IIでは、こちらで良いようです。 非同期回路はシステムによって違う場合があるようですね。

関連する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 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についての質問

    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の文法について、教えてください。 下のリストのように、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

  • 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

  • 2ビットのレジスタのVerilog HDL記述

    QuatusIIで2ビットのレジスタをつくっているのですが、ブロック図をコンパイルするときにエラーがでてしまいます。 エラー内容をみるとVerilog HDL記述が間違えているみたいなのですが、どこが間違えているか教えてください。 /* REG2 */ module REG2module ( EN, CLR_B, IN1, IN2, CLK, Q ); input CLR_B, CLK; input IN1, IN2; output [1:0] Q; output EN; assign EN=FUNC_EN (IN1, IN2); function FUNC_EN; input IN1,IN2; if (IN1>0|IN2>0) FUNC_EN=1; else FUNC_EN=0; endfunction wire [1:0] D; CONECT (IN1,D[0]); CONECT (IN2,D[1]); reg [1:0] Q; always @( posedge CLK or negedge CLR_B ) if( !CLR_B ) Q <= 0; else if(EN) Q <= D; endmodule エラーにはError: Node instance "comb_8" instantiates undefined entity "CONECT" Error: Node instance "comb_9" instantiates undefined entity "CONECT" と出ています。意味を調べたのですが、CONECTが定義されていない?という事は具体的にどうすればいいでしょうか。 CONECT (IN1,D[0]); CONECT (IN2,D[1]); の部分が間違っているのはなんとなくわかるのですが、どうしたらいいかわかりません。 よろしくお願いします

  • 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での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 よろしくお願いします。

  • 「入門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 を切り替えるような書き方はそもそもできないのでは? 皆さんどう思われますか? (インデントがうまくいかず、読みづらくてすいません。)

  • 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を消すことができるでしょうか。

専門家に質問してみよう