Forum: FPGA, VHDL & Co. VHDL Struktur Kaskadieren mit Generic


von Alexx (Gast)


Lesenswert?

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

von kameramann (Gast)


Lesenswert?

Sicher geht das. Einfach einen los verwenden

von Bitwurschtler (Gast)


Lesenswert?

Lass dir mal die GENERATE Anweisung erläutern:
http://www.alvie.com/zpuino/vhdl4.html

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


Lesenswert?

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?

von Vancouver (Gast)


Lesenswert?

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.

von René D. (Firma: www.dossmatik.de) (dose)


Lesenswert?

cordic schreibt man am besten als eine Funktion, die sich rekursiv 
aufruft.
Die Tiefe der Rekursion als generic Wert übergeben.

von Alex (Gast)


Lesenswert?

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

von Alex (Gast)


Angehängte Dateien:

Lesenswert?

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

von Alex (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.