Hallo! Ist es möglich mittels eines generics eine Struktur zu Kaskadieren? Also zB. einen 1 Bit volladdierer zu schreiben und dann mittels eines Generics auszuwählen ein weiviel Bit addierer geschaffen werden soll? Ich brauch es um ein Cordic rechenwerk zu implementieren. LG Alex
Alexx schrieb: > Ich brauch es um ein Cordic rechenwerk zu implementieren. Musst du das Ding aus einzelnen Gattern aufbauen? Oder kannst du nicht einfach den seit langer Zeit unterstützten '+' Operator verwenden?
Das geht mit dem for/generate-Konstrukt von VHDL. Das ist wie eine for-Schleife, die aber bei jedem Durchlauf ein Gatter oder eine Komponente erzeugt, sozusagen eine Schleife im Raum und nicht in der Zeit. Die Anzahl der Schleifendurchläufe kannst Du als generic übergeben. Aber wie Lothar schon geschrieben hat, für einen Adierer lohnt sich das nicht, da kannst Du einfach den "+"-Operator nehmen.
cordic schreibt man am besten als eine Funktion, die sich rekursiv aufruft. Die Tiefe der Rekursion als generic Wert übergeben.
Den Volladdierer habe ich nur als Beispiel gemeint! Ich will einen Logarithmierer auf Basis des Cordics implementieren: Hier Fig. 2 auf Seite 3 ist meine Vorlage: http://hh.diva-portal.org/smash/get/diva2:623021/FULLTEXT01.pdf Die anzahl der Iterationen wollte ich per Generic vorgeben! Das mit der Funktion werd ich mir aufjedenfall auch nochmal ansehen danke für den Tipp! Ein Schritt meiner Berrechnung ist: --xi+1 = xi + yi *u *2^-i --yi+1 = yi + xi *u *2^-i --zi+1 = zi - u*ai --u = gegenteil von sign(y) --ai = arctanh(2^-i) LG alex
Hallo! Danke für eure Tipps! Ich glaube ich konnte damit erreichen was ich wollte! Ich habe leider ein kleines Problem mit meiner Simulation: meine k laufvariable die ich für die ich für das for generate meiner Rom Table benutze erzeugt mehrere instanzen meiner Table! Siehe Screenshot! Die verschiedenen Instanzen unterscheiden sich nur in der Variable k! Ist das nur das Verhalten des Simulators oder werden in meinem FPGA dann auch mehrere Instanzen instanziert? Das ist der generierende Code:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | USE ieee.math_real.all; |
4 | use ieee.numeric_std.all; |
5 | |
6 | |
7 | -- Uncomment the following library declaration if using
|
8 | -- arithmetic functions with Signed or Unsigned values
|
9 | --use IEEE.NUMERIC_STD.ALL;
|
10 | |
11 | -- Uncomment the following library declaration if instantiating
|
12 | -- any Xilinx primitives in this code.
|
13 | --library UNISIM;
|
14 | --use UNISIM.VComponents.all;
|
15 | |
16 | entity log is |
17 | Port ( input : in STD_LOGIC_VECTOR (7 downto 0); |
18 | output : out STD_LOGIC_VECTOR (7 downto 0); |
19 | rst : in STD_LOGIC; |
20 | clk : in STD_LOGIC); |
21 | end log; |
22 | |
23 | architecture Behavioral of log is |
24 | |
25 | component cordic_core is |
26 | generic ( N: integer :=7); |
27 | Port ( x_in : in signed (N downto 0); |
28 | y_in : in signed (N downto 0); |
29 | z_in : in signed (N downto 0); |
30 | atanh: in signed (N downto 0); |
31 | x_out : out signed (N downto 0); |
32 | y_out : out signed (N downto 0); |
33 | z_out : out signed (N downto 0); |
34 | clk : in STD_LOGIC; |
35 | res : in STD_LOGIC; |
36 | iteration : in integer range 0 to N); |
37 | END component; |
38 | |
39 | --Z anzahl der Cordic Schritte ACHTUNG!! muss eine bestimme Zahl sein!
|
40 | --B Bitbreite des Cordic Cores
|
41 | |
42 | constant Z : integer := 8; |
43 | constant B : integer := 10; |
44 | |
45 | --Array für generierte log(2**n) Werte für Bereichsanpassung
|
46 | type Rom8x8 is array (0 to 7) of unsigned(7 downto 0); |
47 | signal LOG_Rom : Rom8x8; |
48 | |
49 | --Array für gererierte Arctanh(2**-i) Werte
|
50 | type RomZxB is array (0 to Z) of signed (B-1 downto 0); |
51 | signal ATANH_Rom : RomZxB; |
52 | |
53 | --n = wieviel wurde geschoben
|
54 | signal n : integer range 0 to 7; |
55 | --platzhalter für reset
|
56 | signal res : std_logic := '0'; |
57 | |
58 | --in die Temp Vektoren muss der startwert bei temp(0) geschrieben werden
|
59 | --mittels for generate werden die xi+1s erzeugt
|
60 | --daweil per clock, kann aber auch als ewig langes Rechenwerk implementiert werden! vermutlich besser!!
|
61 | |
62 | type temp_vector is array (0 to Z+1) of signed (B-1 downto 0); |
63 | signal x_temp : temp_vector; |
64 | signal y_temp : temp_vector; |
65 | signal z_temp : temp_vector; |
66 | |
67 | |
68 | begin
|
69 | -- TODO
|
70 | -- Tabelle berechnen beginnend mit log(2) bis log (2^8) für input vektor
|
71 | -- table: for i in 0 to 7 generate
|
72 | -- LOG_Rom(i) <= to_unsigned( integer( log10(real(2*i)+1.0)/log10(256)*255 ),8);
|
73 | -- end generate;
|
74 | |
75 | |
76 | -- TODO anschaun wo das komma sein muss!
|
77 | |
78 | -- Tabelle berechnen beginnend mit arctanh(2**-1)
|
79 | --atanh(1/2) = 0.54....
|
80 | table: for k in 0 to Z generate |
81 | ATANH_Rom(k) <= to_signed(integer(arctanh(real(2**(-real((k+1)))))*real((2**(B-1)))),(B)); |
82 | --ATANH_Rom(k) <= to_signed( integer( round(arctanh(real(2**(-real((i+1)))))*real((2**(B))))),(B));
|
83 | end generate; |
84 | |
85 | -- TODO muss noch gemacht werden!!
|
86 | --könnte man auch mit takt shiften bis es passt, wäre gut mit Rechenwerk ohne takt!
|
87 | --output <= z_temp(Z+1) ... muss noch auf 8 bit und mit log verknüft werden!
|
88 | --wir brauchen ja x= input+1 und y=input-1
|
89 | --wenn beide signed sind müsste auch gehen: x= 01xxxxxxxx(8-bit input) und y= 11xxxxxxxx
|
90 | --also ist w=0,xxxxxxxx und wir müssen nur log(2**8) addieren nachdem das letzte z auf log10 Basis gebracht wurde!
|
91 | normalize_value:process(input) |
92 | begin
|
93 | if input(7)='1' then n <= 7; |
94 | elsif input(6)='1' then n <= 6; |
95 | elsif input(5)='1' then n <= 5; |
96 | elsif input(4)='1' then n <= 4; |
97 | elsif input(3)='1' then n <= 3; |
98 | elsif input(2)='1' then n <= 2; |
99 | elsif input(1)='1' then n <= 1; |
100 | elsif input(0)='1' then n <= 0; |
101 | else output <= "00000000"; |
102 | end if; |
103 | |
104 | end process; |
105 | |
106 | |
107 | --Cordic blöcke werden instanziert und miteinander Verbunden. Schnittstellen nach außen sind temp Vektoren
|
108 | cordic_gen: |
109 | for i in 0 to Z generate |
110 | Module: cordic_core |
111 | generic map (N => B-1) |
112 | port map (x_temp(i), y_temp(i), z_temp(i), ATANH_Rom(i), x_temp(i+1), y_temp(i+1), z_temp(i+1), clk, res, i); |
113 | end generate; |
114 | |
115 | |
116 | end Behavioral; |
Kleine Frage am rande: ist das so richtig dass ich meine mit for generate generierten Components mit einem externen Array verbinde oder gibt es eine bessere möglichkeit? Danke für eure Hilfe! LG Alex
Edit: ja bin draufgekommen dass ich in den Kommentaren das Signed Format nicht verstanden hab!
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.