Forum: FPGA, VHDL & Co. VHDL Grundlagen Binaer to BCD


von chris (Gast)


Lesenswert?

Es soll eine 10bit Binärzahl in eine 4 Stellen BCD gewandelt.

Weil ich LUTs sparen will und FPGAs so schnell sind, hier mal ein Etwas 
anderer Ansatz: Einfach BCD-Counter schnell bis zum gewünschten 
Anzeigewert hochzählen ( wie beim alten Autotacho ).
Was haltet Ihr von der Version unter VHDL-Gesichtspunkten?
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.all;
3
USE ieee.numeric_std.all;
4
5
entity bin2bcd is
6
  port(
7
    sysClk: in std_logic;
8
    data: in std_logic_vector ( 9 downto 0 );
9
    start: in std_logic;
10
11
    digit0: out std_logic_vector ( 3 downto 0 );
12
    digit1: out std_logic_vector ( 3 downto 0 );
13
    digit2: out std_logic_vector ( 3 downto 0 );    
14
    digit3Bit: out std_logic; 
15
    
16
    ready: out std_logic:='0'
17
  );
18
end entity bin2bcd;
19
20
architecture rtl of bin2bcd is
21
  signal counter: integer range 0 to 1023:=0;
22
  signal dig0: integer range 0 to 9:=0;
23
  signal dig1: integer range 0 to 9:=0;
24
  signal dig2: integer range 0 to 9:=0;
25
  signal dig3Bit: std_logic := '0';
26
begin
27
  process begin
28
    wait until rising_edge(sysClk);
29
    if(start='1') then  
30
      counter<=to_integer(unsigned(data));
31
      digit0 <= x"0";
32
      digit1 <= x"0";
33
      digit2 <= x"0";
34
      digit3Bit<='0';      
35
    else
36
      if(counter>0) then
37
        ready<='0';
38
        -- digit 0 --
39
        if(dig0<9) then
40
          dig0<=dig0+1;
41
        else
42
          dig0<=0;
43
          -- digit 1 --
44
          if(dig1<9)then
45
            dig1<=dig1+1;
46
          else
47
            dig1<=0;
48
            
49
            -- digit 2 + digit3Bit---
50
            if(dig2<9)then
51
              dig2<=dig2+1;
52
            else
53
              dig2<=0;
54
              dig3Bit<='1';
55
            end if;
56
          end if;
57
          
58
        end if;
59
        
60
        counter<=counter-1;
61
        
62
      else
63
        ready<='1';  
64
        digit0 <= std_logic_vector(to_unsigned(dig0,4));
65
        digit1 <= std_logic_vector(to_unsigned(dig1,4));
66
        digit2 <= std_logic_vector(to_unsigned(dig2,4));
67
        digit3Bit <= dig3Bit;
68
        
69
      end if;
70
    end if;
71
  end process;
72
  
73
  
74
end architecture;

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


Lesenswert?

chris schrieb:
> Was haltet Ihr von der Version unter VHDL-Gesichtspunkten?
Was sagt die Simulation? Besonders, wenn du nicht nur 1 Zahl, sondern 
irgendwann mal eine 2. oder 3. Zahl wandeln willst...
Als Tipp: wo werden dig0..2 denn mal zurückgesetzt?

BTW: ich möchte bezweifeln, dass dieser Ansatz effizienter implementiert 
wird als das alte Shift-Add6-Verfahren.
http://www.lothar-miller.de/s9y/archives/34-Vektor-nach-BCD.html
Auf jeden Fall ist die Laufzeit duchschnittlich länger und nicht 
deterministisch. Das ist unschön.

von chris (Gast)


Lesenswert?

>Was sagt die Simulation? Besonders, wenn du nicht nur 1 Zahl, sondern
>irgendwann mal eine 2. oder 3. Zahl wandeln willst...
>Als Tipp: wo werden dig0..2 denn mal zurückgesetzt?

Eigentlich sollen dig0..2 mit dem Startpuls zurückgesetzt werden:
1
if(start='1') then  
2
  counter<=to_integer(unsigned(data));
3
  digit0 <= x"0";
4
  digit1 <= x"0";
5
  digit2 <= x"0";
6
  digit3Bit<='0';      
7
else
In der Simulation und in der Praxis läuft es auch beim ersten Mal 
korrekt. In der Praxis läuft der gewandelte Wert aber in den 
Folgedurchläufen hoch ....

Im Moment zeigt der Compiler dieses Ergebnis:
################### Begin Area Report (bin2bcd)######################
Number of register bits => 36 of 7209 (0 % )
CCU2D => 6
FD1P3AX => 11
FD1P3IX => 25
GSR => 1
IB => 12
LUT4 => 37
OB => 14

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


Lesenswert?

chris schrieb:
> Eigentlich sollen dig0..2 mit dem Startpuls zurückgesetzt werden:...
Dann musst du das auch hinschreiben: dig0 ist nicht gleich digit0.

> In der Simulation und in der Praxis läuft es auch beim ersten Mal
> korrekt. In der Praxis läuft der gewandelte Wert aber in den
> Folgedurchläufen hoch ....
War zu erwarten. Das tut er auch in der Simulation...

: Bearbeitet durch Moderator
von chris (Gast)


Lesenswert?

>Dann musst du das auch hinschreiben: dig0 ist nicht gleich digit0.

Ich habe vermutlich zu lange hingeschaut und es nicht mehr gesehen.
Du hast völlig recht, das war ein Fehler. Wenn man es ändert, 
funktioniert es korrekt.

von Jürgen S. (engineer) Benutzerseite


Lesenswert?

Bei der Breite lohnt sich eigentlich noch eine Tabelle samt 
Entscheidungsbaum für die Hunderter und jeweils Einer-/Zehnerstellen in 
Form von Logik. Die purzelt aufgrund des binären Eingangsvektors und der 
begrenzten Zahl der LED-Segmente, die damit meist angesteuert werden, 
gewaltig zusammen.

von chris (Gast)


Lesenswert?

Wahrscheinlich ist das dann äquivalent mit dieser Lösung:
Beitrag "Re: 1 Byte in dual 7 Segment Anzeige übersetzen"

von Jürgen S. (engineer) Benutzerseite


Lesenswert?

Stimmt, da scheint einer dasselbe Problem zu haben. Vermutlich wieder 
eine VHDL-Hausarbeit.

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.