痔になりやすい生活習慣とは?

現在Verilog HDLを勉強しており、ひと通り勉強は終わりました。
しかしブロッキング代入[=]とノンブロッキング代入[<=]の使い分けをどこまで暗記すれば良いのか分かりません。
皆様は、[=]と[<=]の使い分け、あるいはネット型、レジスタ型への代入をする際の区別をどのように暗記していますか?「このポイントを理解すれば大丈夫!」みたいなことを教えていただけると助かります。

今思いつく例としては↓のとおりです
・assign文では[=]を使用しなければならない。
・assign文の左辺は[ネット型]のみ
・case文のHPによって[=]を使用しなければならない。
http://veri.jp/ba_nba.html のHPの最後のほうで『ほかにも「assign 文では NBA "<=" が使えません」という誤った注意書き』と書いてありますが、この記述の意味がわかりません。
・回路記述ではダメなのに、シミュレーション記述では問題がない等等、、、
他にもfunction文やalways文の中で式を書く時にも困っています。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

>

http://veri.jp/ba_nba.html
こんな良い解説ページを見つけたのに、なぜ質問しているのかがよく分かりませんが・・・。

まずassign文は継続的代入であって、ブロッキング代入でもノンブロッキング代入でもないので、
ブロッキング代入とノンブロッキング代入の使い分けという議論の対象外です。

また、ブロッキング代入とノンブロッキング代入はレジスタ型に対して使う、
継続的代入はネット型に対して使う、
となるため、型でブロッキング代入とノンブロッキング代入の使い分けなんて言う議論は最初からできないです。(どちらもレジスタ型が相手だから)


解説ページにも書かれていますが、
ブロッキング代入とノンブロッキング代入の違いは、
"右辺の評価" と "左辺への代入" が同時に行われるか、別々に行われるかの違いです。

たとえば、
a = x;
b = a;
としたとき普通のプログラミング言語のように、bもxになって欲しいなら、ブロッキング代入を使いますし、
bにxが代入される前のaの値が入って欲しいなら、ノンブロッキング代入を使うことになります。


always文でFFを生成するときは、その時刻においては代入前の値を参照したい(実際の回路を考えると代入後の値を参照できるのは次のクロックがやってきたときだから)ので、
ノンブロッキング代入を普通は使いますね。
(ブロッキング代入だとレーシング=記述順序で結果が変わってしまうという問題があるというのもありますが。)

それ以外(組み合わせ論理を作るalways、function、シミュレーション記述)は、
特に理由がなければブロッキング代入を使っています(変数を直ちに更新して欲しい場合がほとんどだから)が、
前述のノンブロッキング代入の挙動を理解した上でノンブロッキング代入が必要だと思ったなら
使っていけないわけではないです。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qverilogのcase文

always @(posedge CLK)
begin
case (DIP_SW)
0:Q[0] <= SW1_OUT;
0:Q[1] <= Q[0];
0:Q[2] <= Q[1];
0:Q[3] <= Q[2];
0:Q[4] <= Q[3];
0:Q[5] <= Q[4];
0:Q[6] <= Q[5];
0:Q[7] <= Q[6];
1:Q[7] <= SW1_OUT;
1:Q[6] <= Q[7];
1:Q[5] <= Q[6];
1:Q[4] <= Q[5];
1:Q[3] <= Q[4];
1:Q[2] <= Q[3];
1:Q[1] <= Q[2];
1:Q[0] <= Q[1];
endcase
end
これはプログラムの一部なのですが、0と1の場合で分岐させる予定です。もちろん上のソースでは上手くいきませんでした。case文ではなくif文のほうがよいでしょうか?

always @(posedge CLK)
begin
case (DIP_SW)
0:Q[0] <= SW1_OUT;
0:Q[1] <= Q[0];
0:Q[2] <= Q[1];
0:Q[3] <= Q[2];
0:Q[4] <= Q[3];
0:Q[5] <= Q[4];
0:Q[6] <= Q[5];
0:Q[7] <= Q[6];
1:Q[7] <= SW1_OUT;
1:Q[6] <= Q[7];
1:Q[5] <= Q[6];
1:Q[4] <= Q[5];
1:Q[3] <= Q[4];
1:Q[2] <= Q[3];
1:Q[1] <= Q[2];
1:Q[0] <= Q[1];
endcase
...続きを読む

