Forum: FPGA, VHDL & Co. RAM Inhalt sortieren


von Spartan (Gast)


Lesenswert?

Hallo zusammen,

ich schreibe an einem Algorithmus, der den Inhalt eines Dual-Port-RAM 
von klein nach groß sortieren soll. Dabei versuche ich mich am Bubble 
Sort Algorithmus. Die Beispiele von Lothar Miller habe ich mir bereits 
angesehen.

Wenn man ein Array zur Verfügung hat, ist das Vertauschen der Positionen 
kein Problem.

Nur wie wende ich sowas:
1
if din(i) > din(i+1) then
2
  temp     := din(i);   -- Dreieckstausch
3
  din(i)   <= din(i+1);
4
  din(i+1) <= temp;
5
end if;
auf ein RAM an?

Weiß Jemand, wo man da Beispiele findet?
Bei Google war ich bisher nur wenig erfolgreich.

Viele Grüße

von Duke Scarring (Gast)


Lesenswert?

Spartan schrieb:
> Nur wie wende ich sowas:if din(i) > din(i+1) then
>   temp     := din(i);   -- Dreieckstausch
>   din(i)   <= din(i+1);
>   din(i+1) <= temp;
> end if;
> auf ein RAM an?
Da braucht man eine State Machine (FSM).
Für einen Dualport-RAM, muß die dann ungefähr sowas machen:
1
state_read  => Port A: Wert A lesen,     Port B: Wert B lesen
2
state_write => Port A: Wert B schreiben, Port B: Wert A schreiben

Duke

von Spartan (Gast)


Lesenswert?

Hallo,

zunächst ein mal vielen Dank für den hilfreichen Tipp! Ich habe mich 
gleich daran gemacht und habe eine FSM geschrieben:
1
-------------------------------------------------------------------
2
--State Machine
3
-------------------------------------------------------------------
4
process (clk,reset) is
5
begin
6
  if (reset='1') then
7
    addra <= (others => '0');
8
    state <= stat_READ;  
9
  elsif rising_edge(clk) then
10
    case state is
11
    
12
    --CASE: IDLE
13
    when stat_READ =>   
14
    addra <= addra + 1;
15
    
16
    if(value1 > value2) then
17
      state <= stat_WRITE;
18
    else
19
      state <= stat_READ;
20
    end if;
21
                    
22
    --CASE: WRITE_DPRAM  
23
    when stat_WRITE =>
24
    addra <= addra;
25
    
26
    -- Dreieckstausch, aber wie?
27
    
28
    if(value1 > value2) then
29
      state <= stat_WRITE;
30
    else
31
      state <= stat_READ;
32
    end if;
33
      
34
    --CASE: OTHERS
35
    when others =>
36
        addra <= (others => '0');
37
        state <= stat_READ;        
38
    end case;
39
  end if;
40
end process;


Fragen:
- Macht es Sinn den Adresszähler jedes Mal anzuhalten, wenn zwei Werte 
vertauscht werden müssen?

- Wie führen ich den Tausch durch, also wie erreiche ich das sequentiell 
zunächst an die eine und danach an die andere Adresse geschrieben wird?

