FPGA活用回路&サンプル記述集(3) ―― ビデオ信号処理回路

大中 庸生

module LineBuffer_4lines
 (
 RESET,
 
 WA,
 WEN,
 WCK,
 WD,
 

 RA,
 REN,
 RCK,
 RD0,
 RD1,
 RD2
 

 );
 

 parameter DataWidth = 24; 
//データ幅はRGB各8ビットに対応できるように24ビットを設定しています.
 parameter XADRSWidth = 10; //水平アドレス幅に10ビットを設定,最大1024ピクセル長のラインをサポートします.
 parameter YADRSWidth = 10; //垂直アドレス幅に10ビットを設定.しかしライン・バッファが4本であれば,下位2ビットしか使われません.
  //ここまでのパラメータは必要に応じて変更可能です.
 parameter ADRSWidth = XADRSWidth + YADRSWidth;
 

 input RESET; //リセット入力
 
 input [ADRSWidth-1:0] WA;   //書き込みアドレス入力
 input WEN;                  //書き込みイネーブル入力
 input WCK;                  //書き込みクロック入力
 input [DataWidth-1:0] WD;   //書き込みデータ入力
 

 input [ADRSWidth-1:0] RA;   //読み出しアドレス入力
 input REN;                  //読み出し(データ更新)イネーブル入力
 input RCK;                  //読み出しクロック入力
 output [DataWidth-1:0] RD0; //下位ライン読み出しデータ出力
 output [DataWidth-1:0] RD1; //中間ライン読み出しデータ出力
 output [DataWidth-1:0] RD2; //上位ライン読み出しデータ出力
 

 wire [DataWidth-1:0] RAM_q0;
 wire [DataWidth-1:0] RAM_q1;
 wire [DataWidth-1:0] RAM_q2;
 wire [DataWidth-1:0] RAM_q3;
 

 //メモリ・ブロック選択用のアドレスです.
 //
 wire [1:0] LineAddress = WA[ADRSWidth-1:XADRSWidth];
 
 //書き込み側メモリ・ブロックの選択信号です.
 reg   RAMsel0;
 reg   RAMsel1;
 reg   RAMsel2;
 reg   RAMsel3;
 

 //ブロック図における「デコーダ」です.
 //書き込み側メモリ・ブロックの選択信号をWENとメモリ・ブロック選択用アドレスを元に生成します.
 always @ ( WEN or RESET ) begin
  if( ~ RESET | ~ WEN ) begin
   RAMsel0 <= 0;
   RAMsel1 <= 0;
   RAMsel2 <= 0;
   RAMsel3 <= 0;
  end
  
  else begin
   case ( LineAddress[1:0] ) 
    0: RAMsel0 <= WEN;
    1: RAMsel1 <= WEN;
    2: RAMsel2 <= WEN;
    3: RAMsel3 <= WEN;
    
   endcase
   
  end
  
 end
 

 //4本のライン・バッファメモリです.四つのメモリ・ブロックを使用します.
 RAMDP2 LineBuffer0  (.clka( WCK ), .dina( WD ), .addra( WA[XADRSWidth-1:0] ), .wea( RAMsel0 ), .clkb( RCK ), .addrb( RA[XADRSWidth-1:0] ), .doutb( RAM_q0 ) );
   defparam LineBuffer0.DataWidth = DataWidth;
   defparam LineBuffer0.ADRSWidth = XADRSWidth;
 
 RAMDP2 LineBuffer1  (.clka( WCK ), .dina( WD ), .addra( WA[XADRSWidth-1:0] ), .wea( RAMsel1 ), .clkb( RCK ), .addrb( RA[XADRSWidth-1:0] ), .doutb( RAM_q1 ) );
   defparam LineBuffer1.DataWidth = DataWidth;
   defparam LineBuffer1.ADRSWidth = XADRSWidth;
 
 RAMDP2 LineBuffer2  (.clka( WCK ), .dina( WD ), .addra( WA[XADRSWidth-1:0] ), .wea( RAMsel2 ), .clkb( RCK ), .addrb( RA[XADRSWidth-1:0] ), .doutb( RAM_q2 ) );
   defparam LineBuffer2.DataWidth = DataWidth;
   defparam LineBuffer2.ADRSWidth = XADRSWidth;
 
 RAMDP2 LineBuffer3  (.clka( WCK ), .dina( WD ), .addra( WA[XADRSWidth-1:0] ), .wea( RAMsel3 ), .clkb( RCK ), .addrb( RA[XADRSWidth-1:0] ), .doutb( RAM_q3 ) );
   defparam LineBuffer3.DataWidth = DataWidth;
   defparam LineBuffer3.ADRSWidth = XADRSWidth;
 

 //データ・レジスタです.メモリと,セレクタを通るので一段レジスタをおきます.
 reg [DataWidth-1:0] RD0d;
 reg [DataWidth-1:0] RD1d;
 reg [DataWidth-1:0] RD2d;
 reg RENd;
 
 //読み出しメモリ・セレクタ用アドレスです.
 reg [1:0] R_LineAddress0;
 reg [1:0] R_LineAddress1;
 reg [1:0] R_LineAddress2;
 

 //読み出しメモリ・セレクタ
 always @ (posedge RCK) begin
  if (~ RESET ) begin
   RD0d <= 0;
   RD1d <= 0;
   RD2d <= 0;
   RENd  <= 0;
   R_LineAddress0 <= 0;
   R_LineAddress1 <= 0;
   R_LineAddress2 <= 0;
   
  end
  else begin
   RENd  <= REN; //読み出しメモリ・セレクタは前段にメモリ・ブロックによるレイテンシがあるため,RENを調整します.
   
   //セレクタ用アドレスを生成します.書き込み側垂直アドレスの相対位置を指すようにします.
   R_LineAddress0 <= WA[ADRSWidth-1:XADRSWidth] - 1; //3×3フィルタの下位ライン用のセレクタです.
   R_LineAddress1 <= WA[ADRSWidth-1:XADRSWidth] - 2; //3×3フィルタの中間ライン用のセレクタです.
   R_LineAddress2 <= WA[ADRSWidth-1:XADRSWidth] - 3; //3×3フィルタの上位ライン用のセレクタです.
   
   //読み出しメモリ・セレクタ部です.
   if ( RENd ) begin
    case ( R_LineAddress0[1:0] )
     0: RD0d <= RAM_q0;
     1: RD0d <= RAM_q1;
     2: RD0d <= RAM_q2;
     3: RD0d <= RAM_q3;
    endcase
    case ( R_LineAddress1[1:0] )
     0: RD1d <= RAM_q0;
     1: RD1d <= RAM_q1;
     2: RD1d <= RAM_q2;
     3: RD1d <= RAM_q3;
    endcase
    case ( R_LineAddress2[1:0] )
     0: RD2d <= RAM_q0;
     1: RD2d <= RAM_q1;
     2: RD2d <= RAM_q2;
     3: RD2d <= RAM_q3;
    endcase
    
   end
   
  end
  
 end
 
 //読み出しデータをポートに出力します.
 assign RD0 = RD0d;
 assign RD1 = RD1d;
 assign RD2 = RD2d;
 

endmodule

リスト2-1 4ライン構成のライン・バッファのVerilog HDL記述

組み込みキャッチアップ

お知らせ 一覧を見る

電子書籍の最新刊! FPGAマガジン No.12『ARMコアFPGA×Linux初体験』好評発売中

FPGAマガジン No.11『性能UP! アルゴリズム×手仕上げHDL』好評発売中! PDF版もあります

PICK UP用語

EV(電気自動車)

関連記事

EnOcean

関連記事

Android

関連記事

ニュース 一覧を見る
Tech Villageブログ

渡辺のぼるのロボコン・プロモータ日記

2年ぶりのブログ更新w

2016年10月 9日

Hamana Project

Hamana-8最終打ち上げ報告(その2)

2012年6月26日