EDAboard.com | EDAboard.eu | EDAboard.de | EDAboard.co.uk | RTV forum PL | NewsGroups PL

"Global Variables" for configuration in VHDL

elektroda.net NewsGroups Forum Index - VHDL Language - "Global Variables" for configuration in VHDL

Goto page Previous  1, 2

pvwa
Guest

Thu Jul 15, 2010 11:09 am   



Kevin
On 14 Jul., 15:22, KJ <kkjenni...@sbcglobal.net> wrote:
Quote:
Yes, because you didn't take my suggestion which was to create a
single function that loops through the list of all the modules and
return an array of constant addresses.  Now that you've posted some
code to get a better idea of what you're trying to accomplish, let me
suggest the following which uses the 'Create_Addresses' function that
I posted earlier, modified slightly to take an extra input parameter
that is a 'start address' which would be used to initialize the first
element in the computed addresses

  type arr_integer is array(integer range <>) of integer;
  ...
  function Create_Addresses(V: std_ulogic_vector; Start_Address:
natural) return arr_integer
  ...
  constant Module_A_Address:  arr_integer(Module_A'range) :> Create_Addresses(Module_A, 0);

  constant Module_B_Address:  arr_integer(Module_B'range) := Create_Addresses(Module_A,Module_A_Address(Module_A_Address'right)+1);

  constant Module_C_Address:  arr_integer(Module_C'range) :> Create_Addresses(Module_B, Module_B_Address(Module_B_Address'right)+1);

Now you have three sets of arrays of integers for each of the three
modules, those would be used when instantiating the modules like
this...

...

