Tech Support > Computer Hardware > Microprocessors > Microblaze gone wild
Microblaze gone wild
Posted by eascheiber@yahoo.com on March 16th, 2007


Hi,

I am using Microblaze v4 and here is a snippet of my code:

volatile unsigned int * a0 = (unsigned int *)0x80000680;
void * ptr;
ptr = &pktdsr;

asm("lwi r3, %0, %1;swi r3, %2, %1;" : : "r" (a0), "i" (0),
"r" (ptr));
asm("lwi r3, %0, %1;swi r3, %2, %1;" : : "r" (a0), "i" (4),
"r" (ptr));
asm("lwi r3, %0, %1;swi r3, %2, %1;" : : "r" (a0), "i" (8),
"r" (ptr));
asm("lwi r3, %0, %1;swi r3, %2, %1;" : : "r" (a0), "i" (12),
"r" (ptr));
asm("lwi r3, %0, %1;swi r3, %2, %1;" : : "r" (a0), "i" (16),
"r" (ptr));
asm("lwi r3, %0, %1;swi r3, %2, %1;" : : "r" (a0), "i" (20),
"r" (ptr));
asm("lwi r3, %0, %1;swi r3, %2, %1;" : : "r" (a0), "i" (24),
"r" (ptr));
asm("lwi r3, %0, %1;swi r3, %2, %1;" : : "r" (a0), "i" (28),
"r" (ptr));

What I want is to read addresses
0x80000680
0x80000684
0x80000688
0x8000068c
0x80000690
....

and write the data at pointer ptr, ptr+4, ptr+8, ...

Using chipscope I see MB reading
0x80000680
!!! 0x8000068A !!!!!!!
0x80000688
0x8000068c
0x80000690

so all addresses are correct less 0x8000068A.

Can anyone help me?

Regards,
e

Posted by Zara on March 16th, 2007


On 16 Mar 2007 00:18:33 -0700, eascheiber@yahoo.com wrote:


Are you sure your design meets timing? It may be a bit that does not
change fast enough. You should review your timing constraints, and
build with -timing option

Best regards,

Zara

Posted by eascheiber@yahoo.com on March 16th, 2007


On Mar 16, 8:54 am, Zara <me_z...@dea.spamcon.org> wrote:

Yup, my design does fail timing. However all failed timing constraints
go through the PLB,
more precisely the signal PLB_abort, which has fanout 52. Maybe you
can give me a hint regarding
how to fix this problem.

Thanks,
e


Posted by Zara on March 16th, 2007


On 16 Mar 2007 03:32:40 -0700, eascheiber@yahoo.com wrote:


PLB in microblaze? Do you mean LMB?

Anyhow, using the correct timing constraints in UCF, running a timing
driven map should usually be enough. I do also use
-ignore_keep_hierarchy for map.

But if the signla that is failing constraints is something called
whatever_abort, I am more inclined to think that timing constraints
are not tight enough for your design

You clock input should be set to Nominal frequency + tolerance (or
nominal period -tolerance), and it should also be given the maximum
jitter possible with your oscillator

For instance, for a square 25 MHz clock, +/-20 ppm, with 100 ppm
jitter, data should be like:

NET "CLOCK" TNM_NET = "MY_CLOCK";
TIMESPEC "TS_MY_CLOCK" = PERIOD "MY_CLOCK" 399997 ps HIGH 50 %
INPUT_JITTER 0.40 ns;

Best luck,

Zara

Posted by eascheiber@yahoo.com on March 17th, 2007




Actually I do mean PLB, you see I have a PLB with 2 PPC connected to
it
and a Microblaze connected to OPB and a BGI & BGO.

The system should work at 100 Mhz. Forcing the PLB_Abort to be open
i.e.
writing this to the mhs:
....
PORT PLB_Abort
....
'solves' the timing problem. But I get into another problem, namely
the PPC
won't start up. I use the debugger to download program to a sdram and
run
the processors first for ppc0, then ppc1. The Microblaze code is
downloaded
with the bitstream. Now the mb and ppc1 start, it turns out that ppc0
when
running the __eabi function jumps to some address and gets stuck
there.
So, I replaced the __eabi function, now ppc0 starts, but even without
changes
to ppc1 this doesn't start anymore.

It's SO much fun...

Regards,
e







Posted by jetmarc@hotmail.com on March 21st, 2007


Hi.

I'm quite unexperienced with PLB still. But my understanding is that
PLB_Abort is a "late" signal, ie the sender can decide quite far into
a cycle to abort the cycle. If you have lots of logic levels on your
side of PLB_Abort (as your high fanout suggests), the timing closure
will fail.

Fortunately, the PLB seems to be designed with this in mind. It is
possible to implement all bus transactions, without having to react on
PLB_Abort immediately. That is, there is no need to stack up your
logic levels with those of the sender (in the same bus clock cycle).

In my PLB implementations, I ignore PLB_Abort and just register it
with the bus clock. This gives the whole clock period to the sender
logic and routing into my peripherial. Then, in the next bus clock
cycle, I check the registered version of PLB_Abort if there was an
abort "in the previous cycle". If there was, I correct my state
machine and outputs accordingly.

This relaxes PLB_Abort timing and creates the necessary room for your
logic levels. Both sender and your peripherial can use a full clock
period for decision logic, each!

Kind regards,
Marc



Similar Posts