のくす牧場
コンテンツ
牧場内検索
カウンタ
総計:123,531,738人
911,637,138頁
昨日:4,530人
5,106頁
今日:401人
487頁
最近の注目
人気の最安値情報

    FPGAとは? anchor.png

    • Field Programmable Gate Arrayの略称で、プログラム可能な大規模集積回路(PLD)の一種。
    Page Top

    略語もろもろ anchor.png

    • LSI(Large Scale Integrated circuit) : 大規模集積回路
    • HDL(hardware description language) : ハードウェア記述言語
    • PLD(Programmable Logic Device) : プログラム可能なLSI。
    Page Top

    論理回路 anchor.png

    Page Top

    Verilog HDLによるFPGA設計基本テクニック anchor.png

    Page Top

    はじめに anchor.png

    • 使用環境 : Windows XP
    • 使用言語 : Verilog HDL
    • 使用開発ソフトウェア : ISE project navigator (v13.3)
    • 使用ハードウェア : Spartan-3A Startkit (by Xilinx)
    • 主な参考文献
      • 「FPGAボードで学ぶVerilog HDL 井倉将実 著 CQ出版社」
      • 「入門VerilogHDL記述~ハードウェア言語の速習&実践~ 小林優 著 CQ出版社」
    • 結果について
      • 以下に示すプログラムの結果については、各自で確かめてください。気が向けば結果をPDFで添付する予定(未定)
    Page Top

    簡単なプログラムを設計してFPGAボードで遊んでみる。 anchor.png

    Page Top

    【プログラム】ボタンを押している(いない)ならばLED消灯(点灯)。 anchor.png

    • ソースコード
       module led_onoff1_0120( //モジュール宣言の開始
       SW1_I,  //ポートの定義
       LED1_O, //ポートの定義
       //1)約束事
       //  a)ポート・リストの信号の区切りにはカンマ(,)を用いる。
       //  b)文の終わりにはセミコロン(;)を付ける。
       //  c)Verilog HDLでは大文字・小文字を区別することに注意。
       
      );
      
      input SW1_I;   //スイッチ入力
      output LED1_O; //LED出力
      //1)宣言したポート与える信号方向
      //  input  : 入力信号
      //  output : 出力信号
      //  inout  : 双方向
      
      assign LED1_O = !SW1_I; //SW1_Iの信号を反転して、LEID1_Oに伝える
      //1)assign
      //  assign文は信号の代入を行う記述。
      //2)論理演算子
      // 「!」は論理反転演算子(NOT)です。
       
      endmodule
    • 制約ファイル(.ucfファイル)
      NET "SW1_I" LOC = "U15" | IOSTANDARD = LVTTL | PULLDOWN ;
      NET "LED1_O" LOC = "W21" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
    Page Top

    【プログラム】ボタンでLEDの点灯・消灯を切り替える。 anchor.png

    • ソースコード(.vファイル)
      module led_onoff2_0121( 
        SW1_I,
        LED1_O,
      );
      
       input SW1_I;
       output LED1_O;
       
       reg led_status; //内部レジスタの宣言
       //1)レジスタ宣言 reg
       //  レジスタは、特定の入力信号があったときにだけ出力を変化し、
       //  それ以外の時には入力信号が変化しても出力を保持し続ける。
       //2)regとwire
       //  a)reg宣言  : 順序回路(クロック信号などのタイミングで変化するもの)であることを示す。 
       //  b)wire宣言 : 組み合わせ回路(入力変化とともに即座に出力が変化するもの)であることを示す。
      
       always @(posedge SW1_I) //信号の立ち上がりエッジに変化("L"から"H"への変化)があったとき
        begin
         begin 
          led_status <= !led_status; 
         end
        end
        //1)always文
        //  always文の@()内に書かれた信号に変化あったときのみ、begin~endの動作を行う。
        //2)posedge と negedge
        //  posedge : 立ち上がりエッジ("L"から"H")
        //  negedge : 立ち下がりエッジ("H"から"L")
      
       assign LED1_O = !led_status;
      
      endmodule
    • 制約ファイル(.ucfファイル)
      NET "SW1_I" LOC = "U15" | IOSTANDARD = LVTTL | PULLDOWN ;
      NET "SW1_I" CLOCK_DEDICATED_ROUTE = FALSE;
      NET "LED1_O" LOC = "W21" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
    Page Top

    【プログラム】8つのLEDを順番に点灯・消灯する。 anchor.png

      • ソースコード(.vファイル)
        module led_onoff3(
        reset_i,
        switch_i,
        led_o,
        );
         
        input  reset_i;     //リセット入力
        input  switch_i;    //スイッチ入力
        output [7:0] led_o; //LED出力。8個のレジスタを指定
        //1)バスによる記述
        // 「output [7:0] led_o」は「7から0までのひとまとまりの信号」である
        //  (=8ビット幅のバス信号である)ことを表す。
        //2)1行づつの記述する場合は以下のようにする。
        //  output led_o[0];
        //      (中略)
        //  output led_o[7];
        
        parameter init_value = 8'b00000001 ; //8ビット幅の2進数で8ケタの数値00000001を割り当てる。
        reg [7:0] led_status;
        //1)ビット幅の表現
        // 「8'」のように表現する。
        //2)n進数の表現
        //  2進数  : bまたはB
        //  8進数  : oまたはO
        //  10進数 : dまたはD
        //  16進数 : hまたはH
        //3)regとparameter
        //  a)共通点
        //    変数に値を割り当てるという点が共通。
        //  b)相違点
        //    regで宣言された変数は実際に信号(内部ノード)として生成される。
        //    一方で、parameterで宣言された変数は回路として生成されない。
        
        always @(posedge switch_i or posedge reset_i)
         begin
          if(reset_i == 1'b1) //リセットが押されたら
           begin
            led_status <= init_value; //初期値をフリップフロップに設定  
           end
          else  //スイッチが押されたら
           begin
            led_status <= {led_status[6:0], led_status[7] }; //LEDの消灯が右方向へシフト
            //1)連接演算子である「{}」によって、
            //  led_status[6:0]とled_status[7]を8ビット幅の信号として、
            //  led_status[6:0]に代入。
            //2)上の一行は以下と等価
            //  led_status[0] <= led_status[7]; //シフト動作を開始する。信号を隣のLEDに渡す。
            //             (中略)
            //  led_status[7] <= led_status[6];
            //  注)上の複数行は同時に実行される。
            //3)LEDの消灯を左方向へシフトさせたい場合
            //led_status <= {led_status[0], led_status[7:1] };
         
           end
          end
         
         assign led_o[7:0] = ~led_status[7:0]; //ビット演算子による記述
         //1)ビット演算子による記述
         //  8ビット幅のled_o信号の全ビットを反転するにはビット演算子の「~」を用いる。
         //  (「~」は論理演算子の「!」と等価)
         //2)論理演算子による記述(以下は上の一行と等価)
         //  assign led_o[0] = !led_status[0];
         //                 (中略)
         //  assign led_o[7] = !led_status[7];
         
        endmodule
    • 制約ファイル(.ucfファイル)
      NET "switch_i" LOC = "U15" | IOSTANDARD = LVTTL | PULLDOWN ;
      NET "switch_i" CLOCK_DEDICATED_ROUTE = FALSE;
      NET "reset_i"  LOC = "T15" | IOSTANDARD = LVTTL | PULLDOWN ;
      NET "led_o[0]" LOC = "W21" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "led_o[1]" LOC = "Y22" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "led_o[2]" LOC = "V20" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "led_o[3]" LOC = "V19" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "led_o[4]" LOC = "U19" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "led_o[5]" LOC = "U20" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "led_o[6]" LOC = "T19" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "led_o[7]" LOC = "R20" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
    Page Top

    基本的なゲート回路の実装 anchor.png

    • プリミティブゲートを用いたゲート回路記述
      • Verilog HDLにはあらかじめプリミティブ・ゲートが用意されているので、定義や宣言なしで使用可能。
      • 例)
        //1入力
        not n1(out,in0);      //NOT回路
        //2入力 
        and  an2(out,in0,in1); //AND回路
        or   or2(out,in0,in1); //OR回路
        nand nd2(out,in0,in1); //NAND回路
        nor  nr2(out,in0,in1); //NOR回路
        xor  xr2(out,in0,in1); //XOR回路
        xnor xn2(out,in0,in1); //XNOR回路
        /3入力
         and an3(out,in0,in1,in3); //AND回路
    • 論理式(ビット演算)を用いたゲート回路記述
      • 例)
        //1入力
        assign  out = ~in0;         //NOT回路
        //2入力  
        assign out = in0 & in1;    //AND回路
        assign out = in0 | in1;    //OR回路
        assign out = ~(in0 & in1); //NAND回路
        assign out = ~(in0 | in1); //NOR回路
        assign out = in0 ^ in1 ;   //XOR回路
        assign out = ~(in0 ^ in1); //XNOR回路
        //3入力
        assign out = in0 & in1 & in2; //AND回路
    Page Top

    組み合わせ回路 anchor.png

    • その時点における入力の値の組合せにより出力が決まる論理回路。
    Page Top

    半加算器 anchor.png

    • 概要
      • 半加算器とは
        • 2進数1桁の加算をする回路。
      • スイッチのon/offを入力、LEDの点灯/消灯を出力として半加算器を作る。
    • ソースファイル(.vファイル)
      module halfadd(A,B,S,C);
      
      input  A;
      input  B;
      output S;
      output C;
      
      assign S = A ^ B ; //bit XOR演算
      assign C = A & B ; //bit AND演算
      
      endmodule
    • 制約ファイル(.ucfファイル)
      NET "A" LOC = "U10"| IOSTANDARD = LVTTL | PULLUP ;
      NET "B" LOC = "V8" | IOSTANDARD = LVTTL | PULLUP ;
      NET "S" LOC = "R20" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "C" LOC = "T19" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
    • テストベンチ
      • 概要
        • 信号入出力の様子をシミュレーションし、半加算器が実現していることを確認する。
      • シミュレーション記述
        `timescale 1ns / 1ps // シミュレーション時刻の単位/タイミング計算の丸め誤差
        
        module test;
        
        reg Ain;
        reg Bin;
        wire Sout;
        wire Cout;
        
        parameter step = 100; 
        
        halfadd uut (.A(Ain), .B(Bin), .S(Sout), .C(Cout)); //テスト対象であるmodule halfaddを呼び出す
        //下位モジュール呼び出し時のポート接続は「.定義側ポート名(接続信号)」とする。
        //つまり、Aは下位モジュールのポート名、Ainは上位モジュールである本ソースの接続信号となっている。
        
        initial begin
               Ain = 1'b0; Bin = 1'b0;
         #step Ain = 1'b0; Bin = 1'b1; //100ns後にAinに0を、Binに1を入力。
         //「#<定数>」とすることで、定数分だけ遅延を付加できる。
         //ここでは100シミュレーション・ユニットだけ遅延を付加。
         //1シミュレーション・ユニットは1行目で1nsと設定されているので100nsの遅延を付加している。
         #step Ain = 1'b1; Bin = 1'b0;
         #step Ain = 1'b1; Bin = 1'b1;
         #step $finish; 
        end
              
        endmodule
    Page Top

    全加算器 anchor.png

    • 概要
      • 全加算器とは
        • 下位桁からの繰り上がりを考慮に入れた加算回路。
        • 半加算器とOR回路から成る。
      • 全加算器を組み合わせることで多ビットの加算回路を作ることが可能。
      • スイッチのon/offを入力、LEDの点灯/消灯を出力として全加算器を作る。
    • ソースファイル(.vファイル)
      module fulladd(Ain,Bin,Cin,Sout,Cout);
      
      input Ain, Bin, Cin ;     //入力
      output Sout, Cout ;       //出力
      wire ha1_C, ha1_S, ha2_C; //内部配線 
      
      halfadd ha1(.A(Ain),.B(Bin),.S(ha1_S),.C(ha1_C)); //半加算器1
      halfadd ha2(.A(Cin),.B(ha1_S),.S(Sout),.C(ha2_C));//半加算器2
      assign Cout = ha1_C | ha2_C ; // OR回路
      
      endmodule
    • 制約ファイル(.ucfファイル)
      NET "Ain" LOC = "U8"| IOSTANDARD = LVTTL | PULLUP ;
      NET "Bin" LOC = "U10"| IOSTANDARD = LVTTL | PULLUP ;
      NET "Cin" LOC = "V8" | IOSTANDARD = LVTTL | PULLUP ;
      NET "Sout" LOC = "R20" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
      NET "Cout" LOC = "T19" | IOSTANDARD = LVTTL | SLEW = QUIETIO | DRIVE = 4 ;
    • テストベンチ(シミュレーション)記述
      `timescale 1ns / 1ps
      module test_fulladd;
       
       reg Ain;
       reg Bin;
       reg Cin;
       wire Sout;
       wire Cout;
       parameter step = 50;
      
       // Instantiate the Unit Under Test (UUT)
       fulladd uut (
        .Ain(Ain), 
        .Bin(Bin), 
        .Cin(Cin), 
        .Sout(Sout), 
        .Cout(Cout)
       );
      
       initial 
       begin
             Ain=1'b0; Bin=1'b0; Cin=1'b0;
       #step Ain=1'b0; Bin=1'b1; Cin=1'b0;
       #step Ain=1'b1; Bin=1'b0; Cin=1'b0;
       #step Ain=1'b1; Bin=1'b1; Cin=1'b0;
       #step Ain=1'b0; Bin=1'b0; Cin=1'b1;
       #step Ain=1'b0; Bin=1'b1; Cin=1'b1;
       #step Ain=1'b1; Bin=1'b0; Cin=1'b1;
       #step Ain=1'b1; Bin=1'b1; Cin=1'b1;
       #step $finish;
       end
      endmodule
    Page Top

    順序回路 anchor.png

    • その時点の入力のみならず過去の入力信号にも依存する論理回路。
    • 一種のメモリのように状態(0、1)を記憶する機能がある。

    トップ   凍結 差分 バックアップ 複製 名前変更 リロード印刷に適した表示   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom Powered by xpWiki
    Counter: 1626, today: 1, yesterday: 1
    初版日時: 2012-03-10 (土) 15:25:42
    最終更新: 2012-03-13 (火) 13:20:44 (JST) (2099d) by nakamiya