function problem

O

Olaf Petzold

Guest
Hi,

at this time I try to write a ram banking entity (using XC2S100
internal block ram as one architecture; the infering ram architecture
is working):

entity ram_256x16 is

generic (
RESET_ACTIVE : std_logic := '1';
BIT_WIDTH : positive := 16
);
port (
clk : in std_logic;
rst : in std_logic;
en : in std_logic; -- L75, error below refers
ADDR : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(BIT_WIDTH-1 downto 0);
DO : out std_logic_vector(BIT_WIDTH-1 downto 0);
we : in std_logic
);

end entity ram_256x16;

.....

entity ram_1536x16 is

generic (
RESET_ACTIVE : std_logic := '1';
BIT_WIDTH : positive := 16
);
port (
clk : in std_logic;
reset : in std_logic;
en : in std_logic;
AB : in std_logic_vector(10 downto 0);
DB_I : in std_logic_vector(BIT_WIDTH-1 downto 0);
DB_O : out std_logic_vector(BIT_WIDTH-1 downto 0);
we : in std_logic
);

end entity ram_1536x16;


architecture banking of ram_1536x16 is

alias ADDR : std_logic_vector(7 downto 0) is AB(7 downto 0);
alias CS : std_logic_vector(2 downto 0) is AB(10 downto 8);
signal clk_ram : std_logic;

function chip_sel (
addr : std_logic_vector(CS'length-1 downto 0);
en : std_logic;
idx : unsigned)
return std_logic is

begin
-- L181 won't compile; how to write this?
return (en = '1') and (unsigned(addr) = idx)

end function;

begin -- architecture RAMB4_S16_banking

bank0 : entity work.ram_256x16
port map (
CLK => clk,
RST => reset,
EN => chip_sel(CS, en, 0), -- L198 won't work
ADDR => ADDR,
DO => DB_O,
DI => DB_I,
WE => we
);

....

Concerning the return value of the function I get the error:

** Error:
xc2s100_ram.vhd(181): Type error resolving infix expression "and".

concerning the use of this function for EN = ... of instance bank0:

** Error: xc2s100_ram.vhd(198): No feasible entries for subprogram
"chip_sel".
** Error: xc2s100_ram.vhd(198): The actual for formal 'en' is not a
globally static expression.
** Error: xc2s100_ram.vhd(75): (vcom-1164) The actual expression for
formal port 'en' is an impure function.

What does it mean and how can I correct this?

The reason for this function is to force a logical combination and
avoid latches (generated before using if/else/case clause)

Thanks and Regards,
Olaf
 
Olaf Petzold wrote:

** Error: xc2s100_ram.vhd(75): (vcom-1164) The actual expression for
formal port 'en' is an impure function.

What does it mean and how can I correct this?
your function needs to be in a real process
since it does not have constant args. It needs to
be declared "impure function" as it has side effects.
see:
http://groups.google.com/groups?q=vhdl+actual+%22only+one+argument

-- Mike Treseler
 
** Error: xc2s100_ram.vhd(75): (vcom-1164) The actual expression for
formal port 'en' is an impure function.

What does it mean and how can I correct this?


your function needs to be in a real process
since it does not have constant args. It needs to
be declared "impure function" as it has side effects.
see:
http://groups.google.com/groups?q=vhdl+actual+%22only+one+argument
First, thanks for your help.

I solved the problem using an own process as you mentioned; as I did
right understand functions can't be used here (in VHDL '93 with impure
as well). I solved the problem by:


chip_sel: process (CS, en) is

variable bank, en_v : std_logic_vector(7 downto 0);

begin

case CS is
when "000" => bank := b"0000_0001"; -- bank #0
when "001" => bank := b"0000_0010"; -- bank #1
when "010" => bank := b"0000_0100"; -- bank #2

when "011" => bank := b"0000_1000"; -- bank #3

when "100" => bank := b"0001_0000"; -- bank #4
when "101" => bank := b"0010_0000"; -- bank #5
when others => bank := b"0000_0000";
end case;

case en is
when '0' => en_v := b"0000_0000";
when '1' => en_v := b"1111_1111";
when others => null;
end case;

sel <= bank and en_v;

end process;

...

bank0 : entity work.ram_256x16
port map (
EN => sel(0), -- RAM enable input
...

which looks quite complicated to me. Is there an easier way using std
libraries and their convert functions?

Thanks
Olaf
 
Olaf Petzold wrote:

I solved the problem using an own process as you mentioned;
Good work.

which looks quite complicated to me.
The logic description looks clear to me
and should get the job done. You might
paste this logic into the process now
driving cs and en and make sel an output port.
That would uncomplicated the structural entity.

Is there an easier way using std
libraries and their convert functions?
There are different ways, but yours
is good as any. This is non-numeric bit-banging.

You are welcome.

-- Mike Treseler
 
Hi,

a little bit disappointed over the restrictions/functionality of
functions used in the different contexts, I would like use it even for
the following piece of code (if it possible) to increase the readability:

build_ram: block is

begin
row_blocks: for i in 0 to NUM_COLS-1 generate
col_blocks: for j in 0 to NUM_ROWS-1 generate

-- RAM[en=sel(0),DB(7:0)] RAM[en=sel(1),DB(15:8)]
-- RAM[en=sel(2),DB(23:16)]
-- RAM[en=sel(3),DB(7:0)] RAM[en=sel(4),DB(15:8)]
-- RAM[en=sel(5),DB(23:16)]
-- RAM[en=sel(6),DB(7:0)] RAM[en=sel(7),DB(15:8)]
-- RAM[en=sel(8),DB(23:16)]

ram_i : entity work.ram_512x8
port map (
CLK => clk_buf,
RST => reset,
EN => sel(i*NUM_ROWS + j),
ADDR => ADDR,
DO => DB_O((8*j+7) downto 8*j),
DI => DB_I((8*j+7) downto 8*j),
WE => we
);

end generate;
end generate;

end block;

It does compile. The goal is to create a block ram of 24 bit with, 2k
deep using 4k blocks (yes, it's xilinx Spartan-2 ;-). I would like use
variables, which are forbidden in this context (and no idea how to
write this using a process which would allow this). A function would
have the side effect as mentioned (impure may help? - didn't helped
for the other problem earlier here).

BTW, I use the webpack, where the coregen isn't included/functional;
and I know inferring memory is easier and it's used for an alternate
achitecture.

Thanks
Olaf
 

Welcome to EDABoard.com

Sponsor

Back
Top