Forum: FPGA, VHDL & Co. Anweisung um Block-RAM zu vermeiden ??


von FPGA-Fragender (Gast)


Lesenswert?

Hallo zusammen,

ich arbeite in VHDL an einem größeren Projekt. ( Xilinx XC3S400 ) WEB 
ISE

Ich habe das Problem, dass der Compiler ein Quasi ROM, das in VHDL 
formuliert ist in der Synthese immer als Block-Ram anleget.

DAs wäre zunächst nicht weiter schlimm. Allerdings ist die maximale 
Anzahl der Block-RAMs des Bausteins schon ausgeschöpt und beim Place and 
Route, das sonst fehlerfrei durchläuft, wird angezeigt, dass der Entwurf 
eben nicht in den vorgegebenen Baustein passt.  :-((

Dabei hab ich noch Logik Zellen usw. frei, so dass das ganze auch als 
distri. Logik angelegt werden könnte. Wie kann ich dem Compiler sagen, 
dass er

1. entweder für einen best. Abschnitt kein Block-RAm anlegen soll
2. falls die max. Anzahl an Block-Rams überschritten wird, das ganze in 
distri. Logik angelegt werden soll.

Hier ein Code Beispiel:

entity rom_BitLen_ac_uv is
  PORT ( CLK                        : IN std_logic;
         RST                        : IN std_logic;
         start_section_one          : IN std_logic;
         Value_to_write             : IN  std_logic_vector(7 downto 0);
     BitLen_to_write_ac_uv      : OUT std_logic_vector(4 downto 0)
      );
end rom_BitLen_ac_uv;


architecture Behavioral of rom_BitLen_ac_uv is

type Memory_256_5 is array ( 0 to 255) of std_logic_vector(4 downto 0) ;

constant ROM_AC_UV_BitLen : Memory_256_5 :=(
"00010", "00010", "00011", "00100", "00101", "00101", "00110", "00111", 
"01001", "01010", "01100", "00000", "00000", "00000", "00000", "00000",
"00000", "00100", "00110", "01000", "01001", "01011", "01100", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "00101", "01000", "01010", "01100", "01111", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "00101", "01000", "01010", "01100", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "00110", "01001", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "00110", "01010", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "00111", "01011", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "00111", "01011", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "01000", "10000", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "01001", "10000", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "01001", "10000", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "01001", "10000", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "01001", "10000", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "01011", "10000", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"00000", "01110", "10000", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000",
"01010", "01111", "10000", "10000", "10000", "10000", "10000", "10000", 
"10000", "10000", "10000", "00000", "00000", "00000", "00000", "00000");



signal   my_BitLen_to_write_ac_uv     : std_logic_vector(4 downto 0) ;

begin

-- -------------------------- Stufe 6 -------------------------------
--  BitLen_to_write_dc_ac_y_uv
--  ------------------------------------------------------------------

PROCESS (RST, CLK, start_section_one ) -- BitLen_to_write
BEGIN
 if (CLK'EVENT AND CLK = '1') THEN
      If RST = '1' Then
           my_BitLen_to_write_ac_uv  <= "00010" ; -- 2
      Else
          If (start_section_one = '0') Then
             my_BitLen_to_write_ac_uv  <= my_BitLen_to_write_ac_uv ;
          Else
             my_BitLen_to_write_ac_uv  <= 
ROM_AC_UV_BitLen(conv_integer(Value_to_write)) ;
          END IF ;
      end if ;
  END IF ;
END PROCESS ;

 BitLen_to_write_ac_uv <= my_BitLen_to_write_ac_uv ;

end Behavioral;

--------------------------------------------------------


Ich hab das ganze auch schon so probiert


entity rom_huffcode_ac_y_case is
  PORT ( CLK                               : IN std_logic;
         RST                               : IN std_logic;
         start_section_one                 : IN std_logic;
         Value_to_write                    : IN  std_logic_vector(7 
downto 0);
       HuffCode_to_write_ac_y            : OUT std_logic_vector(15 
downto 0) );
end rom_huffcode_ac_y_case;


architecture Behavioral of rom_huffcode_ac_y_case is


signal   my_HuffCode_to_write_ac_y            : std_logic_vector(15 
downto 0) ;

begin


PROCESS (RST, CLK, start_section_one ) -- HuffCode_to_write
BEGIN
 if (CLK'EVENT AND CLK = '1') THEN
      If RST = '1' Then
           my_HuffCode_to_write_ac_y  <= ( others => '0' ) ;
      Else
          If (start_section_one = '0') Then
             my_HuffCode_to_write_ac_y  <= my_HuffCode_to_write_ac_y ;
          Else


            case Value_to_write is
               when "00000000"   => my_HuffCode_to_write_ac_y  <= 
"1010000000000000" ;
               when "00000001"   => my_HuffCode_to_write_ac_y  <= 
"0000000000000000" ;
               when "00000010"   => my_HuffCode_to_write_ac_y  <= 
"0100000000000000" ;
               when "00000011"   => my_HuffCode_to_write_ac_y  <= 
"1000000000000000" ;
               when "00000100"   => my_HuffCode_to_write_ac_y  <= 
"1011000000000000" ;
               when "00000101"   => my_HuffCode_to_write_ac_y  <= 
"1101000000000000" ;
               when "00000110"   => my_HuffCode_to_write_ac_y  <= 
"1111000000000000" ;
               when "00000111"   => my_HuffCode_to_write_ac_y  <= 
"1111100000000000" ;
               when "00001000"   => my_HuffCode_to_write_ac_y  <= 
"1111110110000000" ;
               when "00001001"   => my_HuffCode_to_write_ac_y  <= 
"1111111110000010" ;
               when "00001010"   => my_HuffCode_to_write_ac_y  <= 
"1111111110000011" ;
               when "00010001"   => my_HuffCode_to_write_ac_y  <= 
"1100000000000000" ;
               when "00010010"   => my_HuffCode_to_write_ac_y  <= 
"1101100000000000" ;
               when "00010011"   => my_HuffCode_to_write_ac_y  <= 
"1111001000000000" ;
               when "00010100"   => my_HuffCode_to_write_ac_y  <= 
"1111101100000000" ;


usw. usw.


Beide Codes funktionieren prima. Aber der Compiler macht immer Block-RaM 
daraus.

Über Core-GEn kann man zwar ein ROM explizit als Distri ARithmetik 
anlegen, aber der CoreGen hat einen BUG.

DAs .Coe File, das ich angelegt hab ist 100% richtig, aber die Werte die 
der CoreGen im Priview anzeigt sind am Anfang falsch.
Ein zwei WErte falsch, danach sind alle anderen Richtig. Damit zu 
arbeiten macht keinen Spass.

Gruß vom FPGA-Fragenden

von TheMason (Gast)


Lesenswert?

versuchs mal mit den optionen. ich glaube da kann man einstellen ob man 
ram oder rom als Blockram oder Distributed ram haben möchte. vielleicht 
gibts da noch eine force-option (bin mir nicht sicher).

gruß
rene

von FPGA-Fragender (Gast)


Lesenswert?

Hallo TheMason,

nix für Ungut, aber dass man in den Optionen irgendwie oder etwas 
einstellen kann hab ich ja auch schon gedacht.

Nur das wie und wo ist ja gerade eben die Frage.  :-))

Wie gesagt ich habs ja schon auf verschiedene Weise versucht.

Gruß vom FPGA-Fragenden

von TheMason (Gast)


Lesenswert?

sry,

habe gerade leider kein ise9.x oder 8.x zur hand.
bin in sachen optimierung bzw. genaues einstellen der optionen leider 
kein experte. bei mir ist nur haften geblieben : rechtsklick auf 
synthesize, optionen und dann ne menge einstellungen :-))
aber da kann man dann meine ich auch den implementierungsstil für 
ram/rom usw festlegen.
vielleicht hülfts dir ja trotzdem :-)

