Driving one signal from two processes

S

Silver

Guest
Hi everyone,

I'm having a problem concerning concurrent write of one signal from
within two processes. My signal acts as a register and is of type
std_logic_vector. It is written and read by one of the processes
synchronously. Another process acts as a "poker" - it allows to
asynchonously read and write the register. When compiling Quartus
presents me with an error message "constant drivers for net". My
question is - how to get over this problem? I already tried diffrent
data types (variable, shared variable) - no luck. I don't have to care
if there are any hazards.

Best regards,
Chris
 
On Fri, 12 Oct 2007 07:00:48 -0700,
Silver <K.Pisaniec@gmail.com> wrote:

I'm having a problem concerning concurrent write of one signal from
within two processes. My signal acts as a register and is of type
std_logic_vector. It is written and read by one of the processes
synchronously. Another process acts as a "poker" - it allows to
asynchonously read and write the register.
You just can't do that. VHDL signal assignment doesn't work
that way. Each process represents a driver on the signal; the
value seen on the signal is the result of applying the signal's
resolution function to all its drivers.

You say you don't care about hazards, so it's easy enough to
make something like this happen. I guess that you are looking
for "last write wins" semantics. The way to get it is to
have THREE processes, one of which implements your last-write-wins
protocol by looking at the outputs of the other two. Don't
expect this to be synthesisable.

signal source1, source2, result: std_logic;
last_write_wins : process
begin
--- Wait until any of the drivers is written.
wait on source1'transaction, source2'transaction;
if source1'active then
-- there was a write to source1 (has priority over source2)
result <= source1;
elsif source2'active then
-- no write to source1, but source2 was written
lresult <= source2;
end if;
end process;

Then write two more processes, one driving source1 and the
other driving source2.
--
Jonathan Bromley, Consultant

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

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

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

I'm having a problem concerning concurrent write of one signal from
within two processes. My signal acts as a register and is of type
std_logic_vector. It is written and read by one of the processes
synchronously. Another process acts as a "poker" - it allows to
asynchonously read and write the register. When compiling Quartus
presents me with an error message "constant drivers for net".
You are asking quartus to short outputs together.

My
question is - how to get over this problem? I already tried diffrent
data types (variable, shared variable)
What happens if you use multiple
variables in a single process?

-- Mike Treseler
 
Another way to attack this is to make the signal registered with an
asynchronous load. I would write something like this:

signal A : std_logic_vector(7 downto 0);

process(clk, reset, load)
begin
if reset = '1' then
A <= (others => '0');
elsif load = '1' then
A <= A_async_load_value;
elsif rising_edge(clk) then
A <= A_sync_load_value;
end if;
end process;

From the second, ansynchronous process, you can control the
asynchronous load signal and the asynchronous load value. I believe
Altera logic cells allow for async loads as well as resets/presets.

On Oct 12, 10:49 am, Mike Treseler <mike_trese...@comcast.net> wrote:
Silver wrote:
I'm having a problem concerning concurrent write of one signal from
within two processes. My signal acts as a register and is of type
std_logic_vector. It is written and read by one of the processes
synchronously. Another process acts as a "poker" - it allows to
asynchonously read and write the register. When compiling Quartus
presents me with an error message "constant drivers for net".

You are asking quartus to short outputs together.

My
question is - how to get over this problem? I already tried diffrent
data types (variable, shared variable)

What happens if you use multiple
variables in a single process?

-- Mike Treseler
 
On 14 Okt., 22:27, dhsch...@gmail.com wrote:
process(clk, reset, load)
begin
if reset = '1' then
A <= (others => '0');
elsif load = '1' then
A <= A_async_load_value;
elsif rising_edge(clk) then
A <= A_sync_load_value;
end if;
end process;
This has to considered a bad code in most cases.

From the second, ansynchronous process, you can control the

asynchronous load signal and the asynchronous load value. I believe
Altera logic cells allow for async loads as well as resets/presets.
Than this is a very special cell if also allowing synchronous
operations. You have typically a latch (if reset elsif load) or a
flipflop (if reset elsif clock_edge).

I would use a latch if you really need to and generate a synchron set
signal in another process. In most cases you have other sollutions
than using a latch when inspecting the overall problem carefully.

bye Thomas
 
On Oct 15, 1:44 am, Thomas Stanka <usenet_nospam_va...@stanka-web.de>
wrote:
On 14 Okt., 22:27, dhsch...@gmail.com wrote:

process(clk, reset, load)
begin
if reset = '1' then
A <= (others => '0');
elsif load = '1' then
A <= A_async_load_value;
elsif rising_edge(clk) then
A <= A_sync_load_value;
end if;
end process;

This has to considered a bad code in most cases.
Why? If we're not concerned about hazard-type conditions as the
original poster says, and he's targeting Altera logic which supports
async load operations (I know the old Apex20k's did, and Stratix II's
do), why not use the abilities that Altera gives you?

From the second, ansynchronous process, you can control the

asynchronous load signal and the asynchronous load value. I believe
Altera logic cells allow for async loads as well as resets/presets.

Than this is a very special cell if also allowing synchronous
operations. You have typically a latch (if reset elsif load) or a
flipflop (if reset elsif clock_edge).

I would use a latch if you really need to and generate a synchron set
signal in another process. In most cases you have other sollutions
than using a latch when inspecting the overall problem carefully.
I agree that there may be a better, less technology-dependaet solution
if the overall system were rethought.

> bye Thomas
 
On 15 Okt., 16:23, Dave <dhsch...@gmail.com> wrote:
process(clk, reset, load)
begin
if reset = '1' then
A <= (others => '0');
elsif load = '1' then
A <= A_async_load_value;
elsif rising_edge(clk) then
A <= A_sync_load_value;
end if;
end process;

This has to considered a bad code in most cases.

Why? If we're not concerned about hazard-type conditions as the
original poster says, and he's targeting Altera logic which supports
async load operations (I know the old Apex20k's did, and Stratix II's
do), why not use the abilities that Altera gives you?
I consider this code a typical "beginner trap", as a lot of tools and
technology combinations wont produce the logic you expect, when using
this code. And someone without experience in digital design might
miss the implication of inferring this element for timing analyses.
The only reason to use this code and consider it not as bad is, if you
can be sure, your synthesis result is like you expect it to be.
 

Welcome to EDABoard.com

Sponsor

Back
Top