FT8U245AM (FTDI社) の制御方法 Verilog-HDL

2002/08/29(更新日 )







FTDI社のFT8U245AMはUSB-001-FIFO等に搭載されております。Verilog-HDLにて、このチップを制御できるようにソースコードを公開します.タイミング等の詳細はVHDL版を参照してください.

▼USB調停回路
 USB_ARBITER.v
▼エコー回路として動作するように記述したトップモジュール
 ECHO_TOP.v


/***        */
/** USB ECHO TOP **/
/*        ***/
module USB_vrg( CLK, PSW3, RXF_N, TXE_N, RD_N, WR, USB_DATA );
//▼クロックは18.432MHz以下にしてください
input CLK, PSW3;
input RXF_N, TXE_N;
output RD_N, WR;
inout [7:0] USB_DATA;

wire BUSY, READY, ENB;
wire RST;
wire [7:0] DATA;

//▼ECHO回路として,利用する
// BUSYがHの時は,調停回路は処理中
assign READY = ~BUSY;
//▼スイッチが負論理の場合
assign RST = ~PSW3;

//▼TG_DO(ターゲットへのデータを出力)をTG_DIに入力
//▼ターゲットへのリード信号をライト信号に入力
USB_ARBITER U0
  ( .CLK(CLK),
   .RST(RST),
   .RXF_N(RXF_N),   // IN
   .TXE_N(TXE_N),   // IN
   .RD_N(RD_N),    // OUT
   .WR(WR),      // OUT
   .BUS_BUSY(BUSY),  // OUT
   .TG_READY(READY), // IN
   .USB_DATA(USB_DATA),
   .TG_DO(DATA),
   .TG_DI(DATA),
   .TG_RD(ENB),
   .TG_WR(ENB) );
endmodule

/***        */
/** USB調停回路 **/
/*        ***/
module USB_ARBITER( CLK , RST ,
          RXF_N , TXE_N ,
          RD_N , WR ,
          BUS_BUSY ,TG_READY ,
          USB_DATA ,
          TG_DO, TG_DI, TG_RD, TG_WR );
input CLK, RST;
input RXF_N, TXE_N;
output RD_N, WR;
output BUS_BUSY;
input TG_READY;
inout [7:0] USB_DATA;
output [7:0] TG_DO;
input [7:0] TG_DI;
output TG_RD;
input TG_WR;

reg [1:0] RD_STATE, WR_STATE;
reg RD_N, WR;
reg [7:0] TG_DO;
reg TG_RD;
reg DIR;
reg RXF_REG, TXE_REG;
reg [7:0] USB_DATA_REG;

//▼ステートマシンで利用するステート番号
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
parameter S3 = 2'b11;

//▼非同期信号なので,念のためD-FFを通す
always @( posedge CLK or posedge RST ) begin
 if ( RST ) begin
  RXF_REG <= 0;
  TXE_REG <= 0;
 end
 else begin
  RXF_REG <= ~RXF_N;
  TXE_REG <= ~TXE_N;
 end
end

//▼DIR=1のとき,USB_DATA_REGとし,それ以外はハイインピーダンス(FPGA側に入力)
assign USB_DATA = (DIR==1) ? USB_DATA_REG : 8'bz;
//▼処理中であれば,BUSY=1とする
assign BUS_BUSY = (WR_STATE==0 && RD_STATE==0) ? 1'b0 : 1'b1;

//▼ムーア形,出力にレジスタを付ける
/***           */
/** READ STATE MACHINE **/
/*           ***/
always @( posedge CLK or posedge RST ) begin
 if ( RST ) begin
  TG_DO <= 0;
  TG_RD <= 0;
  RD_N <= 1;
  RD_STATE <= S0;
 end
 else begin
  case( RD_STATE )
   S0 :
    begin
     //▼ライトサイクル中ではなく,ターゲットモジュールへの書込みが可能
     if( RXF_REG==1 && TG_READY==1 && WR_STATE==0 ) begin
      RD_N <= 0;
      RD_STATE <= S1;
     end
     else begin
      RD_STATE <= S0;
     end
    end
   S1 :
    begin
     TG_DO <= USB_DATA;
     RD_STATE <= S2;
    end
   S2 :
    begin
     RD_N <= 1;
     TG_RD <= 1;
     RD_STATE <= S3;
    end
   S3 :
    begin
     TG_RD <= 0;
     RD_STATE <= S0;
    end
   default : RD_STATE <= S0;
  endcase
 end
end

/***            */
/** WRITE STATE MACHINE  **/
/*            ***/
always @( posedge CLK or posedge RST ) begin
 if( RST ) begin
  WR <= 1;
  DIR <= 0;
  WR_STATE <= S0;
 end
 else begin
  case( WR_STATE )
   S0 :
    begin
     //▼ターゲットからの書込み要求あり
     if( TG_WR==1 ) begin
      //▼レジスタに格納
      USB_DATA_REG <= TG_DI;
      WR_STATE <= S1;
     end
     else begin
      WR_STATE <= S0;
     end
    end
   S1 :
    begin
     //▼リードサイクル中ではなく,USB FIFOに書込み可能
     if( TXE_REG==1 && RD_STATE==0) begin
      WR <= 1;
      DIR <=1;
      WR_STATE <= S2;
     end
    else begin
     WR_STATE <= S1;
    end
   end
   S2 :
    begin
     WR <= 0;
     DIR <= 1;
     WR_STATE <= S3;
    end
   S3 :
    begin
     WR <= 1;
     DIR <= 0;
     WR_STATE <= S0;
    end
   default : WR_STATE <= S0;
  endcase
 end
end
endmodule

メールでのご質問はこちらへどうぞ

HDLのホームページへ