help with if ...(probably very lame question)

M

Mariusz

Guest
Hello. I have one question. I want to use different component depending on
the given address. But when i try to do this using if RelAddress = "xxx"
then i have the error message which says that '=' is not static. I'v been
trying to put this in process, but it gave me even more errors. I also tried
case but it didn't work for me. I'm completely new in vhdl so i just don't
know what should i do to make it work. Any clues?

I would be very gratefull for some help...
Here is my code:

entity mem_part is
Port (
WrEn : in std_logic;
Clk : in std_logic;
Address : in std_logic_vector (0 to 14);
DIn : in std_logic_vector (0 to 0);
DOut : out std_logic_vector (0 to 0));
end mem_part;

architecture Behavioral of mem_part is
signal ToLow, ToHigh : std_logic;
signal FinalAdress : std_logic_vector (0 to 11);
signal RelAddress : std_logic_vector (0 to 2);
begin

ADD: for i in 0 to 2 generate
RelAddress(i) <= Address(i);
end generate;

FINAL: for i in 3 to 14 generate
FinalAdress(i-3) <= Address(i);
end generate;

ToLow <= '0';
ToHigh <= '1';

TRAM1 : if RelAddress = "000" generate
RAM1: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM2 : if RelAddress = "001" generate
RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM2 : if RelAddress = "010" generate
RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM3 : if RelAddress = "011" generate
RAM3: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM4 : if RelAddress = "100" generate
RAM4: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;



end Behavioral;
 
In your design, the if generate selects one memory
to put in the circuit for an entire simulation run.
If this were used to generate hardware, then
you would only have one memory.
If this is what you want, then bring RelAdress
in separately as a generic (hence static - or never
changes during a simulation run).

I think you want 5 memories on a bus.
This requires either tristate outputs or a
multiplexer to select the DOut you want to
read.

For a tristate, decode RelAdress to generate
a separate enable for each memory.

For a multiplexer, use a case statement to
read the DOut back and select an individual
DOut (note each DOut will need a unique name).

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:Jim@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Mariusz wrote:

Hello. I have one question. I want to use different component depending on
the given address. But when i try to do this using if RelAddress = "xxx"
then i have the error message which says that '=' is not static. I'v been
trying to put this in process, but it gave me even more errors. I also tried
case but it didn't work for me. I'm completely new in vhdl so i just don't
know what should i do to make it work. Any clues?

I would be very gratefull for some help...
Here is my code:

entity mem_part is
Port (
WrEn : in std_logic;
Clk : in std_logic;
Address : in std_logic_vector (0 to 14);
DIn : in std_logic_vector (0 to 0);
DOut : out std_logic_vector (0 to 0));
end mem_part;

architecture Behavioral of mem_part is
signal ToLow, ToHigh : std_logic;
signal FinalAdress : std_logic_vector (0 to 11);
signal RelAddress : std_logic_vector (0 to 2);
begin

ADD: for i in 0 to 2 generate
RelAddress(i) <= Address(i);
end generate;

FINAL: for i in 3 to 14 generate
FinalAdress(i-3) <= Address(i);
end generate;

ToLow <= '0';
ToHigh <= '1';

TRAM1 : if RelAddress = "000" generate
RAM1: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM2 : if RelAddress = "001" generate
RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM2 : if RelAddress = "010" generate
RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM3 : if RelAddress = "011" generate
RAM3: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM4 : if RelAddress = "100" generate
RAM4: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;



end Behavioral;
 
Thanx. But i have next questions...

For a tristate, decode RelAdress to generate
a separate enable for each memory.
How i'm supposed to do this?

For a multiplexer, use a case statement to
read the DOut back and select an individual
DOut (note each DOut will need a unique name).
And what DOut has to do with that? And what about DIn?

If You would be so kind and give me some code sample i would be very
gratefull.

--
Regards
Mariusz
 
Mariusz wrote:

For a tristate, decode RelAdress to generate
a separate enable for each memory.


How i'm supposed to do this?
Let the address decide, witch memory block is allowed to write to the
data bus.
The use the following template:

process(cond_signal,data_from_blockX)
begin
if (cond_signal='1') then
dout <= data_from_blockX;
else dout <= (others => 'Z');
end if;
end process;

Make sure, that the bus dout is driven _everytime_! Make sure, that only
_one_ driver is activated.

The signal dout as to be of type std_logic(_vector), because it has to
be resoled (multiple drivers).


For a multiplexer, use a case statement to
read the DOut back and select an individual
DOut (note each DOut will need a unique name).


And what DOut has to do with that? And what about DIn?
You are not allowed to write to one signal from different processes,
except you model a tri-state driver, like described above. Therefor the
output "dout" of every component has to be named different (dout_comp1,
dout_comp2...).
With a case (or if) statement you select, witch dout_compX is chosen
finally. Only in the case (or if) statement dout is driven.

