Forum: FPGA, VHDL & Co. Verdrahtung von Instanzen mit generate


von S. R. (svenska)


Lesenswert?

Hi,

ich möchte mehrere Instanzen eines Blocks (Peripherie) haben können, die 
je nach Adresse selektiert werden. In der Architecture habe ich dazu 
folgenden Code (gekürzt):
1
GEN_channel_src :
2
for I in 0 to NUM_CHANNEL_SRC-1 generate
3
  chsrc : channel_src
4
  port map (
5
    clk    => clk,
6
    sreq   => chsrc_sreq(I),     -- request
7
    saddr  => saddr(5 downto 0), -- address
8
    swdata => swdata,
9
    srdata => chsrc_srdata(I),
10
    sready => chsrc_sready(I),
11
  );
12
  chsrc_sreq(I) <= sreq when
13
    saddr(19 downto 10) = "1000000001" and
14
    saddr(9 downto 6) = std_logic_vector(to_unsigned(natural(I), 4))
15
    else "00";
16
end generate;

Die vorwärts gerichteten Signale (in den Block hinein) kriege ich so 
verarbeitet, aber ich habe ein Problem mit den rückwärts gerichteten 
Signalen. Bisher hatte ich da ein concurrent assignment:
1
  srdata <= ctrl_srdata or chsrc_srdata(0) or chsrc_srdata(1) or chsrc_srdata(2) or chsrc_srdata(3);
2
  sready <= ctrl_sready and chsrc_sready(0) and chsrc_sready(1) and chsrc_sready(2) and chsrc_sready(3);

Was ich natürlich immer anpassen muss, wenn sich die Anzahl der 
Instanzen ändert. Im Prinzip will ich ein wired-or bzw. wired-and haben, 
aber Tristate gibt's im FPGA nicht (muss synthetisierbar sein).

Mit Variablen in einem process sollte das gehen, aber dann ist die 
Verdrahtung optisch getrennt von den Generates. Gibt es da eine bessere 
Lösung?

Schöne Grüße

von SeriousSam (Gast)


Lesenswert?

Ich würde es ungefähr so versuchen:
1
SIGNAL wired_and : std_logic_vector(0 TO NUM_CHANNEL_SRC) := (OTHERS=>'1');
2
SIGNAL wired_or : std_logic_vector(0 TO NUM_CHANNEL_SRC) := (OTHERS=>'0');
im Generate:
1
wired_and(I) <= chsrc_sready(I) and wired_and(I+1);
2
wired_or(I) <= chsrc_srdata(I) or wired_or(I+1);
Danach mit wired_and(0) und wired_or(0) weiterarbeiten. Der Synthesizer 
kann daraus hoffentlich den passenden Baum machen.

von Blechbieger (Gast)


Lesenswert?

Schau dir mal or_reduce und and_reduce in std_logic_misc an.

von Vancouver (Gast)


Lesenswert?

S. R. schrieb:
> aber dann ist die
> Verdrahtung optisch getrennt von den Generates.

Das stimmt zwar, ist aber eigentlich hier kein Problem. Das 
generate-Statement beschreibt eine Menge von gleichartigen Instanzen, 
aber das Gatter zur OR/AND-Verknüpfung der einzelenen Bits deines 
Vektors gibt es nur einmal und ist damit logisch gesehen kein 
Bestandteil der generate loop.

Die kannst die "Veroderung" übrigens sehr elegant berechnen, indem Du 
den Vektor mit einem Null-Vektor vergleichst, bzw. mit einem 1-Vektor 
für die "Verundung".

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


Lesenswert?

Ich habe ein  habe ein Signal BSEL das ein Vector ist.  Das Signal 
fungiert als Auswahlschalter.




---BUS multiplexer
    BBUS_out <= slave(0) when BSEL(0)='1' else  --DRAM
    slave(1)             when BSEL(2)='1' else  --UART
    slave(2);   --Bus Dummy



