www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Problem bei Zuweisung mit nicht konstantem Range im std_logic_vector


Autor: Matthias G. (mgottke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe ein Modul geschrieben in dem vereinfacht dargestellt 4 Byte 
Eingangsdaten (von einem 32-Bit Datenbus) ankommen und nacheinander in 
ein durch ein generic festgelegten Ausgangsvektor (typ std_logic_vector) 
kopiert werden. Dabei ist in einer Tabelle festgelegt in welcher 
Reihenfolge und wie viele Bytes aus den 32-Bit Eingangsdaten und mit 
welchem Offset jeweils in den Ausgabevektor kopiert werden sollen.
Zur Darstellung mal ein Ausschnitt aus dem Erstentwurf:
entity my_modul is
generic
(
   NO_OF_BYTE  : positive -- Breite des Ausgabevektors in Byte
);
port
(
   ...
   indata    : in  std_logic_vector (31 downto 0);
   outdata   : out std_logic_vector (NO_OF_BYTE*8-1 downto 0);
   ...
);
end my_modul;
architecture behavior of my_modul is
   ...
   type copy_param is record
      offset   : natural  range 0 to 3;
      cnt      : positive range 1 to 4;
      posi      : natural  range 0 to NO_OF_BYTE-1;
   end record;
   constant MAX_COPYS : natural := ((NO_OF_BYTE + 3)/4) + 1;   -- max. Anz. der Kopiervorgänge
   type   copy_list is array (0 to MAX_COPYS-1) of copy_param; -- Liste der Kopiervorgänge
   ...
begin
   ...
   copy_proc : process (clk)
   begin
      if rising_edge(clk) then
         ...
         outdata((copy_list(list_pos).posi + copy_list(list_pos).cnt)*8-1 downto copy_list(list_pos).posi*8)
                <= avm_readdata((copy_list(list_pos).offset + copy_list(list_pos).cnt)*8-1 downto copy_list(list_pos).offset*8); -- Zeile der Fehlermeldung (413)
         ...
      end if;
   end process;
end behavior;
Soweit so gut, das funktioniert auch sehr schön in der Simulation, aber 
die Synthese meckert an:
Error (10394): VHDL error at my_modul.vhd(413): left bound of range must be a constant
Die Synthesetools (zumindest das verwendete) sind noch zu "dumm" um den 
Sinn dahinter zu erkennen. Nun stehe ich vor dem Problem wie ich das 
gelöst bekommen.
Dazu habe ich eine synthetisierbare Variante realisiert. Da ist für jede 
Kombination im Record mit generate ein kombinatorischer Vektor 
generiere, den ich dann auf meinen Ausgang muxe. Das führt aber leider 
dazu, dass die Synthese das nicht vernünftig auflösen kann und das 
Design in seiner Größe explodiert. Vermutet habe ich das schon vorher, 
aber einen Versuch war es schon Wert. Mein NO_OF_BYTE in meinem Projekt 
mehrfach instanziiert und liegt zwischen 1 und 16.
Hier mein mein "Explosionsansatz":
...
architecture behavior of my_modul is
   ...
   signal outdata_i : std_logic_vector (NO_OF_BYTE*8-1 downto 0);
   type   type_table is array (0 to 3, 1 to 4, 0 to NO_OF_BYTE-1) of std_logic_vector (32+NO_OF_BYTE*8-1 downto 0);
   signal outdata_table : type_table;
   ...
begin
   ...
   copy_proc : process (clk)
   begin
      if rising_edge(clk) then
         ...
         outdata_i <= outdata_table(copy_list(list_pos).offset, copy_list(list_pos).cnt, copy_list(list_pos).pos)(NO_OF_BYTE*8-1 downto 0);
         ...
      end if;
   end process;
      
   outdata <= outdata_i;

   gen_offset : for offset in 0 to 3 generate
      gen_cnt : for cnt in 1 to 4 generate
         gen_posi : for posi in 0 to NO_OF_BYTE-1 generate
             table_proc : process (indata, outdata_i)
                variable v_indata : std_logic_vector (63 downto 0);
             begin
                user_readdata_table(byte_offset,byte_cnt,user_byte_pos) <= x"00000000" & outdata_i;
                v_indata := x"00000000" & indata;
                outdata_table(offset,cnt,posi)((posi+cnt)*8-1 downto posi*8)
                   <= v_indata((offset+cnt)*8-1 downto offset*8);
            end process;
         end generate;
      end generate;
   end generate;
      
end behavior;
An sich sollte das ohne nennenswerten Ressourcenverbrauch gelingen 
können, da ja jedem Byte im Ausgangsvektor maximal 4 verschiedene Byte 
von den Eingängen her zugewiesen bekommen können. Das sollte doch die 
Synthese das mit einem einfachen Mux hin bekommen. Für jedes Bit im 
Ausgangsvektor müsste ein Mux mit 4 Eingängen entstehen. Bleibt also nur 
noch die Mux-Logik übrig. Allein der Ansatz dazu fehlt mir im Moment.
Hat jemand einen gute Idee wie ich das vielleicht lösen könnte?

Autor: Matthias G. (mgottke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach dem ich so viele Antworten bekommen habe, habe ich das ganze Modul 
nochmal neu aufgesetzt und die Funktionalität mit einem etwas anderen 
Ansatz gelöst. So ein Projekt wächst und verwächst sich auch manchmal. 
Das neue Design ist jetzt schlanker, schicker und schneller. :-)
Leider war aber dafür ein ganzer Tag Arbeit nötig. :-(
Zum Glück gab es schon die Testbench und die Testpattern, so dass an 
dieser Stelle nichts mehr zu tun war. Die Schnittstelle und die 
Funktionalität ist ja gleich geblieben.

Allerdings würde mich schon noch interessieren ob jemand eine Idee hat 
wie ich das Problem mit dem alten Design gelöst bekommen hätte.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Synthesetools (zumindest das verwendete) sind noch zu "dumm" um den
> Sinn dahinter zu erkennen.
Ja nun, sowas ist ja noch ein stupider Multiplexer:
outdata((copy_list(list_pos).posi + copy_list(list_pos).cnt)*8-1 downto copy_list(list_pos).posi*8)
Aber weil du das Ganze taktest, muß auch das Clock-Enable der FFs 
entsprechend umgeschaltet werden. Ich könnte mir vorstellen, dass das 
Probleme machen könnte...

Bei deinem 2. Ansatz ist das alles statisch und die Toolchain kann deine 
Absicht eher erkennen.

> Das neue Design ist jetzt schlanker, schicker und schneller. :-)
Mich hat auch der Verdacht beschlichen, dass du mit dem obigen Ansatz 
irgendwas ziemlich umwegbehaftet lösen wolltest.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.