Need help with overriding generic in top level

Guest
Hello, I need help with this generic thing. I'm much more comfortable
in verilog, and I do this a lot using 'parameter' and 'defparam'.
Somehow I can't do the same thing in VHDL. I've simplified the problem
to the code below:

I have a lower level module, count_ud.vhd with generic=8. On a top
level (top_count_bad), I instantiate two of count_ud.vhd, and I want to
make one 8-bit counter, the other one 7-bit counter. Synplify gives me
an error message for the 7-bit counter with the following message.

@E: CD395 :"C:\PROJECTS\test\count_ud.vhd":38:22:38:31|Constant width 8
does not match context width 7.

When I instantiate two 8-bit counters (top_count_ok below), everything
seems fine. Whenever I try to override with anything other than 8,
synplify complans. Your help is much appreciated. Btw, Modelsim
doesn't give me error/warning in either of the two below. Thanks.

======================================================================
Here is instantiation of one 8-bit and one 7-bit counter that give me
an error message. After this is the code that instantiates two 8-bit
counters that synthesizes fine.
======================================================================
top_count_bad
======================================================================

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity top_count_bad is

generic (
TOTAL_WIDTH : integer := 9);

port (
clk : in std_logic;
rst_n : in std_logic;
up_0 : in std_logic;
up_1 : in std_logic;
down_0 : in std_logic;
down_1 : in std_logic;
top_count : out std_logic_vector(8 downto 0) );

end top_count_bad;

architecture rtl of top_count_bad is

signal count_1 : std_logic_vector(7 downto 0);
signal count_0 : std_logic_vector(6 downto 0);

component count_ud
generic ( WIDTH : integer );

port (
clk : in std_logic;
rst_n : in std_logic;
up : in std_logic;
down : in std_logic;
count : out std_logic_vector(WIDTH-1 downto 0) );
end component;


begin

-- 8-bit counter
counter_1 : count_ud
generic map ( WIDTH => 8 )

port map (
clk => clk,
rst_n => rst_n,
up => up_1,
down => down_1,
count => count_1);

-- 8-bit counter
counter_0 : count_ud
generic map ( WIDTH => 7 )

port map (
clk => clk,
rst_n => rst_n,
up => up_0,
down => down_0,
count => count_0);

top_count <= std_logic_vector( unsigned("0" & count_1) +
unsigned("00" & count_0) );

end rtl;

======================================================================
And here is instantiation of two 8-bit counters that work fine.
I get 16 registers as I expect in synplify.
======================================================================
top_count_ok
======================================================================

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity top_count_ok is

generic (
TOTAL_WIDTH : integer := 9);

port (
clk : in std_logic;
rst_n : in std_logic;
up_0 : in std_logic;
up_1 : in std_logic;
down_0 : in std_logic;
down_1 : in std_logic;
top_count : out std_logic_vector(8 downto 0) );

end top_count_ok;

architecture rtl of top_count_ok is

signal count_1 : std_logic_vector(7 downto 0);
signal count_0 : std_logic_vector(7 downto 0);

component count_ud
generic ( WIDTH : integer );

port (
clk : in std_logic;
rst_n : in std_logic;
up : in std_logic;
down : in std_logic;
count : out std_logic_vector(WIDTH-1 downto 0) );
end component;


begin

-- 8-bit counter
counter_1 : count_ud
generic map ( WIDTH => 8 )

port map (
clk => clk,
rst_n => rst_n,
up => up_1,
down => down_1,
count => count_1);

-- 8-bit counter
counter_0 : count_ud
generic map ( WIDTH => 8 )

port map (
clk => clk,
rst_n => rst_n,
up => up_0,
down => down_0,
count => count_0);

top_count <= std_logic_vector( unsigned("0" & count_1) +
unsigned("0" & count_0) );

end rtl;
 
