Forum: FPGA, VHDL & Co. Eine Zahl in Einsen convertieren


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Alex (alex_s88)


Lesenswert?

Hallo Leute,

ich habe folgende Frage. Ich habe ein Signal, dass beispielsweise den 
Wert 4 enthält. Diesen Wert möchte ich in 4 "Einsen" umwandeln. Also 
quasi so: 4 ->"00001111". Ich habe es schon gelöst aber ich würde gerne 
wissen ob es eine elegantere Möglichkeit gibt? Ich zeig euch mal meinen 
Weg:
1
signal data : integer range 0 to DATA_WIDTH*2 := 0;
2
signal valid_bytes : std_logic_vector(DATA_WIDTH/8-1 downto 0) := (others => '0');
3
  ....    
4
for i in 0 to DATA_WIDTH/8-1 loop
5
    if(i < data/8) then
6
        valid_bytes(i)  <= '1';
7
    end if;
8
end loop;
valid_bytes soll hier die Anzahl an "Einsen" bekommen die in data als 
Wert ausgerechnet wurden. data hat immer ein ganzzahliges vielfaches von 
8.
Kann man das ganze evtl ohne schleifen lösen? Also Resourcen sparender?

Danke sehr

Gruß

Alex

von Sebastian R. (sebastian_r569)


Lesenswert?

(2^1)-1 = 0b1
(2^2)-1 = 0b11
(2^3)-1 = 0b111
(2^4)-1 = 0b1111

aber pow() ist intern sicherlich auch eine Schleife.

von Rüdiger B. (rbruns)


Lesenswert?

Geschwindigkeit oder Platz?
8 Byte Array und Index wenn es schnell gehen muss.

von Alex (alex_s88)


Lesenswert?

Sebastian R. schrieb:
> (2^1)-1 = 0b1
> (2^2)-1 = 0b11
> (2^3)-1 = 0b111
> (2^4)-1 = 0b1111
>
> aber pow() ist intern sicherlich auch eine Schleife.

