ISE 9.2.03i problem

M

Mark McDougall

Hi Xilinx gurus,


I've got some code which I've been running on Altera silcon for several
weeks now, used in a number of different projects, synthesized with
Quartus v8.

It's a simple shift register implemented using a variable in a clocked
process...

process (reset, clk, clk_ena)
variable hactive_v_r : std_logic_vector(3 downto 0) := (others => '0');
begin
if reset = '1' then
hactive_v_r := (others => '0');
elsif rising_edge(clk) and clk_ena = '1' then
...
hactive_v_r := hactive_v_r(hactive_v_r'left-1 downto 0) & hactive_s;
end if;
end process;

BTW 'h_active_s' is a signal declared in the containing entity, and is
definitely not optimised out.

However, when building the project for Xilix under ISE 9.2.03i, I get the
following warnings during synthesis:

WARNING:Xst:653 - Signal <hactive_v_r<3>> is used but never assigned. Tied
to value 0.
WARNING:Xst:1780 - Signal <hactive_v_r<2:0>> is never used or assigned.

As a result, the code doesn't work - the results suggest that this shift
register has indeed been removed from the design.

As I said, this module is used - exactly as-is, in its entirety, in
several Altera modules.

Any idea what my problem is???

Regards,
 
M

Mark McDougall

Mark McDougall wrote:

Interesting - if I change the variables to signals, it works!

Bug?
 
S

sandeep

Mark McDougall wrote:

Interesting - if I change the variables to signals, it works!

Bug?

--
Mark McDougall, Engineer
Virtual Logic Pty Ltd, <http://www.vl.com.au>
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266

My understanding from VHDL point of view is that VARIABLES are visible
only inside process and since not assigned to signal it is optimised.
Is variable "hactive_v_r" being read some where else in code and are
you able to compile it? You should get compilation
error.
Sandeep
 
S

sandeep

Mark McDougall wrote:

Interesting - if I change the variables to signals, it works!

Bug?

--
Mark McDougall, Engineer
Virtual Logic Pty Ltd, <http://www.vl.com.au>
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266

My understanding is that VARIABLES are visible only inside the process
and hence getting optimised. Is the variable
"hactive_v_r" read/used in other part of code and are you able to
compile the code? You should get compilation error too.
--Sandeep
 
M

Mark McDougall

Brian said:
There is something else going on, that you haven't shown us.

Yeah, sorry, it is used elsewhere in the process in an 'if' statement, to
assign the value of a signal.

Regards,
 
M

Mark McDougall

I've little experience with ISE & its idiosyncrasies, but I've since been
told that this type of problem isn't uncommon. Apparently it's a little
too aggressive with its optimisation where duplicate logic is removed...

Regards,
 
D

Duane Clark

Mark said:
I've little experience with ISE & its idiosyncrasies, but I've since been
told that this type of problem isn't uncommon. Apparently it's a little
too aggressive with its optimisation where duplicate logic is removed...

Not sure who told you that, but I do that sort of thing all the time
with variables in ISE 9.2, and have never had a bit of trouble. If you
want to see a program that is extremely aggressive about finding and
removing duplicate logic, try out Synplify sometime. But removing
duplicate logic is a good thing, not bad.

About the only difference in the way I code things is that I always put
the clock enable within the clocked part of the process, and never in
the sensitivity list (a clock enable should not be put there anyway).
 
D

Dave

process (reset, clk, clk_ena)
  variable hactive_v_r  : std_logic_vector(3 downto 0) := (others => '0');
begin
  if reset = '1' then
    hactive_v_r := (others => '0');
  elsif rising_edge(clk) and clk_ena = '1' then
    ...
    hactive_v_r := hactive_v_r(hactive_v_r'left-1 downto 0) & hactive_s;
  end if;
end process;

BTW 'h_active_s' is a signal declared in the containing entity, and is
definitely not optimised out.

However, when building the project for Xilix under ISE 9.2.03i, I get the
following warnings during synthesis:

WARNING:Xst:653 - Signal <hactive_v_r<3>> is used but never assigned. Tied
to value 0.
WARNING:Xst:1780 - Signal <hactive_v_r<2:0>> is never used or assigned.

Could it be that you have a signal declared which has the same name as
the variable? Does anyone know if XST still warns that a signal is
being removed, even if it's actually a variable?

If there were a signal by the same name which is being optimized away,
maybe XST gets confused and gets rid of both.

Dave
 
K

kennheinrich

I've little experience with ISE & its idiosyncrasies, but I've since been
told that this type of problem isn't uncommon. Apparently it's a little
too aggressive with its optimisation where duplicate logic is removed...

Regards,

--
Mark McDougall, Engineer
Virtual Logic Pty Ltd, <http://www.vl.com.au>
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266

I would also expect this to create flops, exactly as you seem to want.
Without the full details of the rest of your code, I took an educated
guess and made up some logic (foo). I tried out the following design
in ISE 9.1.02i and it created some nontrivial logic for hactive_v_r(3
downto 0), after synthesis (only, into the default xcv5vlx50 device)
and a glance at the RTL viewer.

Two other tangential thoughts crossed my mind as well:

(1) why do you have clk_ena in the sensitivity list? Here in the
Castle Anthrax there's only one punishment for random, desparate-
looking sensitivity lists :)

(2) the question has often arisen here, as to why std_logic_arith and
std_logic_unsigned keep rearing their ugly heads in otherwise well-
intentioned code. One answer appeared when I (despite my better
instincts, and due to sheer laziness) used that damn-fool Xilinx
design entry wizard to create the top level shown below. "If Xilinx
does it, it must be right!", right?

Cheers, new Bruce.

- Kenn

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity fidget is
Port ( reset : in STD_LOGIC;
clk : in STD_LOGIC;
clk_ena : in STD_LOGIC;
hactive_input : in STD_LOGIC;
foo_output : out STD_LOGIC);
end fidget;

architecture Behavioral of fidget is
signal foo : std_logic;
signal hactive_s : std_logic;
begin
hactive_s <= hactive_input;
foo_output <= foo;

process (reset, clk, clk_ena)
variable hactive_v_r : std_logic_vector(3 downto 0) := (others =>
'0');
begin
if reset = '1' then
hactive_v_r := (others => '0');
elsif rising_edge(clk) and clk_ena = '1' then
if hactive_v_r = "0000" then
foo <= not foo;
end if;

hactive_v_r := hactive_v_r(hactive_v_r'left-1 downto 0) &
hactive_s;
end if;
end process;

end Behavioral;
 
M

Mark McDougall

Duane said:
But removing
duplicate logic is a good thing, not bad.

Agreed, but I've been told that the problem lies with duplicate logic and
further optimisation that reveals that *one* of the "duplicated" logic
blocks turns out to be ultimately unused - the optimiser then removes the
"duplicated" logic and the *other* block, which *is* required, gets lost...

Not speaking from and ISE experience myself, I'd guess that the order of
optimisations gets a little screwed... or at least side effects aren't
properly analysed.

In any case, I'm assured that turning *OFF* all optimisations results in
correctly-functioning code.

Regards,
 
M

Mark McDougall

Without the full details of the rest of your code, I took an educated
guess and made up some logic (foo). I tried out the following design
in ISE 9.1.02i and it created some nontrivial logic for hactive_v_r(3
downto 0), after synthesis (only, into the default xcv5vlx50 device)
and a glance at the RTL viewer.

I suspect that the problem requires more of my code to be included - the
process itself is rather larger than my snippet in the posting...

Try as I might, I can't see anything wrong with it myself, and the fact
that (1) changing to signals works and (2) quartus works (with the
original code) I still cling to my belief that it's an ISE bug...
(1) why do you have clk_ena in the sensitivity list? Here in the
Castle Anthrax there's only one punishment for random, desparate-
looking sensitivity lists :)

Noted! I probably picked up that habit long ago when first starting out
and never gave it a second thought... you've just made a difference to
someone - take the rest of the day off! :)
(2) the question has often arisen here, as to why std_logic_arith and
std_logic_unsigned keep rearing their ugly heads in otherwise well-
intentioned code. One answer appeared when I (despite my better
instincts, and due to sheer laziness) used that damn-fool Xilinx
design entry wizard to create the top level shown below. "If Xilinx
does it, it must be right!", right?

