modelsim error with synthesizeable VHDL

P

Patrick Erich

Hi,

I want to write a VHDL description in which the hardware generated
depends on some generic variables. For instance a register with
a_width inputs and y_width outputs; like so:

-------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity test is
generic ( a_width: integer;
y_width: integer);
port ( clk: in std_logic;
a : in std_logic_vector(a_width-1 downto 0);
y : out std_logic_vector(y_width-1 downto 0));
end test;


architecture behavior of test is
begin

lb0: process(clk)
begin
if (clk'event and clk='1') then
if (y_width > a_width) then
y(y_width-1 downto a_width) <= (others => '0');
y(a_width-1 downto 0) <= a;
else
y <= a(y_width-1 downto 0);
end if;
end if;
end process;

end behavior;
-------------------------------------------------------------------

This is what I want to do:
1) If y_width is larger than a_width, then I would like to store
the input a in the least significant bits of the register.
2) If y_width is smaller than (or equal to) a_width, then I would
like to store the least significant bits of a.

When using modelsim 5.6a (xilinx edition) to simulate, no problem
occurs as long as y_width is larger than a_width. On the other
hand, when I choose a_width to be larger than y_width modelsim
gives the following error:

# ** Fatal: (vsim-3421) Index 7 is out of range 3 downto 0.
# Time: 0 ps Iteration: 0 Region: /testbench/inst
# FATAL ERROR while loading design
# Error loading design
# Error: Error loading design

This description is synthesizeable according to xilinx's Project
Navigator 5.1i even with y_width smaller than a_width (only
warnings about unused inputs).

Can anyone explain to me please why modelsim is having a problem
with this description (while it is found to be synthesizeable)?

Thanks for your help,
Patrick Erich


This is the testbench
-------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;


entity testbench is end testbench;

architecture behavior of testbench is

component test
generic ( a_width: integer;
y_width: integer);
port ( clk: in std_logic;
a: in std_logic_vector(a_width-1 downto 0);
y: out std_logic_vector(y_width-1 downto 0));
end component;

signal clk: std_logic;
signal a: std_logic_vector(7 downto 0);
signal y: std_logic_vector(3 downto 0);

begin

inst: test generic map (a_width => 8,
y_width => 4)
port map (clk, a, y);

clk <= '0' after 0 ns,
'1' after 10 ns when clk /= '1' else
'0' after 10 ns;

a <= "00000000" after 0 ns,
"11111111" after 60 ns;

end behavior;
-------------------------------------------------------------------
 
T

Tero Kapanen

Hi Patrick,

If you can compile the code it does not mean that it is synthesizeable.

The problem is that the comparison is made in run time not beforehand.

