FT232H是一個單通道USB 2.0高速(480Mb/s)轉換為UART/FIFO IC,具有多種工業標準串行或并行接口配置能力。
1.實驗板卡
FPGA型號:
FT232H型號:
FT232H SINGLE CHANNEL HI-SPEED USB TO MULTIPURPOSE UART/FIFO IC Datasheet
Version 2.0
2.數據手冊說明
選擇的是同步fifo模式。上面是管腳信號說明。
以上是讀寫時序
注意這里的時鐘周期是60mhz,我用的是FPGA上的PLL輸出的60m的時鐘,因為如果要用FT232H輸出的時鐘的話,需要對EEPROM進行配置,配置成FIFO模式,再通過上位機發送同步指令才可以輸出60MHZ時鐘。
時鐘周期等于16.67 ns,也就是時鐘頻率是1/T=1/16.67ns=1/1.67*10^(-9),結果約等于60MHZ。
FT232配置見:FPGA外接FT232H配置FIFO實現USB通信回環測試-CSDN博客
3.代碼設計
FPGA中FIFO IP的時序。寫的時候寫使能和數據是同步的,讀出數據的時候,讀出的數據延遲讀使能信號一個周期。
3.1?ft232h_top
module ft232h_top(/////////////////////////////debuginput jtag_inst1_CAPTURE ,input jtag_inst1_DRCK ,input jtag_inst1_RESET ,input jtag_inst1_RUNTEST ,input jtag_inst1_SEL ,input jtag_inst1_SHIFT ,input jtag_inst1_TCK ,input jtag_inst1_TDI ,input jtag_inst1_TMS ,input jtag_inst1_UPDATE ,output jtag_inst1_TDO ,/////////////////////////////////input i_usb_60m ,//input reset ,input rxf_n ,input txe_n ,output rd_n ,output wr_n ,output siwu_n ,output oe_n , //oe_n:0,FT232h數據輸出;oe_n:1,FPGA數據輸入到FT232中去 input [7:0] data_in ,output [7:0] data_out ,output [7:0] data_out_oe );wire empty;
wire [7:0]data_wr;
wire wr_fifo;
wire rst_busy;
wire full;
wire [7:0] data_rd;
wire reset ;
wire [7:0]data_count;
wire rd_fifo_flag_r;
wire rd_fifo_flag;assign siwu_n=1'b1; //用于喚醒主機電腦fifo u_fifo(
.full_o ( full ),
.empty_o ( empty ),
.rdata ( data_rd ),
.clk_i ( i_usb_60m ),
.wr_en_i ( wr_fifo ),
.rd_en_i ( rd_fifo ),
//.a_rst_i ( vio_reset_n ),
.a_rst_i ( reset ),
.wdata ( data_wr ),
.datacount_o ( data_count ),
.rst_busy ( ) //高電平有效,高電平復位
);ft232h_send ft232h_send_inst(.clk_60m (i_usb_60m) ,//.reset (vio_reset_n) ,.reset (reset) ,.rxf_n (rxf_n) , .data_in (data_in) , .wr_n (wr_n),.rd_n (rd_n) , .oe_n (oe_n) , .empty_o (empty) ,.full_o (full) ,//.rst_busy (rst_busy) ,.data_wr (data_wr) , .wr_fifo (wr_fifo)
);ft232h_recv ft232h_recv_inst(.clk_60m (i_usb_60m) ,//.reset (vio_reset_n) ,.reset (reset) ,.txe_n (txe_n),.rd_n (rd_n),.oe_n (oe_n),.rxf_n (rxf_n),.wr_fifo (wr_fifo),.wr_n (wr_n),.data_out (data_out),.data_out_oe(data_out_oe),//.rst_busy (rst_busy),.data_count (data_count),.full_o (full),.empty_o (empty) ,.data_rd (data_rd) ,.rd_fifo (rd_fifo) ,.rd_fifo_flag_r (rd_fifo_flag_r),.rd_fifo_flag (rd_fifo_flag)
);edb_top edb_top_inst (.bscan_CAPTURE ( jtag_inst1_CAPTURE ),.bscan_DRCK ( jtag_inst1_DRCK ),.bscan_RESET ( jtag_inst1_RESET ),.bscan_RUNTEST ( jtag_inst1_RUNTEST ),.bscan_SEL ( jtag_inst1_SEL ),.bscan_SHIFT ( jtag_inst1_SHIFT ),.bscan_TCK ( jtag_inst1_TCK ),.bscan_TDI ( jtag_inst1_TDI ),.bscan_TMS ( jtag_inst1_TMS ),.bscan_UPDATE ( jtag_inst1_UPDATE ),.bscan_TDO ( jtag_inst1_TDO ),.la0_clk ( i_usb_60m ),.la0_rxf_n ( rxf_n ),.la0_txe_n ( txe_n ),.la0_rd_n ( rd_n ),.la0_wr_n ( wr_n ),.la0_oe_n ( oe_n ),.la0_data_in ( data_in ),.la0_data_out ( data_out ),.la0_data_out_oe ( data_out_oe ),.la0_siwu_n ( siwu_n ),.la0_reset ( reset ),.la0_data_wr ( data_wr ),.la0_empty ( empty ),.la0_full ( full ),.la0_wr_fifo ( wr_fifo ),.la0_data_rd ( data_rd ),.la0_rd_fifo ( rd_fifo ),.la0_data_count (data_count),.la0_rd_fifo_flag_r (rd_fifo_flag_r ),.la0_rd_fifo_flag (rd_fifo_flag ),.vio0_clk ( i_usb_60m ),.vio0_data_in ( data_in ),.vio0_data_out ( data_out ),.vio0_data_out_oe ( data_out_oe ),.vio0_reset ( reset )
);endmodule
3.2??ft232h_send
//讀出FT232H的值,也就是驅動FT232H發送數據,
module ft232h_send(input clk_60m ,input reset ,input rxf_n , //FT232h輸出的信號,當rxf_n為低時,fpga可以通過驅動RD低來讀取數據。input [7:0] data_in , //FT232h從上位機中讀出的數據input wr_n , output reg rd_n , //output reg oe_n , //oe_n:驅動FT232H引腳上的數據輸出到FPGA//fifo信號 input empty_o ,input full_o ,//input rst_busy ,output reg [7:0] data_wr , // data_wr_reg:要寫入FPGA里面的FIFO的數據。output reg wr_fifo //fifo的寫使能信號
);reg [7:0] data_wr_reg;reg rxf_n_r ;
reg wr_n_r ;
reg empty_o_r ;
reg oe_n_r;
reg rd_n_r;always@(posedge clk_60m or posedge reset)beginif(reset==1'b1)oe_n<=1'b1;else if(rxf_n==1'b0&&wr_n==1'b1) oe_n<=1'b0;else oe_n<=1'b1;
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)rd_n<=1'b1;else beginif(oe_n==0 && wr_n == 1&&rxf_n==1'b0) rd_n<=1'b0;elserd_n<=1'b1;end
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)rd_n_r<=1'b1;else beginrd_n_r<=rd_n;end
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)data_wr<='d0;else if(oe_n==1'b0&&wr_n==1'b1&&rd_n==1'b0)data_wr<=data_in;elsedata_wr<=8'h00;
end//wr_fifo:wr_fifo延遲rd_n一個周期
always@(posedge clk_60m or posedge reset)beginif(reset==1'b1)wr_fifo <= 1'b0;else if (rd_n_r==1'b1&&rd_n==1'b0&&rxf_n==1'b0&&full_o==1'b0&&wr_n==1'b1) wr_fifo <= 1'b1;else if(rxf_n==1'b1)wr_fifo <= 1'b0;elsewr_fifo<=wr_fifo;
endendmodule
3.3?ft232h_recv
module ft232h_recv(input clk_60m ,input reset ,input txe_n ,input rd_n ,input oe_n ,input rxf_n ,input wr_fifo ,output reg wr_n ,output reg [7:0] data_out ,output reg [7:0] data_out_oe ,//fifo信號//input rst_busy ,input data_count ,input full_o ,input empty_o ,input [7:0] data_rd ,output reg rd_fifo ,output reg rd_fifo_flag_r,output reg rd_fifo_flag
);reg rd_fifo_r;
reg rd_fifo_flag;
//reg rd_fifo_flag_r;
reg empty_o_r ;always@(posedge clk_60m or posedge reset)beginif(reset==1'b1)empty_o_r<=1'b0;elseempty_o_r<=empty_o;
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)rd_fifo<=1'b0;else if(txe_n==1'b0&&empty_o==1'b0&&rd_n==1'b1)rd_fifo<=1'b1;elserd_fifo<=1'b0;
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)rd_fifo_flag<=1'b0;else if(rd_fifo==1'b1&&rd_fifo_r==1'b0)rd_fifo_flag<=1'b1;elserd_fifo_flag<=1'b0;
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)rd_fifo_flag_r<=1'b0;else rd_fifo_flag_r<=rd_fifo_flag;
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)rd_fifo_r<=1'b0;elserd_fifo_r<=rd_fifo;
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)begindata_out<='d0;endelsedata_out<=data_rd;
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)begindata_out_oe<='d0;endelse if(rd_fifo_flag==1'b1&&txe_n==1'b0&&empty_o==1'b0&&rd_n==1'b1)data_out_oe<=8'hff;else if(empty_o_r==1'b1||txe_n==1'b1)data_out_oe<='d0;elsedata_out_oe<=data_out_oe;
endalways@(posedge clk_60m or posedge reset)beginif(reset==1'b1)wr_n<=1'b1;else beginif(rd_fifo_flag==1'b1&&txe_n==1'b0&&empty_o==1'b0&&rd_n==1'b1)wr_n<=1'b0; else if(empty_o_r==1'b1||txe_n==1'b1)wr_n<=1'b1;elsewr_n<=wr_n;end
endendmodule
4.波形分析
5.管腳綁定
6.注意事項
(1)如果要使用外部輸入的時鐘作為FPGA的工作時鐘,需要對時鐘進行約束。
例如:
(2)下載比特流文件出錯的原因
使用上面這個版本有bug,燒錄比特流文件的時候,直接在下載比特流文件界面下載,把頻率改成5mhz,然后再debug界面直接連接,不再下載。
(3)連接usb線的時候需要下載正確的驅動
(4)為什么要用相位差為270°的時鐘?
(5)PLL的使用說明
PLL用法