Wired Or in VHDL

M

Marc Jenkins

Guest
Hello folks,

Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

Thanks,
Marc
 
On Friday, July 25, 2014 5:58:07 AM UTC-4, Marc Jenkins wrote:
Hello folks,
Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

Wired-or simply means that there are multiple drivers on a net. In VHDL land, the std_logic that nearly everybody uses for every signal definition can have multiple drivers.

Kevin Jennings
 
In article <lqu4v4$upa$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 5:58 AM, Marc Jenkins wrote:
Hello folks,

Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

The question is why would you want that? To use a wired or you would
need to have open collector (or open drain) outputs with a pull up
resistor. Compared to just adding an OR gate this is a very slow method
or very power hungry, take your pick.

Do you really plan to use a wired or? Or do you expect this to be
replaced with a real gate and are using it as shorthand?

Most synthesis tools I'm aware of correctly map multiple drivers on a "wor" net
to a logical 'or' gate. It's perfectly synthesizable, and quite useful.

We've been using this construct for over 10 years on our Xilinx FPGAs
on our CPU register bus. The returned read data (for when the CPU
is issuing a read) is collected on a "wor" bus. All the slaves
drive 0 when NOT addressed. When addressed, and issued a read, the
one slave drives the actual read data on the bus.

Works a charm, and greatly simplifies our code.

Regards,

Mark
 
On 7/25/2014 5:58 AM, Marc Jenkins wrote:
Hello folks,

Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

The question is why would you want that? To use a wired or you would
need to have open collector (or open drain) outputs with a pull up
resistor. Compared to just adding an OR gate this is a very slow method
or very power hungry, take your pick.

Do you really plan to use a wired or? Or do you expect this to be
replaced with a real gate and are using it as shorthand?

--

Rick
 
In article <lquep6$6cl$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 2:41 PM, Mark Curry wrote:
In article <lqu4v4$upa$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 5:58 AM, Marc Jenkins wrote:
Hello folks,

Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

The question is why would you want that? To use a wired or you would
need to have open collector (or open drain) outputs with a pull up
resistor. Compared to just adding an OR gate this is a very slow method
or very power hungry, take your pick.

Do you really plan to use a wired or? Or do you expect this to be
replaced with a real gate and are using it as shorthand?

Most synthesis tools I'm aware of correctly map multiple drivers on a "wor" net
to a logical 'or' gate. It's perfectly synthesizable, and quite useful.

We've been using this construct for over 10 years on our Xilinx FPGAs
on our CPU register bus. The returned read data (for when the CPU
is issuing a read) is collected on a "wor" bus. All the slaves
drive 0 when NOT addressed. When addressed, and issued a read, the
one slave drives the actual read data on the bus.

Works a charm, and greatly simplifies our code.

Synthesizable yes, useful...?

Very useful. We've got a much cleaner, reusable structure setup for
register configuration. There's nothing to do to add/subtract (sometimes
via the setting of a parameter) more registers on the bus. It just works.

It's a bit hard to describe in a small example. But we've got significant
code size reduction using this structure. Some were uncomfortable at first
with the "multi-driver" implications, or collision problems. But we've found
that neither are a problem at all.

Regards,

Mark
 
In article <lqunq3$bq$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 5:56 PM, Mark Curry wrote:
In article <lquep6$6cl$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 2:41 PM, Mark Curry wrote:
In article <lqu4v4$upa$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 5:58 AM, Marc Jenkins wrote:
Hello folks,

Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

The question is why would you want that? To use a wired or you would
need to have open collector (or open drain) outputs with a pull up
resistor. Compared to just adding an OR gate this is a very slow method
or very power hungry, take your pick.

Do you really plan to use a wired or? Or do you expect this to be
replaced with a real gate and are using it as shorthand?

Most synthesis tools I'm aware of correctly map multiple drivers on a "wor" net
to a logical 'or' gate. It's perfectly synthesizable, and quite useful.

We've been using this construct for over 10 years on our Xilinx FPGAs
on our CPU register bus. The returned read data (for when the CPU
is issuing a read) is collected on a "wor" bus. All the slaves
drive 0 when NOT addressed. When addressed, and issued a read, the
one slave drives the actual read data on the bus.

Works a charm, and greatly simplifies our code.

Synthesizable yes, useful...?

