• 0
tschaboo

VHDL: Why are those 2 variants not equivalent?

Question

Hello,

 

my design is made up of two files, which I both attached. I have the following problem, which I absolutely can't explain: If I move the statement "u_address <= u_address + 1;" from line 122 in top.vhd to line 128, the design behaves differently. In my eyes there should be no difference at all if I make this signal assignment before or after the "if"!?! What happens is, that with the first variant the Leds stay dark - as expected - but with the second variant Led(0) lights up after a second. Which means that u_error_cnt was incremented exaclty once!

 

Is it possible that I hit a bug in ISE 14.7?

 

Thanks

PSRAM_nopage.vhd

top.vhd

Share this post


Link to post
Share on other sites

9 answers to this question

Recommended Posts

  • 0

I also attach my .ucf file in case someone wants to try this on a Nexys 3.

 

The problem is absolutely reproducible on my end. I synthesized both variants severel times and programmed both variants several times to the FPGA. The result is always as described above.

Nexys3_Master.ucf

Share this post


Link to post
Share on other sites
  • 0

Hi,

the observation that it reliably changes with the text file edit may be misleading. I'm staring deep into the crystal ball here but have a look at this regarding determinism of ISE's P&R.

I suspect the problem is different and gets randomly triggered. I think we've all experienced situations where you hit a brick wall and start to doubt the device, the tools and your own sanity. And I can only encourage you to get to the bottom of it, otherwise there will always remain some nagging doubt. Or maybe it's one variant of the old rule that often we spend 90 % of the time on 10 % of the work.

Can you explain every single warning, also the unrelated ones (e.g. register xyz gets optimized away?)

Do you get timing errors (if so, fix them first), and do you have good timing margins? One dirty hack is to fake a higher clock frequency (e.g. set 110 MHz when it's 100 MHz in reality). This effectively creates extra margin - if you see any change in behavior (e.g. the "bad" variant passes), timing plays a role. And / or run the whole design at lower frequency.

Taking a random guess, I'd look into the data sheet and double-check the timing constraints for the RAM IOs.

 

 

Share this post


Link to post
Share on other sites
  • 0

Hello xc6lx45,

 

thanks for your answer, I really appreciate it.

I guess your suspicion that the problem is different is correct. I'm just so new to VHDL and FPGAs that I wanted to make sure, that my edit really should be equivalent. I did restructure the code several times now, and the problem (being that error_cnt gets incremented to 1) came and went. 😉 Currently it's gone. As a software engineer I'm used to +/-1 errors, but this is kind of different.

Anyway, regarding your remarks:

RAM timing: I have to check on the setup- and hold-constraints again. But in general it should be fine. I tried it slower - didn't make a difference. I tried it faster: there's quite some reserve. Spec says that the answer is guaranteed after 70ns but it worked fine down to 50ns. Any less and I got garbage.

FPGA timing: The timing analysis always showed 145MHz or more. I'm running at 100MHz so that should be fine.

Warnings: I understand all of them. They are about unused signals and they are correct. There is one NOTICE though that I don't understand:

INFO:Xst:2261 - The FF/Latch <WE_clk_DFF_53> in Unit <PSRAM_nopage> is equivalent to the following 15 FFs/Latches, which will be removed : <WE_clk_DFF_56> <WE_clk_DFF_54> <WE_clk_DFF_55> <WE_clk_DFF_59> <WE_clk_DFF_57> <WE_clk_DFF_58> <WE_clk_DFF_62> <WE_clk_DFF_60> <WE_clk_DFF_61> <WE_clk_DFF_65> <WE_clk_DFF_63> <WE_clk_DFF_64> <WE_clk_DFF_68> <WE_clk_DFF_66> <WE_clk_DFF_67> 

I don't know what that means or where those flip-flops come from.

Share this post


Link to post
Share on other sites
  • 0

>> or where those flip-flops come from.

You might have a look at the synthesized design, try to explain why there are 16 parallel but logically equivalent WE paths. It seems odd indeed. Did you accidentally create combinational latches (~ a signal with "memory" of an earlier state that may change outside of clock events)? Locate one and check whether it is clock-driven. And if not, why.

My understanding (not using VHDL on a day-to-day-basis) is that a signal assignment in sequential code is delayed so the change should be equivalent.

 

Share this post


Link to post
Share on other sites
  • 0

Thanks again for your help!

I looked at the generated RTL Schematic and found nothing suspicious. As far as I understood it, the WE_clk_DFF_xx registers connect to the tri-state-BUFTs  T-port. And it makes sense that those are all 16 the same, because I switch all 16 at once between 'Z' and output. Why there are first 16 flip-flops generated and only later combined into 1 - I don't know.

The "Device Utilization Summary" says that there are 0 slice registers "used as Latches".

 

It would be so helpful to see inside the FPGA. I guess if I had access to a logic analyzer I could route a few signals to output pins and watch them...

I guess I could also somehow construct a simple model of the PSRAM so that I could simulate the whole thing. But I didn't look into simulation much yet. Is on my TODO list.

Share this post


Link to post
Share on other sites
  • 0

Be careful with nested if..then..else statements. This structure implies priority. In ISE you can view the synthesis results in an RTL view to see a schematic of how it interpreted your code. Did you try an simulate the two variants? You haven't found a bug in either ISE or VHDL but figuring this out might be a valuable exercise.

In VHDL the ':=' and '<=' assignments are not equivalent

Share this post


Link to post
Share on other sites
  • 0

I don't believe this is a bug but rather a misunderstanding of VHDL. Unfortunately, VHDL process block is very vaguely described in textbooks.

In VHDL statements within the process are carried out sequentially. Moving a statement from one position to another can produce a different outcome. However, it depends on a type of statement, for example, values assigned to signals are not carried out immediately but scheduled to occur at the end of the processor or on clock events.

I would recommend to check how it works by simulating a piece of code in doubt.

Share this post


Link to post
Share on other sites
  • 0
54 minutes ago, zygot said:

Be careful with nested if..then..else statements

Yes, I'm careful. As far as I understand the RTL it looks like it's correct. It's just not that easy to decipher sometimes.

54 minutes ago, zygot said:

In VHDL the ':=' and '<=' assignments are not equivalent

Yes, I learned the difference between signal and variable the hard way. Took me half a day to find out.

55 minutes ago, zygot said:

Did you try an simulate the two variants?

No, not yet. I yet have to learn how to simulate. That's on the agenda for this week.

 

Luckily, since the RAM is static, the memory stays intact as long as the power is on. Therefore I could use the Digilent Adept 2 utility to fill the RAM with random data before my design runs [1], and read out the RAM afterwards. The result fascinates me: On the first run of writes address 0x1 doesn't get written. That's the 1 error the readback indicated. Now, if it would be 0x0 or 0xfff... I would know where to look. But 0x1?! Fascinating. And frustrating. But I learned a lot today.

I think I'm going to put this aside for now. I will try to access the RAM synchronously. Let's see if similar/related bugs appear there ... or if I don't get it to work at all ... or if it just magically works.

Thanks again!

[1] a different, modified design - not the one I uploaded here.

Share this post


Link to post
Share on other sites
  • 0

Hello Notarobot!

5 minutes ago, Notarobot said:

for example, values assigned to signals are not carried out immediately but scheduled to occur at the end

Yes, that's what I found out yesterday. And indeed the command in question was such an assignment to a signal. Therefore it really should have been no different.

5 minutes ago, Notarobot said:

I would recommend to check how it works by simulating a piece of code in doubt.

Will do!

Thanks!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now