Coincidently, I've just spent a few days going through my entire code base
and removing all references to std_logic_arith. The most painful by far
was my copious use of EXT(), which is now replaced with a much more
cumbersome and less-flexible use of RESIZE(). :( It's something I've been
putting off but every time I read a post on the subject I felt another
pang of guilt! ;)

Thanks for your comments!

Regards,
 
K

KJ

Mark McDougall said:
(e-mail address removed) wrote:

Try as I might, I can't see anything wrong with it myself, and the fact
that (1) changing to signals works and (2) quartus works (with the
original code) I still cling to my belief that it's an ISE bug...

You've submitted this as a bug to the good folks at Xilinx, correct? It
doesn't help you with the tool this time around, but eventually it gets
fixed (if the submitters persist) or you move on to other tools, other
suppliers.

KJ
 
K

kennheinrich

You've submitted this as a bug to the good folks at Xilinx, correct?  It
doesn't help you with the tool this time around, but eventually it gets
fixed (if the submitters persist) or you move on to other tools, other
suppliers.

KJ

I think there might be a mis-attribution here: it was Mark, not I, who
clings to his belief.

But more topically, Brian Drummond suggested in another post that
there could be other stuff happening in other logic that causes the
optimization to occur. If the code can be simplified to the point
where it can be posted here and still show the bug, I will be happy to
try it out on my version of ISE (and if motivated, even try out
another synthesizer). If there's a real tool bug lurking here, let's
kick it back the the vendor.

