Rechnen mit unsigned vs. signed und einer division

OP #2811768
Lesenswert?

Hallo,
irgendwie steh ich auf dem Schlauch. Ich kriege von einem bipolaren AD 
zwei 12 Bit Werte, welche ich mir als zweierkomplement oder als straight 
binary (0 bis 4095) ausgeben kann. Diese liegen mir dann als 
std_logic_vector vor, welche ich dann entsprechend in signed oder 
unsigned casten kann oder muss ich noch was beachten?

zweierkomplement wäre ja signed und straight binary unsigned oder?

Mach ich das am besten mit den Werten als Zweierkomplement oder mit dem 
straight binary?

Später muss ich das Ergebnis dividieren, so das der Quotient  immer 
zwischen -1 und 1 liegt. Dafür wollt ich den IP-Core von Lothar Miller 
verwenden.

http://www.lothar-miller.de/s9y/archives/29-Division-in-VHDL.html

oder hat da jemand eine andere Idee, weil mein Quotient ja nicht größer 
als 1 wird?!

Danke für eure hilfe :-)
Moderator (Firma: Titel) Persönliche Seite #2811851
Lesenswert?

Marc K. schrieb:
> Mach ich das am besten mit den Werten als Zweierkomplement
Eher ja. Denn sonst hast du nur positive Werte und musst selber noch den 
Offset abziehen...

> Später muss ich das Ergebnis dividieren, so das der Quotient  immer
> zwischen -1 und 1 liegt.
Wie willst du denn diesen Zahlenbereich darstellen?

> oder hat da jemand eine andere Idee, weil mein Quotient ja nicht größer
> als 1 wird?!
Denk dir einfach das Komma vor das MSB.
Dann hast du eine Zahl von -1...+0.999, und das ganz ohne Rechnen...
:-o
OP #2811896
Lesenswert?

ok vielen dank. Ich werde es mit dem Zweierkomplement machen :-)

Lothar Miller schrieb:
> Wie willst du denn diesen Zahlenbereich darstellen?

Das hab ich mich auch gefragt. Ich weiß noch nicht so recht wie ich das 
realisieren soll.


Lothar Miller schrieb:
> Denk dir einfach das Komma vor das MSB.
>
> Dann hast du eine Zahl von -1...+0.999, und das ganz ohne Rechnen...
>
> :-o

Ich muss die Divison aber durchführen, der Divisor ändert sich immer so 
das halt keine größere Zahl als 1 rauskommt. Mich interessiert 
eigentlich nur das vorzeichen und paar Nachkommastellen.
Moderator (Firma: Titel) Persönliche Seite #2811963
Lesenswert?

Marc K. schrieb:
> Ich muss die Divison aber durchführen,
Warum?

> keine größere Zahl als 1 rauskommt.
Nach wie vor die Frage: wie willst du mit Integerzahlen eine Zahl 
kleiner 1 darstellen?
Weiterhin meine Antwort: denk dir einfach ein "Null Komma" vor die 12 
Bit. Dann hat das führende Bit (links) die Wertigkeit 1/2, das nächste 
1/4, dann 1/8, 1/16, usw. Je weiter du nach rechts kommst, umso weniger 
ist ein Bit wert. Genau so, wie du es von gewöhnlichen Integerzahlen 
gewöhnt bist.

So wird das bei Signalprozessoren, die mit Festkommazahlen rechnen, auch 
gern gemacht. Und dafür gibt es massenweise Literatur.
OP #2812311
Lesenswert?

Lothar Miller schrieb:
> Marc K. schrieb:
>
>> Ich muss die Divison aber durchführen,
>
> Warum?

Da sich mein Dividend und Divisor unabhängig ändert. Ich jedoch weiß das 
nur der bereich (-1 bis 1) rauskommen kann. Sonst ist ein fehler im AD 
Wert. Ich weiß auch das dies mit Integer nicht möglich ist...

ich werd mich erstmal einlesen und vermutlich löst sich das Problem. ich 
dachte nur vielleicht gehts auch ganz einfach :-)

vielen dank für die antwort :-)
Gast #2817625
Lesenswert?

Du hast doch für beide einen Skalierungsfaktor drin. Z.B. wird die 1 
immer als 32768 dargstellt. Das betrifft dann Zähler und Nenner. 
Rauskommen "tut" dann bei einer Division (egal ob mit core oder manuell) 
immer einen Bitfolge, die du nur zu interpretieren brauchst. Also: Bit 
einsammeln und für jeden shift nach links, den Du zusätzlich machst, 
musst du hinterher einen "weginterpretieren".

Bei einem core kannst Du so teilen, dass vorne die 1 rauskommt und dann 
sofort den Rest weiterverarbeiten, indem du nochmal teilst. Oder, Du 
multiplizierst = schiebst den Zähler so weit nach links, dass Du genug 
Stellen rausbekommst.