Very useful. We've got a much cleaner, reusable structure setup for
register configuration. There's nothing to do to add/subtract (sometimes
via the setting of a parameter) more registers on the bus. It just works.

It's a bit hard to describe in a small example. But we've got significant
code size reduction using this structure. Some were uncomfortable at first
with the "multi-driver" implications, or collision problems. But we've found
that neither are a problem at all.

No need for examples. I understand perfectly what you are describing.
But this is a construct that is in some respects the equivalent of a
global variable and creates issues for verifying code depending on your
methods. If it works for you then great. :)

Rickman,

I was among those that cast a suspicious eye on the construct when I
first saw it. But it really works fine and is NOT comparable to
a global variable at all IMHO.

I think of it as the same mux as others do by hand to
mux the readdata back - just broken up. i.e. think
of the readmux as a sum of products:
y = ( sel0 & in0 ) | ( sel1 & in1 ) | ( sel2 & in2 ) | ...

Where we force the slave modules themselves to do the "AND" masking.
Then the 'OR' is taken care of automatically with the 'wor' multi-driver.

There's really no verification issues that we have with using this.
It's very straightforward.

--Mark
 
On 7/25/2014 2:41 PM, Mark Curry wrote:
In article <lqu4v4$upa$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 5:58 AM, Marc Jenkins wrote:
Hello folks,

Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

The question is why would you want that? To use a wired or you would
need to have open collector (or open drain) outputs with a pull up
resistor. Compared to just adding an OR gate this is a very slow method
or very power hungry, take your pick.

Do you really plan to use a wired or? Or do you expect this to be
replaced with a real gate and are using it as shorthand?

Most synthesis tools I'm aware of correctly map multiple drivers on a "wor" net
to a logical 'or' gate. It's perfectly synthesizable, and quite useful.

We've been using this construct for over 10 years on our Xilinx FPGAs
on our CPU register bus. The returned read data (for when the CPU
is issuing a read) is collected on a "wor" bus. All the slaves
drive 0 when NOT addressed. When addressed, and issued a read, the
one slave drives the actual read data on the bus.

Works a charm, and greatly simplifies our code.

Synthesizable yes, useful...?

--

Rick
 
On 7/25/2014 5:56 PM, Mark Curry wrote:
In article <lquep6$6cl$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 2:41 PM, Mark Curry wrote:
In article <lqu4v4$upa$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 5:58 AM, Marc Jenkins wrote:
Hello folks,

Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

The question is why would you want that? To use a wired or you would
need to have open collector (or open drain) outputs with a pull up
resistor. Compared to just adding an OR gate this is a very slow method
or very power hungry, take your pick.

Do you really plan to use a wired or? Or do you expect this to be
replaced with a real gate and are using it as shorthand?

Most synthesis tools I'm aware of correctly map multiple drivers on a "wor" net
to a logical 'or' gate. It's perfectly synthesizable, and quite useful.

We've been using this construct for over 10 years on our Xilinx FPGAs
on our CPU register bus. The returned read data (for when the CPU
is issuing a read) is collected on a "wor" bus. All the slaves
drive 0 when NOT addressed. When addressed, and issued a read, the
one slave drives the actual read data on the bus.

Works a charm, and greatly simplifies our code.

Synthesizable yes, useful...?

Very useful. We've got a much cleaner, reusable structure setup for
register configuration. There's nothing to do to add/subtract (sometimes
via the setting of a parameter) more registers on the bus. It just works.

It's a bit hard to describe in a small example. But we've got significant
code size reduction using this structure. Some were uncomfortable at first
with the "multi-driver" implications, or collision problems. But we've found
that neither are a problem at all.

No need for examples. I understand perfectly what you are describing.
But this is a construct that is in some respects the equivalent of a
global variable and creates issues for verifying code depending on your
methods. If it works for you then great. :)

--

Rick
 
On 7/25/2014 8:06 PM, Mark Curry wrote:
In article <lqunq3$bq$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 5:56 PM, Mark Curry wrote:
In article <lquep6$6cl$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 2:41 PM, Mark Curry wrote:
In article <lqu4v4$upa$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:
On 7/25/2014 5:58 AM, Marc Jenkins wrote:
Hello folks,

Verilog supports the net type "wor" to implement a wired or logic.
Is something similar possible in VHDL?

Target plattform is an ASIC.

The question is why would you want that? To use a wired or you would
need to have open collector (or open drain) outputs with a pull up
resistor. Compared to just adding an OR gate this is a very slow method
or very power hungry, take your pick.

