02-09-2010 12:09 PM
I am using a pblaze connected to a block RAM. The first thing it should do at startup is run a loop that copies some parameters from the block RAM into the pblaze scratchpad. Once in awhile (< 1% of the time), I'll see a problem right after FPGA configuration when the pblaze starts up. The symptoms that I see seem to indicate that either the block RAM contents did not get read correctly, or maybe the loop did not even execute.
Is there any known issue with allowing the pblaze to start running right at startup? I do not assert the pblaze reset, but it has an internal reset that will assert at global set/reset (GSR.) I can pulse the reset after startup, and then the problem clears up.
I could not find any good description of the timing sequence between global reset (GSR) and other events, like RAM being ready for access, I think this is referred to as GTS in the data sheet. This is on a Virtex 4 LX device. The clock is a stable external clock, so DCM locking does not come into play here.
02-10-2010 09:26 AM - edited 02-10-2010 09:27 AM
Assuming you've got the proper INIT generics set for your parameter BRAM, then it should be alive when startup is finished. This is also how the PicoBlaze works.
You might wish to make a simple local reset for your PicoBlaze out of a shift register:
signal pbReset_sr : std_logic_vector(3 downto 0) := "1111";
pbReset : process (clk) is
pbReset_sr <= pbReset_sr(2 downto 0) & '0';
end process pbReset;
and connect pbReset_sr(3) to the PicoBlaze's reset input in your instantiation.
At startup the shift register gets loaded with all ones and the PicoBlaze is held in reset. You shift zeros in, so it takes four clock ticks to clear the shift register and hence the PicoBlaze reset.
02-10-2010 10:06 AM
I haven’t come across this happening before but I can’t quite imagine what it could be. KCPSM3 already has a 2 stage shift register that requires 2 clock edges to release an internal reset nice and synchronously so that would apply after configuration when the reset input is tied Low. I would be surprised if the BRAM wasn’t ready by then.
If the BRAM wasn’t ready to be read then we can assume that the instruction presented to KCPSM3 would be “00000” which means ‘LOAD s0, 00’. The program counter would still increment normally but that would be where the instruction you actually put at address zero would be missed. So maybe you could do an experiment where you make ‘LOAD s0, 42’ your first instruction and then see what value is in ‘s0’ when things get going.
If delaying reset more on start up does make it work then it does look like the cause but I’m still puzzled how the logic would be running that much faster than the BRAM. What device is it and what is your clock frequency?
Does it matter how you configure the device? e.g. Master mode verses iMPACT via JTAG?
02-10-2010 06:31 PM
I'm using a Virtex 4-LX15. The clock is 25 MHz, free-running external input.
I've thought of running a little experiment to see if I can catch it doing something weird. Also thought of delaying reset, which might make the problem go away, but it kind of leaves me wondering if that solution is robust, if there is no specified upper bound between reset being released and BRAM being ready.
If I find something interesting from my experiment, I'll post it.
02-12-2010 07:17 AM
Here is my experiment: I have a loop where the board software loads the FPGA using slave parallel (selectMAP) This is normally how we do it. I have a picoblaze program that loads each general purpose register with a value, does some NOPs, then writes these values to a BRAM. This runs once right at configuration. Then I check the memory contents.
VHDL "ROM_Form.vhd", "fanctrl_pb.vhd", "prog_rom"
; test to see if any corruption
LOAD s0, $80
LOAD s1, $81
LOAD s2, $82
LOAD s3, $83
LOAD s4, $84
LOAD s5, $85
LOAD s6, $86
LOAD s7, $87
LOAD s8, $88
LOAD s9, $89
LOAD sA, $8A
LOAD sB, $8B
LOAD sC, $8C
LOAD sD, $8D
LOAD sE, $8E
LOAD sF, $8F
OR s0, s0
OR s0, s0
OR s0, s0
OR s0, s0
OR s0, s0
OR s0, s0
OR s0, s0
OR s0, s0
OR s0, s0
OR s0, s0
OUT s0, $70
OUT s1, $71
OUT s2, $72
OUT s3, $73
OUT s4, $74
OUT s5, $75
OUT s6, $76
OUT s7, $77
OUT s8, $78
OUT s9, $79
OUT sA, $7A
OUT sB, $7B
OUT sC, $7C
OUT sD, $7D
OUT sE, $7E
OUT sF, $7F
eend: JUMP eend
I got it to fail a couple of times, after 200 to 400 loops for each test. In each case, the first BRAM location had the wrong data: 0x81 instead of 0x80.
02-16-2010 06:12 AM
Thanks for posting your experimental results but now I am really struggling to work out a reason. At 25MHz clock rate in a Virtex-4 device I just don’t think there is a timing issue in any normal sense. What really gets me about your observations is that you say the value that appears to have been loaded into s0 is 81 rather than 81. That really implies that the BRAM was ready to be read but the wrong value came out.
It appears that the value loaded was the same value you stored at address 001 so I wonder if that is really what got read or if we just got one bad bit (lsb)? If you feel up to trying another experiment then may be you could put some more interesting pattern values like A5 and 5A at the first two locations to see if the issue is more than one bit. When you do hit the issue then I’d also like to know if a manual reset (rather than reconfiguration) provides the correct values.
Normally following configuration you expect a lot of ‘zeros’ to be everywhere. So unless we forced the situation then the program address would be zero, BRAM contents would be all zero and most other signals would be zero. PicoBlaze and its program ROM do force that situation a bit but nevertheless I would still expect to see bad values being biased towards zero than showing partially correct values that have an additional ‘1’.
My two guesses right now are either that the BRAM contents are not being initialised correctly or that one path through the interconnect is partially defective. Of course there should be no reason for either case. If you have more than one device exhibiting the same issue then that would generally rule out silicon defects but I don’t know if you have more than one to try.
I’ll keep thinking!
02-16-2010 11:01 AM
For the original design, the symptoms were reported for several different boards and different FPGA builds. On my setup, I was able to get out of the failed state by performing a manual reset. I believe I tried a loop with a bunch of pblaze resets, but not configuration, and did not see the problem.
I can try some more interesting values and post the results.
02-17-2010 10:34 AM
I modified my test to use some more interesting values, so it expects to see:
5A, A5, 6A, A6, 7A, A7...
I got it to fail again after a couple of rounds of looping until failure. The results in both cases:
A5, A5, 6A, A6, 7A, A7 ...
So it seems that the first instruction is somehow mis-executing. The data from the second command ends up in the first register. I then ran a manual pblaze reset and the memory went back to the expected values.
02-19-2010 06:03 AM
03-19-2010 07:39 AM
Just a few words to bring this thread to some kind of conclusion.
Investigations have confirmed that the BRAM holding the PicoBlaze program is ready to be read following device configuration and PicoBlaze was starting to execute the code it was reading from it. The intermittent issue observed was actually happening a few clock cycles after start up and appears to relate to a suspicious clock transition which is probably resulting in a double clock or narrow spike which would represent operation outside of device specification. It will be appreciated that proving that beyond doubt is a challenge but having ruled out anything else and narrowed down the effect to a particular clock edge we can at least say with confidence that this is not going to be a common issue when using PicoBlaze (and hasn’t been reported in the last 5 years either).
The probable cause for the quality of this clock being compromised is related to the fact that it occurs in the period following start up when the design is waking up and starting to do things. Device outputs become active and switch to their initial states and circuits start clocking resulting in the possibility of a voltage dip during the initial power surge, possible ground bounce due to the number of simultaneously switching outputs (SSO) or a combination of both. In the end, it is how the clock is observed by the circuits inside the device and not what is observed on the clock input pin (assuming that is good).
Although it would be nice to absolutely prove the cause of these intermittent cases (and may be we will one day), the solution was simply to hold PicoBlaze in reset for a few more clock cycles after configuration. This would have avoided the suspicious clock edge completely and at the same time it will have lowered the initial demands on the power supply.
Thanks again for all the experiments you performed.