std_logic resolution

H

Hilko

Hi,

i try to prevent my compiler (Altera Quartus) from optimizing away some
signals. Therefore i assign parallel to my logic some "default-logic"
with weak signals. The shortened source code follows ...

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

-------------------------------------------------------------------------------
entity test is
port (
reset_n: in std_logic;
clk : in std_logic;
a_in : in std_logic;

b_out : out std_logic_vector(7 downto 0)
);

end entity test;



-------------------------------------------------------------------------------
architecture arch of test is

signal b : unsigned(7 downto 0);

begin


-- ========================================
-- default logic start
-- ========================================

b <= (others => 'L');

-- ========================================
-- default logic end
-- ========================================


main : process(reset_n, clk) is

begin
if reset_n = '0' then
b <= (others => '0');
elsif rising_edge(clk) then
if a_in = '1' then
b <= x"0A";
else
b <= x"0B";
end if;
end if;
b_out <= std_logic_vector(b);
end process main;
end architecture arch;

The following error occurs
Error (10028): Can't resolve multiple constant drivers for net "b[7]"
at formatter.vhd(31)

What is wrong ?

Thanks in advance,
Hilko
 
M

Mike Treseler

Hilko said:
i try to prevent my compiler (Altera Quartus) from optimizing away some
signals. Therefore i assign parallel to my logic some "default-logic"
with weak signals.

It might be easier to move such signals to
the port declaration until they are needed elsewhere.
Or run a sim instead of synthesis.
The following error occurs
Error (10028): Can't resolve multiple constant drivers for net "b[7]"
at formatter.vhd(31)

I see no multiple drive problem in the posted code.
What is wrong ?

Maybe you trimmed too much from the actual code
to cause the error.

-- Mike Treseler
 
A

Andy

Quartus may not like the fact none of the drivers for the signal are
ever 'Z' (for a tristate bus). Does your target architecture support
pulldowns? Even if so, they would never win, since main always drives
a forcing value. I think there may be a hint in the error message about
multiple CONSTANT drivers (i.e. drivers that never alter their
strength?).

Andy
 
J

Jeremy Ralph

You're getting the multiple drivers problem because you are
concurrently assigning b from two locations i) in the main process and
ii) after your "default start logic" comment. I'd remove the line "b
<= (others => 'L');" (which will happen forever, not just at startup)
and only drive the b signal from the main process. Each signal should
only be driven from one process. Initial values (other than reset
values) don't really make sense for a sequential signal.

Also, I'm not sure it makes sense to assign b_out in a clocked process?
I'd move "b_out <= std_logic_vector(b);" outside of the main
process?

So long as a_in is not constant and b_out is used in your design (or
are ports at the toplevel) they shouldn't get optimzed out during
synthesis.
 
H

Hilko

Hi,
thank for all suggestions.

Mike said:
It might be easier to move such signals to
the port declaration until they are needed elsewhere.

I know, but this is sometimes laboriously.
Or run a sim instead of synthesis.

I'm using the Altera internal simulator exclusively.
I'm not sure if Altera Quartus can compile for simulation purpose only.
(Any suggestions about this are welcome!) I think, you consider
I should use modelsim for a simulation ? I'm not able to do this so
far.
But if this is the way out, I will see if it's possible....
Maybe you trimmed too much from the actual code
to cause the error.

No, the shortened code results in the same error.
Quartus may not like the fact none of the drivers for the
signal are ever 'Z' (for a tristate bus).

There is no tristate bus used.
Does your target architecture support pulldowns?

There exists "Weak Pull-Up Resistor" option for pins only,
but for internal signals i'm not sure.
Even if so, they would never win, since main always drives a forcing value.

You are right.
I think there may be a hint in the error message about
multiple CONSTANT drivers (i.e. drivers that never alter their strength?).

Yes: .....multiple constant (non-tri-state) drivers are contending for
the specified net......
But my understanding of std_logic is, that multiple parallel drivers
are resolved
through a resolution-function. e.g. 'L' and '1' results in
'1'.

Jeremy said:
You're getting the multiple drivers problem because you are
concurrently assigning b from two locations i) in the main process and
ii) after your "default start logic" comment.

Yes, but I thought this is the reason why there is a
"resolution-function".

I'd remove the line "b <= (others => 'L');" (which will happen forever, not just at startup)
and only drive the b signal from the main process.
Each signal should only be driven from one process.

OK, now it works, but except b(3) and b(0) the rest of signal b is
reduced away.

Also, I'm not sure it makes sense to assign b_out in a clocked process?
I'd move "b_out <= std_logic_vector(b);" outside of the main process?