Do you really plan to use a wired or? Or do you expect this to be
replaced with a real gate and are using it as shorthand?

Most synthesis tools I'm aware of correctly map multiple drivers on a "wor" net
to a logical 'or' gate. It's perfectly synthesizable, and quite useful.

We've been using this construct for over 10 years on our Xilinx FPGAs
on our CPU register bus. The returned read data (for when the CPU
is issuing a read) is collected on a "wor" bus. All the slaves
drive 0 when NOT addressed. When addressed, and issued a read, the
one slave drives the actual read data on the bus.

Works a charm, and greatly simplifies our code.

Synthesizable yes, useful...?

Very useful. We've got a much cleaner, reusable structure setup for
register configuration. There's nothing to do to add/subtract (sometimes
via the setting of a parameter) more registers on the bus. It just works.

It's a bit hard to describe in a small example. But we've got significant
code size reduction using this structure. Some were uncomfortable at first
with the "multi-driver" implications, or collision problems. But we've found
that neither are a problem at all.

No need for examples. I understand perfectly what you are describing.
But this is a construct that is in some respects the equivalent of a
global variable and creates issues for verifying code depending on your
methods. If it works for you then great. :)

Rickman,

I was among those that cast a suspicious eye on the construct when I
first saw it. But it really works fine and is NOT comparable to
a global variable at all IMHO.

I think of it as the same mux as others do by hand to
mux the readdata back - just broken up. i.e. think
of the readmux as a sum of products:
y = ( sel0 & in0 ) | ( sel1 & in1 ) | ( sel2 & in2 ) | ...

Where we force the slave modules themselves to do the "AND" masking.
Then the 'OR' is taken care of automatically with the 'wor' multi-driver.

There's really no verification issues that we have with using this.
It's very straightforward.

I might not understand this correctly since I am much more the VHDL
programmer (where the wire or is seldom used, in fact, can that be
done?) than a Verilog programmer... So there is one net with multiple
drivers. When *any* of the drivers outputs a 1 the net is a 1, hence
the wire or name.

So if you have a 1 on the net when you aren't expecting a 1, how do you
identify the driver unless you look at the inputs to all the drivers in
all the different modules? To me that is a problem and is one of the
reasons why buses like this are a PITA to debug in real hardware. This
is commonly referred to as "hanging" the bus.

By using an explicit mux the only signal that can drive the output of
the mux is the signal that is selected at that moment. Look at the
select lines, look at the corresponding input and continue to trace back
from there.

This is not an insurmountable problem. As I said this is commonly used
in real hardware, just not inside chips very often. You say it makes
the code easier to read, I think it splits the logic for a simple mux
across multiple modules and makes it harder to debug.

Consider a software technique of encapsulating decisions and functions.
The wire or is the opposite of that since the mux logic is spread
across modules.

Different horses for different courses. :)

--

Rick
 
On Saturday, 26 July 2014 10:15:54 UTC+8, rickman wrote:
On 7/25/2014 8:06 PM, Mark Curry wrote:

In article <lqunq3$bq$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:

On 7/25/2014 5:56 PM, Mark Curry wrote:

In article <lquep6$6cl$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:

On 7/25/2014 2:41 PM, Mark Curry wrote:

In article <lqu4v4$upa$1@dont-email.me>, rickman <gnuarm@gmail.com> wrote:

On 7/25/2014 5:58 AM, Marc Jenkins wrote:

Hello folks,



Verilog supports the net type "wor" to implement a wired or logic.

Is something similar possible in VHDL?



Target plattform is an ASIC.



The question is why would you want that? To use a wired or you would

need to have open collector (or open drain) outputs with a pull up

resistor. Compared to just adding an OR gate this is a very slow method

or very power hungry, take your pick.



Do you really plan to use a wired or? Or do you expect this to be

replaced with a real gate and are using it as shorthand?



Most synthesis tools I'm aware of correctly map multiple drivers on a "wor" net

to a logical 'or' gate. It's perfectly synthesizable, and quite useful.



We've been using this construct for over 10 years on our Xilinx FPGAs

on our CPU register bus. The returned read data (for when the CPU

is issuing a read) is collected on a "wor" bus. All the slaves

drive 0 when NOT addressed. When addressed, and issued a read, the