Ralf
 
I think it will be really hard, cause i just don't understand it at all. I
would be very gratefull if You would change my code to work properly. Or
maybe just the part of it. Cause i just don't understand how i'm supposed to
use multiple components by changing data_from_blockX.
Anyway - when i put my component in process, compiler gives me an error
which says that DI must have default value, and that port map is unexpected.

For a tristate, decode RelAdress to generate
a separate enable for each memory.


How i'm supposed to do this?

Let the address decide, witch memory block is allowed to write to the
data bus.
The use the following template:

process(cond_signal,data_from_blockX)
begin
if (cond_signal='1') then
dout <= data_from_blockX;
else dout <= (others => 'Z');
end if;
end process;

Make sure, that the bus dout is driven _everytime_! Make sure, that only
_one_ driver is activated.

The signal dout as to be of type std_logic(_vector), because it has to
be resoled (multiple drivers).


For a multiplexer, use a case statement to
read the DOut back and select an individual
DOut (note each DOut will need a unique name).


And what DOut has to do with that? And what about DIn?

You are not allowed to write to one signal from different processes,
except you model a tri-state driver, like described above. Therefor the
output "dout" of every component has to be named different (dout_comp1,
dout_comp2...).
With a case (or if) statement you select, witch dout_compX is chosen
finally. Only in the case (or if) statement dout is driven.

Ralf
 
Mariusz wrote:

I think it will be really hard, cause i just don't understand it at all. I
would be very gratefull if You would change my code to work properly. Or
maybe just the part of it. Cause i just don't understand how i'm supposed to
use multiple components by changing data_from_blockX.
Anyway - when i put my component in process, compiler gives me an error
which says that DI must have default value, and that port map is unexpected.

If Jim guessed right, you want 5 RAM-instances, each for a different
address range. The following code is not tested. (I have no VHDL
simulator at this computer.) There are some comments in the code,
because your code was not clear to me.


-- note: (0 to 14) is not recommended
-- use (14 downto 0)
-- I left the entitiy unchanged - make your corrections.
entity mem_part is
Port (
WrEn : in std_logic;
Clk : in std_logic;
Address : in std_logic_vector (0 to 14);
DIn : in std_logic_vector (0 to 0); -- 0 to 0????
DOut : out std_logic_vector (0 to 0)); -- 0 to 0????
end mem_part;


architecture Behavioral of mem_part is
signal en_RAM1, en_RAM2, en_RAM3, en_RAM4, en_RAM5 : std_ulogic;

signal dout_RAM1,dout_RAM2,dout_RAM3,dout_RAM4,dout_RAM5 :
std_logic_vector(0 downto 0)); -- 0 to 0????

signal ToLow, ToHigh : std_logic;
signal FinalAdress : std_logic_vector (0 to 11);
signal RelAddress : std_logic_vector (0 to 2);
begin

ADD: process(Address) -- I replaced the generate statement
begin
for i in 0 to 2 loop
RelAddress(i) <= Address(i);
end loop;
end process;

FINAL: process(Address)
begin
for i in 3 to 14 loop
FinalAdress(i-3) <= Address(i);
end loop;
end generate;
-- The last two processes can be written simpler, but I am no sure,
what was your intention. So I left the structure similar.


ToLow <= '0';
ToHigh <= '1';

-- RAM selector
process(RelAdress)
begin
-- defaults (for combinational logic)
en_RAM1<='0';
en_RAM2<='0';
en_RAM3<='0';
en_RAM4<='0';
en_RAM5<='0';
case RelAdress is
when "000" => en_RAM1<='1';
when "001" => en_RAM2<='1';
when "010" => en_RAM3<='1';
when "011" => en_RAM4<='1';
when "100" => en_RAM5<='1';
when others => null;
end case;
end process;


RAM1: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM1,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut_RAM1);

RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM2,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut2);

RAM3: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM3,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut_RAM3);

RAM4: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM4,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut_RAM4);

RAM5: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM5,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut_RAM5);

-- tri state mux variant:
process(en_RAM1,DOut_RAM1)
begin
if (en_RAM1) then
dout<=DOut_RAM1;
else dout<=(others=>'Z');
end if;
end process;

process(en_RAM2,DOut_RAM2)
begin
if (en_RAM2) then
dout<=DOut_RAM2;
else dout<=(others=>'Z');
end if;
end process;

process(en_RAM3,DOut_RAM3)
begin
if (en_RAM3) then
dout<=DOut_RAM3;
else dout<=(others=>'Z');
end if;
end process;

