www.mikrocontroller.net

Forum: FPGA, VHDL & Co. umwandlung BCD in Bin


Autor: Alex Alex (alexvhdl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich beschaeftige mich jetzt mit der Umwandlung von BCD in Bin.

ich komme klar wie man Bin in Bcd umwandlen kann, aber umgekehrt habe 
ich keine Ahnung.

es waere schoen, wenn ihr da mal reinschauen koenntet um mit Tipps zu 
geben.

hier ist das Programm , die umwandlung bin in BCD :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity BinzuBCD is
    Port ( Clk :    in  STD_LOGIC;
           Init :   in  STD_LOGIC;
        Rst:  in  STD_LOGIC;
           ModIn :  in  STD_LOGIC;
           ModOut : out  STD_LOGIC;
           Q :      out  STD_LOGIC_VECTOR (3 downto 0));
end BinzuBCD;

architecture Behavioral of BinzuBCD is
   signal Bcd: STD_LOGIC_VECTOR (3 downto 0);
begin
   process( Clk,Init)
  begin
     if rising_edge( Clk) then
       if Init='1' then
         Bcd <= "0000";
      elsif Rst='0' then
        case Bcd is
          when "0000" => Bcd <= "000" & ModIn;  -- 0*2 + ModIn
          when "0001" => Bcd <= "001" & ModIn;  -- 1*2 + ModIn
          when "0010" => Bcd <= "010" & ModIn;  -- 2*2 + ModIn
          when "0011" => Bcd <= "011" & ModIn;  -- 3*2 + ModIn
          when "0100" => Bcd <= "100" & ModIn;  -- 4*2 + ModIn
          when "0101" => Bcd <= "000" & ModIn;  -- 5*2 + ModIn 
(ModOut=1)
          when "0110" => Bcd <= "001" & ModIn;  -- 6*2 + ModIn 
(ModOut=1)
          when "0111" => Bcd <= "010" & ModIn;  -- 7*2 + ModIn 
(ModOut=1)
          when "1000" => Bcd <= "011" & ModIn;  -- 8*2 + ModIn 
(ModOut=1)
          when "1001" => Bcd <= "100" & ModIn;  -- 9*2 + ModIn 
(ModOut=1)
          when others => Bcd <= "0000";
        end case;
      end if;
    end if;
  end process;

  ModOut <= '1' when Bcd>=5 else '0';
  Q      <= Bcd;

end Behavioral;




library IEEE;
use IEEE.std_logic_1164.all;

entity BCDwandler is
  generic (N   : integer :=3);
  port (Clk  : in std_logic;
        Rst  : in std_logic;
        Init   : in std_logic;  -- initialisierung
        ModIn  : in std_logic;  -- carry in
        ModOut : out std_logic; -- carry out
        Q      : out std_logic_vector(4*N -1 downto 0) -- BCD Ergebnis
       );
end;

architecture arch of BCDwandler is

  component BinzuBCD is
  port (Clk : in std_logic;
        Rst : in std_logic;
        Init : in std_logic;
        ModIn : in std_logic;
        ModOut : out std_logic;
        Q : out std_logic_vector(3 downto 0)
       );
  end component;

  signal ModBreite : std_logic_vector(1 to N+1);

begin


BCDAnzahl : for i in 1 to N generate
  Rgs: BinzuBCD
        port map
        (Clk => Clk,
        Rst => Rst,
        Init => Init,
        ModIn => ModBreite(I+1),
        ModOut => ModBreite(I),
        Q      => Q(I*4-1 downto I*4-4));
  end generate;

  ModOut <= ModBreite(1);
  ModBreite(N+1) <= ModIn;

end;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alex Alex schrieb:
> ich komme klar wie man Bin in Bcd umwandlen kann, aber umgekehrt habe
> ich keine Ahnung.

Die Richtung BCD nach Bin ist eigentlich viel einfacher.
Z.B. für 4 BCD-Stellen:
use numeric_std.all
:
 port (
  bcd : in  std_logic_vector(15 downto 0);
  bin : out std_logic_vector(15 downto 0)
 );
:
process (bcd)
variable h : integer;
begin
  h :=     to_integer(unsigned(bcd_vect(3 downto 0));  
  h := h + to_integer(unsigned(bcd_vect(7 downto 4))*10;  
  h := h + to_integer(unsigned(bcd_vect(11 downto 8))*100;
  h := h + to_integer(unsigned(bcd_vect(15 downto 12))*1000;
  result <= std_logic_vector(to_unsigned(h,16));
end process;


> use IEEE.STD_LOGIC_ARITH.ALL;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
Vergiss die alten obsoleten Synopsys-Libs am besten schnell wieder, oder 
fang besser gleich gar nicht damit an. Nimm statt dessen (nicht 
zusätzlich!!!) die genormte numeric_std.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst die Berechnung natürlich auch herumdrehen und mit der 
Tausenderstelle anfangen:
use numeric_std.all
:
 port (
  bcd : in  std_logic_vector(15 downto 0);
  bin : out std_logic_vector(15 downto 0)
 );
:
process (bcd)
variable h : integer;
begin
  h :=        to_integer(unsigned(bcd_vect(15 downto 12));
  h := h*10 + to_integer(unsigned(bcd_vect(11 downto 8));
  h := h*10 + to_integer(unsigned(bcd_vect(7 downto 4));  
  h := h*10 + to_integer(unsigned(bcd_vect(3 downto 0));  
  result <= std_logic_vector(to_unsigned(h,16));
end process;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Alex,
Fragen, die auch andere irgendwann interessieren könnten, bitte nicht 
als PM, sondern einfach hier im Thread stellen. Nimms mir nicht übel, 
wenn ich die Fragen hier beantworte... ;-)

> Z.B. für die BCD-Zahl 3927 (Eingabe von 0011 1001 0010 0111)es wurde
> erst einer-stelle 0111 mit Hilfe to_integer in 7 umgewandelt und H mit 7
> zugewiesen wurde. 10er-stelle 0010 wurde in 20 (am Ende mal 10)
> umgewandelt, H bekommt den wert 20+7. u.w. H bekommt den wert 3927,
> wurde dann mit Hilfe to_unsigned in 16bit lang vector umgewandelt.
> result ist die umgewandelte binär-Zahl.
> habe ich richtig verstanden?
Richtig, fast:
> es wurde erst einer-stelle 0111 mit Hilfe to_integer in 7 umgewandelt
Da wird im FPGA nicht wirklich etwas umgewandelt, es ist eine reine 
VHDL-Typkonvertierung.
Ich könnte das z.B. auch so schreiben:
use numeric_std.all
:
 port (
  bcd : in  std_logic_vector(15 downto 0);
  bin : out std_logic_vector(15 downto 0)
 );
:
process (bcd)
variable h : unsigned(15 downto 0);
begin
  h :=     unsigned(bcd_vect(3 downto 0));  
  h := h + unsigned(bcd_vect(7 downto 4))*10;  
  h := h + unsigned(bcd_vect(11 downto 8))*100;
  h := h + unsigned(bcd_vect(15 downto 12))*1000;
  result <= std_logic_vector(h);
end process;
Oder sogar so:
use numeric_std.all
:
 port (
  bcd : in  unsigned(15 downto 0);
  bin : out unsigned(15 downto 0)
 );
:
process (bcd)
variable h : unsigned(15 downto 0);
begin
  h :=     bcd_vect(3 downto 0);  
  h := h + bcd_vect(7 downto 4)*10;  
  h := h + bcd_vect(11 downto 8)*100;
  h := h + bcd_vect(15 downto 12)*1000;
  result <= h;
end process;
Alle diese Lösungen geben genau die selbe Hardware...

> fehlt es doch noch Entity und architecture oder?
Korrekt. Dafür sind die Platzhalter (Doppelpunkte) da.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.