mikrocontroller.net

Forum: FPGA, VHDL & Co. Asynchroner Datenbus an FPGA


Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich hab hier einen kleinen FPGA (LatticeMACHXO) an einem 
Adress/Datenbus. Im FPGA sind eine paar Register die über den Datenbus 
gelesen und beschrieben werden können. Ein gemeinsamer Takt steht nicht 
zur Verfügung. Der Takt des FPGAs ist aber so hoch das ich mindestens 
eine (evtl. mehr) Flanken während der Low-Zeit des WR-Signals habe. Das 
Ganze sieht (vereinfacht) zur Zeit etwa so aus:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;   

entity slave is

port( 
    -- data bus from host
    DATA:   inout std_logic_vector(15 downto 0);  
    ADR:    in std_logic_vector(5 downto 1);
    RD:     in std_logic;
    WR:     in std_logic;
    CS:     in std_logic;
   
    -- system interface
    RST:        in std_logic;   -- Global system reset
    CLK:        in std_logic;   -- 25MHz clock
    
    );
end;

architecture behavior of slave is
    
    -- internal mapping register of direct inputs
    signal gpio_out     : std_logic_vector(15 downto 0);
    
    -- internal spi related register
    signal spi_reg_out  : std_logic_vector(0 to 15);
    
begin
    
    ----------------------------------------------------------------------------
    -- clock synchronous stuff for SPI and data bus connection
    process (CLK, RST, WR)
    begin
        if RST = '0' then        

            spi_reg_out <= (others => '0');
            gpio_out <= (others => '0');
        
        elsif falling_edge(CLK) then
            
            if CS = '0' and WR = '0' then
                
                if ADR = "10000" then          -- write to 16 (spi output)
                    spi_reg_out <= DATA;
                elsif ADR = "10010" then       -- write to 18 (gpio output)
                    gpio_out <= DATA;
                end if;            
            
            elsif cs_int = '1' then
            
                --SPI state machine
                -- some code here
                
            end if;
                    
        end if;
    end process;
    
end behavior;


Leider hab ich damit ab und an (bei rund 1% der Zugriffe) falsche Daten 
im FPGA. Wie macht man sowas den richtig? Ich würde die Daten ja mit der 
steigenden Flanke von WR übernehmen wenn CS = '0'. Aber dann hab ich 
zwei asynchrone Takte im System was die Sache auch nicht wirklich 
vereinfacht. Ich bin leider nicht so der VHDL Experte.

Matthias

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie macht man sowas den richtig?
Der Ansatz passt schon:
1. Schritt: asynchrones Übernehmen der Daten (und der Adresse) in ein 
lokales Pufferregister mit der steigenden Flanke von WR
2. Schritt: Einsynchronisieren von WR und eine synchrone 
Flankenerkennung der steigenden Flanke, dabei die Daten synchron aus dem 
lokalen Pufferregister übernehmen

> Aber dann hab ich zwei asynchrone Takte im System
> was die Sache auch nicht wirklich vereinfacht.
Das ist hier nicht schlimm, denn mit der WR-Signal kann sauber die 
Datenübergabe geregelt werden.

So wie du es machst:
            if CS = '0' and WR = '0' then
                
                if ADR = "10000" then          -- write to 16 (spi output)
                    spi_reg_out <= DATA;
                elsif ADR = "10010" then       -- write to 18 (gpio output)
                    gpio_out <= DATA;
                end if;            
müssen die Adressen bereits bei der fallenden Flanke des WR-Signals 
stabil sein, sonst könnten irgendwelche Daten an die falsche Adresse 
geschrieben werden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.