KEEP_HIERARCHY

I have a digital receiver module needed in a MicroBlaze system that I coded in Verilog. The module is responsible for accepting, parsing, and storing receive data from a part our company makes. The part is responsible for driving the clock and data at 26 MHz. Our internal clock on our MicroBlaze embedded system is 38.4 MHz.

I desinged the block as two separate modules. The first module is basically a shift register that clocks in the serial data from the part when an enable line goes high (also driven by the external part). This module works in the 26 MHz clock domain. The second module is a state machine that accepts 96-bit chunks of data from the previous module, parses that data based on the format being sent (a MBlaze software register setting), and stores it in 32-bit chunks in internal block ram. This module works in the 38.4 MHz clock domain.

So the part sends the enable signal and that tells the 26MHz shift register to start clocking in data. After 96-bits are received, the module sends a trigger to the state machine logic. The state machine is in a WAIT condition - having already intitalized the data format via a software write. The state machine grabs the 96-bit chunk, parses it into 1 or 2 32-bit chunks (depends on format), discards the rest, and stores the data in block RAM.

I threw it in our MicroBlaze project, built the design, and started testing. I have a pattern generator set up to simulate the protocol that the extrenal part will be responsible for providing (our part is in fab). I have to use the EDK software debugger in order to see the data stored to memory. Everything appeared to be working fine. However, after increasing the data in the pattern, it was obvious that random errors were occuring in the data stored to RAM. There would occassionlly be incorrect values stored. I had the data coming in as a binary count and sometimes the count would glitch. It didn't occur often, but we can't have any errors.

So, I tried two things. The first was to put some synchronization flip flops in the state machine. Initially I had my concerns about crossing clock domains, but since I was going from a slower one to a faster one I didn't worry much. I put a couple each for the data being passed from the 26 MHz clock domain, and for the trigger being passed from the

26 MHz clock domain. After building this, the problem still occurred.

I then put a KEEP_HIERACHY constraint on the top level module that instantiates the two modules discussed. Low and behold, that worked. I have tested extensively and there have been no errors.

Does anyone have any insight into why keeping the hierarchy intact works? I always try to design correct hierarchies in my modules...meaning hierarchy that makes sense. And all signals are registered at module boundaries. To me, the design discussed above is well-partitioned. I don't know what XST would "optimize" when the KEEP_HIERACHY was NOT specified. Just curious if anyone had any input.

I didn't check to see what area penalties, if any, occured after placing the constraint. I doubt it would make much difference.

Thanks!

Reply to
motty
Loading thread data ...

Motty -

It sounds like you did everything correctly. You shift in 96 bits in the

26MHz clock domain, and after the data has been shifted in and is stable, you assert a 1-bit trigger to the 38.4MHz state machine, right? And you re-sync the trigger (and only the trigger) with the 38.4MHz clock, right? If that's all true then you did nothing wrong and I can't explain the effect of the KEEP_HIERARCHY constraint. If you did anything different than what I described then you probably had probalems crossing the clock boundary and the effect of KEEP_HIERARCHY may have been a coincidence.

Sorry, that's the best I can offer. By the way, the abililty to partition logic cleanly is a great skill to have.

Rob

Reply to
RobJ

I wouldn't have synchronised the data but re-timed the 'data ready' pulse into the 38MHz domain a few more clock cycles to make sure the data had settled when the ready pulse was detected.

Have you tested after multiple P&R runs?

You might have just had a lucky build or two that have been seeded differently because of the keep hierarchy constraint.

Nial

Reply to
Nial Stewart

I suspect you've got a design problem that is accentuated by routing delays. I can't think of any reason that KEEP_HIERARCHY would effect something like this.

After you receive the 96 bits from the external device, are more bits being shifted in or does the incoming data stream stop?

If data is still being received, is it possible that the shift register has received another bit before the parallel data has been transfered to the MBlaze?

Maybe you should try registering the 96 bits into a holding register when all 96 have been received. This gives quite a while for any delay in the 'valid' signal to cause the data to be handed off into the MBlaze clock domain.

John Providenza

Reply to
johnp

I actually synched both the data and the trigger. I can see how that would produce the same erros though. I guess I chalk it up to working b/c of P and R differences.

I should probably go back and put a holding register in the 26 MHz module and just resynch the trigger into the 38.4 domain using a couple of flip flops. The shift register still shifts in data when it triggers the state machine (I can't lose a bit and the data stream is continuous - until the enable goes low). I guess it is VERY possible that the data is sometimes unstable when it crosses into the 38.4 domain. There is only one 26 MHz cycle available for this, and depending on the phase relationship of the two clocks, I could see timing issues arrising. Putting a holding register in plus the trigger synch flops in the 38.4 module should allow plenty of time for the data to be stable.

Thanks all for the replys!! .

Reply to
motty

Let us know if the holding register scheme helps!

John Providenza

Reply to
johnp

I had assumed you were transferring the data to an output_register(95..0) in the 26 MHz domain at the same time as you generate the 'data ready' signal.

Exaclty, you can re-time the enable signal into the 38MHz domain a number of clock cycles so the data should be settled at the 38MHz register inputs.

Nial.

Reply to
Nial Stewart

Hi people,

I ran into a similar problem with a similar design, with an embedded

8-bit cpu and some cross domain signals. The design works with chipscope, while it does not without it. Now, adding a KEEP_HIERARCHY constrain actually makes it work again, and that without chipscope. I am pretty sure that KEEP_HIERARCHY will keep module ports that the PAR tools think is better to trim. So that it would be crucial to add the property. Just to be on the safe side, I re-ran the flow a couple of more times, with and without the attribute and it indeed makes the difference.

Pretty much sure MAP is trimming off where it is not suppose to.

My two rupee :) JA

Reply to
jaxato

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.