Beispiel:

Zählerwert = Z, Nennerwert = N, mit -N < Z < +N;

Digitale Darstellung:

ZD = 32768 x Z =  -32768*Z < ZD < 32767*Z

Wenn Z aus z.B: einem ADC stammt und selber schon 15 Bit hat, hast du 
eben rund 30Bit+Signum. Dann könntest Du reduzieren.

Gehen wir also davon aus, dass wir 31 Bit im Zähler haben und 31 im 
Nenner.

Du rechnest dann einfach  ZD & "00000000" / ND und heraus kommt eine 
Zahl mit 8 Stellen vor dem Komma. Den Rest, den der Core auswirft, 
kannst Du dann verwerfen. Der teil der Schaltung wird dann auch nicht 
synthetisiert. Habe das bei Altera exzessiv durchgecheckt.
OP #2824243
Lesenswert?

Lothar Miller schrieb:
> Marc K. schrieb:
>> Diese meinten man kann es einfach mit "/" implementieren.
>> Wie es aussieht funktioniert es auch :-/
> Kann Altera auch.
> Aber sieh mal nach, wie es mit dem Ressourcenverbrauch aussieht.
> Was kostet dich eine 32/16 Division, die in 1 Takt fertig ist?

Das sagt die synthese bei folgendem code:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4

5
entity Div is
6
  port (
7
    div_out : OUT std_logic_vector (5 downto 0);
8
    clk  : IN std_logic;
9
    zahl_32 : IN std_logic_vector(5 downto 0);
10
    zahl_16 : IN std_logic_vector(5 downto 0)
11
   );
12
End Div;
13

14
architecture BEHAV of div is
15

16
signal ergebnis : unsigned (5 downto 0);
17

18
begin 
19
process (clk)
20
begin
21
if (rising_edge(clk)) then
22
ergebnis <=  unsigned(zahl_32) / unsigned(zahl_16);
23
end if;
24
end process;
25

26
div_out <= std_logic_vector(ergebnis);
27

28
end BEHAV;

Compile report:
===============

    CORE                       Used:    151  Total:  38400   (0.39%)
    IO (W/ clocks)             Used:     19  Total:    147   (12.93%)
    Differential IO            Used:      0  Total:     65   (0.00%)
    GLOBAL (Chip+Quadrant)     Used:      1  Total:     18   (5.56%)
    PLL                        Used:      0  Total:      2   (0.00%)
    RAM/FIFO                   Used:      0  Total:     60   (0.00%)
    Low Static ICC             Used:      0  Total:      1   (0.00%)
    FlashROM                   Used:      0  Total:      1   (0.00%)
    User JTAG                  Used:      0  Total:      1   (0.00%)

Wolltest du das wissen?
OP #2824332
Lesenswert?

Lothar Miller schrieb:
> Marc K. schrieb:
>> Wolltest du das wissen?
> Jein...
> Einen Divider für 6 Bit kann ich in ein BRAM packen...
>
> Ich wollte das eigentlich für 32/16 Bits wissen:
>
1
>     :
2
>     zahl_32 : IN std_logic_vector(31 downto 0);
3
>     zahl_16 : IN std_logic_vector(16 downto 0)
4
>     :
5
>


 CORE                       Used:   1799  Total:  38400   (4.68%)
    IO (W/ clocks)             Used:     81  Total:    147   (55.10%)
    Differential IO            Used:      0  Total:     65   (0.00%)
OP #2824334
Lesenswert?

Lothar Miller schrieb:
> Marc K. schrieb:
>> Wolltest du das wissen?
> Jein...
> Einen Divider für 6 Bit kann ich in ein BRAM packen...
>
> Ich wollte das eigentlich für 32/16 Bits wissen:
>>     :
>     zahl_32 : IN std_logic_vector(31 downto 0);
>     zahl_16 : IN std_logic_vector(16 downto 0)
>     :
>



 CORE                       Used:   1799  Total:  38400   (4.68%)
    IO (W/ clocks)             Used:     81  Total:    147   (55.10%)
    Differential IO            Used:      0  Total:     65   (0.00%)






> Und auch: Wie schnell kannst du dieses Design takten?

Wo seh ich das?
Moderator (Firma: Titel) Persönliche Seite #2824944
Lesenswert?

Marc K. schrieb:
>   zahl_32 : IN std_logic_vector(5 downto 0);
>   zahl_16 : IN std_logic_vector(5 downto 0)
>     CORE                    Used:    151  Total:  38400   (0.39%)

Marc K. schrieb:
>     zahl_32 : IN std_logic_vector(31 downto 0);
>     zahl_16 : IN std_logic_vector(15 downto 0)
>  CORE                       Used:   1799  Total:  38400   (4.68%)
Da wird tatsächlich ein kombinatorischer Divider gebaut.

