Problem with case-statement

V

Volker

Guest
Hi,

I have a VHDL Design containing a case statement. If I compile this design
with QuartusII 9.0 I get no error; compiling this design in ModelSim Altera
Starter Edition I get some errors like "Array type case expression must be
of a locally static subtype" and "Case choice must be a locally static
expression".

I Think the reason is that I use a "generic expression" in the
case-statement. Why did Quartus compile that without errors and ModelSim do
not? The synthesized Design will work, but I will do the simulation as well.

Any ideas to solve the problem?

The code:


library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;

entity VERSION_REGISTER is
generic(CPLD_VER: NATURAL:= 0;
HW_VER : NATURAL:= 2;
HW_TYPE : NATURAL:= 3;
MAX_CS_LINES: POSITIVE:= 16;-- max generated CS-Lines in complete design
START_CS_NR : NATURAL:= 0);-- CS-Line number of first version-register
port(CS : in BIT_VECTOR((MAX_CS_LINES-1) downto 0);
nRD : in STD_LOGIC;
DATA : out STD_LOGIC_VECTOR(7 downto 0));
end VERSION_REGISTER;

architecture BEHAVIOR of VERSION_REGISTER is
begin

process(CS, nRD)
variable ZERO : BIT_VECTOR((MAX_CS_LINES-1) downto 0):=(others=>'0');--
zero vector of length MAX_CS_LINES
variable SHIFT_PATTERN : BIT_VECTOR((MAX_CS_LINES-1) downto
0):=(0=>'1',others=>'0');-- pattern of length MAX_CS_LINES all zero but
Bit0=1
begin