schau in
http://www.dossmatik.de/mais-cpu.html
Datei MAIS.vhd

von S. R. (svenska)


Lesenswert?

Vancouver schrieb:
> Das stimmt zwar, ist aber eigentlich hier kein Problem.

Jetzt hab ichs mit einem Prozess gelöst, der über die Instanzen in eine 
Variable iteriert und das funktioniert. Ich gehe mal davon aus, dass der 
Synthesizer sich das schon passend hinfummelt. :-)

Vancouver schrieb:
> Die kannst die "Veroderung" übrigens sehr elegant berechnen, indem Du
> den Vektor mit einem Null-Vektor vergleichst, bzw. mit einem 1-Vektor
> für die "Verundung".

Das geht, wenn man die Bits in einem Vektor verarbeiten will, aber ich 
habe Arrays von Bits (ready-Signale) bzw. Arrays von Vektoren 
(rdata-Signale). Damit geht das nicht.

René D. schrieb:
> Ich habe ein  habe ein Signal BSEL das ein Vector ist.  Das Signal
> fungiert als Auswahlschalter.

So ein Signal habe ich nicht (bzw. nur implizit durch die Kombination 
aus Request und Adresse). Das eigentliche Problem war aber, die Slaves 
nicht explizit auflisten zu müssen.

von VHDL hotline (Gast)


Lesenswert?

Wenn du es unbedingt im generate haben möchtest, dann baue dir eine 
1-Bit OR bzw. AND entity und instanzierie die mit.

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


Lesenswert?

> René D. schrieb:
>> Ich habe ein  habe ein Signal BSEL das ein Vector ist.  Das Signal
>> fungiert als Auswahlschalter.
>
> So ein Signal habe ich nicht (bzw. nur implizit durch die Kombination
> aus Request und Adresse). Das eigentliche Problem war aber, die Slaves
> nicht explizit auflisten zu müssen.

Es wird bei mir letztendlich auch aus den Adressen gebildet.
Dafür habe ich ein Funktion geschrieben die aus den Adressen das Select 
Signal konvertiert.
1
function BSEL_f (higher_addr : in std_logic_vector(31 downto 28) )
2
    return std_logic_vector
3
  is
4
  
5
    variable var    : std_logic_vector(15 downto 0);
6
    
7
  begin
8
  
9
    case higher_addr(31 downto 28) is
10
      when "0000" =>    var:="0000000000000001";  --0
11
      when "0001" =>    var:="0000000000000010";  --1
12
      when "0010" =>    var:="0000000000000100";  --2
13
      when "0011" =>    var:="0000000000001000";  --3
14
      when "0100" =>    var:="0000000000010000";  --4
15
      when "0101" =>    var:="0000000000100000";  --5
16
      when "0110" =>    var:="0000000001000000";  --6    
17
      when "0111" =>    var:="0000000010000000";  --7
18
      when "1000" =>    var:="0000000100000000";  --8
19
      when "1001" =>    var:="0000001000000000";  --9
20
      when "1010" =>    var:="0000010000000000";  --A
21
      when "1011" =>    var:="0000100000000000";  --B
22
      when "1100" =>    var:="0001000000000000";  --C
23
      when "1101" =>    var:="0010000000000000";  --D
24
      when "1110" =>    var:="0100000000000000";  --E    
25
      when "1111" =>    var:="1000000000000000";  --F   
26
      when others =>    var:="0000000000000000";                                            
27
    end case;
28
29
    return var;
30
  end;

von Duke Scarring (Gast)


Lesenswert?

René D. schrieb:
> case higher_addr(31 downto 28) is
>       when "0000" =>    var:="0000000000000001";  --0
>       when "0001" =>    var:="0000000000000010";  --1
>       when "0010" =>    var:="0000000000000100";  --2

Ah, der gute alte 74LS138 in VHDL...

von (º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· (Gast)


Lesenswert?

> Ah, der gute alte 74LS138 in VHDL...

Eher der 74154...

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.