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


von Alex A. (alexvhdl)


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;

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


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:
1
use numeric_std.all
2
:
3
 port (
4
  bcd : in  std_logic_vector(15 downto 0);
5
  bin : out std_logic_vector(15 downto 0)
6
 );
7
:
8
process (bcd)
9
variable h : integer;
10
begin
11
  h :=     to_integer(unsigned(bcd_vect(3 downto 0));  
12
  h := h + to_integer(unsigned(bcd_vect(7 downto 4))*10;  
13
  h := h + to_integer(unsigned(bcd_vect(11 downto 8))*100;
14
  h := h + to_integer(unsigned(bcd_vect(15 downto 12))*1000;
15
  result <= std_logic_vector(to_unsigned(h,16));
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.

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


Lesenswert?

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

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


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:
1
use numeric_std.all
2
:
3
 port (
4
  bcd : in  std_logic_vector(15 downto 0);
5
  bin : out std_logic_vector(15 downto 0)
6
 );
7
:
8
process (bcd)
9
variable h : unsigned(15 downto 0);
10
begin
11
  h :=     unsigned(bcd_vect(3 downto 0));  
12
  h := h + unsigned(bcd_vect(7 downto 4))*10;  
13
  h := h + unsigned(bcd_vect(11 downto 8))*100;
14
  h := h + unsigned(bcd_vect(15 downto 12))*1000;
15
  result <= std_logic_vector(h);
16
end process;
Oder sogar so:
1
use numeric_std.all
2
:
3
 port (
4
  bcd : in  unsigned(15 downto 0);
5
  bin : out unsigned(15 downto 0)
6
 );
7
:
8
process (bcd)
9
variable h : unsigned(15 downto 0);
10
begin
11
  h :=     bcd_vect(3 downto 0);  
12
  h := h + bcd_vect(7 downto 4)*10;  
13
  h := h + bcd_vect(11 downto 8)*100;
14
  h := h + bcd_vect(15 downto 12)*1000;
15
  result <= h;
16
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.

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.