one slave drives the actual read data on the bus.



Works a charm, and greatly simplifies our code.



Synthesizable yes, useful...?



Very useful. We've got a much cleaner, reusable structure setup for

register configuration. There's nothing to do to add/subtract (sometimes

via the setting of a parameter) more registers on the bus. It just works.



It's a bit hard to describe in a small example. But we've got significant

code size reduction using this structure. Some were uncomfortable at first

with the "multi-driver" implications, or collision problems. But we've found

that neither are a problem at all.



No need for examples. I understand perfectly what you are describing.

But this is a construct that is in some respects the equivalent of a

global variable and creates issues for verifying code depending on your

methods. If it works for you then great. :)



Rickman,



I was among those that cast a suspicious eye on the construct when I

first saw it. But it really works fine and is NOT comparable to

a global variable at all IMHO.



I think of it as the same mux as others do by hand to

mux the readdata back - just broken up. i.e. think

of the readmux as a sum of products:

y = ( sel0 & in0 ) | ( sel1 & in1 ) | ( sel2 & in2 ) | ...



Where we force the slave modules themselves to do the "AND" masking.

Then the 'OR' is taken care of automatically with the 'wor' multi-driver.



There's really no verification issues that we have with using this.

It's very straightforward.



I might not understand this correctly since I am much more the VHDL

programmer (where the wire or is seldom used, in fact, can that be

done?) than a Verilog programmer... So there is one net with multiple

drivers. When *any* of the drivers outputs a 1 the net is a 1, hence

the wire or name.



So if you have a 1 on the net when you aren't expecting a 1, how do you

identify the driver unless you look at the inputs to all the drivers in

all the different modules? To me that is a problem and is one of the

reasons why buses like this are a PITA to debug in real hardware. This

is commonly referred to as "hanging" the bus.



By using an explicit mux the only signal that can drive the output of

the mux is the signal that is selected at that moment. Look at the

select lines, look at the corresponding input and continue to trace back

from there.



This is not an insurmountable problem. As I said this is commonly used

in real hardware, just not inside chips very often. You say it makes

the code easier to read, I think it splits the logic for a simple mux

across multiple modules and makes it harder to debug.



Consider a software technique of encapsulating decisions and functions.

The wire or is the opposite of that since the mux logic is spread

across modules.



Different horses for different courses. :)



--



Rick

Haven't tried resolution functions on Xilinx. But from the sound of it, I believe your 'wor' can be easily done with a custom resolution function in VHDL:

entity test is port(d0,d1:in std_ulogic; q:eek:ut resolved_wor std_ulogic);
end entity test;

architecture rtl of test is begin
q<=d0;
q<=d1;
end architecture rtl;

Not sure if Vivado supports this though. With a bit of hacking, you can get Quartus to support this. Last I know, Quartus chokes on custom resolved ports, so you need to declare an internal signal that uses the custom resolution function:
signal s:resolved_wor std_ulogic;

and treat s as having multiple drivers from d0 and d1. Then drive the output q from the internal resolved signal s.

You can write custom resolution functions to resolve outputs on OR, AND, or anything you want. We prefer not to have special keywords like wor, wand, etc. that clutter our language. :) These things can be easily written as custom functions by the designer.

-dan
 
In article <b4f036fe-5d34-41ad-aa72-884d9f0a2302@googlegroups.com>,
Daniel Kho <daniel.kho@gmail.com> wrote:

Haven't tried resolution functions on Xilinx. But from the sound of it, I
believe your 'wor' can be easily done with a custom resolution function in
VHDL:

entity test is port(d0,d1:in std_ulogic; q:eek:ut resolved_wor std_ulogic);
end entity test;

architecture rtl of test is begin
q<=d0;
q<=d1;
end architecture rtl;

Not sure if Vivado supports this though. With a bit of hacking, you can get
Quartus to support this. Last I know, Quartus chokes on custom resolved ports,
so you need to declare an internal signal
that uses the custom resolution function:
signal s:resolved_wor std_ulogic;

and treat s as having multiple drivers from d0 and d1. Then drive the output
q from the internal resolved signal s.

You can write custom resolution functions to resolve outputs on OR, AND, or
anything you want. We prefer not to have special keywords like wor, wand, etc.
that clutter our language. :) These things
can be easily written as custom functions by the designer.

Dan,

