Forum: FPGA, VHDL & Co. Schieberegister - ich blicke nicht mehr durch


von Andreas B. (loopy83)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe ein hoffentlich triviales Problem, aber ich durchblicke es 
einfach nicht. Wie sagt man so schön, ich sehe den Wald vor lauter 
Nullen und Einsen nicht mehr :)

Es geht um ein einfaches 4bit Schieberegister, in das serielle Daten 
geladen werden. Wenn 4bit neue Daten geladen wurden, wird ein Signal 
"full" auf 1 gesetzt und die 4bit neuen Daten werden an den Ausgang 
gelegt.

Hier ist der Code dazu:
1
SR_4bit: process (CLOCK_SR)
2
begin
3
 if rising_edge(CLOCK_SR) then  
4
  if (RESET_SR = '1')
5
  then   AUSGANG <= (others => '0');
6
  COUNT_INT <= 0;
7
  else
8
  AUSGANG(0) <= DATA_IN_SR;
9
  AUSGANG(1) <= AUSGANG(0);
10
  AUSGANG(2) <= AUSGANG(1);
11
  AUSGANG(3) <= AUSGANG(2);
12
  if (COUNT_INT < 3)
13
  then   COUNT_INT <= COUNT_INT + 1;
14
    FULL_INT <= '0';
15
    DATA_OUT_SR <= "0000";
16
  elsif (COUNT_INT = 3) then
17
    COUNT_INT <= 0;
18
    FULL_INT <= '1';
19
    DATA_OUT_SR <= AUSGANG;
20
  end if;
21
 end if;
22
end if;  
23
end process SR_4bit;

Im Anhang habe ich die Simulation dazu angehängt.

Ich verstehe nicht, wieso nach dem vierten Takt am Ausgang (data_out_sr) 
quasi der vorletzte Schritt anliegt und nicht die 4 neuen bits.

Ich schifte doch alles noch einmal um ein Bit nach links. Da wird dann 
ebenfalls der Counter auf 3 abgefragt und die Ausgangsdaten an den 
Ausgang gelegt. Wieso braucht es einen Takt mehr, um die Daten an den 
Ausgang zu legen?

Wie könnte ich das Problem lösen?
Ich möchte quasi 4 neue Bits laden und diese dann ausgaben. Das Full 
Signal dient als Schreibtakt eines Fifos, in das natürlich nur neue 
Daten geschrieben werden sollen.

Ich hoffe es gibt eine Lösung für das Problemchen.

Den Counter einfach von 3 auf 4 setzen und abfragen geht leider nicht, 
da im 5. Takt schon wieder neue Daten anliegen, die gespeichert werden 
sollen... ich habe also wirklich nur 4 Takte zum parallelisieren und 
ausgeben.

DANKE!!

MfG Andi

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


Lesenswert?

Dein Stichwort heißt Latency...

Das SR AUSGANG wird zwar weitergeschoben, aber erst am Ende des 
Prozesses aktualisiert. Du könntest also genauso gut schreiben:
1
SR_4bit: process (CLOCK_SR)
2
begin
3
  if rising_edge(CLOCK_SR) then  
4
    if (RESET_SR = '1')then  
5
      AUSGANG <= (others => '0');
6
      COUNT_INT <= 0;
7
    else
8
      if (COUNT_INT < 3) then   
9
        COUNT_INT <= COUNT_INT + 1;
10
        FULL_INT <= '0';
11
        DATA_OUT_SR <= "0000";
12
      elsif (COUNT_INT = 3) then
13
        COUNT_INT <= 0;
14
        FULL_INT <= '1';
15
        DATA_OUT_SR <= AUSGANG;
16
      end if;
17
      AUSGANG(0) <= DATA_IN_SR;  --> BTW: das hier geht kürzer so: AUSGANG <= AUSGANG(2 downto 0) & DATA_IN_SR;
18
      AUSGANG(1) <= AUSGANG(0);  --
19
      AUSGANG(2) <= AUSGANG(1);  --
20
      AUSGANG(3) <= AUSGANG(2);  --
21
    end if;
22
  end if;  
23
end process SR_4bit;
Ist dir dieser Sachverhalt bekannt?
Das ist der Unterschied zwischen Variablen und Signalen...

So ginge es:
1
SR_4bit: process (CLOCK_SR)
2
variable ausgsr : std_logic_vector(3 downto 0);
3
begin
4
  ausgsr := AUSGANG;  -- Defaultzuweisung, sonst gibts ein Latch   :-o
5
  if rising_edge(CLOCK_SR) then  
6
    if (RESET_SR = '1')then  
7
      AUSGANG <= (others => '0');
8
      COUNT_INT <= 0;
9
    else
10
      ausgsr := ausgsr(2 downto 0) & DATA_IN_SR; -- wird sofort zugewiesen
11
      if (COUNT_INT < 3) then   
12
        COUNT_INT <= COUNT_INT + 1;
13
        FULL_INT <= '0';
14
        DATA_OUT_SR <= "0000";
15
      elsif (COUNT_INT = 3) then
16
        COUNT_INT <= 0;
17
        FULL_INT <= '1';
18
        DATA_OUT_SR <= ausgsr;   -- den aktuellen Wert zuweisen
19
      end if;
20
      AUSGANG <= ausgsr;         -- Wert in Signal merken
21
    end if;
22
  end if;  
23
end process SR_4bit;

von mki (Gast)


Lesenswert?

Ich glaub du vergisst das du mit a<=b eine nichtblockierende Zzuweisung 
hast. Das Ergebnis wird erst am Ende des Taktes zugewiesen und liegt den 
ganzen nächsten Takt an. Aber Wichtig ist doch nur dass das ready Signal 
dann anliegt wenn gültige Daten da sind - und das tut es ja wohl. So 
würde ich mir um diesen einen Takt Phasenverschiebung keine großen 
Gedanken machen.

von Andreas B. (loopy83)


Lesenswert?

Hallo,

ich habe es jetzt ein wenig anders gelöst.
Aber vorweg, der Unterschied zwischen signal und variable war mir nicht 
bekannt. Habe bisher immer nur mit signalen gearbeitet... wieder etwas 
dazu gelernt.

Hier meine Lösung:

Ich nehme quasi nur ein 3bit Schieberegister und hänge dann im 4. Takt 
einfach den aktuellen Wert von Data-in als 4bit hinten an.
Laut Simulation funktioniert es wunderbar.
1
SR_4bit: process (CLOCK_SR)
2
begin
3
if rising_edge(CLOCK_SR) then  
4
  if (RESET_SR = '1')
5
  then   AUSGANG <= (others => '0');
6
        COUNT_INT <= 0;
7
  else
8
  AUSGANG(0) <= DATA_IN_SR;
9
  AUSGANG(1) <= AUSGANG(0);
10
  AUSGANG(2) <= AUSGANG(1);
11
  if (COUNT_INT < 3)
12
  then   COUNT_INT <= COUNT_INT + 1;
13
    FULL_INT <= '0';
14
    DATA_OUT_SR <= "0000";
15
  elsif (COUNT_INT = 3) then
16
    COUNT_INT <= 0;
17
    FULL_INT <= '1';
18
    DATA_OUT_SR <= AUSGANG & DATA_IN_SR;
19
  end if;
20
  end if;
21
end if;  
22
end process SR_4bit;

DANKE für Eure Hilfe!

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.