Aベストアンサー

同じラベルを重ねて書かない。
ステートメントが複数あるならbegin-endで囲む。
----------------------------------------
always @(posedge CLK)
begin
  case (DIP_SW)
    0:
    begin
      Q[0] <= SW1_OUT;
      Q[1] <= Q[0];
      Q[2] <= Q[1];
      Q[3] <= Q[2];
      Q[4] <= Q[3];
      Q[5] <= Q[4];
      Q[6] <= Q[5];
      Q[7] <= Q[6];
    end

    1:
    begin
      Q[7] <= SW1_OUT;
      Q[6] <= Q[7];
      Q[5] <= Q[6];
      Q[4] <= Q[5];
      Q[3] <= Q[4];
      Q[2] <= Q[3];
      Q[1] <= Q[2];
      Q[0] <= Q[1];
    end
  endcase
end
----------------------------------------

ただ、Qが(レジスタ配列などではなく)ただの多ビット信号なら、
そもそも代入文を8つも並べる必要性がなさそう。
----------------------------------------
always @(posedge CLK)
begin
  case (DIP_SW)
    0: Q <= {Q[6:0], SW1_OUT};
    1: Q <= {SW1_OUT, Q[7:1]};
  endcase
end
----------------------------------------

> case文ではなくif文のほうがよいでしょうか?
これくらいならif文で十分なようには思える。

同じラベルを重ねて書かない。
ステートメントが複数あるならbegin-endで囲む。
----------------------------------------
always @(posedge CLK)
begin
  case (DIP_SW)
    0:
    begin
      Q[0] <= SW1_OUT;
      Q[1] <= Q[0];
      Q[2] <= Q[1];
      Q[3] <= Q[2];
      Q[4] <= Q[3];
      Q[5] <= Q[4];
      Q[6] <= Q[5];
      Q[7] <= Q[6];
    end

    1:
    begin
      Q[7] <= S...続きを読む

Qverilogで配列の任意の8bitを取り出す方法

配列の中の任意の8bitを取り出すのに、
 hoge[fuga:fuga + 8]
と書きましたが、エラーになってしまいました。

配列の添え字には、変数は記述できないのでしょうか?
とすると、他にどの様な書き方があるのでしょうか?
教えてください。よろしくお願いします。
(verilog初心者です)

Aベストアンサー

1. Verilog2001ならばできます。相対バス幅指定構文がありますので。

2. Verilog1995での逃げとしては、
hoge[fuga:fuga + 8] と書かないで
{hoge[fuga],hoge[fuga+1],hoge[fuga+2],・・(省略)・・・,hoge[fuga+8]}と書くことです。

試してみてください。

QVerilog HDLで立下りと立ち上がり両方のエッジを検出する方法を

Verilog HDLで立下りと立ち上がり両方のエッジを検出する方法を探しています。
色々試してみたのですが、そのようなことはできないとエラーがでました。
元の周波数を2倍にして立ち上がりだけ見るという方法は、今回私が想定している仕様では使えないので、どうしても両エッジを検出したいのです。
どなたかご存知の方いらっしゃいましたら回答のほうよろしくお願いします。
ちなみに使用しているFPGAはXC3S200で使用ツールはXilinx社のISEです。

Aベストアンサー

回答が無いようなのでHDLはよく知らないのですが参考になりそうなページを貼っておきます。
http://fenrir.naruoka.org/archives/000701.html
原因は両エッジを検出できるようなフリップフロップが普通のFPGAには無いことのようですが、解決策はよく分かりません。

Qprintf で二進表示を行いたい。

すみません。教えていただきたいことがあります。
printf で普通のintの値をフォーマット指定子を使用して二進表示をしたかったのですが見当たりませんでした。
どうにかintの内容を二進で確認したいのですが、どのようにすれば良いですか?
宜しくお願いします。

