cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
9,212 Views
Registered: ‎02-09-2010

Block RAM ready at startup?

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.

 

Tags (1)
0 Kudos
9 Replies
Highlighted
Historian
Historian
9,194 Views
Registered: ‎02-25-2008

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

    begin

        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.

Message Edited by bassman59 on 02-10-2010 09:27 AM
----------------------------Yes, I do this for a living.
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
9,189 Views
Registered: ‎09-05-2007

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?

 
Ken Chapman
Principal Engineer, Xilinx UK
0 Kudos
Highlighted
Visitor
Visitor
9,180 Views
Registered: ‎02-09-2010

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.

 

 

0 Kudos
Highlighted
Visitor
Visitor
9,157 Views
Registered: ‎02-09-2010

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.

 

COE "fanctrl.coe"
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.

 

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
9,138 Views
Registered: ‎09-05-2007

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!
Ken Chapman
Principal Engineer, Xilinx UK
0 Kudos
Highlighted
Visitor
Visitor
9,132 Views
Registered: ‎02-09-2010

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.

 

0 Kudos
Highlighted
Visitor
Visitor
9,118 Views
Registered: ‎02-09-2010

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.

 

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
9,103 Views
Registered: ‎09-05-2007

Thanks for working so hard to capture these infrequent cases. I will see if I can come up with any theories and potential mechanisms that could explain what is a rare but apparently predictable situation.  
Ken Chapman
Principal Engineer, Xilinx UK
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
8,925 Views
Registered: ‎09-05-2007

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.

 

Ken Chapman
Principal Engineer, Xilinx UK
0 Kudos