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
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.
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;
> des ganze soll aber in "Software" gelöst werden Ein FPGA ist keine Software.
1 | hund := (cValue/100); |
2 | zehn := (cValue-cValue/100)/10; |
3 | 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:
1 | :
|
2 | space(1) := dectohex(zehn); |
3 | :
|
4 | :
|
5 | when "00001000" => return "1000"; |
6 | when "00001001" => return "1001"; |
7 | when others => return "XXXX"; |
8 | :
|
warum schreibst du nicht einfach "nur":
1 | 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 ;-)
> 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-Vektor-nach-BCD
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.
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.std_logic_unsigned.all; |
4 | use ieee.numeric_std.all; |
5 | |
6 | -- -------------------------------------------------------------------------
|
7 | -- Funktionsweise: Siehe Xilinx Application Note XAPP029
|
8 | -- http://www.xilinx.com/support/documentation/application_notes/xapp029.pdf
|
9 | -- -------------------------------------------------------------------------
|
10 | |
11 | entity bin2bcd is port ( clk : in std_logic; |
12 | init : in std_logic; |
13 | bin_in : in std_logic; |
14 | bcd_out : out std_logic_vector(3 downto 0); |
15 | bcd_carry_out : out std_logic); |
16 | end bin2bcd; |
17 | |
18 | |
19 | architecture behavior of bin2bcd is |
20 | |
21 | signal shiftreg : std_logic_vector(3 downto 0) := "0000"; |
22 | |
23 | begin
|
24 | |
25 | process(clk) is |
26 | begin
|
27 | if rising_edge(clk) then |
28 | |
29 | if init = '1' then |
30 | shiftreg <= "0000"; |
31 | else
|
32 | case shiftreg(3 downto 0) is |
33 | when "0101" => shiftreg <= "000" & bin_in; |
34 | when "0110" => shiftreg <= "001" & bin_in; |
35 | when "0111" => shiftreg <= "010" & bin_in; |
36 | when "1000" => shiftreg <= "011" & bin_in; |
37 | when "1001" => shiftreg <= "100" & bin_in; |
38 | when others => shiftreg <= shiftreg(2 downto 0) & bin_in; |
39 | end case; |
40 | end if; |
41 | |
42 | end if; |
43 | end process; |
44 | |
45 | bcd_out <= shiftreg(3 downto 0); |
46 | bcd_carry_out <= '1' when conv_integer(shiftreg(3 downto 0)) >= 5 and init = '0' else |
47 | '0'; |
48 | |
49 | end behavior; |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.