Forum: FPGA, VHDL & Co. State Machine mit warte-state


von Andreas B. (loopy83)


Lesenswert?

Hallo zusammen,

ich möchte gerne mit einem parallelen Bus vom FPGA lesen können. Der 
Busmaster setzt seine Signale wie Chipselect und output-en auf '0' und 
wenn die Lesebedingung erfüllt ist, lege ich mit jeder Taktflanke Daten 
auf den Bus.

Nun habe ich das Problem, dass scheinbar bei jedem Lesezugriff, wo die 
Lesebedingung erfüllt ist, zwei Taktflanken enthalten sind, obwohl nur 
ein Wert gelesen wird. Der Master bekommt also nur jeden zweiten Wert 
mit.

Als Lösung habe ich mir eine Statemachine gebaut, die bei der ersten 
Flanke die Daten auf den Bus legen soll und dann in einen Warte-state 
springt und dort auf CS = '1' abfragt. Denn dann ist der Lesezugriff 
vorbei. Somit würde nur ein Wert gelesen und auch nur ein Wert auf den 
Bus gelegt.

Nun scheint das aber noch nicht so ganz zu funktionieren, es werden 
weiterhin zwei Werte auf den Bus gelegt, aber nur einer gelesen.

Habe ich alles richtig beschrieben?
1
  process (PClk)
2
  begin
3
    if rising_edge(PClk) then
4
      if reset = '0' then
5
        per_state <= LESEN;
6
      else
7
        case per_state is
8
          -- LESEN
9
          when LESEN =>
10
            if (PCS1 = '0' and POEn = '0' and PRnW = '1' and EMPTY_FIFO_A ='0' and EMPTY_FIFO_B ='0') then
11
              if PADD(22) ='0' then
12
                RD_EN_A <= '1';
13
                PDATA <= PDATA_A;
14
                per_state <= WARTE;
15
              else
16
                RD_EN_B <= '1';
17
                PDATA <= PDATA_B;
18
                per_state <= WARTE;
19
              end if;
20
            else
21
              RD_EN_A <= '0';
22
              RD_EN_B <= '0';
23
              PDATA <= (others => 'Z');
24
            end if;
25
          -- WARTE
26
          when WARTE =>
27
            if (PCS1 = '0' and POEn = '0' and PRnW = '1') then
28
              RD_EN_A <= '0';
29
              RD_EN_B <= '0';
30
              PDATA <= (others => 'Z');
31
              per_state <= LESEN;
32
            end if;
33
        end case;
34
      end if;
35
    end if;
36
  end process;

Wie ich es aktuell gemacht habe ist, dass bei der ersten Flanke die 
Daten auf den Bus gelegt werden (entweder aus Fifo A oder B) und bei der 
zweiten Flanke dann die daten HighZ gelegt werden. Aber bei der dritten 
Flanke würden dann wieder Daten auf den Bus gelegt werden. Wie kann ich 
beschreiben, dass nur die erste Flanke berücksichtigt wird und dann erst 
der LESEN state wieder angesprungen wird, wenn CS = '1' geht?

Vielen Dank!
Andi

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Indem du im Zustand WARTE auch wirklich wartest. derzeit machst du 
eigentlich das selbe wie in LESEN...
1
          when WARTE =>
2
            RD_EN_A <= '0';
3
            RD_EN_B <= '0';
4
            PDATA <= (others => 'Z');
5
            if (PCS1 = '1') then -- deselektiert -> bereit für nächsten Lesezugriff
6
              per_state <= LESEN;
7
            end if;
Die anderen Signale POEn und PRnW solltest du dir in dem Zusammenhang 
auch mal anschauen: sind die beim Warten nötig?

von Andreas B. (loopy83)


Lesenswert?

Mhm... klingt logisch... scheinbar zu logisch um selber darauf zu 
kommen.
Ich werde es gleich mal austesten.

Zum wiederholten Male... Vielen Vielen Dank Lothar!

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.