Aベストアンサー

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if ( value & bit ){
  putchar('1');
 }
 else{
  putchar('0');
 }
}
printf( " です。\n" );

最後に:
・1バイトが 8 ビットの環境が前提です。→まぁ、普通は 8 ビットですが…。
・上記のサンプルを関数などにすれば使いやすくなります。→print_bin()など
・以上。おわり。

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if...続きを読む

QVerilogで出てくるデルタ遅延について

LSI設計で出てくるデルタ遅延について教えてください。
・デルタ遅延とは、どの様なものなのでしょうか?
・どの様な場合に考慮する必要があるのでしょうか?

また、やさしく解説しているHPなどあれば教えてください。

よろしくお願いします。

Aベストアンサー

基本的には、デルタ遅延が問題になるような設計は「してはいけない」んで、少なくとも論理設計者の立場から言えば、まあ知らなくても問題はないような気もするのですが。

googleで検索しても、日本語ではいいページがみつかりませんでした。英語だと、こことかどうでしょう。
http://www.people.vcu.edu/~rhklenke/tutorials/vhdl/modules/m10_23/sld042.htm
簡単に言えば、シミュレーションの結果がシミュレータによって異ならないように、評価のやり方を定めているといえばいいでしょうか。

ただ、デルタ遅延が問題になるのは、細いグリッチが発生したらどうなるかとか、FFでデータ変化とクロック立ち上がりが同時にきたらどうなるか、とかなどの場合です。
そして、実際の回路が正しく動作するためには、グリッチが発生してもしなくても正しく動作するようにしておかなければなりませんし、FFのデータ変化が、クロックのsetup/hold時間以内に来てはいけません。ということは、デルタ遅延が問題になって動作が変わってしまうような回路は、実回路でも必ず問題を起こします。

実際の回路記述ではなくて、テストベンチの記述なら、まあデルタ遅延に頼った書き方をしても、いいといえばいいですが、基本的には避けたほうがいいでしょう。

基本的には、デルタ遅延が問題になるような設計は「してはいけない」んで、少なくとも論理設計者の立場から言えば、まあ知らなくても問題はないような気もするのですが。

googleで検索しても、日本語ではいいページがみつかりませんでした。英語だと、こことかどうでしょう。
http://www.people.vcu.edu/~rhklenke/tutorials/vhdl/modules/m10_23/sld042.htm
簡単に言えば、シミュレーションの結果がシミュレータによって異ならないように、評価のやり方を定めているといえばいいでしょうか。

ただ、デル...続きを読む

Qプルアップ抵抗値の決め方について

ほとんどこの分野に触れたことがないので大変初歩的な質問になると思います。

図1のような回路でプルアップ抵抗の値を決めたいと思っています。
B点での電圧を4.1Vとしたい場合について考えています。その場合、AB間での電圧降下は0.9Vとなります。

抵抗値×電流=0.9Vとなるようにプルアップ抵抗の値を決めるべきだと考えていますが、この抵抗に流れる電流が分からないため、決めるのは不可能ではないでしょうか?

抵抗値を決めてからやっと、V=IRより流れる電流が決まるため、それから再度流れる電流と抵抗を調節していって電圧降下が0.9Vとなるように設定するのでしょうか。どうぞご助力お願いします。



以下、理解の補足です。
・理解その1
ふつう、こういう場合は抵抗値を計算するためには、電圧降下と抵抗に流れる電流が決まっていることが前提だと考えていました。V=IRを計算するためには、この変数のうち2つを知っていなければならないからです。
また、例えば5V/2Aの電源を使った場合、マイコン周りは電源ラインからの分岐が多いため、この抵抗に2A全てが流るわけではないことも理解しています。

電源ラインからは「使う電流」だけ引っ張るイメージだと理解しているのですが、その「使う電流」が分からないため抵抗値を決定できません。(ポート入力電流の最大定格はありますが…)


・理解その2
理解その1で書いたように、抵抗値を計算するためには、電圧降下と抵抗に流れる電流が必要だと理解しています。図2を例に説明します。Rの値を決めたいとします。
CD間の電圧降下が5Vであることと、回路全体を流れる電流が2Aであることから、キルヒホッフの法則より簡単にRの値とそれぞれの抵抗に流れる電流が分かります。今回の例もこれと同じように考えられないのでしょうか。

