Hallo, ich bin dabei Uni-bedingt einen Multiplizierer zu basteln und komme leider seit fast einer halben Woche nicht weiter. Ich finde einfach nicht den Fehler und habe das Gefühl dass ich den Wald vor lauter Bäumen nicht sehe. Wenn ich das ganze mit ISim simuliere ist mein Produktvektor komplett Undefined. Da ich inzwischen ziemlich im Zeitdruck mit der Abgabe bin wollt ich mal schauen ob mir jemand hier im Forum weiterhelfen kann - bin ich über jeden Tipp dankbar. Code des Multiplizieres: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Multio2signed is port( multiplicand : in signed; multiplicator : in signed; product : out signed; error : out std_ulogic ); end; architecture behav of Multio2signed is constant m: positive := multiplicand'length; constant n: positive := multiplicator'length; type Table is array (natural range <>) of signed(m-1 downto 0); signal A : Table(0 to n-1); signal B : Table(0 to n); signal c1 : signed(m downto 0); begin Multiprozess : process begin B(0)<=(others=>'0'); assert product'length=m+n; error <= '0'; -- Belegung Matrix A for i in 0 to n-1 loop if multiplicator(i) = '1' then A(i)<=multiplicand; elsif multiplicator(i) = '0' then A(i)<=(others=>'0'); else error <= '1'; end if; end loop; --Belegung Matrix B und Produktzuweisung for k in 1 to n loop c1<=resize(A(k-1),m+1)+resize(B(k-1),m+1); product(k-1 downto k-1)<=c1(0 downto 0); B(k)<=c1(m downto 1); end loop; product(m+n-1 downto n)<=c1(m downto 1); wait; end process; end; Testbench: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity Multio2signed_tb is end; architecture test of Multio2signed_tb is signal mcand_int : signed(3 downto 0) :=(others => '0'); signal mtor_int : signed(3 downto 0) :=(others => '0'); signal p_int : signed((mcand_int'length + mtor_int'length - 1) downto 0) :=(others => '0'); signal error : std_ulogic; begin Multi : entity work.Multio2signed port map (multiplicand => mcand_int, multiplicator => mtor_int, product => p_int, error => error ); stimuli : process begin mcand_int <= "0110"; mtor_int <= "1101"; wait for 10 ms; assert error = '0' report "Fehler"; assert p_int = "01001110" report "Unexpected Result" ;-- severity FAILURE; wait; end process; end;
Am einfachsten wäre wohl, da du ja schon die numeric_std und signed verwendest: product <= multiplicand * multiplicator;
Die Aufgabe besteht dadrin den Multiplizierer ohne "*" Operanden hinzubekommen ;)
super, und dann gibt's mal wieder VHDL ohne irgendeinen Kommentar der grob beschreibt, was man denn eigentlich machen wollte... Nee, ich werde hier nicht versuchen, reverse-engineering zu betreiben!
Dafür steht da ein
> wait;
@Klaus M:
muss dein Zeug synthetisierbar sein?
@IKmiller ich weiß nicht genau was du mit synthetisierbar meinst, aber ich denke nein. Der Code soll nur fehlerfrei über ISim simuliert werden können. @Rest Ah sorry, total vergessen, also,der Plan war/ist, am Beispiel mit der Multiplikation von 0110 * 1101: (siehe Bild) multiplicand (m bit lang) * multiplicator (n bit lang) = produkt (m+n bit lang) Erst alle "einzel" Multiplikationen vom least significant bit aus bis zum most sig. bit (vom Bultiplikator) durch eine Schleife ausführen und die Ergebnisse davon in der Matrix A speichern. also : 1 * 0110 = (0110) 0 * 0110 = (0000) wobei dies die Matrix A darstellen soll 1 * 0110 = (0110) 1 * 0110 = (0110) Dann im nächsten Schritt die Matrix B in einer Schleife generieren. Diese hat in der ersten Zeile nur "0000" und entsteht danach durch Addition von ihrer vorherigen Zeile mit der entsprechenden Zeile aus A, wobei hier das least significant bit nur temporär in c1 gespeichert bzw ans produkt weitergegeben wird. Dies dann bis zum Ende ausführen und am Schluß den Kopf des Produktes von c1 erhalten. Ich hoffe zusammen mit dem Bild ist dies einigermaßen verständlich. Hier auch nochmal der Code in VHDL:
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | entity Multio2signed is |
6 | port( |
7 | multiplicand : in signed; |
8 | multiplicator : in signed; |
9 | product : out signed; |
10 | error : out std_ulogic |
11 | );
|
12 | end; |
13 | |
14 | architecture behav of Multio2signed is |
15 | |
16 | |
17 | |
18 | constant m: positive := multiplicand'length; |
19 | constant n: positive := multiplicator'length; |
20 | |
21 | type Table is array (natural range <>) of signed(m-1 downto 0); |
22 | signal A : Table(0 to n-1); |
23 | signal B : Table(0 to n); |
24 | signal c1 : signed(m downto 0); |
25 | |
26 | begin
|
27 | |
28 | |
29 | |
30 | Multiprozess : process |
31 | |
32 | begin
|
33 | B(0)<=(others=>'0'); |
34 | assert product'length=m+n; |
35 | error <= '0'; |
36 | |
37 | |
38 | -- Belegung Matrix A
|
39 | |
40 | for i in 0 to n-1 loop |
41 | |
42 | if multiplicator(i) = '1' then |
43 | A(i)<=multiplicand; |
44 | elsif multiplicator(i) = '0' then |
45 | A(i)<=(others=>'0'); |
46 | else error <= '1'; |
47 | end if; |
48 | end loop; |
49 | |
50 | |
51 | |
52 | |
53 | --Belegung Matrix B und Produktzuweisung
|
54 | |
55 | for k in 1 to n loop |
56 | c1<=resize(A(k-1),m+1)+resize(B(k-1),m+1); |
57 | product(k-1 downto k-1)<=c1(0 downto 0); |
58 | B(k)<=c1(m downto 1); |
59 | end loop; |
60 | product(m+n-1 downto n)<=c1(m downto 1); |
61 | wait; |
62 | end process; |
63 | |
64 | end; |
:
Bearbeitet durch User
Ein Tipp zum Thema "Schleifen mit Signalen": Signale übernehmen in VHDL erst beim nächsten "wait" oder am Prozessende den zuletzt an sie zugewiesenen Wert... Du brauchst für solche Schleifen als "Zwischenspeicher" immer Variablen. Ich würde für so eine stumpfsinnige und praxisferne Aufgabe (es gibt wie schon gesagt den fertigen Operator) einfach mal per Reverse Engeneering angehen: wie ist der Operator in der numeric_std umgesetzt? Den Quellcode dafür gibts an jeder Ecke...
:
Bearbeitet durch Moderator
Gute, wenn auch knappe Seite zu Multiplizierer in FPGA: http://www.andraka.com/multipli.htm Am besten für eine der Grundstrukturen z.B Wallace-tree entscheiden und die dann als hierarchische Blockstrukter über generate-Anweisungen aufbauen. MfG,
berndl schrieb: > super, und dann gibt's mal wieder VHDL ohne irgendeinen Kommentar der > grob beschreibt, was man denn eigentlich machen wollte... > > Nee, ich werde hier nicht versuchen, reverse-engineering zu betreiben! Das ist wirklich ein Problem, vieler Entwickler, dass sie ihre Gedanken nicht formulieren können oder wollen, weil sie es nicht für nötig halten. Dabei wäre es wichtig, das SOLL zu kennen, um die Art der Umsetzung und ihre Defizite zu begreifen und nicht nur das IST zu sehen und das SOLL zu erraten. Ok, bei vielen Dingen ist es trivial (genug), damit das "reverse engineering" durch den Gegenüber klappt, aber das Schwierige daran ist, dass dadurch, dass man es so nie richtig lernt zu formulieren und zu dokumentieren und dann, wenn es gebraucht würde, weil die Probleme komplexer werden, es dann nur unzureichend kann. Damit bleibt man im Hamsterrad.
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.