Da stehe ich total auf dem Schlauch ... :-(

von Falk B. (falk)


Lesenswert?

@ Spartan (Gast)

>zunächst ein mal vielen Dank für den hilfreichen Tipp! Ich habe mich
>gleich daran gemacht und habe eine FSM geschrieben:

Deine Einrückung ist schlecht, man sieht die einzelnen States nicht gut.

>- Macht es Sinn den Adresszähler jedes Mal anzuhalten, wenn zwei Werte
>vertauscht werden müssen?

Sinn wird nicht gemacht. Er ist da oder auch nicht.
Wie lautet deine Antwort auf die Frage und warum?

>- Wie führen ich den Tausch durch, also wie erreiche ich das sequentiell
>zunächst an die eine und danach an die andere Adresse geschrieben wird?

Du musst die Datensätze in zwei Registern zwischenspeichern (sie werden 
sowieso gelesen), dann vertauscht in den RAM zurück schreiben.

von Spartan (Gast)


Lesenswert?

Sorry,

wer lesen kann ist klar im Vorteil! Man nutzt beide Ports zum lesen und 
zum schreiben.

Ich wollte die Ganze Zeit einen Lese und einen Schreibport haben, das 
ist natürlich Quatsch.

Super, vielen vielen Dank für den genialen Tipp!!

von Falk B. (falk)


Lesenswert?

@ Spartan (Gast)

>wer lesen kann ist klar im Vorteil! Man nutzt beide Ports zum lesen und
>zum schreiben.

Kann man machen, für die reine Übung ist das auch OK. Aber in einer 
REALEN Anwendung müssen die Daten ja auch anderweitig in den RAM 
geschrieben/gelesen werden. Dann ist es meist besser, einen PORT für den 
Normalzugriff zu lassen und einen für den Sortiervorgang.

>Ich wollte die Ganze Zeit einen Lese und einen Schreibport haben, das
>ist natürlich Quatsch.

Nö, das ist auch möglich und sinnvoll.

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


Lesenswert?

Falk Brunner schrieb:
> Sinn wird nicht gemacht.
Aber Unsinn und Blödsinn kann man machen? Skurrile Welt... :-/

Das mit dem Dreickstausch und dem Problem mit dem "Daten hineinbekommen" 
hatte ich schon mal woanders erwähnt:
Beitrag "RAM basierter Bubble Sort in VHDL"

: Bearbeitet durch Moderator
von Spartan (Gast)


Lesenswert?

Hallo zusammen,

in dem verlinkten Beitrag wird zwar keine FSM benutzt, aber die Idee ist 
sehr ähnlich zu meiner.

Ich lese Port A des RAMs seriell aus (geht ja auch nicht anders) und 
schreibe den Wert (n) und (n+1) jeweils in ein Register.

Die beiden Register vergleiche ich miteinander. Je nach Ergebniss muss 
ich die Werte vertauschen oder eben nicht.

Bis hierhin ist das kein Problem.

Sind die Werte vertauscht schreibe ich Sie über Port B wieder zurück. 
Und genau hier liegt das Problem.

Ich benötige einen Takt zum vergleichen und einen weiteren zum zurück 
schreiben. Danach ist mein Adresszähler bei Port A scon bei (n+3). Das 
ist alles nur kein Bubble was ich da betreibe.

Ich möchte einen Prozess, der wie ein Uhrwerk durchläuft, wie löst man 
das am Besten?

Da denkt man immer sortieren ist sooo einfach :-D

Grüße,
Spartan

von Falk B. (falk)


Lesenswert?

@ Spartan (Gast)

>Ich benötige einen Takt zum vergleichen und einen weiteren zum zurück
>schreiben.

Nicht unbedingt, das kann man ggf. in EINEM Takt machen. Das hat aber 
den Nachteil, dass die Logiktiefe größer wird und dadurch die maximal 
erreichbare Taktrequenz sinkt.

> Danach ist mein Adresszähler bei Port A scon bei (n+3). Das
>ist alles nur kein Bubble was ich da betreibe.

Genau.

>Ich möchte einen Prozess, der wie ein Uhrwerk durchläuft, wie löst man
>das am Besten?

Mit einer FSM. Im Falle der Vertauschung muss der Zähler zurück 
springen.

von MJF (Gast)


Lesenswert?

Hallo,

eine kleine Idee, wie es vielleicht schneller geht. Die beiden 
benachbarten Adressen immer lesen und schreiben. Die gelesenen Werte 
tauschen oder nicht tauschen und beide zurückschreiben. Durch die Latenz 
"verschieben" sich die Daten im Speicher, dies kann aber wieder 
rückgerechnet werden. Da die Lese-Adresse immer um eins weitergeht, muss 
einer der gelesenen Werte nicht aus dem Speicher genommen werden, 
sondern von der vorhergehenden Vergleichsoperation abgeleitet werden.

Ist spät (Schlaflosigkeit), aber ich glaube es geht.

Gruß

Markus

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.