- Kenn
 
K

KJ

(Note: I haven't used Quartus; I may be doing it an injustice here)

But here's my worry: What if XST is actually right; and Quartus is one
step behind the pack in its optimisation technology (generating correct
but sub-optimal results)?

As always (and I'm assuming that Mark has already done this), you
always run the simulator first to make sure that the design is
functionally correct. Optimization that changes the observable
function is incorrect optimization.

Kevin Jennings
 
M

Mike Treseler

KJ said:
As always (and I'm assuming that Mark has already done this), you
always run the simulator first to make sure that the design is
functionally correct. Optimization that changes the observable
function is incorrect optimization.

Yes. It is not the job of synthesis to guess
the cases where I don't want register sharing or duplication.
If the netlist sims correctly, synthesis is correct.

To get a register to duplicate or not share as
I wish, I have to describe the requirement
as a device constraint, or change my logical description
to rule out the unwanted register usage.

For example, if I want to avoid sharing of the
second register in a synchronizer, I could
either make an explicit device-specific constraint,
or add a third flop to the synchronizer.

-- Mike
 
J

jtw

Brian Drummond said:
OK, you're right. As long as the simulation test coverage is adequate, I
was spouting nonsense there.

- Brian

Just be aware that there are occasions where the simulation can be
incorrect; just the other day, I was modifying a [non-clocked] process, but
forgot to add a key signal to the sensitivity list. So, simulation was
'incorrect'--at least, undesired--and synthesis would have produced the
desired behavior. (In this case, it was in the test bench, so synthesis
would have been immaterial.)

I found and corrected it quickly, and there is a compiler option to warn
about synthesis mismatch, but still.... It is possible to have simulation
wrong and synthesis correct, as well as vice-versa.

JTW
 
K

kennheinrich

OK, you're right. As long as the simulation test coverage is adequate, I
was spouting nonsense there.

Just be aware that there are occasions where the simulation can be
incorrect; just the other day, I was modifying a [non-clocked] process, but
forgot to add a key signal to the sensitivity list.  So, simulation was
'incorrect'--at least, undesired--and synthesis would have produced the
desired behavior.  (In this case, it was in the test bench, so synthesis
would have been immaterial.)

I found and corrected it quickly, and there is a compiler option to warn
about synthesis mismatch, but still....  It is possible to have simulation
wrong and synthesis correct, as well as vice-versa.

JTW

Two wrongs don't make a right. Wrong #1: describe the wrong logic
(according to well defined, intentioned language semantics) by
accidentally mis-typing the sensitivity list, then (wrong #2) claim
that the synthesis tool ought to be ignoring the semantics of the
language. While this would certainly not be the first time this has
occurred (and I've probably been bitten by it, too), it's not really
accurate to say "simulation is incorrect".

- Kenn
 
M

Mark McDougall

Brian said:
I suspect something obscure in the logic you didn't post is causing it
to be simplified; therefore the other block appears redundant.

The code in question is a video controller, and the offending
variable/signal is simply a pipeline delay for one of the signals. In
fact, the controller has a number of pipeline delays and it would appear
that a *pair* of them were being (incorrectly) optimised out.

Anyway, I'm not going to defiantly claim there is definitely nothing wrong
with my code, so I'll endeavour to put together a small sample project and
see if I can't reproduce the problem.

And in answer to other threads, the code simulates correctly, and works
exactly as expected on Altera silicon. There's really nothing complicated
in this scenario, believe me - a couple of counters and some pipeline
shift registers.

Regards,
 
B

Brian Davis

Brian said:
... and I have seen *some* evidence that there *may* be a problem with
pipeline delays implemented as variables (actually a variable array, to
easily control the length); or the transition between signals and such
delays. About a year ago, on XST 7.1.

It manifested as a cycle difference between the length of the pipeline
in simulation, and the same pipeline in practice.
I saw a similar bug in XST 9.1 (fixed in 9.2), that would
drop (add?) a pipeline stage on inferred memories under certain
conditions. I never boiled this down to a testcase, as the problem
went away in XST 9.2, and I ended up using Synplify on that job
anyhow due to other problems with XST.

XST attempts to push extra register stages into the BRAM by
enabling the output pipeline register; under certain conditions,
XST would lose track of what it was doing, and wire up the BRAM
incorrectly. I saw this on a pipelined inferred ROM, where the
synthesized circuit was off by one cycle from the simulation.

I forget the exact details, but XST would either push the BRAM
address register input back one stage without enabling the BRAM
data pipeline register; or, enable the register but connect one
BRAM address port to the original address, the other to the
earlier address stage, and then wire the data up to the wrong
output port. ( Whichever one it was showed up clearly as a weird
connection to the BRAM in the schematic viewer. )

Brian
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top