I'm not a VHDL person - can you detail more? How's the custom resolution
function written? I.e. How's it support the variable number of inputs to
the function?

i.e. I want the 'resolved_wor' to resolve a variable number of drivers on the
net. There's only one net. The net may driven locally, or thru a connection
to a sub-entity's output port.

Can I do this with VHDL, using custom resolution functions?

Xilinx is dragging their feet supporting wor's in verilog thru Vivado. They've
always supported it in ISE at least since ISE 6.xx, probably forever.
If I can give them a VHDL example too, it might help.

Thanks,

Mark
 
On Friday, 1 August 2014 04:58:39 UTC+8, Mark Curry wrote:
Dan,



I'm not a VHDL person - can you detail more? How's the custom resolution

function written? I.e. How's it support the variable number of inputs to

the function?



i.e. I want the 'resolved_wor' to resolve a variable number of drivers on the

net. There's only one net. The net may driven locally, or thru a connection

to a sub-entity's output port.



Can I do this with VHDL, using custom resolution functions?



Xilinx is dragging their feet supporting wor's in verilog thru Vivado. They've

always supported it in ISE at least since ISE 6.xx, probably forever.

If I can give them a VHDL example too, it might help.



Thanks,



Mark

Hi Mark,
There are some pretty good references on designing your own custom resolution functions in VHDL. I just did a search and found this:
http://vhdl.renerta.com/source/vhd00058.htm

There are also predefined (standard) resolution functions within the standard VHDL packages, and anyone can read them.

An example of resolved_or (or resolved_wor in my previous post):

function resolved_or(s:std_ulogic_vector) return std_logic is
variable result:std_ulogic:='0';
begin
for i in s'range loop
result:=result or s(i);
end loop;
return result;
end function resolved_or;

These custom functions may be defined within an architecture (before the BEGIN), or within a VHDL package.

-dan
 
On Friday, 1 August 2014 04:58:39 UTC+8, Mark Curry wrote:

I'm not a VHDL person - can you detail more? How's the custom resolution
function written? I.e. How's it support the variable number of inputs to
the function?

Sorry for the multiple posting. Posted too quickly without reading your entire question. :|

A resolution function accepts as argument, a vector (or array) of the signal you wish to have multiple drivers on. Say for example you have a signal (or output) net q as in my previous example, that you wish to have multiple sources driving it. q is of an unresolved type std_ulogic, but you can apply the resolution function "resolved_wor" to resolve q to a deterministic value from multiple sources driving it.
q:eek:ut resolved_wor std_ulogic;

To write a resolution function for q, you create one that accepts a vector of std_ulogic (we can use the predefined std_ulogic_vector), and this array contains all the multiple drivers that would be driving q. The resolution function can then be written to resolve the output based on any resolution logic you want. This can be a simple OR or AND, or can as complex as need be. The output (return value) of a resolution function must therefore be of a resolved type (such as std_logic).

function resolved_wor(s:std_ulogic_vector) return std_logic is begin
...
end function resolved_wor;

-dan
 
In article <078f85e7-b935-403d-896e-9d8493b63fb9@googlegroups.com>,
Daniel Kho <daniel.kho@gmail.com> wrote:
On Friday, 1 August 2014 04:58:39 UTC+8, Mark Curry wrote:

I'm not a VHDL person - can you detail more? How's the custom resolution
function written? I.e. How's it support the variable number of inputs to
the function?


Sorry for the multiple posting. Posted too quickly without reading
your entire question. :|

A resolution function accepts as argument, a vector (or array) of
the signal you wish to have multiple drivers on. Say for example
you have a signal (or output) net q as in my previous example, that
you wish to have multiple sources driving it. q is of an unresolved
type std_ulogic, but you can apply the resolution function
"resolved_wor" to resolve q to a deterministic value from multiple
sources driving it.
q:eek:ut resolved_wor std_ulogic;

To write a resolution function for q, you create one that accepts a
vector of std_ulogic (we can use the predefined std_ulogic_vector),
and this array contains all the multiple drivers that would be
driving q. The resolution function can then be written to resolve the
output based on any resolution logic you want. This can be a simple OR
or AND, or can as complex as need be. The output (return
value) of a resolution function must therefore be of a resolved type
(such as std_logic).

function resolved_wor(s:std_ulogic_vector) return std_logic is begin
...
end function resolved_wor;