Yes, you are right. This was a little inattention.
So long as a_in is not constant and b_out is used in your design (or
are ports at the toplevel) they shouldn't get optimzed out during
synthesis.

Yes, but the internal signals are sometimes optimized away.
For simulation with the Altera internal simulator it's annoyingly.

Hilko
 
N

Nicolas Matringe

Hilko a écrit :
I'm using the Altera internal simulator exclusively.
I'm not sure if Altera Quartus can compile for simulation purpose only.
(Any suggestions about this are welcome!) I think, you consider
I should use modelsim for a simulation ? I'm not able to do this so
far.
But if this is the way out, I will see if it's possible....

Hi
You can download ModelSim XE Starter from Xilinx's web site. It's free
and still works quite well with Altera-targeted designs.

Nicolas
 
J

Jeremy Ralph

Yes, but I thought this is the reason why there is a
"resolution-function".

Perhaps, I don't know much about this. But I would be very careful
with this sort of thing... How portable is it across tools and
architectures? Will it be treated the same in simulation as it is in
synthesis?
OK, now it works, but except b(3) and b(0) the rest of signal b is
reduced away.

Strange I would think registers would be inferred for b(3) and b(1
downto 0) and the rest would be optimized away (tided to a constant)
since there is no way in the vhdl for these values to ever change. How
are you driving a_in, reset_n? Does the synthesis tool think these are
constant or variable? What are you doing with b_out? Does the
synthesis tool think this is needed somewhere? I would think you would
attach these to FPGA pins to limit optimizations.

For simulation, there is also http://www.symphonyeda.com/. I was quite
impressed.
 
H

Hilko

Jeremy said:
How are you driving a_in, reset_n? Does the synthesis tool think these are
constant or variable? What are you doing with b_out? Does the
synthesis tool think this is needed somewhere? I would think you would
attach these to FPGA pins to limit optimizations.

The above entity is the top-level design file.
Therefore all the port signals are routed to pins.

Hilko
 
G

Gerhard Hoffmann

but if this parallel logic is constant, the compiler still might decide
that the circuits that use it have no effect.
It might be easier to move such signals to
the port declaration until they are needed elsewhere.
Or run a sim instead of synthesis.

I once had too much unused logic in a virtex 4 and ISE 8.1 crashed over it.
Well, it said something like "cannot continue, bye" with no further hints
when linking / globally optimizing the modules.
ISE 7.1 had no problems with this.

I declared one spare pin as bit_gutter and used xor_reduce() from
IEEE reduce pack to provide as many loads as needed.

Worked nicely (although Modelsim warned that xor_reduce
is implemented recursively).

regards, Gerhard
 
L

lundril

The error is simple to explain:

You drive b two times (as already explained by someone else):

first time:
b <= (others => 'L');

second time:
in " main : process (...)".

This kind of construct can be simulated, but not synthesized into real
hardware. (In hardware this would mean you put a pull-down on b,
which isn't possible in an Altera device...)

As for your main problem:

If you don't want quartus II to optimize away some registers, there is
a simple way to do that:

change your declaration of "b" to the following:

attribute preserve : boolean;
signal b : unsigned(7 downto 0);
attribute preserve of b : signal is true;

(Have a look into the Quartus II manual and search for "preserve").

By adding the "preserve" attribute to "b" you tell quartus to
not optimize away your registers.

Some other style questions : Why do you use "unsigned" for "b" if
you only do use constants like X"0A" to assign a value ?
Just use "STD_LOGIC_VECTOR". (Why mixing types when one
type is enough for what you want to do.)

As already written by someone else:
putting the
"b_out <= std_logic_vector(b);"
line into your process is simply wrong.
In simulation this would mean, that you change the value of "b_out"
only
if "reset_n" or "clk" changes its value (because "b" is NOT in the
sensitivity
list of the process.) In hardware this means Quartus II would have to
implement a register which reacts on the falling and rising edges of
"CLK" and
"Reset_n" to come close to the behaviour if you simulate that.
That is definitely not what you seem to accomplish.
 
H

Hilko

By adding the "preserve" attribute to "b" you tell quartus to
not optimize away your registers.

Thanks, that is what i'm looking for.
Some other style questions : Why do you use "unsigned" for "b" if
you only do use constants like X"0A" to assign a value ?
Just use "STD_LOGIC_VECTOR". (Why mixing types when one
type is enough for what you want to do.)

It's just a sample code that should show the
"optimizing"-problem. The original code where it is derived from is
much longer and much meaningful (i hope so).

As already written by someone else:
putting the
"b_out <= std_logic_vector(b);"
line into your process is simply wrong.
.....

I 100% agree. It was just a little inattention of mine.
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top