process(en_RAM4,DOut_RAM4)
begin
if (en_RAM4) then
dout<=DOut_RAM4;
else dout<=(others=>'Z');
end if;
end process;

process(en_RAM5,DOut_RAM5)
begin
if (en_RAM5) then
dout<=DOut_RAM5;
else dout<=(others=>'Z');
end if;
end process;

-- no RAM is selected -> drive the bus
process(en_RAM1,en_RAM2,en_RAM3,en_RAM4,en_RAM5)
begin
if (en_RAM1='0' AND en_RAM2='0' AND en_RAM3='0' AND en_RAM4='0' AND
en_RAM5='0') then
dout<=(others=>'0');
else dout<=(others=>'Z');
end if;
end process;



Another question: Is RAMB4_S1 a real RAM block? If yes, often there are
tri state output drivers included, this means, if you disable the RAM,
the output becomes 'Z' and the final mux partially obsolete and only the
last process is needed.


Note: I guessed like Jim Lewis, what your code should do, but I am not
sure. Therefor check *semantics*!
(Syntactical mistakes will be found, too - I guess. ;-) )


Ralf
 
Thanx a lot. And Yes, i wanted to have 5 different memory block. Now i'm
going to check out Your code :)

Uzytkownik "Ralf Hildebrandt" <Ralf-Hildebrandt@gmx.de> napisal w wiadomosci
news:bu6iaa$e3rff$1@ID-8609.news.uni-berlin.de...
Mariusz wrote:

I think it will be really hard, cause i just don't understand it at all.
I
would be very gratefull if You would change my code to work properly. Or
maybe just the part of it. Cause i just don't understand how i'm
supposed to
use multiple components by changing data_from_blockX.
Anyway - when i put my component in process, compiler gives me an error
which says that DI must have default value, and that port map is
unexpected.


If Jim guessed right, you want 5 RAM-instances, each for a different
address range. The following code is not tested. (I have no VHDL
simulator at this computer.) There are some comments in the code,
because your code was not clear to me.


-- note: (0 to 14) is not recommended
-- use (14 downto 0)
-- I left the entitiy unchanged - make your corrections.
entity mem_part is
Port (
WrEn : in std_logic;
Clk : in std_logic;
Address : in std_logic_vector (0 to 14);
DIn : in std_logic_vector (0 to 0); -- 0 to 0????
DOut : out std_logic_vector (0 to 0)); -- 0 to 0????
end mem_part;


architecture Behavioral of mem_part is
signal en_RAM1, en_RAM2, en_RAM3, en_RAM4, en_RAM5 : std_ulogic;

signal dout_RAM1,dout_RAM2,dout_RAM3,dout_RAM4,dout_RAM5 :
std_logic_vector(0 downto 0)); -- 0 to 0????

signal ToLow, ToHigh : std_logic;
signal FinalAdress : std_logic_vector (0 to 11);
signal RelAddress : std_logic_vector (0 to 2);
begin

ADD: process(Address) -- I replaced the generate statement
begin
for i in 0 to 2 loop
RelAddress(i) <= Address(i);
end loop;
end process;

FINAL: process(Address)
begin
for i in 3 to 14 loop
FinalAdress(i-3) <= Address(i);
end loop;
end generate;
-- The last two processes can be written simpler, but I am no sure,
what was your intention. So I left the structure similar.


ToLow <= '0';
ToHigh <= '1';

-- RAM selector
process(RelAdress)
begin
-- defaults (for combinational logic)
en_RAM1<='0';
en_RAM2<='0';
en_RAM3<='0';
en_RAM4<='0';
en_RAM5<='0';
case RelAdress is
when "000" => en_RAM1<='1';
when "001" => en_RAM2<='1';
when "010" => en_RAM3<='1';
when "011" => en_RAM4<='1';
when "100" => en_RAM5<='1';
when others => null;
end case;
end process;


RAM1: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM1,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut_RAM1);

RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM2,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut2);

RAM3: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM3,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut_RAM3);

RAM4: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM4,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut_RAM4);

RAM5: RAMB4_S1 port map( WE=>WrEn,
EN => en_RAM5,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut_RAM5);

-- tri state mux variant:
process(en_RAM1,DOut_RAM1)
begin
if (en_RAM1) then
dout<=DOut_RAM1;
else dout<=(others=>'Z');
end if;
end process;

process(en_RAM2,DOut_RAM2)
begin
if (en_RAM2) then
dout<=DOut_RAM2;
else dout<=(others=>'Z');
end if;
end process;

process(en_RAM3,DOut_RAM3)
begin
if (en_RAM3) then
dout<=DOut_RAM3;
else dout<=(others=>'Z');
end if;
end process;

