[Evaluation and experience of Zhongke Yihaiwei EQ6HL45 development platform] +07.USB test and simulation (zmj)
[Copy link]
[Evaluation and experience of Zhongke Yihaiwei EQ6HL45 development platform] +07.USB test and simulation (zmj)
The Zhongke Yihaiwei EQ6HL45 development platform contains a USB2.0 communication interface, which can realize USB communication between FPGA and PC.
This article mainly covers USB2.0 interface, testing and simulation. In particular, the actual test shows that there are bit errors in the USB2.0 communication between the PC and the FPGA. After code function simulation, the FPGA's USB2.0 interface program can send and receive data normally in the simulation environment, so it is speculated that the bit errors are caused by the mismatch between the USB firmware and the FPGA interface program.
1. USB2.0 interface
1.1 FT232H chip
The Zhongke Yihaiwei EQ6HL45 development platform uses the FTDI Chip FT232H single-channel high-speed USB chip to realize USB2.0 data communication between the development board and the computer.
The FT232H chip supports USB2.0 high-speed communication (HS speed 480Mb/s) and full-speed communication (FS speed 12Mb/s). The data interface supports different data communication modes (FIFO, I2C, SPI, JTAG). After power-on, the external EEPROM configuration content is read to determine the data communication mode. The configuration method can also be conveniently modified through a PC. The function of the interface pins of the USB chip is multiplexed. For details, please refer to the chip manual of the FT232H. The depth of the read and write cache is 1k bytes.
//------FT232H Manual
FT232HL.pdf
(1.66 MB, downloads: 4)
1.2 Working Mode
FT232H supports UART or FIFO mode, and can be configured into a variety of industrial serial or parallel interfaces:
//------FT232H chip supports multiple interface modes
Can be configured as UART interface
FT245 synchronous FIFO interface
FT245 asynchronous FIFO interface
Synchronous or asynchronous Bit-Bang interface
MPSSE interface
Fast serial port
CPU FIFO interface
FT1248 interface
In the development board, the firmware in the EEPROM is configured as the "FT245 synchronous FIFO interface".
In the development board, the firmware in the EEPROM is configured as the "FT245 synchronous FIFO interface".
It should be pointed out that the FT232H chip requires an external 12MHz crystal input clock signal, and it outputs a 60MHz clock signal through Pin-29 for use by peripherals.
1.3 USB2.0 interface implementation
The working mode of the USB chip FT232H is set by the firmware pre-burned in the EEPROM. The data interface signal is connected to the IO of the FPGA. The data communication of FT232H is carried out through the programming of the FPGA. The hardware connection of FT232H is connected in accordance with the "FT245 synchronous FIFO interface" method, as shown in the figure:
//------Schematic diagram
1.4 USB2.0 Partial Interface Definition
Understanding the interface functions of the FT232H chip can help you better understand its working principle.
Definition of some important interface signals of USB2.0:
//------FT232H_Interfaces
//---1.clock_nc
a.ft_clk
//Output 60MHz clock signals.
b.ft_siwu_n 立刻发送/唤醒功能
//Tied to "1'b1" if not used.
//---2.RD: usb -> fpga
a.ft_rxf_n[00:00] 低表示接收FIFO数据可读
//When high, do not read data from the FIFO.
//When low, there is data available in the FIFO which can be read by driving RD# low.
//When in synchronous mode, data is transferred on every clock that RXF# and RD# are both low.
//Note that the OE# pin must be driven low at least 1 clock period before asserting RD# low.
b.ft_oe_n[00:00] USB数据输出使能
//Output enable when low to drive data onto D0-7.
//This should be driven low at least 1 clock period
//before driving RD# low to allow for data buffer turn-around.
c.ft_rd_n[00:00] 数据接收 FIFO 读信号,低有效
//Enables the current FIFO data byte to be driven onto D0...D7 when RD# goes low.
//The next FIFO data byte (if available) is fetched from the receive FIFO buffer each CLKOUT cycle until RD# goes high.
//---3.WR: fpga -> usb
a.ft_txe_n[00:00] 低表示发送FIFO数据可以写
//When high, do not write data into the FIFO.
//When low, data can be written into the FIFO by driving WR# low.
//When in synchronous mode, data is transferred on every clock that TXE# and WR# are both low.
b.ft_wr_n[00:00] 数据发送FIFO写信号,低有效
//Enables the data byte on the D0...D7 pins to be written into the transmit FIFO buffer when WR# is low.
//The next FIFO data byte is written to the transmit FIFO buffer each CLKOUT cycle until WR# goes high.
//---4.DATA: inout
a.ft_data[07:00]
//D7 to D0 bidirectional FIFO data.
//This bus is normally input unless OE# is low.
1.5 FT245 Synchronous FIFO Mode Timing
FT245 synchronous FIFO mode timing (for detailed timing, refer to the FT232H manual):
//------ FT245 synchronous FIFO mode timing:
In the read sequence, FT232H first pulls RXF# low, and then the data in FIFO can be read. FPGA can pull OE# low first, and then pull RD# low after at least one clock cycle, and collect data on the rising edge of CLKOUT.
In the write sequence, FT232H pulls TXE# low, indicating that writing is now possible, and FPGA can pull WR# low to write data on the rising edge of CLKOUT.
2. USB2.0 test
The FPGA code implements the loopback function of the FT245 synchronous FIFO mode.
Operation process:
//------Operation process:
a. Connect the power supply, JTAG interface and mini-USB interface;
b. Open the host computer "USB test tool/usbtools";
c. Burn the program, open the Debug interface, and observe the sending and receiving data through the host computer.
//------Abnormal phenomenon:
a. The PC sends and receives inconsistent data, the received data has one more than the sent data, and there is a bit error;
b.FPGA finds that the received data is abnormal through the Debug window;
c. Based on this, it can be judged that the data anomaly is caused by the FT232H chip.
//------Physical picture of USB2.0 interface on expansion board
//------Test results of host computer
//------eLINX Debug signal
3. USB2.0 interface emulation
3.1 Simulation function design
The simulation code has the following functions:
-
Excitation clock and reset signals.
-
According to the timing of "FT245 synchronous FIFO mode", the simulation sends data first and then receives data, and repeats it 10 times.
-
Monitor the data sent and received inside the monitor code in real time and print it.
//------Excitation clock and data
//------clock
initial begin
sys_clk = 0 ;
end
always #(PERIOD_100MHz / 2) sys_clk = ~sys_clk ;
/*
initial begin
sys_clk = 0 ;
forever #(PERIOD_100MHz / 2) sys_clk = !sys_clk ;
end
*/
assign ft_clk = sys_clk ;
//------reset
initial begin
sys_rst_n = 1'b0 ;
#1000;
sys_rst_n = 1'b1 ;
end
//------data_gen(随机数通过$random产生)
always@(posedge sys_clk)begin
if(data_gen_en == 1'b1)
data_gen = $random ;
end
assign ft_data = (ft_rxf_n == 1'b1)? 8'hz : data_gen ;
//------Repeat sending and receiving 10 times (implemented by repeat)
repeat(10) begin
#100;//usb -> fpga
ft_rxf_n = 1'b0 ;
ft_txe_n = 1'b1 ;
data_gen_en = 1'b1 ;
#100;
ft_rxf_n = 1'b1 ;
ft_txe_n = 1'b1 ;
data_gen_en = 1'b0 ;
#100;//fpga -> usb
ft_rxf_n = 1'b1 ;
ft_txe_n = 1'b0 ;
data_gen_en = 1'b0 ;
#100;
ft_rxf_n = 1'b1 ;
ft_txe_n = 1'b1 ;
data_gen_en = 1'b0 ;
end
//------Internal signal monitoring (implemented by monitor)
//------Monitor
initial begin
//---
#100;
$display("**********************************\n");
$display("//------Dump / Monitor all data.\n");
$display("**********************************\n");
//---
while(1)begin
//forever begin //forever will cause dead-lock.
@(posedge sys_clk)
if(u_top.ft232h_m0.buf_wr)begin
$display("Data usb2fpga is %x.",u_top.ft232h_m0.buf_data);
end
if(u_top.ft232h_m0.buf_rd)begin
$display("Data fpga2usb is %x.",u_top.ft232h_m0.ft_data_out);
end
end
end
3.2 Simulation Log
The MOdelsim simulation Log is as follows: It mainly prints the data received and sent ten times (random numbers). After comparison, the received and sent data are consistent, which verifies that the FPGA code function is OK .
//------Modelsim仿真Log
VSIM(paused)> run -all
# **********************************
#
# //------Dump / Monitor all data.
#
# **********************************
#
# Data usb2fpga is 81.
# Data usb2fpga is 09.
# Data usb2fpga is 63.
# Data usb2fpga is 0d.
# Data usb2fpga is 8d.
# Data usb2fpga is 65.
# Data usb2fpga is 12.
# Data usb2fpga is 01.
# Data fpga2usb is 81.
# Data fpga2usb is 09.
# Data fpga2usb is 63.
# Data fpga2usb is 0d.
# Data fpga2usb is 8d.
# Data fpga2usb is 65.
# Data fpga2usb is 12.
# Data fpga2usb is 01.
# Data usb2fpga is 3d.
# Data usb2fpga is ed.
# Data usb2fpga is 8c.
# Data usb2fpga is f9.
# Data usb2fpga is c6.
# Data usb2fpga is c5.
# Data usb2fpga is aa.
# Data usb2fpga is e5.
# Data fpga2usb is 3d.
# Data fpga2usb is ed.
# Data fpga2usb is 8c.
# Data fpga2usb is f9.
# Data fpga2usb is c6.
# Data fpga2usb is c5.
# Data fpga2usb is aa.
# Data fpga2usb is e5.
# Data usb2fpga is 8f.
# Data usb2fpga is f2.
# Data usb2fpga is ce.
# Data usb2fpga is e8.
# Data usb2fpga is c5.
# Data usb2fpga is 5c.
# Data usb2fpga is bd.
# Data usb2fpga is 2d.
# Data fpga2usb is 8f.
# Data fpga2usb is f2.
# Data fpga2usb is ce.
# Data fpga2usb is e8.
# Data fpga2usb is c5.
# Data fpga2usb is 5c.
# Data fpga2usb is bd.
# Data fpga2usb is 2d.
# Data usb2fpga is 0a.
# Data usb2fpga is 80.
# Data usb2fpga is 20.
# Data usb2fpga is aa.
# Data usb2fpga is 9d.
# Data usb2fpga is 96.
# Data usb2fpga is 13.
# Data usb2fpga is 0d.
# Data fpga2usb is 0a.
# Data fpga2usb is 80.
# Data fpga2usb is 20.
# Data fpga2usb is aa.
# Data fpga2usb is 9d.
# Data fpga2usb is 96.
# Data fpga2usb is 13.
# Data fpga2usb is 0d.
# Data usb2fpga is d5.
# Data usb2fpga is 02.
# Data usb2fpga is ae.
# Data usb2fpga is 1d.
# Data usb2fpga is cf.
# Data usb2fpga is 23.
# Data usb2fpga is 0a.
# Data usb2fpga is ca.
# Data fpga2usb is d5.
# Data fpga2usb is 02.
# Data fpga2usb is ae.
# Data fpga2usb is 1d.
# Data fpga2usb is cf.
# Data fpga2usb is 23.
# Data fpga2usb is 0a.
# Data fpga2usb is ca.
# Data usb2fpga is 8a.
# Data usb2fpga is 41.
# Data usb2fpga is d8.
# Data usb2fpga is 78.
# Data usb2fpga is 89.
# Data usb2fpga is eb.
# Data usb2fpga is b6.
# Data usb2fpga is c6.
# Data fpga2usb is 8a.
# Data fpga2usb is 41.
# Data fpga2usb is d8.
# Data fpga2usb is 78.
# Data fpga2usb is 89.
# Data fpga2usb is eb.
# Data fpga2usb is b6.
# Data fpga2usb is c6.
# Data usb2fpga is 2a.
# Data usb2fpga is 0b.
# Data usb2fpga is 71.
# Data usb2fpga is 85.
# Data usb2fpga is 4f.
# Data usb2fpga is 3b.
# Data usb2fpga is 3a.
# Data usb2fpga is 7e.
# Data fpga2usb is 2a.
# Data fpga2usb is 0b.
# Data fpga2usb is 71.
# Data fpga2usb is 85.
# Data fpga2usb is 4f.
# Data fpga2usb is 3b.
# Data fpga2usb is 3a.
# Data fpga2usb is 7e.
# Data usb2fpga is d9.
# Data usb2fpga is 62.
# Data usb2fpga is 4c.
# Data usb2fpga is 9f.
# Data usb2fpga is 8f.
# Data usb2fpga is f8.
# Data usb2fpga is b7.
# Data usb2fpga is 9f.
# Data fpga2usb is d9.
# Data fpga2usb is 62.
# Data fpga2usb is 4c.
# Data fpga2usb is 9f.
# Data fpga2usb is 8f.
# Data fpga2usb is f8.
# Data fpga2usb is b7.
# Data fpga2usb is 9f.
# Data usb2fpga is 89.
# Data usb2fpga is 49.
# Data usb2fpga is d0.
# Data usb2fpga is d7.
# Data usb2fpga is 51.
# Data usb2fpga is 96.
# Data usb2fpga is 0c.
# Data usb2fpga is c2.
# Data fpga2usb is 89.
# Data fpga2usb is 49.
# Data fpga2usb is d0.
# Data fpga2usb is d7.
# Data fpga2usb is 51.
# Data fpga2usb is 96.
# Data fpga2usb is 0c.
# Data fpga2usb is c2.
# Data usb2fpga is 3d.
# Data usb2fpga is 12.
# Data usb2fpga is 7e.
# Data usb2fpga is 6d.
# Data usb2fpga is 39.
# Data usb2fpga is 1f.
# Data usb2fpga is d3.
# Data usb2fpga is 85.
# Data fpga2usb is 3d.
# Data fpga2usb is 12.
# Data fpga2usb is 7e.
# Data fpga2usb is 6d.
# Data fpga2usb is 39.
# Data fpga2usb is 1f.
# Data fpga2usb is d3.
# Data fpga2usb is 85.
# **********************************
#
# //------Simulation_Stop.
#
# //------Stop @ 6000 ns.
#
# **********************************
#
# Break in Module usb_sim_top at D:/tronlong/eHighWay/prj/7_usb_loopback_top/usb_loopback_top.srcs/sim_1/new/usb_sim_top.v line 112
VSIM(paused)>
3.3 Simulation waveform
By observing the simulation waveform wave, we can see that FPGA realizes data transmission and reception, and the data transmission and reception are correct.
//------
Random write data (hexadecimal): 81 09 63 0d 8d 65 12 01 //The first group, a total of ten groups. buf_wr/buf_data
The final read data (hexadecimal): 81 09 63 0d 8d 65 12 01 //The first group, a total of ten groups. buf_rd/ft_data_out
Attached. USB simulation code usb_sim_top.v
//------usb_sim_top.v
`timescale 1 ns/ 1 ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 11-16-2022 16:19:00
// Design Name:
// Module Name: usb_sim_top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module usb_sim_top( );
//------------------------------------------------------------------
//------parameter
parameter PERIOD_100MHz = 10 ;//100MHz = 10.0ns
parameter PERIOD_60MHz = 16.7;// 60MHz = 16.7ns
//------
reg sys_rst_n ;
reg sys_clk ;//Work@60MHz Sim@100mhz //------FT232H_Interfaces
wire ft_clk ;//Work@60MHz: usb-clock output to fpga.
//---RD: usb -> fpga //Data available
reg [00:00] ft_rxf_n ;//When high, do not read data from the FIFO.
//When low, there is data available in the FIFO which can be read by driving RD# low.
//When in synchronous mode, data is transferred on every clock that RXF# and RD# are both low.
//Note that the OE# pin must be driven low at least 1 clock period before asserting RD# low.
wire [00:00] ft_oe_n ;//Output enable when low to drive data onto D0-7.
//This should be driven low at least 1 clock period
//before driving RD# low to allow for data buffer turn-around.
wire [00:00] ft_rd_n ;//Enables the current FIFO data byte to be driven onto D0...D7 when RD# goes low.
//The next FIFO data byte (if available) is fetched from the receive FIFO buffer each CLKOUT cycle until RD# goes high.
//---WR: fpga -> usb //Space available
reg [00:00] ft_txe_n ;//When high, do not write data into the FIFO.
//When low, data can be written into the FIFO by driving WR# low.
//When in synchronous mode, data is transferred on every clock that TXE# and WR# are both low.
wire [00:00] ft_wr_n ;//Enables the data byte on the D0...D7 pins to be written into the transmit FIFO buffer when WR# is low.
//The next FIFO data byte is written to the transmit FIFO buffer each CLKOUT cycle until WR# goes high.
//---
wire [00:00] ft_siwu_n ;//Send Immediate / WakeUp signal combines two functions.
//Tied to "1'b1" if not used.
//---DATA: inout
wire [07:00] ft_data ;//D7 to D0 bidirectional FIFO data.
//This bus is normally input unless OE# is low.
//------
reg [07:00] data_gen ;
reg [00:00] data_gen_en ;
//------------------------------------------------------------------clock_reset
//------clock
initial begin
sys_clk = 0 ;
end
always #(PERIOD_100MHz / 2) sys_clk = ~sys_clk ;
/*
initial begin
sys_clk = 0 ;
forever #(PERIOD_100MHz / 2) sys_clk = !sys_clk ;
end
*/
assign ft_clk = sys_clk ;
//------reset
initial begin
sys_rst_n = 1'b0 ;
#1000;
sys_rst_n = 1'b1 ;
end
//------------------------------------------------------------------work
//------
initial begin
//---
ft_rxf_n = 1'b1 ;
ft_txe_n = 1'b1 ;
data_gen_en = 1'b0 ;
#1200;
repeat(10) begin
#100;//usb -> fpga
ft_rxf_n = 1'b0 ;
ft_txe_n = 1'b1 ;
data_gen_en = 1'b1 ;
#100;
ft_rxf_n = 1'b1 ;
ft_txe_n = 1'b1 ;
data_gen_en = 1'b0 ;
#100;//fpga -> usb
ft_rxf_n = 1'b1 ;
ft_txe_n = 1'b0 ;
data_gen_en = 1'b0 ;
#100;
ft_rxf_n = 1'b1 ;
ft_txe_n = 1'b1 ;
data_gen_en = 1'b0 ;
end
//---
#1000 ;
$display("**********************************\n");
$display("//------Simulation_Stop.\n");
$display("//------Stop @ %t ns.\n",$time/1000);
$display("**********************************\n");
$stop();
#1000 ;
$display("**********************************\n");
$display("//------Simulation_Stop.\n");
$display("//------Finish @ %t ns.\n",$time/1000);
$display("**********************************\n");
$finish();
end
//------Monitor
initial begin
//---
#100;
$display("**********************************\n");
$display("//------Dump / Monitor all data.\n");
$display("**********************************\n");
//---
while(1)begin
//forever begin //forever will cause dead-lock.
@(posedge sys_clk)
if(u_top.ft232h_m0.buf_wr)begin
$display("Data usb2fpga is %x.",u_top.ft232h_m0.buf_data);
end
if(u_top.ft232h_m0.buf_rd)begin
$display("Data fpga2usb is %x.",u_top.ft232h_m0.ft_data_out);
end
end
end
//------data_gen
always@(posedge sys_clk)begin
if(data_gen_en == 1'b1)
data_gen = $random ;
end
assign ft_data = (ft_rxf_n == 1'b1)? 8'hz : data_gen ;
//------------------------------------------------------------------
top u_top(
.sys_clk ( ),//input 50MHz NC
.rst_n (sys_rst_n ),//input
.ft_clk (ft_clk ),//input 60MHz
.ft_rxf_n (ft_rxf_n ),//input Data available
.ft_txe_n (ft_txe_n ),//input Space available
.ft_oe_n (ft_oe_n ),//output
.ft_rd_n (ft_rd_n ),//output
.ft_wr_n (ft_wr_n ),//output
.ft_siwu_n (ft_siwu_n ),//output
.ft_data (ft_data ) //inout [07:00]
);
//------------------------------------------------------------------
endmodule
//------Project files
//------end
|