gruß
rene

von Stefan H. (stefanhanke)


Lesenswert?

Wenn du in der "Synthesis Guide" nichts findest, gibt es immer noch den 
"Distributed Memory Generator", der dir entsprechende Cores erzeugt.
 -- stefan

von Michael N. (bigmike47)


Lesenswert?

rechtsklick auf synthesize --> properties --> hdl options --> ram bzw. 
rom style
geht auch im vhdl code mit dem attribute RAM_STYLE (oder eben 
ROM_STYLE), so kann man das auf einzelne entities oder module 
beschränken

von FPGA-Fragender (Gast)


Lesenswert?

Hallo zusammen,

ganz herzliches Dankeschön für jeden Beitrag.

Dem Hinweis von Michael Niegl werde ich genauer nachgehen, denn ich 
möchte ja nicht für alle module sondern für ausgewählte Module eine 
gewisse vorgabe erzwingen.

Ich hab allerdings bis jetzt  noch keine compiler Anweisungen in VHDL 
explizit gesetzt und weiß nicht genau wie man das formulieren muss.

Kann mir jemand ein Beispiel geben wie ganz allgemein solche Anweisungen 
aussehen.

z.B.

option RAM_STYLE  = xyz_Wert

oder so ähnlich ???

Gruß vom FPGA-Fragenden

von Michael N. (bigmike47)


Lesenswert?

attribute ram_style : string;
atrtibute ram_style of "name" : entity/module/whatever is "parameter"

von Stefan H. (stefanhanke)


Lesenswert?

"XST User Guide" -- "Synthesis Guide" gibts net ;-) --, p. 381
> attribute ram_style: string;
> attribute ram_style of {signal_name|entity_name}: {signal|entity} is
> “{auto|block|distributed|pipe_distributed}”;

 -- stefan

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.