Genau das ist der Zusammenhang den ich zuerst gesucht hatte, danke :)
So hab ich jetzt gelöst.
1
valid_bytes    <= std_logic_vector(to_unsigned(2**(data/8)-1, valid_bytes'length));
Es sieht aber so aus, als ob es genausoviele Resourcen braucht wie meine 
vorherige Lösung. Nichts­des­to­trotz sieht es viel elganter aus :)

Rüdiger B. schrieb:
> Geschwindigkeit oder Platz?
> 8 Byte Array und Index wenn es schnell gehen muss.

Es geht eher um Platz. Mein FPGA ist schon ziemlich voll und ich 
versuche überall wo es nur geht den Code zu optimieren.
Die idee klingt interessant. Ich probiers mal aus danke

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


Lesenswert?

Alex schrieb:
> Kann man das ganze evtl ohne schleifen lösen? Also Resourcen sparender?
Wieso braucht diese Lösung viele Ressourcen? Warum nimmst du an, dass 
eine Schleife viele Ressourcen braucht?

> valid_bytes soll hier die Anzahl an "Einsen" bekommen die in data als
> Wert ausgerechnet wurden.
Ich würde das so machen:
1
process (input) 
2
variable x : std_logic_vector(...);
3
begin
4
     x := (others=>'0'); 
5
     x(to_integer(unsigned(input))) := '1'; 
6
     valid_bytes <= x-1;
7
 end process;

Alex schrieb:
> Mein FPGA ist schon ziemlich voll und ich versuche überall wo es nur
> geht den Code zu optimieren.
Du musst nicht "den Code optimieren", sondern die Logik verkleinern. 
Aber letztlich wird da in jedem Fall irgendwie ein Multiplexer 
herauskommen. Sogar die Lösung mit dem RAM ist im Grunde nur ein 
Multiplexer.

> Es sieht aber so aus, als ob es genausoviele Resourcen braucht wie meine
> vorherige Lösung.
Kann man im Report nachschauen. Wenn man ein kleines Dreizeiler-Projekt 
nur mit diesem Codeschnipsel macht, sieht man das recht deutlich.

: Bearbeitet durch Moderator
von DSGV-Violator (Gast)


Lesenswert?

Alex schrieb:
> Ich habe es schon gelöst aber ich würde gerne
> wissen ob es eine elegantere Möglichkeit gibt?

> Es geht eher um Platz. Mein FPGA ist schon ziemlich voll und ich
> versuche überall wo es nur geht den Code zu optimieren.

> Kann man das ganze evtl ohne schleifen lösen? Also Resourcen sparender?

Komplett falscher Ansatz - eine FPGA-Optimierung über die 
"Schein-Methode "Elegante VHDL-Programmierung" zu versuchen.

Abgesehen davon, das das Verhältnis zwischen "Elegante Programmierung" 
und "Softwareengineering" so etwas das selbe ist wie zwischen 
"Astrologie" und "Astronomie", beginnt jede Optimierung mit eine 
Aufstellung der verfügbaren Ressourcen auf der einen Seite (welcher 
FPGA-Typ, Auslastungsgrad bezogen auf die einzelnenenSubkomponenten 
(M-Slic, L-Slice,BRAM, FF, IO, DSEP48, ..) auf der einen Seite und den 
Anforderungen/Requirements auf der anderen Seite.

Dann überlegt man kurz mit welchen Grundtypen man die Funktion 
relisieren könnte (NAND, MUX,PROM-LUT) und schaut dann, ob die 
Optimierungstools  aktiviert sind und nicht durch hier unnötige 
constraints (bspw. rst am Shiftregister) be-/verhindert werden. (bspw.: 
https://docs.xilinx.com/v/u/en-US/wp275 )

Anschließend beschreibt man die Funktion vollständig und lässt die tools 
die Arbeit machen. Dann schafft ein Quine–McCluskey aus einer dicken 
Wahrheitstabelle eine schnuckelige kleine Realisierung aus wenigen 
LUT's/CarryChain/MUX7F Primitiven.

Und natürlich kann man statt auf die Details, auch aufs "grosse Ganze" 
schauen. Also hat man das PCB passend zu den "package footprint 
migration path" gebaut, kann ma einfach einen größeren Typ draufsetzen.
Oderman taucht u.U. Teile des Designs während der Laufzeit aus (partial 
Reconfiguration). Oder eben "Doing more by doing less", alles weglassen, 
was man nicht braucht.

Es kommt halt darauf an, die FPGA-Technologie zu kennen und zu 
beherrschen; "schönes Coden in Verilog/VHDL/PupsHDL" ist dabei 
nebensächlich.
Wer auf "elegante VHDL-Programmierung" pocht, impliziert eigentlich, das 
er hinsichtlich FPGA-Realität reichlich ahnungslos ist.

--
Ich geh davon aus, das es egal ist, ob die Konvertierung in 10 
nanosekunden oder einer mikrosekunden abgeschlossen ist und deshalb mit 
einer Realisierung als Shiftregister mitLSB-Eingang auf '1' 
(valid-bytes) und Zählersteuerung (data) ansetzen. Aber nur wenn eine 
Alternative zu Beitrag "Re: Eine Zahl in Einsen convertieren" 
nötig ist.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Algorithmus-Vorschlag:

Aufgrund der Vielzahl möglicher ProgSprachen hier nur eine allgemeine 
Beschreibung:

a) erforderliche Anzahl von Einsen aus einem String oder Char-Array 
"herausschneiden"

b) mit gleicher Methodik die führenden Nullen auffüllen

c) fertig

Keine Schleifen, keine "höhere" Mathematik, im Idealfall nur zwei 
Befehle ...

: Bearbeitet durch User
von DSGV-Violator (Gast)


Lesenswert?

Frank E. schrieb:

> b) mit gleicher Methodik die führenden Nullen auffüllen

OMG, noch nie was von 'FF-Reset' gehört, das man denkt hier müsse mensch 
die Tasse mit '0'- oder mit '1'-Kaffee "auffüllen" ...

> c) fertig
>
> Keine Schleifen, keine "höhere" Mathematik, im Idealfall nur zwei
> Befehle ...

Es gibt keine Befhle im FPGA, nicht bevor die nicht an FPGA-Entwickler 
implementiert hat.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

DSGV-Violator schrieb:

> OMG, noch nie was von 'FF-Reset' gehört, das man denkt hier müsse mensch
> die Tasse mit '0'- oder mit '1'-Kaffee "auffüllen" ...

Oh, FPGA - dann hast du natürlich recht, hatte ich nicht gelesen, 
dachte, es geht um C, C++, Java, Basic, Python ...

Hab' den Beitrag über "Forum" allgemein gefunden, nicht die Sparte dazu 
wahrgenommen.

von DSGV-Violator (Gast)


Lesenswert?

Frank E. schrieb:
>> OMG, noch nie was von 'FF-Reset' gehört, das man denkt hier müsse mensch
>> die Tasse mit '0'- oder mit '1'-Kaffee "auffüllen" ...
>
> Oh, FPGA - dann hast du natürlich recht, hatte ich nicht gelesen,
> dachte, es geht um C, C++, Java, Basic, Python ...
>
> Hab' den Beitrag über "Forum" allgemein gefunden, nicht die Sparte dazu
> wahrgenommen.

