Forum: FPGA, VHDL & Co. FT2232H und riesen Slack


von Marcel D. (diablokiller999)


Angehängte Dateien:

Lesenswert?

Hi Leutz!
Ich versuche momentan ein Interface für den FTDI 2232H auf meinem FPGA 
zu implementieren. Jedoch funktioniert die Verbindung je nach Kompilat 
nur manchmal, häufig nicht und auch die Verbindung bricht immer wieder 
ab. Wie sich zeigt, habe ich wohl ordentliche Laufzeitprobleme, als 
Neuling aber nicht viel Ahnung davon, wie ich diese beseitigen kann. Ich 
weiß, dass ich gewisse Pfade im SDC-File per Constraints anpassen kann, 
jedoch finde ich kaum Literatur dafür.

Laut Simulation sollte meine Implementierung funktionieren(?), ich habe 
den Read und Write Fall in zwei Prozesse unterteilt, wobei der Read die 
Priorität genießt und sich beide gegenseitig von der Verwendung des 
Datenbusses ausschließen. Wie man in Signaltap sieht, wird mein A4 einen 
Takt zu spät auf den Datenbus gelegt (der Preload sollte es, wie in der 
Simulation, einen Takt vor dem LOW der oWR-Leitung anlegen) und das 
letzte Datenwort kommt erst nach dem HIGH auf oWR auf der Datenleitung 
an. Beim Lesen habe ich ein ähnliches Problem.
1
Write_USB:  process(iUSB_clk)
2
    begin
3
        if(falling_edge(iUSB_clk)) then
4
            if(ireset_n = '0') then
5
                oWR         <= '1';
6
                oTXRead     <= '0';
7
                nTXRun      <= '0';
8
                Datainout   <= (others => 'Z');
9
                stateTX     <= idle; 
10
                nTXE_Int    <=  '0';
11
            else
12
                case stateTX is
13
                    when idle =>
14
                        Datainout   <= (others => 'Z');
15
                        nTXRun      <= '0'; --  Release interface for RX
16
                        oWR         <= '1'; --  Set Write enable to high
17
                        oTXRead     <= '0'; --  Stop reading from FIFO
18
                        if(iTXEmpty = '0' AND iTXE = '0' AND iRXF = '1' AND nRXRun = '0') then  --  If TX Data available, TX to USB possible,no Read data available and RX not running
19
                            Datainout   <= iTXData; --  Send Data to bus 
20
                            nTXRun      <= '1'; --  Allocate USB Interface by blocking out RX
21
                           stateTX     <= prepare_data; --  Change state
22
                        end if;
23
                    
24
                    when prepare_data =>
25
                        oWR             <= '0';
26
                        oTXRead         <= '1'; --  Send Read Acknowledge to FIFO
27
                        stateTX         <= write_to_USB; --  Change state
28
                    when write_to_USB =>
29
                        if(iRXF = '0' AND iTXEmpty = '0') then --  If Read data available AND TX FIFO not empty
30
                            stateTX     <= idle; --  Change state back to idle
31
                            -- oTXRead     <= '0'; --  Stop reading from FIFO
32
                            Datainout   <= iTXData; --  Send out last Byte to USB
33
                        end if;
34
                        if((iTXE = '1' OR iTXEmpty = '1') OR --  If TX not possible OR TX FIFO is empty 
35
                             (iTXEmpty = '1' AND iRXF = '0')) then --  OR Read Data available AND TX FIFO empty simultaneous
36
                            stateTX     <= idle; --  Change state to idle
37
                            oTXRead     <= '0'; --  Stop writing Read Acknowledge to FIFO
38
                            oWR         <= '1'; --  Set Write enable to high
39
                            Datainout   <= (others => 'Z'); --  Set Output to high impedence
40
                        end if;
41
                        if(iTXE = '0' AND iTXEmpty = '0' AND iRXF = '1') then --  If TX available and TX FIFO not empty and no Data to receive
42
                            Datainout   <= iTXData; --  Send Data to Bus
43
                            oTXRead     <= '1'; --  Send Read Acknowledge to FIFO
44
                            oWR         <= '0'; --  Pull down Write Enable
45
                            stateTX     <= write_to_USB; --  Stay in state