ほとんどこの分野に触れたことがないので大変初歩的な質問になると思います。

図1のような回路でプルアップ抵抗の値を決めたいと思っています。
B点での電圧を4.1Vとしたい場合について考えています。その場合、AB間での電圧降下は0.9Vとなります。

抵抗値×電流=0.9Vとなるようにプルアップ抵抗の値を決めるべきだと考えていますが、この抵抗に流れる電流が分からないため、決めるのは不可能ではないでしょうか?

抵抗値を決めてからやっと、V=IRより流れる電流が決まるため、それから再度流れる電流と抵抗を調...続きを読む

Aベストアンサー

NO1です。

スイッチがONした時に抵抗に流れる電流というのは、最大入力電流や最大入力電圧
という仕様から読めば良いのでしょうか。
→おそらくマイコンの入力端子の電流はほとんど0なので気にしなくてよいと思われます。
入力電圧は5Vかけても問題ないかは確認必要です。

マイコンの入力電圧として0Vか5Vを入れたいのであれば、抵抗値は、NO3の方が
言われているとおり、ノイズに強くしたいかどうかで決めれば良いです。
あとは、スイッチがONした時の抵抗の許容電力を気にすれば良いです。
例えば、抵抗を10KΩとした場合、抵抗に流れる電流は5V/10kΩ=0.5mAで
抵抗で消費する電力は5V×0.5mA=0.0025Wです。
1/16Wの抵抗を使っても全く余裕があり問題ありません。
しかし、100Ωとかにしてしまうと、1/2Wなどもっと許容電力の大きい抵抗を
使用しなければいけません。
まあ大抵、NO3の方が書かれている範囲の中間の、10kΩ程度付けておけば
問題にはならないのでは?

QVHDLとVerilogの違いについて

Verilogでの回路設計の経験はあるのですが、VHDLでの経験がありません。
今度の仕事はVHDLで回路設計をしなくてはいけなそうなのですが、ちょっと心配です。
Verilogとの違いは何なんでしょうか?
またVerilogを知っていればすぐに理解ができるものなのでしょうか?

Aベストアンサー

私はVHDL専門で、Verilogのことはよく知りませんが。

一般的印象としては、VHDLは無駄な記述が多く、Verilogはそれが少ないです。(Verilogにはないentity宣言が無駄に思える)

言語の習得については、VHDLを先に覚えておいたほうがいいという人が多いようです。なぜかVerilogを先に知っている人はVHDLが取っ付きにくいらしいです。

VHDLは「ada」というプログラム言語をもとに開発された「使用記述言語」で、
Verilogは「C言語」をもとに開発された「シミュレーション専用言語」です。
その辺の関係で、VHDLに比べて論理合成不可能な記述が多いと聞いたことがあります。

先日CQ出版から発売された「HDLによる高性能ディジタル回路設計」の巻末付録に「HDL対照表」が書かれているので、2言語を比較する参考にしてみてください。

QUSBホスト機能とは何ですか?

よくMP3プレーヤーの仕様に「USBホスト機能」と書かれていますが、これはどんな機能なのですか?
(「USBストレージクラス」とは違うのでしょうか?)

Aベストアンサー

USBホスト機能とは、USBの周辺機器を接続するための「親」になる機能です。USBは、その対応機器が「ホスト」「デバイス」に別れており、「ホスト」は「デバイス」に対し接続制御を行える端末、「デバイス」は「ホスト」から制御信号を与えられて初めてデータ伝送が行える端末、という区別が為されます。

通常は、「ホスト」になるのはPCであって、「デバイス」はPCの周辺機器ということになります。例えばPCとマウスをUSBで繋ぐとき、PCがホスト、マウスがデバイスになります。この時、PCのUSBインターフェースはホスト専用ですし、マウスはデバイス専用ということになります。間違ってもこの関係が逆転することはあり得ません。
デジカメをPCに繋ぐときも同じことが言え、PCが「ホスト」、デジカメが「デバイス」です。同じようにプリンタをPCに繋ぐときはPCが「ホスト」、プリンタが「デバイス」になります。