-- finally here the mdoules according the setup constants are
generated

 gen_Module_A : for i in 1 to Module_A(0) generate
   iModule_A : entity work.ModuleA
     generic map (Address => Module_A_Address(i),
                 (Version => Module_A(i))
     port map(...)
 end generate;

The only change from your code then is to use the pre-computed
constants as the address generic.



So i have to write for each module, according functions, which do the
calculations!

Not really.  As I showed, one 'function' covered nearly all of the
computations.  The only other calculation is the part that links
address from the end of the 'Module A' list to the address start of
the 'Module B' list.  This is accomplished with the added parameter to
'Create_Addresses' which allows for an arbitrary 'first' address to
use and then invoking that function by passing it the address of the
end of the 'Module A' list and adding 1 (i.e. the
"Module_A_Address(Module_A_Address'right)+1" portion of the call to
define Module_B_Address

  constant Module_B_Address:  arr_integer(Module_B'range) :> Create_Addresses(Module_A, Module_A_Address(Module_A_Address'right)
+1);

Module B and C are similarly linked.

Now imagine i want to change my code, e.g. i remove Module_B, then ALL
the dependent functions have to be changed also!!

I would 'remove' a module by having a flag indicating whether the
module is to be generated or not.  I'm not quite sure if that's what
you're doing or not.

This is really the main point!
My code is still in work and constantly changing. This is meant by
"removing"! I really want to be able to remove/substitute/add modules
in the source code without having to change too much in other parts
(functions)!

As far as i understand, you put the task of address generation into
the generation of constant vectors, which are then finally used! These
vectors have to be linked "manually", by using the next proper start
adresses (range.right) as paramter in "Create_Addresses()". The task
of linking the addresses remains (the crucial problem!). And again, if
i have to change my code i have to be very careful to reestablish the
linking!

Again, I thought there is a much simpler solution (something like
"impure functions" see below!)

But your proposal (in contrary to mine) is interesting anyway! Maybe
it simplifies overall editing of my code! Give me some time and i will
give it a try!

Quote:

I simply search for another solution, where the calculation can be
done in the Modules itself and this is not depended on other modules
(or functions) but simply on the fact of beeing instanciated or not!
My thinking was of a kind of "global variable", which is simply
incremented

You can't do it with the way that you're viewing the problem which is
in terms of some *variable*.  You can do it though by viewing the
problem in terms of generating a *constant* vector which is what I'm
trying to get across.

So there would be only one function "NextAddress" be needed, similar
to this:

function NextAddress() return integer is
        global variable pos: integer := 0; this is the initialization of the
variable
begin
        pos := pos +1;
        return pos;
end;

That function simply lacks an input to indicate whether something
should be included or not and some base address to start at.  Other
than that it is doing essentially the same thing as the
'Create_Addresses' function that I posted, the crucial difference is
that my function returns something that can be used to generate the
vector of constants that you need.

But nothingh like this seems to be possible in VHDL!?

It is...the mental hurdle is to stop viewing this address calculation
as being some variable that needs incrementing but instead see it as
the computation of a set of constants.

My thinking was also of writing out the number+1 to a file and read it
back, whenever the function is called, but i learned that file
read&write in VHDL is not possible??

That approach would not be a good path to go down.

Why? Would'nt it work?

Greetings, appreciating you patience!
Peter

pvwa
Guest

Thu Jul 15, 2010 11:13 am   



On 14 Jul., 15:49, Andy <jonesa...@comcast.net> wrote:
Quote:
If you built an array of n_vers's (they would have to be fixed length
(i.e. padded with additional unused version numbers for uninstantiated
modules), then you could have one address function that iterated
through the array up to the current module/instance to calculate the
address, without using shared variables.

You could take it a step further by eliminating the number of modules
(1st) element in the array, and use -1 as a version number that
indicates the module is not instantiated.

Andy

I would have preferred a solution with a kind of "shared variable",
but this seems not to work!?
Thanks
Peter

pvwa
Guest

Thu Jul 15, 2010 12:02 pm   



On 14 Jul., 17:10, Tricky <trickyh...@gmail.com> wrote:
Quote:
On 14 July, 14:44, pvwa <vwal...@physi.uni-heidelberg.de> wrote:





On 14 Jul., 15:34, pvwa <vwal...@physi.uni-heidelberg.de> wrote:

On 14 Jul., 11:24, Tricky <trickyh...@gmail.com> wrote:
        impure function NextAddress return integer is
        begin
                pos := pos +1;
                return pos;
        end function NextAddress;

If i remove the keyword impure it gives me this warning:

WARNING: HDLParsers:3310 - "C:/VHDL/TestSharedVariable/
TestModules.vhd" Line 25. Function NextAddress is not pure.  VHDL 87
allowed this; VHDL 93 requires the keyword IMPURE.

So what's going on?

So the old globally static chestnut.
The only way round this I can think of is to create an array type and
create a constant, but I doubt this will work either:

type addr_array_t is array (0 to N_ENTITIES-1) of natural;
Constant addr_array : addr_array_t := ( others => NextAddress);

then when you instantiate the entity, you say:

Generic Map(Addr => addr_array(i))

No this works, and is what Kevin (above) proposes!
Using the impure function there does not help because then everything
is static and i was looking for a solution which works with
instantiation (calling the function in Generic Map or maybe even in
the module itself!!).

Peter

pvwa
Guest

Thu Jul 15, 2010 2:00 pm   



Hi all,

it seems i have a solution!

This is my code (only for testing!):

I have a pkg File where the impure function NextAddress is defined:
----------------------------------------------------
package Test_pkg is
shared variable pos : integer := 0;
impure function NextAddress return integer;
end Test_pkg;

package body Test_pkg is

impure function NextAddress return integer is
begin
pos := pos+1;
return pos;
end function NextAddress;

end Test_pkg;
----------------------------------------------------

Now i use this function inside (not with Generic) in my Module:

----------------------------------------------------
entity MyModule is
Port ( x : in std_logic_vector(3 downto 0);
y : out std_logic);
end MyModule;

architecture Behavioral of MyModule is
constant ModuleAddress: integer := NextAddress;
begin
y <= '1' when Conv_integer(x)=ModuleAddressA else '0';
end Behavioral;
----------------------------------------------------

It is necessary to use the function for setting up a constant
"ModuleAddress" and use this in the address decoder!
Direct use of the function "NextAddress" in the comparator gives no
syntax error it simply does not work!!??
Has anybody a explanation for that!

No my top entity, where i instantiate 10 Modules.
Whenever a module is instantiated it should have a consecutive
address:

----------------------------------------------------
entity TestModules is
Port ( a : in std_logic_vector (3 downto 0);
b : out std_logic_vector (1 to 10));
end TestModules;

architecture Behavioral of TestModules is
begin

gen: for i in 1 to 10 generate
Module: entity work.myModule
Port Map(x => a,
y => b(i));
end generate;

end Behavioral;
----------------------------------------------------

No syntax error!
Now i test my circuitry with this testbench:

----------------------------------------------------
BEGIN

uut: TestModules PORT MAP(
a => a,
b => b
);

tb : PROCESS
BEGIN
wait for 100 ns;
a <= "0000"; --0
wait for 100 ns;
a <= "0001"; --1
wait for 100 ns;
a <= "0010"; --2
wait for 100 ns;
a <= "0011"; --3
wait for 100 ns;
a <= "0100"; --4
wait;
END PROCESS;

END;
----------------------------------------------------

Unfortunately i cannot give you a picture, but it shows the correct
answers of 4 Modules!
Now i have to synthesize and implement to be really sure everything
works as expected!

This seemes to me a very elegant possibility and simplifies my design
significantly!

One (little) disadvantage with not beeing able to transfer the address
via Generic is the missing of this information in the report!
I am not used to it, but how can i report (Assert?) my generated
addresses?

Thanks Tricky, to show me the way!
Peter

Tricky
Guest

Thu Jul 15, 2010 4:11 pm   



Quote:

It is necessary to use the function for setting up a constant
"ModuleAddress" and use this in the address decoder!
Direct use of the function "NextAddress" in the comparator gives no
syntax error it simply does not work!!??
Has anybody a explanation for that!

Because every time you call NextAddress, it changes the address. So
You would have to get lucky for the incoming address to match in the
ever changing match. Setting it to a constant means it never changes.


Quote:

One (little) disadvantage with not beeing able to transfer the address
via Generic is the missing of this information in the report!
I am not used to it, but how can i report (Assert?) my generated
addresses?

Asserts can be placed almost anywhere. for what you want, just put it
inside the architecture.
Try this:
assert false report my_ent'PATH_NAME & ": Address of something = " &
integer'image(ConstantAddress) severity NOTE;

Now, as discussed previously in another thread, asserts get treated
different by different synthesisors. I Know Quartus handles them very
well, but other synthesisors either ignore them or mishandle them and
just print Failures/errors as warnings!

Andy
Guest

Thu Jul 15, 2010 8:24 pm   



On Jul 15, 3:13 am, pvwa <vwal...@physi.uni-heidelberg.de> wrote:
Quote:
On 14 Jul., 15:49, Andy <jonesa...@comcast.net> wrote:

If you built an array of n_vers's (they would have to be fixed length
(i.e. padded with additional unused version numbers for uninstantiated
modules), then you could have one address function that iterated
through the array up to the current module/instance to calculate the
address, without using shared variables.

You could take it a step further by eliminating the number of modules
(1st) element in the array, and use -1 as a version number that
indicates the module is not instantiated.

Andy

I would have preferred a solution with a kind of "shared variable",
but this seems not to work!?
Thanks
Peter

Do you want a solution, or do you want to use shared variables? Pick
one.

Andy

Weng Tianxiang
Guest

Thu Jul 15, 2010 8:47 pm   



On Jul 15, 6:11 am, Tricky <trickyh...@gmail.com> wrote:
Quote:
It is necessary to use the function for setting up a constant
"ModuleAddress" and use this in the address decoder!
Direct use of the function "NextAddress" in the comparator gives no
syntax error it simply does not work!!??
Has anybody a explanation for that!

Because every time you call NextAddress, it changes the address. So
You would have to get lucky for the incoming address to match in the
ever changing match. Setting it to a constant means it never changes.



One (little) disadvantage with not beeing able to transfer the address
via Generic is the missing of this information in the report!
I am not used to it, but how can i report (Assert?) my generated
addresses?

Asserts can be placed almost anywhere. for what you want, just put it
inside the architecture.
Try this:
assert false report my_ent'PATH_NAME & ": Address of something = " &
integer'image(ConstantAddress) severity NOTE;

Now, as discussed previously in another thread, asserts get treated
different by different synthesisors. I Know Quartus handles them very
well, but other synthesisors either ignore them or mishandle them and
just print Failures/errors as warnings!

"Direct use of the function "NextAddress" in the comparator gives no
syntax error it simply does not work!!?? "

It really works, but in a different way from your expecting respect.

You use "ModuleAddress" function in order to set a constant which is
called during synthesization.

Your "ModuleAddress" function in comparator is called when it is used
in implementation.

You didn't test to see "ModuleAddress" function in implementation.

Your method really gives a good example on how to use shared variable
and impure function
and the method has universal application meanings.

Thank you.

Weng

Martin Thompson
Guest

Fri Jul 16, 2010 10:27 am   



Tricky <trickyhead_at_gmail.com> writes:

Quote:
Try this:
assert false report my_ent'PATH_NAME & ": Address of something = " &
integer'image(ConstantAddress) severity NOTE;

or just:

report my_ent'PATH_NAME & ": Address of something = " & etc....

Cheers,
Martin
--
martin.j.thompson_at_trw.com
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.co.uk/capabilities/39-electronic-hardware

pvwa
Guest

Fri Jul 16, 2010 12:24 pm   



On 15 Jul., 19:47, Weng Tianxiang <wtx...@gmail.com> wrote:
Quote:
"Direct use of the function "NextAddress" in the comparator gives no
syntax error it simply does not work!!?? "

It really works, but in a different way from your expecting respect.

You use "ModuleAddress" function in order to set a constant which is
called during synthesization.

This would have been what i wanted!
But even here, when i look at the RTL Schematic, i still see the adder
from the impure function!
It seems the synthesis does NOT really use it as a constant!!!???

Quote:

Your "ModuleAddress" function in comparator is called when it is used
in implementation.

As hardware function!?

Quote:

You didn't test to see "ModuleAddress" function in implementation.

And this is where i am stuck now!
Simulation did work as expected!

But the implementation (Xilinx ISE 9.1) does not! Sad
I tried my actual code (which is quite large) and it produces a lot of
strange errors already in synthesis!

Also my test code (see above) does synthesize but not map:

Running related packing...
ERROR:Pack:198 - NCD was not produced. All logic was removed from
design. This
is usually due to having no input or output PAD connections in the
design and
no nets or symbols marked as 'SAVE'. You can either add PADs or
'SAVE'
attributes to the design, or run 'map -u' to disable logic trimming
in the
mapper.

And this has something to do with the sharing variable construct.
Because when i replace this constant "pos" with simply a "real"
constant (3):

y <= '1' when Conv_integer(x)=3 else '0';

it implements!

Now your turn!

Peter (frustrated!)

Tricky
Guest

Fri Jul 16, 2010 4:29 pm   



On 16 July, 10:24, pvwa <vwal...@physi.uni-heidelberg.de> wrote:
Quote:
On 15 Jul., 19:47, Weng Tianxiang <wtx...@gmail.com> wrote:

"Direct use of the function "NextAddress" in the comparator gives no
syntax error it simply does not work!!?? "

It really works, but in a different way from your expecting respect.

You use "ModuleAddress" function in order to set a constant which is
called during synthesization.

This would have been what i wanted!
But even here, when i look at the RTL Schematic, i still see the adder
from the impure function!
It seems the synthesis does NOT really use it as a constant!!!???

That because it is NOT constant.
the line of code you had:

y <= '1' when Conv_integer(x)=NextAddress else '0';

is really a process that looks like this:

process(x)
begin
if Conv_integer(x) = NextAddress then
y <= '1';
else
y <= '0';
end;
end process;

Because of this, next address is called every time x changes. Meaning
that the address incremenets for every change on X. Hence why XST put
an adder into the circuit.

KJ
Guest

Sat Jul 17, 2010 2:32 am   



On Jul 15, 4:09 am, pvwa <vwal...@physi.uni-heidelberg.de> wrote:
Quote:
I would 'remove' a module by having a flag indicating whether the
module is to be generated or not.  I'm not quite sure if that's what
you're doing or not.

This is really the main point!
My code is still in work and constantly changing. This is meant by
"removing"! I really want to be able to remove/substitute/add modules
in the source code without having to change too much in other parts
(functions)!

In that case you should switch tools. Stop using simulation and
synthesis tools and start using a word processor to create a
specification instead. It's much easier to manipulate addresses,
ports, bit fields, structures and functional descriptions in words and
diagrams first. Then you start coding...to that specification.

Quote:

As far as i understand, you put the task of address generation into
the generation of constant vectors, which are then finally used!

That's the point...create the constants as constants, not variables.

Quote:
These
vectors have to be linked "manually", by using the next proper start
adresses (range.right) as paramter in "Create_Addresses()". The task
of linking the addresses remains (the crucial problem!).

It's only a 'problem' because of your methodology which which seems to
be neither 'top/down' nor 'bottom/up'. At the start of this thread, I
assumed that you had your basic design structure and were looking for
a way to configure modules and address spaces that might (or might
not) be included in a particular instance of some more general and
somewhat stable design. But it seems that is not the case at all,
you're in the initial design creation stage and haven't taken the time
to simply write down what you intend the design to do.

Addresses of modules are rarely 'fluid', they are not something that
change from run to run, for the simple reason that most of the times
those addresses become interfaces to some other design that is outside
of the control of your synthesis tool (i.e. some software person who
controls the device). Those people will need hard fixed addresses,
bit definitions and such that don't change simply because you decide
to reorder modules within a text file in your code.

If you instead give a go at working all of these issues out where it
is much easier to make big changes (i.e. in your specification for
your design in words and figures) life will be much easier.

Quote:
And again, if
i have to change my code i have to be very careful to reestablish the
linking!


Actually if you have the overall architecture of your design worked
out, you'll find that you won't need any of this manual linking and
your whole purpose for starging this thread will become moot.

Quote:
Again, I thought there is a much simpler solution (something like
"impure functions" see below!)


The simplest solution is to first write a specification
document...THEN start writing code to that specification.

Not only will that document come in handy for yourself when it comes
to coding and verifying the design but it will be useful to others who
will have to write code to control your device. Even if that 'other'
person is actually 'you' writing code, you'll find that document comes
in handy because you have a completely different perspective when
you're writing code to control something than you had when you were
writing code to create that exact same something. The same difference
of perspective occurs when it comes to writing a testbench to control
and test something you designed yourself. It's the difference between
looking in at a design versus looking out from a design...it really is
a totally different viewpoint.

Quote:
But your proposal (in contrary to mine) is interesting anyway! Maybe
it simplifies overall editing of my code! Give me some time and i will
give it a try!


Actually my proposal (and the whole other sub-thread having to do with
shared variables) are probably both very poor paths for you to go down
at this point. They are more relevant in the context of some more
general (and relatively stable) overall design that you are trying to
create specific design instances that include or don't include
modules, or the number of modules of a particular type is a design
parameter. In that context, the method I outlined is probably the
best and simplest way since it is explicitly calculating constants
that are in fact constants. Using shared variables to create
constants is...well...unusual.

Kevin Jennings

pvwa
Guest

Thu Jul 22, 2010 12:38 pm   



Hi Tricky!

On 16 Jul., 15:29, Tricky <trickyh...@gmail.com> wrote:
Quote:
On 16 July, 10:24, pvwa <vwal...@physi.uni-heidelberg.de> wrote:

On 15 Jul., 19:47, Weng Tianxiang <wtx...@gmail.com> wrote:

"Direct use of the function "NextAddress" in the comparator gives no
syntax error it simply does not work!!?? "

It really works, but in a different way from your expecting respect.

You use "ModuleAddress" function in order to set a constant which is
called during synthesization.

This would have been what i wanted!
But even here, when i look at the RTL Schematic, i still see the adder
from the impure function!
It seems the synthesis does NOT really use it as a constant!!!???

That because it is NOT constant.
the line of code you had:

y <= '1' when Conv_integer(x)=NextAddress else '0';

is really a process that looks like this:

process(x)
begin
  if Conv_integer(x) = NextAddress then
    y <= '1';
  else
    y <= '0';
  end;
end process;

Because of this, next address is called every time x changes. Meaning
that the address incremenets for every change on X. Hence why XST put
an adder into the circuit.

Yes, i understand this, but as i said, i used this code:

architecture Behavioral of MyModule is
constant ModuleAddress: integer := NextAddress;
begin
y <= '1' when Conv_integer(x)=ModuleAddress else '0';
end Behavioral;

So, i first generate the constant ModuleAddress, which seems to work
fine in the Simulator, but fails in the implementation!

Peter

Tricky
Guest

Thu Jul 22, 2010 2:04 pm   



On 22 July, 10:38, pvwa <vwal...@physi.uni-heidelberg.de> wrote:
Quote:
Hi Tricky!

On 16 Jul., 15:29, Tricky <trickyh...@gmail.com> wrote:



On 16 July, 10:24, pvwa <vwal...@physi.uni-heidelberg.de> wrote:

On 15 Jul., 19:47, Weng Tianxiang <wtx...@gmail.com> wrote:

"Direct use of the function "NextAddress" in the comparator gives no
syntax error it simply does not work!!?? "

It really works, but in a different way from your expecting respect..

You use "ModuleAddress" function in order to set a constant which is
called during synthesization.

This would have been what i wanted!
But even here, when i look at the RTL Schematic, i still see the adder
from the impure function!
It seems the synthesis does NOT really use it as a constant!!!???

That because it is NOT constant.
the line of code you had:

y <= '1' when Conv_integer(x)=NextAddress else '0';

is really a process that looks like this:

process(x)
begin
  if Conv_integer(x) = NextAddress then
    y <= '1';
  else
    y <= '0';
  end;
end process;

Because of this, next address is called every time x changes. Meaning
that the address incremenets for every change on X. Hence why XST put
an adder into the circuit.

Yes, i understand this, but as i said, i used this code:

architecture Behavioral of MyModule is
        constant ModuleAddress: integer := NextAddress;
begin
        y <= '1' when Conv_integer(x)=ModuleAddress else '0';
end Behavioral;

So, i first generate the constant ModuleAddress, which seems to work
fine in the Simulator, but fails in the implementation!

Peter

It could be that the synthesisor doesnt like what you're doing with
shared variables, as it isnt exactly a normal way to go about things.
Find out what ModuleAddress has been set to in the implementation, and
maybe raise and enhancement request.

Goto page Previous  1, 2

elektroda.net NewsGroups Forum Index - VHDL Language - "Global Variables" for configuration in VHDL

Arabic versionBulgarian versionCatalan versionCzech versionDanish versionGerman versionGreek versionEnglish versionSpanish versionFinnish versionFrench versionHindi versionCroatian versionIndonesian versionItalian versionHebrew versionJapanese versionKorean versionLithuanian versionLatvian versionDutch versionNorwegian versionPolish versionPortuguese versionRomanian versionRussian versionSlovak versionSlovenian versionSerbian versionSwedish versionTagalog versionUkrainian versionVietnamese versionChinese version
RTV map EDAboard.com map News map EDAboard.eu map EDAboard.de map EDAboard.co.uk map Opony