if (CS = ZERO) then -- if no CS for CPLD active, set Databus to high Z
DATA <= (others =>'Z');
elsif (nRD'EVENT and nRD='0') then
case CS is
when (SHIFT_PATTERN sll START_CS_NR) => DATA <=
CONV_STD_LOGIC_VECTOR(CPLD_VER, 8);--CPLD version register
when (SHIFT_PATTERN sll (START_CS_NR +1))=> DATA <=
CONV_STD_LOGIC_VECTOR(HW_VER, 8);--HW version register
when (SHIFT_PATTERN sll (START_CS_NR +2))=> DATA <=
CONV_STD_LOGIC_VECTOR(HW_TYPE, 8);--HW type register
when others => DATA <= (others =>'Z');
end case;
end if;

end process;

end BEHAVIOR;



Thanks for help!
 
On Fri, 8 May 2009 07:07:09 +0200, "Volker" wrote:

I have a VHDL Design containing a case statement. If I compile this design
with QuartusII 9.0 I get no error; compiling this design in ModelSim Altera
Starter Edition I get some errors like "Array type case expression must be
of a locally static subtype" and "Case choice must be a locally static
expression".

I Think the reason is that I use a "generic expression" in the
case-statement.
Partly, yes. Generics are "globally static", whereas case
choices must be "locally static" - a much stronger requirement.

Why did Quartus compile that without errors and ModelSim do
not?
ModelSim rather strictly obeys the VHDL language rules, and
correctly gave you an error for code that is technically
wrong. Quartus (like many synthesis tools) understands
what you mean, and bends the language rules enough to
make it work.

Any ideas to solve the problem?
It is possible to rewrite the code in various ways,
but the simplest solution is to ask ModelSim to
bend the rules in the same way as Quartus. Look
inside your modelsim.ini file and find this section:

; Keep silent about case statement static warnings.
; Default is to give a warning.
; NoCaseStaticError = 1

; Keep silent about warnings caused by aggregates that are not locally
static.
; Default is to give a warning.
; NoOthersStaticError = 1

; Treat as errors:
; case statement static warnings
; warnings caused by aggregates that are not locally static
; Overrides NoCaseStaticError, NoOthersStaticError settings.
; PedanticErrors = 1

Un-comment the line "NoCaseStaticError = 1". Make sure
that PedanticErrors is NOT set (the standard default is OK).

VHDL language pedants will perhaps be displeased with me
for telling you this, but it's useful to know.....
--
Jonathan Bromley, Consultant

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

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Thanks for telling this, but I use the ModelSim Altera Starter Edition and
in the modelsim.ini file there is no such entry :-(
Can I add these commands?

Any ideas to solve the problem?

It is possible to rewrite the code in various ways,
but the simplest solution is to ask ModelSim to
bend the rules in the same way as Quartus. Look
inside your modelsim.ini file and find this section:

; Keep silent about case statement static warnings.
; Default is to give a warning.
; NoCaseStaticError = 1

; Keep silent about warnings caused by aggregates that are not locally
static.
; Default is to give a warning.
; NoOthersStaticError = 1

; Treat as errors:
; case statement static warnings
; warnings caused by aggregates that are not locally static
; Overrides NoCaseStaticError, NoOthersStaticError settings.
; PedanticErrors = 1

Un-comment the line "NoCaseStaticError = 1". Make sure
that PedanticErrors is NOT set (the standard default is OK).

VHDL language pedants will perhaps be displeased with me
for telling you this, but it's useful to know.....
--
Jonathan Bromley, Consultant

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

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Fri, 8 May 2009 07:07:09 +0200, "Volker" <jreeg@gmx.de> wrote:

Hi,

I have a VHDL Design containing a case statement. If I compile this design
with QuartusII 9.0 I get no error; compiling this design in ModelSim Altera
Starter Edition I get some errors like "Array type case expression must be
of a locally static subtype" and "Case choice must be a locally static
expression".

I Think the reason is that I use a "generic expression" in the
case-statement. Why did Quartus compile that without errors and ModelSim do
not? The synthesized Design will work, but I will do the simulation as well.

Any ideas to solve the problem?
In my opinion, CASE really comes into its own where the expression arms contain
ranges or lists.

case Inst is
when Mult downto Add => ...
when Load | Store => ...

Synthesis can take advantage of this to optimise well. The problem here is that
the actual value of the START_CS_NR generic is not known when the entity is
compiled. I believe this makes the optimisation impossible; so CASE cannot
really do better than IF/THEN/ELSIF. To reject the code altogether may be a bit
severe, but I (grudgingly) appreciate the warning that something is amiss.

IF is not subject to the same restrictions as CASE, and is just as compact in
this example. So one option is...
-----------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;

entity VERSION_REGISTER is
generic( CPLD_VER : NATURAL := 0;
HW_VER : NATURAL := 2;
HW_TYPE : NATURAL := 3;
MAX_CS_LINES: POSITIVE:= 16;
-- max generated CS-Lines in complete design
START_CS_NR : NATURAL :=0);
-- CS-Line number of first version-register
port( CS : in BIT_VECTOR((MAX_CS_LINES-1) downto 0);
nRD : in STD_LOGIC;
DATA : out STD_LOGIC_VECTOR(7 downto 0));
end VERSION_REGISTER;

architecture BEHAVIOR of VERSION_REGISTER is
begin

process(CS, nRD)
constant ZERO : BIT_VECTOR((MAX_CS_LINES-1) downto 0):=(others=>'0');
constant SHIFT_PATTERN : BIT_VECTOR((MAX_CS_LINES-1) downto 0):=
(0=>'1',others=>'0');
function SLV8(NUM : NATURAL) return STD_LOGIC_VECTOR is
begin
return STD_LOGIC_VECTOR(to_unsigned(NUM, 8));
end SLV8;

begin

if CS = ZERO then -- if no CS for CPLD active, set Databus to high Z
DATA <= (others =>'Z');
elsif (nRD'EVENT and nRD='0') then
if CS = SHIFT_PATTERN sll (START_CS_NR) then DATA <= SLV8(CPLD_VER);
elsif CS = SHIFT_PATTERN sll (START_CS_NR + 1) then DATA <= SLV8(HW_VER);
elsif CS = SHIFT_PATTERN sll (START_CS_NR + 2) then DATA <= SLV8(HW_TYPE);
else DATA <= (others =>'Z');
end if;
end if;

end process;

end BEHAVIOR;
-----------------------------

My preference is to use the standard libs, not std_logic_arith etc.
I also prefer to factor out type conversion ugliness into a function, wherever
it's used more than once.
(I also omit the redundant parentheses around expressions; it helps to remind me
not to descend into bad habits from my old C days)

Another solution is to make START_CS_NR visible at compile time.
One way is to place it in a package, instead of passing it as a generic.

Whether this is a good thing is a design decision; should it really be variable
on an instance-by-instance basis in the same design, or is it fixed for this
design but subject to change in a future version?

I suggest you might want the latter for MAX_CS_LINES, or there is a danger of
propagating different widths of chip select bus around different parts of the
design, especially when you have to change it and forget to update one generic.

If you can live with defining the register map in a package, here's another
option... (the package is a separate file; "use work.mytypes.all;" in every file
that needs it)
-----------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;

package mytypes is

constant MAX_CS_LINES : POSITIVE:= 16;
-- max generated CS-Lines in complete design

constant START_VERSION_CS_NR : NATURAL :=0;
-- add other blocks to register map here
constant START_DMA_CS_NR : NATURAL :=3;

-- new type removes a lot of clutter and helps make the design intent clearer
subtype CS_Type is BIT_VECTOR((MAX_CS_LINES-1) downto 0);
constant ZERO : CS_Type := (others=>'0');
constant SHIFT_PATTERN : CS_Type := (0=>'1', others=>'0');

-- define the register map in this package
constant CPLD_VER_CS : CS_Type := SHIFT_PATTERN sll START_VERSION_CS_NR;
constant HW_VER_CS : CS_Type := SHIFT_PATTERN sll (START_VERSION_CS_NR + 1);
constant HW_TYPE_CS : CS_Type := SHIFT_PATTERN sll (START_VERSION_CS_NR + 2);
-- ditto for DMA regs, whatever

-- Trivially easy to port to 16-bit or even 23-bit(!) later...
subtype Data_Type is STD_LOGIC_VECTOR(7 downto 0);

function To_Data(NUM : NATURAL) return Data_Type;

end package mytypes;

package body mytypes is

function To_Data(NUM : NATURAL) return Data_Type is
begin
return STD_LOGIC_VECTOR(to_unsigned(NUM, Data_Type'Length));
end To_Data;

end package body mytypes;

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

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;

use work.mytypes.all;

entity VERSION_REGISTER is
generic( CPLD_VER : NATURAL := 0;
HW_VER : NATURAL := 2;
HW_TYPE : NATURAL := 3);
port( CS : in CS_Type;
nRD : in STD_LOGIC;
DATA : out Data_Type );
end VERSION_REGISTER;

architecture BEHAVIOR of VERSION_REGISTER is
begin

process(CS, nRD)
-- constant ZERO : CS_Type := (others=>'0'); -- moved to package
begin

if CS = ZERO then -- if no CS for CPLD active, set Databus to high Z
DATA <= (others =>'Z');
elsif nRD'EVENT and nRD='0' then
case CS is
-- when SHIFT_PATTERN sll START_CS_NR => DATA <= To_Data(CPLD_VER);
when CPLD_VER_CS => DATA <= To_Data(CPLD_VER);
when HW_VER_CS => DATA <= To_Data(HW_VER);
when HW_TYPE_CS => DATA <= To_Data(HW_TYPE);
when others => DATA <= (others =>'Z');
end case;
end if;

end process;

end BEHAVIOR;

-----------------------------
 
Volker wrote:
Thanks for telling this, but I use the ModelSim Altera Starter Edition and
in the modelsim.ini file there is no such entry :-(
Can I add these commands?
89 Wed May 06 tmp> mkdir foo
90 Fri May 08 tmp> cd foo
91 Fri May 08 tmp/foo> ls

92 Fri May 08 tmp/foo> vlib work
93 Fri May 08 tmp/foo> ls
work
94 Fri May 08 tmp/foo> vmap work work
Copying /flip/usr1/modeltech/linux/../modelsim.ini to modelsim.ini
Modifying modelsim.ini
95 Fri May 08 tmp/foo> ls
modelsim.ini work


-- Mike Treseler
 
On Fri, 8 May 2009 16:17:24 +0200, "Volker" <jreeg@gmx.de> wrote:

I use the ModelSim Altera Starter Edition and
in the modelsim.ini file there is no such entry :-(
Can I add these commands?
Go for it. The worst that can happen is that ModelSim AE will
simply ignore the added options. But I reckon that's unlikely.
--
Jonathan Bromley, Consultant

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

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

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

Welcome to EDABoard.com

Sponsor

Back
Top