If you change your process to something like:
-- lb0: process(clk) --
lb0: process(clk)
variable width : integer;
begin
if (clk'event and clk='1') then

if (y_width > a_width) then
width := a_width;
else
width := y_width;
end if;

y <= (others => '0');
y <= a(width-1 downto 0);

end if;
end process;
-- lb0: process(clk) --

Then there does not happen illegal indexing, i.e. the index is not outside
of the index range.

- tero
 
I

Ian Poole

Hi Patrick

This looks like a Modelsim oddity. I played with it a bit, and it seems to
be doing some hybrid of elaboration time checking of generics and run-time
checking of indexes. Anyway, as a work around, you could use GENERATE. Note,
there is no ELSE GENERATE!


library ieee;
use ieee.std_logic_1164.all;

entity test is
generic ( a_width: integer;
y_width: integer);
port ( clk: in std_logic;
a : in std_logic_vector(a_width-1 downto 0);
y : out std_logic_vector(y_width-1 downto 0));
end test;


architecture behavior of test is
begin

gen0:if y_width > a_width generate
lb0: process(clk)
begin
if (clk'event and clk='1') then
y(y_width-1 downto a_width) <= (others => '0');
y(a_width-1 downto 0) <= a;
end if;
end process;
end generate;

gen1: if not (y_width > a_width) generate
lb1: process(clk)
begin
if (clk'event and clk='1') then
y <= a(y_width-1 downto 0);
end if;
end process;
end generate;


end behavior;


HTH

--
Ian Poole, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
C

Charles M. Elias

Hi,

I want to write a VHDL description in which the hardware generated
depends on some generic variables. For instance a register with
a_width inputs and y_width outputs; like so:

-------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;

entity test is
generic ( a_width: integer;
y_width: integer);
port ( clk: in std_logic;
a : in std_logic_vector(a_width-1 downto 0);
y : out std_logic_vector(y_width-1 downto 0));
end test;


architecture behavior of test is
begin

lb0: process(clk)
begin
if (clk'event and clk='1') then
if (y_width > a_width) then
y(y_width-1 downto a_width) <= (others => '0');
y(a_width-1 downto 0) <= a;
else
y <= a(y_width-1 downto 0);
end if;
end if;
end process;

end behavior;
-------------------------------------------------------------------

This is what I want to do:
1) If y_width is larger than a_width, then I would like to store
the input a in the least significant bits of the register.
2) If y_width is smaller than (or equal to) a_width, then I would
like to store the least significant bits of a.

When using modelsim 5.6a (xilinx edition) to simulate, no problem
occurs as long as y_width is larger than a_width. On the other
hand, when I choose a_width to be larger than y_width modelsim
gives the following error:

# ** Fatal: (vsim-3421) Index 7 is out of range 3 downto 0.
# Time: 0 ps Iteration: 0 Region: /testbench/inst
# FATAL ERROR while loading design
# Error loading design
# Error: Error loading design

This description is synthesizeable according to xilinx's Project
Navigator 5.1i even with y_width smaller than a_width (only
warnings about unused inputs).

Can anyone explain to me please why modelsim is having a problem
with this description (while it is found to be synthesizeable)?

Thanks for your help,
Patrick Erich


This is the testbench
-------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;


entity testbench is end testbench;

architecture behavior of testbench is

component test
generic ( a_width: integer;
y_width: integer);
port ( clk: in std_logic;
a: in std_logic_vector(a_width-1 downto 0);
y: out std_logic_vector(y_width-1 downto 0));
end component;

signal clk: std_logic;
signal a: std_logic_vector(7 downto 0);
signal y: std_logic_vector(3 downto 0);

begin

inst: test generic map (a_width => 8,
y_width => 4)
port map (clk, a, y);

clk <= '0' after 0 ns,
'1' after 10 ns when clk /= '1' else
'0' after 10 ns;

a <= "00000000" after 0 ns,
"11111111" after 60 ns;

end behavior;
-------------------------------------------------------------------

Patrick,

My Active-HDL simulator got the same error. The simulator is
apparently evaluating (probably not the right word) the part of the if
statement "if (y_width > a_width) then..." even when the if condition
is not true. Someone with more knowledge about simulators will have
to tell us why. However the following approach gets rid of the error:

library ieee;
use ieee.std_logic_1164.all;

entity test is
generic ( a_width: integer;
y_width: integer);
port ( clk: in std_logic;
a : in std_logic_vector(a_width-1 downto 0);
y : out std_logic_vector(y_width-1 downto 0));
end test;


architecture behavior of test is
begin

gen0 : if y_width > a_width generate
lb0: process(clk)
begin
if (clk'event and clk='1') then
y(y_width-1 downto a_width) <= (others => '0');
y(a_width-1 downto 0) <= a;
end if;
end process;
end generate;

gen1: if y_width <= a_width generate
lb1: process(clk)
begin
if (clk'event and clk='1') then
y <= a(y_width-1 downto 0);
end if;
end process;
end generate;

--lb0: process(clk)
-- begin
-- if (clk'event and clk='1') then
-- if (y_width > a_width) then
-- y(y_width-1 downto a_width) <= (others => '0');
-- y(a_width-1 downto 0) <= a;
-- else
-- y <= a(y_width-1 downto 0);
-- end if;
-- end if;
-- end process;
end behavior;

I only tested this with the testbench as shown in your post.

Best regards,

Charles
 
P

Patrick Erich

Using GENERATE indeed solved my problem. It results in the same
hardware synthesized (as the original description), while making
simulation possible.

thanks,
Patrick
 
J

Jar0d

Il giorno 25 Nov 2003, Patrick Erich attirava la mia attenzione
scrivendo:
Using GENERATE indeed solved my problem. It results in the same
<cut>

another solution could be

-- Start VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity test is
generic ( a_width: integer:=8;
y_width: integer:=4);
port ( clk: in std_logic;
a : in std_logic_vector(a_width-1 downto 0);
y : out std_logic_vector(y_width-1 downto 0));
end test;

architecture behavior of test is

constant m_width : INTEGER := min(a_width,y_width);

begin

lb0: process(clk)

begin
if (clk'event and clk='1') then

y <= (others=>'0');

y(m_width - 1 downto 0) <= a(m_width - 1 downto 0);

end if;

end process;

end behavior;

-- END VHDL

--
Telecom Italia Lab
System on Chip/Design and IP Library
Massimiliano GIMONDO
Via G. Reiss Romoli, 274
10148 - Torino - ITALY
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top