>> Und auch: Wie schnell kannst du dieses Design takten?
> Wo seh ich das?
Das ist eine wichtige Zahl, die solltest du mit einem Blick erkennen 
können. Such mal im Synthese- oder Implementation-Report nach MHz.
OP #2825030
Lesenswert?

>>> Und auch: Wie schnell kannst du dieses Design takten?
>> Wo seh ich das?
> Das ist eine wichtige Zahl, die solltest du mit einem Blick erkennen
> können. Such mal im Synthese- oder Implementation-Report nach MHz.




Alles was ich mit MHz im Report gefunden habe.
1
Clock Summary
2
**************
3

4
Start      Requested     Requested     Clock      Clock          
5
Clock      Frequency     Period        Type       Group          
6
-----------------------------------------------------------------
7
System     1.0 MHz       1000.000      system     system_clkgroup
8
=================================================================
9

10

11

12

13
Performance Summary 
14
*******************
15

16

17
Worst slack in design: NA
18

19
                   Requested     Estimated     Requested     Estimated               Clock        Clock              
20
Starting Clock     Frequency     Frequency     Period        Period        Slack     Type         Group              
21
---------------------------------------------------------------------------------------------------------------------
22
top|clk            100.0 MHz     NA            10.000        NA            NA        inferred     Inferred_clkgroup_0
23
=====================================================================================================================
24

25

26
##### START OF TIMING REPORT #####[
27
# Timing Report written on Thu Sep 06 16:08:47 2012
28
#
29

30

31

32
Requested Frequency:    100.0 MHz
33
Wire load mode:         top
34
Paths requested:        5
35
Constraint File(s):    
36
@N: MT320 |Timing report estimates place and route data. Please look at the place and route timing report for final timing.
37

38
@N: MT322 |Clock constraints cover only FF-to-FF paths associated with the clock.
Gast #2825643
Lesenswert?

M. K. schrieb:
> Ich nutzte Synplify Pro AE F-2012.03MSP1. Da gehts.

Mit Synplify Pro F-2012.03L geht es auch.

Resourcen auf ECP3-35
1
Design Summary
2
   Number of registers:    96
3
      PFU registers:    16
4
      PIO registers:    80
5
   Number of SLICEs:          1187 out of 16632 (7%)
6
      SLICEs(logic/ROM):      1187 out of 13428 (9%)
7
      SLICEs(logic/ROM/RAM):     0 out of  3204 (0%)
8
          As RAM:            0 out of  3204 (0%)
9
          As Logic/ROM:      0 out of  3204 (0%)
10
   Number of logic LUT4s:     709
11
   Number of distributed RAM:   0 (0 LUT4s)
12
   Number of ripple logic:    641 (1282 LUT4s)
13
   Number of shift registers:   0
14
   Total number of LUT4s:     1991

Geschwindigkeit (Speedgrade 9)
1
----------------------------------------------------------------------------
2
Preference                              |   Constraint|       Actual|Levels
3
----------------------------------------------------------------------------
4
                                        |             |             |
5
FREQUENCY NET "clk_c" 50.000000 MHz ;   |   50.000 MHz|   15.296 MHz|  94 *
6
                                        |             |             |
7
----------------------------------------------------------------------------



Ich habe noch Eingangsregister hinzugefügt, ohne hatte er mit dem 
Constraint nix am Hut.
Gast #2825689
Lesenswert?

Das ganze nochmal für einen MachXO2 (LCMXO2-4000HE Speedgrade 6)

Spannend ist der Unterschied zwischen der neuen Lattice Synthese Engine 
(LSE) und Synplify Pro

LSE:
1
Design Summary
2
   Number of registers:    80
3
      PFU registers:    0
4
      PIO registers:    80
5
   Number of SLICEs:           362 out of  2160 (17%)
6
      SLICEs(logic/ROM):       362 out of   540 (67%)
7
      SLICEs(logic/ROM/RAM):     0 out of  1620 (0%)
8
          As RAM:            0 out of  1620 (0%)
9
          As Logic/ROM:      0 out of  1620 (0%)
10
   Number of logic LUT4s:      69
11
   Number of distributed RAM:   0 (0 LUT4s)
12
   Number of ripple logic:    297 (594 LUT4s)
13
   Number of shift registers:   0
14
   Total number of LUT4s:     663
15

16

17

18
----------------------------------------------------------------------------
19
Preference                              |   Constraint|       Actual|Levels
20
----------------------------------------------------------------------------
21
                                        |             |             |
22
FREQUENCY NET "clk_c" 50.000000 MHz ;   |   50.000 MHz|    9.568 MHz| 284 *
23
                                        |             |             |
24
----------------------------------------------------------------------------