46
                        end if;
47
                   when others =>
48
                        stateTX <= idle;
49
               end case;
50
            end if;
51
        end if;
52
end process;
Hier mal exemplarisch der Write-Fall.
Hat einer 'ne Idee, wie ich die Daten constrainen muss und/oder einen 
guten Link an der Hand, mit dem ich mich ein bisschen belesen kann?

von Markus F. (mfro)


Lesenswert?

Marcel D. schrieb:
> oder einen
> guten Link an der Hand, mit dem ich mich ein bisschen belesen kann

http://www.alterawiki.com/wiki/TimeQuest_User_Guide

Da steht vermutlich mehr drin, als Du wissen willst.

von Gustl B. (-gb-)


Lesenswert?

Hallo, ich verwende einen FT232H aber nur schreibend, also die Daten 
gehen vom FPGA zum PC. Die Daten kommen im FPGA aus einem 
Dual-Clock-FIFO, und werden aus diesem FIFO mit der 60MHz Clock "CLKOUT" 
gelesen. Das ist die Clock vom FT232H.
fifo_rd, fifo_empty sind die Signale zum/vom FIFO. Die Daten zum FT232H 
sind direkt mit dem Ausgang des FIFO (im FPGA) verbunden.
1
WR <= '0' when (TXE = '0' and fifo_rd_buff = '1') or (TXE = '0' and fail = '1') else '1';
2
fifo_rd <= '1' when TXE = '0' and fifo_empty = '0' else '0';
3
process 
4
  begin   
5
  wait until rising_edge(CLKOUT);
6
  fifo_rd_buff <= fifo_rd;
7
  TXE_buff <= TXE;
8
  fifo_empty_buff <= fifo_empty;
9
  if TXE = '0' then
10
    fail <= '0';
11
  end if;
12
  if fifo_empty_buff = '0' and TXE = '1' and TXE_buff = '0' then
13
    fail <= '1';
14
  end if;
15
end process;
1
fifo0: fifo_generator_0 PORT MAP(
2
    wr_clk => CLK100, --100MHz
3
    rd_clk => CLKOUT,--60MHz
4
    din => fifo_din,
5
    wr_en => fifo_wr,
6
    rd_en => fifo_rd,
7
    dout => D, --geht direkt zum FT232H
8
    full => fifo_full,
9
    empty => fifo_empty);

Das funktioniert super bis knapp 40MBytes/s dauerhaft. Der FIFO im FPGA 
sollte mindestens 64kBytes groß sein um abzufangen wenn der PC mal 
gerade nicht lesen will.

Hier 
http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdf 
Seite 41. Ich bin damals nur mit taktsynchronen Signalen nicht 
ausgekommen (zwar fast meistens, aber nicht immer, manchmal gab es 
Fehler) so dass ich ein paar Dinge ausserhalb des getakteten Process 
geschrieben habe.

: Bearbeitet durch User
von Marcel D. (diablokiller999)


Lesenswert?

Danke für den Codeschnippsel!
Ich habe das ganze Design jetzt mal quasi asynchron aufgezogen, mal 
schauen ob das funktioniert (laut Simulation sollte es das). Werde dann 
in etwa 2 Stunden berichten können, so lange dauert der Kompiliervorgang 
leider. Eventuell kann ja jemand nochmal über die Richtigkeit der 
Implementierung drüber schauen, damit meine eigene Dummheit wenigstens 
ausgeschlossen werden kann ;)
1
entity FT2232h_V3_0 is
2
  port
3
    (
4
      iUSB_clk  : in        std_logic;                      --  60 MHz FT232H clock
5
      ireset_n  : in        std_logic;
6
      iTXE      : in        std_logic;                      --  TX allowed (Active low)
7
      iRXF      : in        std_logic;                      --  RX Data available (Active low)
8
      oRD       : out       std_logic;                      --  Read signal (Active low)
9
      oSIWU     : out       std_logic;                      --  Send Immediate / WakeUp
10
      oOE       : out       std_logic;                      --  Output enable (Active low)
11
      oWR       : out       std_logic;                      --  FIFO Buffer Write Enable (Active low)
12
      Datainout : inout     std_logic_vector(7 downto 0);   --  Bidirectional FIFO data 
13
      ---------------------------------------------------
14
      iTXData   : in        std_logic_vector(7 downto 0);   --  Input for Transmit Data from FIFO
15
      oTXRead   : out       std_logic;                      --  Acknowledge for read data
16
      iTXEmpty  : in        std_logic;                      --  Flag for empty TX FIFO
17
      ---------------------------------------------------
18
      oRXWrite  : out       std_logic;                      --  Write signal for RX FIFO
19
      oRXData   : out       std_logic_vector(7 downto 0);   --  Output Data for RX FIFO
20
      iRXFull   : in        std_logic                       --  Flag for full RX FIFO
21
      
22
      );
23
end entity;
24
25
architecture behaviour of FT2232h_V3_0 is
26
  type RX_TYPE is (idle, pull_rd, read_from_USB);
27
  signal stateRX    :   RX_TYPE := idle; 
28
  signal nRXRun     :   std_logic := '0';
29
  signal nTXRun     :   std_logic := '0';
30
begin
31
    Read_USB:  process(iUSB_clk)
32
    begin
33
        if(falling_edge(iUSB_clk)) then
34
            if(ireset_n = '0') then
35
                stateRX     <= idle;
36
            else
37
                case stateRX is
38
                    when idle =>
39
                        if(iRXFull = '0' AND iRXF = '0' AND nTXRun = '0') then --  If RX FIFO not full, RX Data available and TX not running
40
                            stateRX             <= pull_rd; --  Change state
41
                        end if;
42
                    when pull_rd =>
43
                            stateRX         <= read_from_USB;
44
                    when read_from_USB =>
45
                        if(iRXF = '0' AND iRXFull = '0') then --  When Data available on USB
46
                            stateRX         <= read_from_USB; --  Stay in state
47
                        end if;
48
                        if(iRXFull = '1' OR iRXF = '1') then --  If RX FIFO is full or USB RX is empty
49
                            stateRX         <= idle; --  Change back to state 0
50
                        end if;
51
                    when others =>
52
                        stateRX         <= idle;
53
                end case;
54
            end if;
55
        end if;
56
  
57
    end process;
58
oSIWU       <= '1';
59
oWR         <= '0' when (iTXEmpty = '0' AND iTXE = '0' AND iRXF = '1' AND nRXRun = '0' AND oOE = '1') else '1';
60
oOE         <= '0' when (stateRX /= idle) else '1';
61
oRD         <= '0' when (stateRX = read_from_USB) else '1';
62
oTXRead     <= '1' when (iTXEmpty = '0' AND iTXE = '0' AND iRXF = '1' AND nRXRun = '0') else '0';
63
Datainout   <= (others => 'Z') when (iRXF = '0') else iTXData;
64
nTXRun      <= '1' when (iTXEmpty = '0' AND iTXE = '0' AND iRXF = '1' AND nRXRun = '0') else '0';
65
nRXRun      <= '1' when (iRXFull = '0' AND iRXF = '0' AND nTXRun = '0') else '0';
66
oRXData     <= Datainout when (iRXFull = '0' AND iRXF = '0' AND nTXRun = '0') else (others => '0');
67
oRXWrite    <= '1' when (stateRX = read_from_USB) else '0';
68
end behaviour;

von Gustl B. (-gb-)


Lesenswert?

Marcel D. schrieb:
> Werde dann
> in etwa 2 Stunden berichten können, so lange dauert der Kompiliervorgang
> leider.

Ähm ... wieso testest Du das nicht einzeln? Also nur die Anbindung zum 
FT2232H und generierst dazu im FPGA irgendwelche Dummydaten die Du am PC 
leicht überprüfen kannst, z. B. kann man gut einen Zähler verwenden und 
dann gucken ob wirklich alle Zählerwerte in richtiger Reihenfolge am PC 
ankommen.

von Marcel D. (diablokiller999)


Lesenswert?

Weil das Devkit anderweitig in Benutzung ist und ich das auf fertiger 
Hardware testen muss, habe zwar Dinge aus dem Projekt entfernt aber 
leider ist die compile time noch immer gut 2 Stunden für den Arria :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.