process(en_RAM4,DOut_RAM4)
begin
if (en_RAM4) then
dout<=DOut_RAM4;
else dout<=(others=>'Z');
end if;
end process;

process(en_RAM5,DOut_RAM5)
begin
if (en_RAM5) then
dout<=DOut_RAM5;
else dout<=(others=>'Z');
end if;
end process;

-- no RAM is selected -> drive the bus
process(en_RAM1,en_RAM2,en_RAM3,en_RAM4,en_RAM5)
begin
if (en_RAM1='0' AND en_RAM2='0' AND en_RAM3='0' AND en_RAM4='0' AND
en_RAM5='0') then
dout<=(others=>'0');
else dout<=(others=>'Z');
end if;
end process;



Another question: Is RAMB4_S1 a real RAM block? If yes, often there are
tri state output drivers included, this means, if you disable the RAM,
the output becomes 'Z' and the final mux partially obsolete and only the
last process is needed.


Note: I guessed like Jim Lewis, what your code should do, but I am not
sure. Therefor check *semantics*!
(Syntactical mistakes will be found, too - I guess. ;-) )


Ralf
 
I compiled ur code using modelsim.
all i had to do was add a component declaration for ur RAM and changed
the labels for the generate statements since two statements had the
same label.
seems ur code is compiling just fine and i didnt see any compilation
error as u have said . wonder what that was all about.
Sajan

Here is ur code with the veru slight changes i have mentioned.


library ieee;
use ieee.std_logic_1164.all;
library std;

entity mem_part is
Port (
WrEn : in std_logic;
Clk : in std_logic;
Address : in std_logic_vector (0 to 14);
DIn : in std_logic_vector (0 to 0);
DOut : out std_logic_vector (0 to 0));
end mem_part;

architecture Behavioral of mem_part is
signal ToLow, ToHigh : std_logic;
signal FinalAdress : std_logic_vector (0 to 11);
signal RelAddress : std_logic_vector (0 to 2);

component RAMB4_S1 is port (
WE: in std_logic;
EN: in std_logic;
RST: in std_logic;
Clk: in std_logic;
Addr: in std_logic_vector(0 to 11);
DI : in std_logic_vector(0 to 0);
DO : out std_logic_vector(0 to 0)
);
end component;

begin

ADD: for i in 0 to 2 generate
RelAddress(i) <= Address(i);
end generate;

FINAL: for i in 3 to 14 generate
FinalAdress(i-3) <= Address(i);
end generate;

ToLow <= '0';
ToHigh <= '1';

TRAM0 : if RelAddress = "000" generate
RAM0: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;

TRAM1 : if RelAddress = "001" generate
RAM1: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;

TRAM2 : if RelAddress = "010" generate
RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;

TRAM3 : if RelAddress = "011" generate
RAM3: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;

TRAM4 : if RelAddress = "100" generate
RAM4: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;

end Behavioral;


"Mariusz" <mariusz@elysium.home.pl> wrote in message news:<40046a0e@news.home.net.pl>...
Hello. I have one question. I want to use different component depending on
the given address. But when i try to do this using if RelAddress = "xxx"
then i have the error message which says that '=' is not static. I'v been
trying to put this in process, but it gave me even more errors. I also tried
case but it didn't work for me. I'm completely new in vhdl so i just don't
know what should i do to make it work. Any clues?

I would be very gratefull for some help...
Here is my code:

entity mem_part is
Port (
WrEn : in std_logic;
Clk : in std_logic;
Address : in std_logic_vector (0 to 14);
DIn : in std_logic_vector (0 to 0);
DOut : out std_logic_vector (0 to 0));
end mem_part;

architecture Behavioral of mem_part is
signal ToLow, ToHigh : std_logic;
signal FinalAdress : std_logic_vector (0 to 11);
signal RelAddress : std_logic_vector (0 to 2);
begin

ADD: for i in 0 to 2 generate
RelAddress(i) <= Address(i);
end generate;

FINAL: for i in 3 to 14 generate
FinalAdress(i-3) <= Address(i);
end generate;

ToLow <= '0';
ToHigh <= '1';

TRAM1 : if RelAddress = "000" generate
RAM1: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM2 : if RelAddress = "001" generate
RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM2 : if RelAddress = "010" generate
RAM2: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM3 : if RelAddress = "011" generate
RAM3: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;
TRAM4 : if RelAddress = "100" generate
RAM4: RAMB4_S1 port map( WE=>WrEn,
EN => ToHigh,
RST => ToLow,
Clk => Clk,
Addr => FinalAdress,
DI=> DIn,
DO=> DOut);
end generate;



end Behavioral;
 

Welcome to EDABoard.com

Sponsor

Back
Top