Saturday, 17 May 2014

verilog - Beginner with fpga and timing issues


I got myself a spartan-3an evaluation board in order to learn fpga programming and some verilog. It's taken a little while to stop seeing it in terms of a sequential programming language and to start seeing it in terms of connections between blocks of hardware but I'm getting there.


I've made a small "program" that takes a image defined in "ram" and displays it on the vga port. The ram is just a set of reg's like this


reg ram[4095:0]; // Video memory for 64x64 pixel display

I used the patterns in the help and the compiler has inferred that it should put this into a blockmem and it all works nicely.


My doubt is about timing though.



I have one "always" block incrementing a counter for the vga horizontal position, and one incrementing a counter for the vga vertical position. Then I have another always block that uses that counter to generate an address into a "reg" that indxes the memory.


There is then another "always" block triggered by a clock that reads that memory.


My doubt is this - I'm generating the sync pulses based on the counters. That's fine, but I'm generating the address in the video memory too from those counters to read the pixel. However that read will occur on the next clock pulse so my pixel data will be output one clock cycle later than I'm expecting. I'll calculate the address on one clock cycle but not have the pixel data available until the next one.


Have I understood that situation correctly? And if so, what do I do about it? Ignore it because it won't be visible? I could probably buffer the sync pulses too and delay them in the same way. Or I could pre adjust the calculated memory address to compensate in advance.


What do people generally do in this kind of situation? Or is every case different?



Answer




Have I understood that situation correctly?



Yes - if some part of your output data is available later than other parts, you have to delay the other parts so they line up.



It's not a fudge, or a "bad" thing to do - it's just what has to be done to make the outputs right.



I could probably buffer the sync pulses too and delay them in the same way.



That's what I'd do. (EDIT: And as Yann reminded me, delaying signals can be very cheap in Xilinx FPGAs - 16 ticks can fit in a single look-up table + 1 more in the flipflop that's next to the LUT)



Or I could pre adjust the calculated memory address to compensate in advance.



That's another option, but will probably take more logic.


No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...