Verilog-HDL 文法(3):多bit信号,演算子 2015/09/27 |
[CategoryTop] [Prev] [Next] |
[目次]・多bit信号 + bit幅 + レジスタ配列 ・演算子 + 演算子の種類 + 関係演算子 + 連接演算子 + リダクション演算子 ●多bit信号 ◆bit幅 ・バス等の多bit信号は、信号宣言時にbit幅と範囲を [MSB:LSB] 形式で指定します。 MSB : Most Significant Bit (最上位bit) LSB : Least Significant Bit (最下位bit) ┌─────────────────────────────────────┐ input [3:0] w_adr, r_adr; // 4bitの入力 w_adr と r_adr input [0:15] w_dat; // 16bitの入力 w_dat wire [7:0] d_bus; // 8bitのwire reg [7:4] bk_adr; // 4bitのregister └─────────────────────────────────────┘ ・内部的には「配列」として処理されるので、添え字を付けることでアクセスするbit を指定することが可能です。 assign bank = r_adr[3]; ・代入式の左辺に置くこともできます。 assign w_adr[7] = offset; ・bit範囲を指定することも可能です。 ┌─────────────────────────────────────┐ wire [7:0] simd_h, simd_l; assign simd_h = data[15:8]; assign simd_l = data[7:0]; └─────────────────────────────────────┘ ・左辺と右辺のbitが異なっている場合 左辺bit幅 < 右辺bit幅 : 右辺の上位bitが切り捨てられる 左辺bit幅 > 右辺bit幅 : 左辺の上位bitは'0'になる となります。また宣言範囲外のbit指定は文法エラーになるケースがほとんどです。 ・原則として左辺/右辺のbit幅が合わない演算式は書かないようにしましょう。恐ら くそのような記述を許すデザインガイドは存在しないでしょうから。 ◆レジスタ配列 ・多bitのreg信号の場合、2次元配列としてメモリを構成することが可能です。以下の 形式で記述します。(*1) ┌─────────────────────────────────────┐ reg [15:0] ic_mem [0:63]; // 16bitデータ × 64ワードのメモリ <----------- 16bit -----------> □□□□ □□□□ □□□□ □□□□ ↑ □□□□ □□□□ □□□□ □□□□ | : : : : 64word : : : : | □□□□ □□□□ □□□□ □□□□ ↓ └─────────────────────────────────────┘ ・レジスタ配列の場合はword単位でのみアクセス可能です。bit選択はできません。 例えばアドレス4番地のデータには ┌─────────────────────────────────────┐ wire [15:0] dbuf; assign dbuf = ic_mem[4]; └─────────────────────────────────────┘ のように記述してアクセスします。 ●演算子 ◆演算子の種類 ・演算子には以下の種類があります(演算優先順)。演算内容はC言語と似ているので 「わかりくい」と思われるものだけに説明を付けています。 ┌─────────────────────────────────────┐ Verilog-HDL演算子 | +-- 算術演算子 (+, -, *, /, %) | % : 剰余 | +-- ビット演算子 (~, &, |, ^, ~^) | ~ : NOT | ^ : Exclusive OR | ~^ : Exclusive NOR | +-- リダクション演算子 (&, ~&, |, ~|, ^, ~^) <---- 単項演算子 | ~& : NAND | ~| : NOR | +-- 論理演算子 (!, &&, ||) | +-- 関係演算子 (==, !=, ===, !==, <, <=, >, >=) | === : 等しい(x, z比較も含む) | !== : 異なる(x, z比較も含む) | +-- シフト演算子 (<<, >>) | +-- 3項演算子 | (a)? b : c ---> if (a) then b else c | +-- 連接演算子 ({ }) 信号bitのリスト連結 └─────────────────────────────────────┘ ◆関係演算子 ・関係演算子は、2値の大小/一致/不一致を判定します。演算結果は trueの場合 : 1'b1 falseの場合 : 1'b0 が返されます。 ・C言語のように「false:0, true:0ではない」といった定義ではなく、0/1で定義され ているので、判定結果を信号で使用することが可能です。 assign match_flag = (r_addr == w_addr); ※値に'x'や'z'が含まれる場合 ・比較対象の値に'x'や'z'が含まれる場合、大小関係の比較(>,<,>=,<=)は不能なの で、常に結果はfalse(0)になります。 ・しかし、'x', 'z'を含んだ「一致/不一致」の判定演算子は存在します。 === : 一致判定 !== : 不一致判定 ・ただし、上記の演算子は論理合成時に使用できません(実際には物理値の判定しか できないから)。シミュレーション上でのみ記述できます。 ◆連接演算子 ・連接演算子{ }は、{ }で括られた信号を、1つの多bit信号として扱います。 ┌─────────────────────────────────────┐ wire [7:0] data_h1, data_h2; wire [7:0] data_l1, data_l2; wire [15:0] data_buf; assign data_buf1 = { data_h1, data_l1 }; assign { data_l2, data_h2 } = data_buf; // 左辺にも使用できます └─────────────────────────────────────┘ ・これは、シミュレーション上では1つの配列(リスト)にすることを意味します。 ・連接演算子は繰り返し記述も可能です。下記の例では、4'b0011を2回繰り返してい ます。 { 2{4'b0011} } ---> 8'b0011_0011 と同じ ・連接演算子は、ハードワイヤリングになるか、fanout確保のためbufferを介する 論理合成結果になります。ゲートが絡む点は忘れないで下さい。 ◆リダクション演算子 ・リダクション演算子は単項演算子として使用します。多bit信号のそれぞれのbitに 演算を行い、結果は1bitで返ります。 ┌─────────────────────────────────────┐ reg [3:0] data; assign parity_bit = ^data; // 下記と等価です // assign parity_bit = data[3] ^ data[2] ^ data[1] ^ data[0]; └─────────────────────────────────────┘ ・多bitのリダクション演算は多段ゲートになるので注意して下さい。 (*1)大きなレジスタ配列を論理合成目的で書くことはほとんどありません。大抵はマクロ になります。プロセスが進むたびに議論となりますが、面積を確認した結果やっぱり マクロになるのが今までの傾向です。書くとすればレジスタファイル等です。 [Revision Table] |Revision |Date |Comments |----------|-----------|----------------------------------------------------- |1.00 |2003-11-08 |初版 |1.01 |2003-11-18 |リンク追加 [end] Copyright(C) 2015 Altmo
|