Need help with overriding generic in top level

F

fastgreen2000

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;
 
A

a

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
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
 
F

fastgreen2000

a said:
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.
The problem is when the top module overrides the WIDTH value in either
(or both) of the lower level module.

It isn't so much that I need to get this working - I can find ways to
get around this problem for now. I, however, would really like to know
how to take advantage of 'resuability' with generics
 
T

Tim Hubberstey

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.
 
F

fastgreen2000

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 said:
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.
http://www.marmot-eng.com
 
A

a

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
 
A

Allan Herriman

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).

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
 
F

fastgreen2000

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.
 
A

Allan Herriman

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
 
M

Mike Treseler

Allan said:
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.

std_ulogic is also a good candidate
for top in and out bit ports.
It matches std_logic in port maps without
conversion and gives you drive error
detection for free at compile time.

-- Mike Treseler
 

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,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top