Ja, da wäre es besser gewesen, der TO hätte die Beweggründe für seine 
Anfrage (Zitat: "Mein FPGA ist schon ziemlich voll ") in den 
Threadtitel, oder wenigstens in seine Eröffnungsbeitrag beschrieben.

Mglw. hat aber auch das Screendesign von Browser und Forum seinen Anteil 
daran, das hier Themengebiete wild verwechselt werden und der Diskurs 
"quer über die Landschaft galoppiert".

--
Vielleicht sollte man die Forumsanmeldung mit einen kleine 
Einführungskurs (durch-click.schulung) aka "Wie erkenne ich, das mein 
Beitrag deppern platziert und scheisse geschrieben ist" verbinden ...

von Val D. (valeri_d)


Lesenswert?

Alex schrieb:
> ein Signal, dass beispielsweise den Wert 4 enthält.
Auch, wenn die Aufgabe noch künstlich und völlig nicht nachvollziehbar 
erscheint, ist eine Schleife um die einz. Bits nötig.

von Gerald K. (geku)


Lesenswert?

1. Eingangswert runterzählen
2. Solange Schieberegister (Ausgangswert) mit '1' "füttern" bis 
Eingangswert Null ist

von DSGV-Violator (Gast)


Lesenswert?

Val D. schrieb:
> Alex schrieb:
>> ein Signal, dass beispielsweise den Wert 4 enthält.
> Auch, wenn die Aufgabe noch künstlich und völlig nicht nachvollziehbar
> erscheint, ist eine Schleife um die einz. Bits nötig.

Nö. Alternativen:
-manualles loop unrolling im behavourial code
-niederschrift als array (LUT)
-niederschrift als condidional signal assignment
-direkte Instanziierung vom Hardware Componenten (i.e. Block-speicher)
...

Wemm das zuviel V-HDL tipperei ist, kann ja auch einen Coregenerator als 
script (tcl, python) schreiben. Und in einem solchen script wird man die 
benutzung von Schleifenkonstrukten nicht vwemeiden wollen.

von Alex (alex_s88)


Lesenswert?

Lothar M. schrieb:
> Alex schrieb:
>> Kann man das ganze evtl ohne schleifen lösen? Also Resourcen sparender?
> Wieso braucht diese Lösung viele Ressourcen? Warum nimmst du an, dass
> eine Schleife viele Ressourcen braucht?

Das weiss ich selber nicht warum ich das denke :D Das ist mir an manchen 
Stellen in der Vergangenheit so aufgefallen, dass Schleifen viel LUT's 
fressen insbesondere wenn man darin noch komplexe if Abfragen hat.

>> valid_bytes soll hier die Anzahl an "Einsen" bekommen die in data als
>> Wert ausgerechnet wurden.
> Ich würde das so machen:
>
1
> process (input)
2
> variable x : std_logic_vector(...);
3
> begin
4
>      x := (others=>'0');
5
>      x(to_integer(unsigned(input))) := '1';
6
>      valid_bytes <= x-1;
7
>  end process;
8
>

Danke für den Lösungsvorschlag. Das ist auch eine interessante Idee.

Danke auch an alle anderen Beiträge.
Ok Sorry, nächstes mal versuche ich die Überschrift besser zu wählen. :)

von -gb- (Gast)


Lesenswert?

Alex schrieb:
> Das weiss ich selber nicht warum ich das denke :D Das ist mir an manchen
> Stellen in der Vergangenheit so aufgefallen, dass Schleifen viel LUT's
> fressen insbesondere wenn man darin noch komplexe if Abfragen hat.

Wenn die Komplexität das hergibt, wird die sich durch die Schleife 
bildende HW eben so umfangreich. Die Verzeigungen sind ja parallel 
implementiert. Wäre die Frage, ob man die Multiplexer restrukturieren 
lassen kann.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Ich würde das so machen:process (input)
> variable x : std_logic_vector(...);
> begin
>      x := (others=>'0');
>      x(to_integer(unsigned(input))) := '1';
>      valid_bytes <= x-1;
>  end process;

Einwandfreie Lösung, 2^n-1

von Gustl B. (-gb-)



Lesenswert?

Damit das Herumgestochere ein Ende hat hier mal ein kleiner Versuch.
Flatten hierarchy und resource sharing habe ich ausgeschaltet.

Ja ... ist in etwa sehr identisch (-:

Edith hat G_DATA_WIDTH mal auf 256 gesetzt und siehe da, jetzt bekommt 
man ein leicht anderes Bild.

: Bearbeitet durch User
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.