Yeah - doesn't solve my problem. There's no "std_ulogic_vector" for the
input to the function. There's only *ONE* net. The one net with multiple
(resolved type) drivers on it.

I don't see how this is "custom resolution function" is different
than any other function? (Again, I'm not VHDL person).

What I'm trying to do (verilog speak, sorry):
cpu_reg cpu_reg1 ( `BUS_CONNECT, .data_o( reg1_val ) );

cpu_reg cpu_reg2 ( `BUS_CONNECT, .data_o( reg2_val ) );

cpu_reg cpu_reg3 ( `BUS_CONNECT, .data_o( reg3_val ) );
....

The `BUS_CONNECT is simple a verilog macro (probably a structure (record?)
in VHDL) that hooks up the CPU bus interface. All the read data, is a
wor net.

Theres only one "read_data" net (an output of this entity) on BUS_CONNECT.
(Think of it as 1 bit to make the testcase easier). "read_data" is 'wor'
resolved for the multiple drivers on it.

Generics/etc will conditionally compile in/out many cpu_regs. So I don't
know how many drivers "read_data" has apriori. Nor could I easily define
the width of the "std_ulogic_vector" input to your function.

--Mark
 
On 7/31/2014 6:04 PM, Daniel Kho wrote:
On Friday, 1 August 2014 04:58:39 UTC+8, Mark Curry wrote:
Dan,



I'm not a VHDL person - can you detail more? How's the custom resolution

function written? I.e. How's it support the variable number of inputs to

the function?



i.e. I want the 'resolved_wor' to resolve a variable number of drivers on the

net. There's only one net. The net may driven locally, or thru a connection

to a sub-entity's output port.



Can I do this with VHDL, using custom resolution functions?



Xilinx is dragging their feet supporting wor's in verilog thru Vivado. They've

always supported it in ISE at least since ISE 6.xx, probably forever.

If I can give them a VHDL example too, it might help.



Thanks,



Mark

Hi Mark,
There are some pretty good references on designing your own custom resolution functions in VHDL. I just did a search and found this:
http://vhdl.renerta.com/source/vhd00058.htm

There are also predefined (standard) resolution functions within the standard VHDL packages, and anyone can read them.

An example of resolved_or (or resolved_wor in my previous post):

function resolved_or(s:std_ulogic_vector) return std_logic is
variable result:std_ulogic:='0';
begin
for i in s'range loop
result:=result or s(i);
end loop;
return result;
end function resolved_or;

These custom functions may be defined within an architecture (before the BEGIN), or within a VHDL package.

The resolved_or function you posted does not implement a wired or. The
type used is just std_ulogic and the assignment is
result := result or s(i);

This is the or of all the bits in a bus.

--

Rick
 
On Thu, 31 Jul 2014 19:23:38 -0400
rickman <gnuarm@gmail.com> wrote:

On 7/31/2014 6:04 PM, Daniel Kho wrote:
On Friday, 1 August 2014 04:58:39 UTC+8, Mark Curry wrote:

An example of resolved_or (or resolved_wor in my previous post):

function resolved_or(s:std_ulogic_vector) return std_logic is
variable result:std_ulogic:='0';
begin
for i in s'range loop
result:=result or s(i);
end loop;
return result;
end function resolved_or;

These custom functions may be defined within an architecture (before the BEGIN), or within a VHDL package.

The resolved_or function you posted does not implement a wired or. The
type used is just std_ulogic and the assignment is
result := result or s(i);

This is the or of all the bits in a bus.

Which, when used as a resolution function, makes the signal equal to
the OR of all its drivers, i.e. a wired OR. Doesn't it?

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 
On 7/31/2014 7:18 PM, Mark Curry wrote:
In article <078f85e7-b935-403d-896e-9d8493b63fb9@googlegroups.com>,
Daniel Kho <daniel.kho@gmail.com> wrote:
On Friday, 1 August 2014 04:58:39 UTC+8, Mark Curry wrote:

I'm not a VHDL person - can you detail more? How's the custom resolution
function written? I.e. How's it support the variable number of inputs to
the function?


Sorry for the multiple posting. Posted too quickly without reading
your entire question. :|

A resolution function accepts as argument, a vector (or array) of
the signal you wish to have multiple drivers on. Say for example
you have a signal (or output) net q as in my previous example, that
you wish to have multiple sources driving it. q is of an unresolved
type std_ulogic, but you can apply the resolution function
"resolved_wor" to resolve q to a deterministic value from multiple
sources driving it.
q:eek:ut resolved_wor std_ulogic;

To write a resolution function for q, you create one that accepts a
vector of std_ulogic (we can use the predefined std_ulogic_vector),
and this array contains all the multiple drivers that would be
driving q. The resolution function can then be written to resolve the
output based on any resolution logic you want. This can be a simple OR
or AND, or can as complex as need be. The output (return
value) of a resolution function must therefore be of a resolved type
(such as std_logic).

function resolved_wor(s:std_ulogic_vector) return std_logic is begin
...
end function resolved_wor;


Yeah - doesn't solve my problem. There's no "std_ulogic_vector" for the
input to the function. There's only *ONE* net. The one net with multiple
(resolved type) drivers on it.

I don't see how this is "custom resolution function" is different
than any other function? (Again, I'm not VHDL person).

What I'm trying to do (verilog speak, sorry):
cpu_reg cpu_reg1 ( `BUS_CONNECT, .data_o( reg1_val ) );

cpu_reg cpu_reg2 ( `BUS_CONNECT, .data_o( reg2_val ) );

cpu_reg cpu_reg3 ( `BUS_CONNECT, .data_o( reg3_val ) );
....

The `BUS_CONNECT is simple a verilog macro (probably a structure (record?)
in VHDL) that hooks up the CPU bus interface. All the read data, is a
wor net.

Theres only one "read_data" net (an output of this entity) on BUS_CONNECT.
(Think of it as 1 bit to make the testcase easier). "read_data" is 'wor'
resolved for the multiple drivers on it.

Generics/etc will conditionally compile in/out many cpu_regs. So I don't
know how many drivers "read_data" has apriori. Nor could I easily define
the width of the "std_ulogic_vector" input to your function.

I think I see where Daniel is coming from. Try reading this link. I
guess the function resolved_wor gets applied to your multiple drivers
when you declare the signal q:eek:ut resolved_wor std_ulogic;

http://vhdl.renerta.com/mobile/source/vhd00058.htm

So disregard my prior post..... :(

--

Rick
 
On Friday, 1 August 2014 07:18:47 UTC+8, Mark Curry wrote:
Yeah - doesn't solve my problem. There's no "std_ulogic_vector" for the

input to the function. There's only *ONE* net. The one net with multiple

(resolved type) drivers on it.

Yes, the 'q' in my previous example is also a single net, with multiple drivers driving it.


What I'm trying to do (verilog speak, sorry):

cpu_reg cpu_reg1 ( `BUS_CONNECT, .data_o( reg1_val ) );
cpu_reg cpu_reg2 ( `BUS_CONNECT, .data_o( reg2_val ) );
cpu_reg cpu_reg3 ( `BUS_CONNECT, .data_o( reg3_val ) );

...

The `BUS_CONNECT is simple a verilog macro (probably a structure (record?)
in VHDL) that hooks up the CPU bus interface. All the read data, is a
wor net.

Don't really understand this Verilog code, sorry. Is that within an @always block? So are those transactions?


Generics/etc will conditionally compile in/out many cpu_regs. So I don't
know how many drivers "read_data" has apriori. Nor could I easily define
the width of the "std_ulogic_vector" input to your function.

As long as you leave the vector width unconstrained in your resolution function, you don't need to specify how many drivers there are. Upon elaboration of your design, the resolution function takes in the vector of all multiple drivers - it finds all the multiple driving nets, and groups them into an array automatically. The size of the array is automatically calculated upon elaboration. It's all done behind the scenes for you.

-dan
 
In article <5c10d684-fcd4-4bfc-8fac-f855084ceb4e@googlegroups.com>,
Daniel Kho <daniel.kho@gmail.com> wrote:
On Friday, 1 August 2014 07:18:47 UTC+8, Mark Curry wrote:
Yeah - doesn't solve my problem. There's no "std_ulogic_vector" for the

input to the function. There's only *ONE* net. The one net with multiple

(resolved type) drivers on it.


Yes, the 'q' in my previous example is also a single net, with multiple
drivers driving it.


What I'm trying to do (verilog speak, sorry):

cpu_reg cpu_reg1 ( `BUS_CONNECT, .data_o( reg1_val ) );
cpu_reg cpu_reg2 ( `BUS_CONNECT, .data_o( reg2_val ) );
cpu_reg cpu_reg3 ( `BUS_CONNECT, .data_o( reg3_val ) );

...

The `BUS_CONNECT is simple a verilog macro (probably a structure (record?)
in VHDL) that hooks up the CPU bus interface. All the read data, is a
wor net.


Don't really understand this Verilog code, sorry. Is that within an
@always block? So are those transactions?

Sorry, should have been more clear. Those are all just instaciations.
The "multiple driver" read_data is all within `BUS_CONNNECT.
To expand it (leaving some connections out to synplify):

wor rddata_o;
cpu_reg cpu_reg1 ( .addr_i( addr_i ), .cs_i( cs_i ), .wrdata_i( wrdata_i ), .rwn_i( rwn_i ), .rddata_o( rddata_o ) );
cpu_reg cpu_reg2 ( .addr_i( addr_i ), .cs_i( cs_i ), .wrdata_i( wrdata_i ), .rwn_i( rwn_i ), .rddata_o( rddata_o ) );
cpu_reg cpu_reg3 ( .addr_i( addr_i ), .cs_i( cs_i ), .wrdata_i( wrdata_i ), .rwn_i( rwn_i ), .rddata_o( rddata_o ) );

rddata_o has multiple drivers. I want them resolved like a verilog 'wor', but
in VHDL. I'm having trouble figuring out how to tie the VHDL "resolution function" "resolved_wor"
to the single net "rddata_o". "rddata_o" is both the input, and output of the function...
How do I hook it up?

--Mark
 
On Saturday, August 2, 2014 5:47:30 AM UTC+12, Mark Curry wrote:

rddata_o has multiple drivers. I want them resolved like a verilog 'wor', but
in VHDL. I'm having trouble figuring out how to tie the VHDL "resolution function" "resolved_wor"
to the single net "rddata_o". "rddata_o" is both the input, and output of the function...
How do I hook it up?

You specify a resolution function to use in a subtype indication declaring signals. The simulator provides an array type of the base type of the signal having a value for every driver on the net and calls the function internally.

A resolution function has one argument, an array vector and returns a result that is of the same base type.

This is from package std_logic_1164 for std_logic:

type stdlogic_table is array(STD_ULOGIC, STD_ULOGIC) of STD_ULOGIC;

-------------------------------------------------------------------
-- resolution function
-------------------------------------------------------------------
constant resolution_table : stdlogic_table := (
-- ---------------------------------------------------------
-- | U X 0 1 Z W L H - | |
-- ---------------------------------------------------------
('U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U'), -- | U |
('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'), -- | X |
('U', 'X', '0', 'X', '0', '0', '0', '0', 'X'), -- | 0 |
('U', 'X', 'X', '1', '1', '1', '1', '1', 'X'), -- | 1 |
('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X'), -- | Z |
('U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X'), -- | W |
('U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X'), -- | L |
('U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X'), -- | H |
('U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X') -- | - |
);

function resolved (s : STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result : STD_ULOGIC := 'Z'; -- weakest state default
begin
-- the test for a single driver is essential otherwise the
-- loop would return 'X' for a single driver of '-' and that
-- would conflict with the value of a single driver unresolved
-- signal.
if (s'length = 1) then return s(s'low);
else
for i in s'range loop
result := resolution_table(result, s(i));
end loop;
end if;
return result;
end function resolved;

Additionally if you were to look at the truth table for wor and trior in the 1064 (Verilog) standard you'd find that wor works identically to using the std_ulogic subtype X01Z (which is also resolved, using the same resolution function shown above).

Further package std_logic_1164 provides To_X01Z conversion functions that can be used to pre-filter std_logic and std_logic_vector values to X01Z values. They are conversion functions (1 input, a return value from a pure function) and functions are expressions ( can be used for example in port map associations) and the result is base type compatible with std_logic.

If you only ever assign 'X', '0', '1' or 'Z' to a standard logic value And you provide a default value that is one of those four values you don't need to do anything to get the same effect as using wor in Verilog.

The To_X01Z functions can be used to filter MVL9 signal values ('U','X','0', '1', 'Z', 'W', 'L','H', '-') to 'X', '0', '1', 'Z' when assignment is out of your control.

VHDL's std_logic_1164 package already provides the functionality you're after.
 

Welcome to EDABoard.com

Sponsor

Back
Top