Synplify Pro:
1
Design Summary
2
   Number of registers:    93
3
      PFU registers:    13
4
      PIO registers:    80
5
   Number of SLICEs:          1199 out of  2160 (56%)
6
      SLICEs(logic/ROM):       540 out of   540 (100%)
7
      SLICEs(logic/ROM/RAM):   659 out of  1620 (41%)
8
          As RAM:            0 out of  1620 (0%)
9
          As Logic/ROM:    659 out of  1620 (41%)
10
   Number of logic LUT4s:     617
11
   Number of distributed RAM:   0 (0 LUT4s)
12
   Number of ripple logic:    641 (1282 LUT4s)
13
   Number of shift registers:   0
14
   Total number of LUT4s:     1899
15

16
----------------------------------------------------------------------------
17
Preference                              |   Constraint|       Actual|Levels
18
----------------------------------------------------------------------------
19
                                        |             |             |
20
FREQUENCY NET "clk_c" 50.000000 MHz ;   |   50.000 MHz|    7.048 MHz|  97 *
21
                                        |             |             |
22
----------------------------------------------------------------------------

Mit dem LSE werden viel weniger Resourcen gebraucht, es ist obendrein 
noch schneller obwohl der kritische Pfad über fast 3 mal so viele 
Logikebenen geht.
Gast #2825820
Lesenswert?

Du solltest am Eingang UND Ausgang mindestens 2, besser 3 Register 
haben, damit er

a) in die IO-FFs kommt
b) bequem zu jeder Resource kommt.

Damit ist sicher gestellt, dass das ausgerechnete Tempo wirklich das 
Maximum ist, dass die Architektur in einer günstigen Umgebung kann.


Habe beispielhaft einen Divider mit 160 Stellen gemacht:

signed(Zaehler(79 downto 0) & Leerbits(79 downto 0)) / signed (Nenner(79 
downto 0));

Er braucht nach 6 min Synthese >33.000 slices im Spartan3 und kommt auf 
etwas über 1MHz :-)

Nach Optimierung durch Trans & MAP (insgesamt 49 min) braucht er 154.000 
slices und schafft knapp 3 MHz

Da waren die alten DX33-Copros schon schneller :-)

Gibt es eigentlich CoProzessor-Chips als fertige ASICs?
Sowas liesse sich doch an einen FPGA anschliessen, die könnten dann 
DIV/LOG/SQR berechnen.
Moderator (Firma: Titel) Persönliche Seite #2826038
Lesenswert?

Spartanist schrieb:
> Lothar Miller schrieb:
>> Da wird tatsächlich ein kombinatorischer Divider gebaut.
> Klaro und wenn man dem genug FF-stages hinten dran packt, kann die
> Synthese ihn per register retiming auch auf das jeweils benötigte Tempo
> bringen.
Das ist aber immer langsamer als ein nicht aufgeteilter Pfad und dazu 
ein Multicycle Constraint, weil ja für jedes FF noch die Setup-Zeit 
dazukommt...
Gast #2826221
Lesenswert?

Lothar Miller schrieb:
> Das ist aber immer langsamer als ein nicht aufgeteilter Pfad und dazu
> ein Multicycle Constraint,
Nun, dieses gilt ja generell: Sobald Speicher hinzutreten, wird der 
Zeitpfad länger, aber oft benötigt man die pipelinefähige Schaltung, um 
bei jedem  Takt Daten einspeisen zu können.
Gast #2826288
Lesenswert?

Doch, natürlich - unser Beispiel schon.. Oben die Kombinatorik hat 0,x 
Takte und benutzt damit einen Takt. Einen, der langsam genug ist. Eine 
beschleunigte Architektur braucht dann mehr Takte, nämlich die, die man 
künstlich angehängt hat und wird Dank balancing schneller.

Sie ist dann immer noch pipelinefähig.

Du hast natürlich dann Recht, wenn eine nicht gepipelinte Architektur 
mit FFs nachversorgt wird.
Gast #2826724
Lesenswert?

Michael schrieb:
> Sie ist dann immer noch pipelinefähig.

Da wage ich mal vorsichtig zu widersprechen...

Wenn du eine <10MHz Logik durch Zugabe von Registern und anpassen der 
Constraints auf ~100MHz hochzwiebelst ist das mitnichten pipelined. 
Pipelined wuerde bedeuten, dass du jeden 100MHz Takt neue Daten in die 
Stufe reinfuetterst und dass nach ~10 Zyklen dann das jeweilige Ergebnis 
rausfaellt.

Wenn du das ganze pipelined machen willst musst du schon eine adequate 
FSM schreiben die in jeder pipeline-Stufe eben auch die Daten 
entsprechend auf die naechste Stufe verteilt. Das ist dann aber 
Design/Handarbeit

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren