mikrocontroller.net

Forum: FPGA, VHDL & Co. unsigned => hex


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an Alle,

hätte da ein Problem bei der Umrechnung einer Zahl im unsigned(7 downto 
0) Format in hex (3 downto 0)

Die Zahl in unsigned ist z.b.: 11111111 -> 255
Diese soll in drei hex zahlen der Form 3 downto 0 gebracht werden
also hex1 = 0x02
hex2 = 0x05
hex3 = 0x05

wie kann das am effektivsten gelöst werden da meine Umrechnung zu 
langsam scheint für die Hardwarebeschreibung nach der Synthese um genau 
10 MHz zu wenig.

thx

Autor: spartanne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Möglichkeit wäre es (falls verfügbar) ein BlockRAM als Decoder-ROM 
zu nutzen. Die Adresse ist dein Eingangsdatum, am Datenausgang erhälst 
du deine neu formatierten Daten.
Dann noch den Datenausgang auf die 3 Signale mappen:
hex1 <= data_out(12 downto 8);
hex2 <= data_out(7 downto 4);
hex3 <= data_out(3 downto 0);
Also ein BlockRAM organisiert als 256x12. Musst du dann nur noch 
initialisieren und fertig. Schnell, verbraucht keine Logikresourcen, 
Ergebnis nach einem Takt.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
des ganze soll aber in "Software" gelöst werden also sprich eine eigne 
function

hab mal sowas uneffektives geschrieben aber dass ist anscheinend nicht 
die beste Lösung:

 type afield is array(3 downto 0) of std_ulogic_vector(3 downto 0);

 function unstohex(cValue : unsigned(cCounterWidth-1 downto 0)) return 
afield is
    variable hund : unsigned(cCounterWidth-1 downto 0);
    variable space : afield;
    variable zehn : unsigned(cCounterWidth-1 downto 0);
    variable ein : unsigned(cCounterWidth-1 downto 0);


    begin
      hund := (cValue/100);
      zehn := (cValue-cValue/100)/10;
      ein := cValue-(cValue/100+((cValue-cValue/100)/10));

      space(3) := dectohex(to_unsigned(0,cCounterWidth));
      space(2) := dectohex(hund);
      space(1) := dectohex(zehn);
      space(0) := dectohex(ein);

      return space;
   end function;

   function dectohex(cin : unsigned(cCounterWidth-1 downto 0)) return 
std_ulogic_vector is
   begin
       case cin is
        when "00000000" => return "0000";
        when "00000001" => return "0001";
        when "00000010" => return "0010";
        when "00000011" => return "0011";
        when "00000100" => return "0100";
        when "00000101" => return "0101";
        when "00000110" => return "0110";
        when "00000111" => return "0111";
        when "00001000" => return "1000";
        when "00001001" => return "1001";
        when others => return "XXXX";
      end case;
   end function;

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

Bewertung
0 lesenswert
nicht lesenswert
> des ganze soll aber in "Software" gelöst werden
Ein FPGA ist keine Software.
      hund := (cValue/100);
      zehn := (cValue-cValue/100)/10;
      ein := cValue-(cValue/100+((cValue-cValue/100)/10));
Aha, ein C Programmierer am FPGA.
Du hast auf den mir bekannten FPGAs keine kombinatorische Divison. 
Deshalb kannst du so etwas zwar beschreiben und simulieren, aber niemals 
in reale Hardware abbilden.
Auf welcher FPGA Plattform arbeitest du?

Wenn du neu auf dem Gebiet der Hardwarebeschreibung bist, dann vergiss 
mal zwischendurch (so etwa bis Anfang 2010) die Keywords function und 
procedure. Das sind in der /Beschreibungssprache VHDL/ ganz andere 
Syntaxelemente als in der Programmiersprache C. Und die machen daher 
auch ganz was anderes.
Du sollest dich eher mal damit befassen, was Komponenten und Instanzen 
sind.

EDIT:
      :
      space(1) := dectohex(zehn);
        :
        :
        when "00001000" => return "1000";
        when "00001001" => return "1001";
        when others => return "XXXX";
      :
warum schreibst du nicht einfach "nur":
      space(1) <= zehn(3 downto 0);
Das ist eine Zuweisung der unteren 4 Bits.
Wobei ich den Sinngehalt des davor geschriebenen bereits kommentiert 
habe.


BTW:
Am besten vergisst du auch gleich mal das Keyword variable und 
verwendest (vorerst) nur Signale. Das ist ein ernstgemeinter Tipp, kein 
Witz.
Du stehst noch wesentlich weiter vorne am Anfang, als du selber meinst 
;-)

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

Bewertung
0 lesenswert
nicht lesenswert
> Diese soll in drei hex zahlen der Form 3 downto 0 gebracht werden
Was du also willst, sind BCD-Zahlen (Binär Codierte Dezimalzahlen)
Ich habe mir zu dem Thema hier mal was festgehalten:
http://www.lothar-miller.de/s9y/categories/28-Vekt...

Autor: Gast111 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieses Problem hatte ich letztens auch. Hier meine Lösung. Sie ist nicht 
generisch und braucht 4 Takte pro Dezimalstelle. Dafür ist sie sehr 
klein synthetisierbar (4 Slices). Für mehrstellige Dezimalzahlen muss 
man mehrere dieser Blöcke kaskadieren.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

-- -------------------------------------------------------------------------
-- Funktionsweise: Siehe Xilinx Application Note XAPP029
-- http://www.xilinx.com/support/documentation/application_notes/xapp029.pdf
-- -------------------------------------------------------------------------

entity bin2bcd is port (  clk        : in  std_logic;
                  init        : in  std_logic;
                  bin_in      : in  std_logic;
                  bcd_out      : out  std_logic_vector(3 downto 0);
                  bcd_carry_out  : out  std_logic);
end bin2bcd;


architecture behavior of bin2bcd is

  signal shiftreg    : std_logic_vector(3 downto 0)  := "0000";

begin

  process(clk) is
  begin
    if rising_edge(clk) then

      if init = '1' then
        shiftreg  <= "0000";
      else
        case shiftreg(3 downto 0) is
          when "0101"    => shiftreg <= "000" & bin_in;
          when "0110"    => shiftreg <= "001" & bin_in;
          when "0111"   => shiftreg <= "010" & bin_in;
          when "1000"   => shiftreg <= "011" & bin_in;
          when "1001"   => shiftreg <= "100" & bin_in;
          when others   => shiftreg <= shiftreg(2 downto 0) & bin_in;
        end case;
      end if;

    end if;
  end process;

  bcd_out      <= shiftreg(3 downto 0);
  bcd_carry_out  <=  '1'  when conv_integer(shiftreg(3 downto 0)) >= 5 and init = '0'  else
              '0';

end behavior;

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.