ところが最近は、PC抜きでデジカメとプリンタを繋いでデジカメの写真をプリントしようという機能が付けられるようになりました。この時、デジカメとプリンタは両方とも「デバイス」ですから、そのままでは接続しても動作しません(制御信号を与える役目の装置がない)。よって、例えばデジカメにUSBホスト/デバイスの両方になれる機能を持たせることで、他にUSBホストがいる場合(PCとデジカメを繋いだ場合)はデジカメはUSBデバイスに、他にUSBホストがいない場合(デジカメとプリンタを繋いだ場合)はデジカメがUSBホストに、というように、ケースバイケースで様々な組み合わせを可能にするような周辺機器が登場しています。

MP3プレイヤーのUSBホスト機能がどういった役に立つのかはそのMP3プレイヤーによって異なりますが、USBホスト機能がある場合は他のUSB周辺機器を繋げることで、PC抜きで様々な動作が可能になっている、と思えば良いでしょう。
当然ですが、USBストレージクラスとは別の用語となります。

USBホスト機能とは、USBの周辺機器を接続するための「親」になる機能です。USBは、その対応機器が「ホスト」「デバイス」に別れており、「ホスト」は「デバイス」に対し接続制御を行える端末、「デバイス」は「ホスト」から制御信号を与えられて初めてデータ伝送が行える端末、という区別が為されます。

通常は、「ホスト」になるのはPCであって、「デバイス」はPCの周辺機器ということになります。例えばPCとマウスをUSBで繋ぐとき、PCがホスト、マウスがデバイスになります。この時、PCのUSBインターフェース...続きを読む

Qverilogで、配列の一部をタスクに渡したい

verilog初心者です。

以下の様な配列があったとして、array[50]~array[99]に対してデータ処理をするタスクを作りたい場合、どの様にすればよいのでしょうか?
 reg[7:0] array[0:99];

Cでいうところの、こんな感じの事がやりたいのです。
 unsinged int array[100];
 func(&array[50]); /* array[50]~array[99]に対してデータ処理 */

よろしくお願いします。

Aベストアンサー

1.のものです。

simだけでよいならば、functionではなくtaskを使うのもひとつ方法です。(taskも大抵は論理合成できますが)

taskならばそのモジュール内で(手前で)宣言されている全てのヴァリアントにアクセスできます。

もっといえば、functionを使わずベタに書けば(手前で)宣言されている全てのヴァリアントにアクセスできます。

wireへの代入方法は基本中の基本です。

wire[400-1:0] tmp;
integer i;
for( i=0 ; i<50 ;i=i+1)
begin
assign tmp[i*8+0]=array[i][0];
assign tmp[i*8+1]=array[i][1];
assign tmp[i*8+2]=array[i][2];
assign tmp[i*8+3]=array[i][3];
assign tmp[i*8+4]=array[i][4];
assign tmp[i*8+5]=array[i][5];
assign tmp[i*8+6]=array[i][6];
assign tmp[i*8+7]=array[i][7];
end

こんな感じです。細かいチェックはしていません。ケアレスミスはご容赦ください。

verilog1995方式ですとfor文中の[]のバス記述の、「コロン」 の前後にforの変数を記述するのは許可されません。(確か・・)
従って : の無い記述にするために1bitづつベタ書します。
(verilog2001では相対バス幅記述が可能です。これを使うと1行でかけます。)

1.のものです。

simだけでよいならば、functionではなくtaskを使うのもひとつ方法です。(taskも大抵は論理合成できますが)

taskならばそのモジュール内で(手前で)宣言されている全てのヴァリアントにアクセスできます。

もっといえば、functionを使わずベタに書けば(手前で)宣言されている全てのヴァリアントにアクセスできます。

wireへの代入方法は基本中の基本です。

wire[400-1:0] tmp;
integer i;
for( i=0 ; i<50 ;i=i+1)
begin
assign tmp[i*8+0]=array[i][0];
assign tmp[...続きを読む

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。


人気Q&Aランキング