Have you tried an instantiation with two 7-bit counters?
The top_count_bad code looked fine to me, but the synthesis error points
to the count_ud component (and hence source). I think you may need to
dig one level of hierarchy deeper.
-a
fastgreen2000@yahoo.com wrote:
Hello, I need help with this generic thing. I'm much more comfortable
in verilog, and I do this a lot using 'parameter' and 'defparam'.
Somehow I can't do the same thing in VHDL. I've simplified the problem
to the code below:

I have a lower level module, count_ud.vhd with generic=8. On a top
level (top_count_bad), I instantiate two of count_ud.vhd, and I want to
make one 8-bit counter, the other one 7-bit counter. Synplify gives me
an error message for the 7-bit counter with the following message.

@E: CD395 :"C:\PROJECTS\test\count_ud.vhd":38:22:38:31|Constant width 8
does not match context width 7.

When I instantiate two 8-bit counters (top_count_ok below), everything
seems fine. Whenever I try to override with anything other than 8,
synplify complans. Your help is much appreciated. Btw, Modelsim
doesn't give me error/warning in either of the two below. Thanks.

======================================================================
Here is instantiation of one 8-bit and one 7-bit counter that give me
an error message. After this is the code that instantiates two 8-bit
counters that synthesizes fine.
======================================================================
top_count_bad
======================================================================

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity top_count_bad is

generic (
TOTAL_WIDTH : integer := 9);

port (
clk : in std_logic;
rst_n : in std_logic;
up_0 : in std_logic;
up_1 : in std_logic;
down_0 : in std_logic;
down_1 : in std_logic;
top_count : out std_logic_vector(8 downto 0) );

end top_count_bad;

architecture rtl of top_count_bad is

signal count_1 : std_logic_vector(7 downto 0);
signal count_0 : std_logic_vector(6 downto 0);

component count_ud
generic ( WIDTH : integer );

port (
clk : in std_logic;
rst_n : in std_logic;
up : in std_logic;
down : in std_logic;
count : out std_logic_vector(WIDTH-1 downto 0) );
end component;


begin

-- 8-bit counter
counter_1 : count_ud
generic map ( WIDTH => 8 )

port map (
clk => clk,
rst_n => rst_n,
up => up_1,
down => down_1,
count => count_1);

-- 8-bit counter
counter_0 : count_ud
generic map ( WIDTH => 7 )

port map (
clk => clk,
rst_n => rst_n,
up => up_0,
down => down_0,
count => count_0);

top_count <= std_logic_vector( unsigned("0" & count_1) +
unsigned("00" & count_0) );

end rtl;

======================================================================
And here is instantiation of two 8-bit counters that work fine.
I get 16 registers as I expect in synplify.
======================================================================
top_count_ok
======================================================================

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity top_count_ok is

generic (
TOTAL_WIDTH : integer := 9);

port (
clk : in std_logic;
rst_n : in std_logic;
up_0 : in std_logic;
up_1 : in std_logic;
down_0 : in std_logic;
down_1 : in std_logic;
top_count : out std_logic_vector(8 downto 0) );

end top_count_ok;

architecture rtl of top_count_ok is

signal count_1 : std_logic_vector(7 downto 0);
signal count_0 : std_logic_vector(7 downto 0);

component count_ud
generic ( WIDTH : integer );

port (
clk : in std_logic;
rst_n : in std_logic;
up : in std_logic;
down : in std_logic;
count : out std_logic_vector(WIDTH-1 downto 0) );
end component;


begin

-- 8-bit counter
counter_1 : count_ud
generic map ( WIDTH => 8 )

port map (
clk => clk,
rst_n => rst_n,
up => up_1,
down => down_1,
count => count_1);

-- 8-bit counter
counter_0 : count_ud
generic map ( WIDTH => 8 )

port map (
clk => clk,
rst_n => rst_n,
up => up_0,
down => down_0,
count => count_0);

top_count <= std_logic_vector( unsigned("0" & count_1) +
unsigned("0" & count_0) );

end rtl;

have youtrie
 
fastgreen2000@yahoo.com wrote:

a wrote:

Have you tried an instantiation with two 7-bit counters?
The top_count_bad code looked fine to me, but the synthesis error

points

to the count_ud component (and hence source). I think you may need

to

dig one level of hierarchy deeper.


The lower level module, count_ud.vhd, compiles and synthesizes fine by
itself.
That may very well be true but that doesn't change the fact that the
problem lies in the count_ud.vhd module.

The most likely cause is that you have the default value for your
generic specified as 8 and something else in the module specified with a
fixed size of 8 instead of depending on the generic. There is nothing
wrong with the code you have posted.
--
Tim Hubberstey, P.Eng. . . . . . Hardware/Software Consulting Engineer
Marmot Engineering . . . . . . . VHDL, ASICs, FPGAs, embedded systems
Vancouver, BC, Canada . . . . . . . . . . . http://www.marmot-eng.com
 
Oops, yes, you (both) are correct. I had the reset value fixed to 8
bits and didn't realize it. I miss verilog a lot, but I'll get over
it. Here is the underlying module, count_ud.vhd. I thought I had
included it in the original post. If you see anything that could be
improved, I'd appreciate it. I'm still not very clear on when to use
which type (unsigned, sl/slv, su/suv...) For now, it synthesizes it
the way I want (15 registers using top_count_bad).

Thanks again.

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

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;

entity count_ud is

generic (
WIDTH : integer := 8
);

port (
clk : in std_logic;
rst_n : in std_logic;
up : in std_logic;
down : in std_logic;
count : out std_logic_vector(WIDTH-1 downto 0)
);

end count_ud;

architecture rtl of count_ud is

signal up_down_case : std_logic_vector(1 downto 0);
signal count_temp : unsigned(WIDTH-1 downto 0);
signal reset_value : integer := 0;

begin -- rtl



up_down_case <= up & down;

process ( clk )
begin

if ( clk'event and clk = '1' ) then
if ( rst_n = '0' ) then
--------------------------------------
-- count_temp <= "00000000";
--------------------------------------
count_temp <= to_unsigned(0, WIDTH);
else
case up_down_case is
when "10" => count_temp <= count_temp + 1;
when "01" => count_temp <= count_temp - 1;
when others => count_temp <= count_temp;
end case;
end if;
end if;
end process;


count <= std_logic_vector(count_temp);

end;

Tim Hubberstey wrote:
fastgreen2000@yahoo.com wrote:

a wrote:

Have you tried an instantiation with two 7-bit counters?
The top_count_bad code looked fine to me, but the synthesis error

points

to the count_ud component (and hence source). I think you may need

to

dig one level of hierarchy deeper.


The lower level module, count_ud.vhd, compiles and synthesizes fine
by
itself.

That may very well be true but that doesn't change the fact that the
problem lies in the count_ud.vhd module.

The most likely cause is that you have the default value for your
generic specified as 8 and something else in the module specified
with a
fixed size of 8 instead of depending on the generic. There is nothing

wrong with the code you have posted.
--
Tim Hubberstey, P.Eng. . . . . . Hardware/Software Consulting
Engineer
Marmot Engineering . . . . . . . VHDL, ASICs, FPGAs, embedded
systems
Vancouver, BC, Canada . . . . . . . . . . .
http://www.marmot-eng.com
 
no problem, count_ud.vhd looks fine. I did tend to use s/slv for
almost everything and unsigned for counters as you have. I've just gone
from vhdl to verilog and I'm missing vhdl a lot. They both have their
pros and cons, I guess.

one note though : count_temp <= to_unsigned(0, WIDTH);
can also be written as : count_temp <= (others => '0');

but that's just a matter of style.

for a quick comparision of vhdl/verilog syntax you can go to
http://www.confluent.org/wiki/doku.php and click on the HDL comparison link.
-a

fastgreen2000@yahoo.com wrote:
Oops, yes, you (both) are correct. I had the reset value fixed to 8
bits and didn't realize it. I miss verilog a lot, but I'll get over
it. Here is the underlying module, count_ud.vhd. I thought I had
included it in the original post. If you see anything that could be
improved, I'd appreciate it. I'm still not very clear on when to use
which type (unsigned, sl/slv, su/suv...) For now, it synthesizes it
the way I want (15 registers using top_count_bad).

Thanks again.

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

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;

entity count_ud is

generic (
WIDTH : integer := 8
);

port (
clk : in std_logic;
rst_n : in std_logic;
up : in std_logic;
down : in std_logic;
count : out std_logic_vector(WIDTH-1 downto 0)
);

end count_ud;

architecture rtl of count_ud is

signal up_down_case : std_logic_vector(1 downto 0);
signal count_temp : unsigned(WIDTH-1 downto 0);
signal reset_value : integer := 0;

begin -- rtl



up_down_case <= up & down;

process ( clk )
begin

if ( clk'event and clk = '1' ) then
if ( rst_n = '0' ) then
--------------------------------------
-- count_temp <= "00000000";
--------------------------------------
count_temp <= to_unsigned(0, WIDTH);
else
case up_down_case is
when "10" => count_temp <= count_temp + 1;
when "01" => count_temp <= count_temp - 1;
when others => count_temp <= count_temp;
end case;
end if;
end if;
end process;


count <= std_logic_vector(count_temp);

end;

Tim Hubberstey wrote:

fastgreen2000@yahoo.com wrote:


a wrote:


Have you tried an instantiation with two 7-bit counters?
The top_count_bad code looked fine to me, but the synthesis error

points


to the count_ud component (and hence source). I think you may need

to


dig one level of hierarchy deeper.


The lower level module, count_ud.vhd, compiles and synthesizes fine

by

itself.

That may very well be true but that doesn't change the fact that the
problem lies in the count_ud.vhd module.

The most likely cause is that you have the default value for your
generic specified as 8 and something else in the module specified

with a

fixed size of 8 instead of depending on the generic. There is nothing


wrong with the code you have posted.
--
Tim Hubberstey, P.Eng. . . . . . Hardware/Software Consulting

Engineer

Marmot Engineering . . . . . . . VHDL, ASICs, FPGAs, embedded

systems

Vancouver, BC, Canada . . . . . . . . . . .

http://www.marmot-eng.com
 
On 9 Feb 2005 21:12:26 -0800, fastgreen2000@yahoo.com wrote:

if ( clk'event and clk = '1' ) then
could also be written as:

if rising_edge(clk) then

The brackets () around the condition are not needed, as the 'then'
terminates that part of the 'if'.
Rising_edge() is a function that is (almost) the same as (x'event and
x='1'). The differences relate to behaviour at now=0 and also with
metavalues on the clock (neither of which should worry you too much in
a practical design).

--------------------------------------
-- count_temp <= "00000000";
--------------------------------------
count_temp <= to_unsigned(0, WIDTH);
Perhaps this is better expressed as:

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

I realise that this is just treating count_temp as a bunch o'bits
rather than an unsigned (and as such doesn't fit the strongly typed
VHDL methodology), but it is quite commonly done this way, and will be
immediately recognised by anyone reading the code.

Regards,
Allan
 
Thanks again, that helps. I knew about 'when others', but it doesn't
come to my head quickly just yet.

One different question is, how do you normally type inter-module ports?

When I have multiple modules in a verilog design (where you potentially
have a different designer working on a different module) I normally
have the inter-module signals defined before we go off do our work
inside the box.

Do you normally have all inter-module ports defined as sl/slv, and have
each module be responsible for conversion to/from unsigned/integer/etc,
so there is less confusion? Or, so you have different type for
different ports from the start to ease/minimize the conversion?

Have you found one method easier than the other?

You folks are very helpful.

Allan Herriman wrote:
On 9 Feb 2005 21:12:26 -0800, fastgreen2000@yahoo.com wrote:

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

could also be written as:

if rising_edge(clk) then

The brackets () around the condition are not needed, as the 'then'
terminates that part of the 'if'.
Rising_edge() is a function that is (almost) the same as (x'event and
x='1'). The differences relate to behaviour at now=0 and also with
metavalues on the clock (neither of which should worry you too much
in
a practical design).

--------------------------------------
-- count_temp <= "00000000";
--------------------------------------
count_temp <= to_unsigned(0, WIDTH);

Perhaps this is better expressed as:

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

I realise that this is just treating count_temp as a bunch o'bits
rather than an unsigned (and as such doesn't fit the strongly typed
VHDL methodology), but it is quite commonly done this way, and will
be
immediately recognised by anyone reading the code.

Regards,
Allan
 
On 10 Feb 2005 06:34:16 -0800, fastgreen2000@yahoo.com wrote:

Thanks again, that helps. I knew about 'when others', but it doesn't
come to my head quickly just yet.

One different question is, how do you normally type inter-module ports?

When I have multiple modules in a verilog design (where you potentially
have a different designer working on a different module) I normally
have the inter-module signals defined before we go off do our work
inside the box.

Do you normally have all inter-module ports defined as sl/slv, and have
each module be responsible for conversion to/from unsigned/integer/etc,
so there is less confusion? Or, so you have different type for
different ports from the start to ease/minimize the conversion?

Have you found one method easier than the other?
Top level ports (i.e. those that actually end up being pins on your
chip) should be std_logic or std_logic_vector (with descending range,
e.g. 7 downto 0). This will match the gate level VHDL or Verilog that
the back end tools spit out, allowing you to swap between RTL and gate
level representations in your test bench.

Internal ports may use whatever synthesisable datatype you want. If
you are using anything user defined (e.g. an enumerated type, or a two
dimensional array of unsigned, or whatever), you will need to declare
it in a package, then use the package in all the design units that
need that type.
(N.B. the type 'real' is an example of a type that is not
synthesisable on a port.)

In my experience, the data type with the highest level of abstraction
that your synthesiser can handle is best (where 'best' means fastest
to market with fewest bugs). Note that VHDL allows you to group
bunches of signals into records, which allows you to hide a lot of
detail from modules that don't need it.
It isn't possible to have both in and out fields within the same
record though, thus two record types (one for the 'in' signals and one
for the 'out' signals) will be required for i/o type ports.

For example, in a previous job we took this to extremes. A rather
large packet processing module could have a very simple port structure
that looked something like:

port (
clk : in std_logic;
gsr : in std_logic;

cpu_in : in t_cpu_in;
cpu_out : out t_cpu_out;

packet_bus_in : in t_packet_bus;

packet_bus_out : out t_packet_bus
);

This cpu interface encompassed perhaps 72 bits worth of std_logic, and
the packet buses maybe another 140. (I may have simplified this
example a bit!)

We could then completely change the internal workings of the packet
bus, without needing to change a line of code in any of the
interconnecting modules - only the modules that actually operated on
the bus would need to change.

(This is something that is quite powerful, and the feature I miss most
when using Verilog.)

Regards,
Allan

You folks are very helpful.

Allan Herriman wrote:
On 9 Feb 2005 21:12:26 -0800, fastgreen2000@yahoo.com wrote:

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

could also be written as:

if rising_edge(clk) then

The brackets () around the condition are not needed, as the 'then'
terminates that part of the 'if'.
Rising_edge() is a function that is (almost) the same as (x'event and
x='1'). The differences relate to behaviour at now=0 and also with
metavalues on the clock (neither of which should worry you too much
in
a practical design).

--------------------------------------
-- count_temp <= "00000000";
--------------------------------------
count_temp <= to_unsigned(0, WIDTH);

Perhaps this is better expressed as:

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

I realise that this is just treating count_temp as a bunch o'bits
rather than an unsigned (and as such doesn't fit the strongly typed
VHDL methodology), but it is quite commonly done this way, and will
be
immediately recognised by anyone reading the code.

Regards,
Allan
 

Welcome to EDABoard.com

Sponsor

Back
Top