Polygonhell

Material for understanding IOBUF and clock routing

9 posts in this topic

I got my papilio pro board a couple of weeks ago, I'm an experience programmer but I'm new to FPGA, I've read a couple of books on VHDL, and for the most part I understand the basics, I spent the last couple of days implementing an SDRAM controller. I did finally get it working, but it became really apparent my understanding of when to use OBUF's, BUFG's etc etc, was at best an educated guess.

Is there a good discussion on when and why to use the SelectIO resources, I've read the Xilinx piece, but while I think I understand what they are, I have no intuition on when or why to use them.

Thanks

Share this post


Link to post
Share on other sites

Ideally the synthesis will infer most of that for you, except on a few cases.

 

The most relevant one is when you have an FF which drives an IO pin, and  whose output feeds back to the FPGA logic. When this happens, it's not possible to place the FF in the IO Block directly. One option is to replicate the FF, and indeed if you do force the FF to be in an IOB, it will get replicated:

 

Example:
 

Unit <papilio_pro_top> processed.Replicating register sram_inst/ctrl/r_address_11 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_10 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_9 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_8 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_7 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_6 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_5 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_4 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_3 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_2 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_1 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_address_0 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_bank_1 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/r_bank_0 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/rstate_FSM_FFd8 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/rstate_FSM_FFd7 to handle IOB=TRUE attributeReplicating register sram_inst/ctrl/rstate_FSM_FFd9 to handle IOB=TRUE attribute

Now, for clocks:

 

There are two main routing infrastructures inside FPGA. One is a general-purpose, used for data, and another is a fast one, used for clock. The latter does not allow a clock signal to propagate but to clock inputs in the CLBs. Also, not all input pins can drive the IBUFG which feed to the clock routing (or PLL/DCM which will then distribute clock accordingly).

 

For clocks, you really want to instantiate the BUFG. If you use DCM and PLL with feedback, you do want to have a BUFG in the feedback loop.

 

Most of other cases, assumung you have "add IO buffers" selected in the synthesis options, will work correctly.

 

Alvie

Share this post


Link to post
Share on other sites

Thanks, that t least gives me a starting point for building some sort of mental model. I had another question I often see code that does something like the following 

counterNext <= counter + 1;someProc : process (clock) begin    if rising_edge (clock)        counter <= counterNext;    end if;end process;

My assumption is this is done to reduce the skew on the counter relative to the clock because it moves the add outside of the synchronous process. Is my assumption correct here? or is there some other reason to write it this way rather than putting the add inside the process?

 

Thanks 

Share this post


Link to post
Share on other sites

I've been assuming the opposite, that it doesn't make a functional difference which way you do it.

 

I find my own reasons for choosing one over the other have to do with ease of writing/understanding:

1. If it's something simple, then it's easier to put it all in one place with "counter <= counter + 1".

2. But if I might use 'counterNext' in more than one place, I'll want to put the computation of it in one place, and the use of it in however many others are applicable.  I don't know if the synthesis tools can infer that three different references to 'counter + 1' are the same thing, but if nothing else it's easier for me to tell that only a single "add" is happening.

3. And sometimes, when working on something tricky, I've found it easier to understand if I separate the synchronous and asynchronous parts.

Share this post


Link to post
Share on other sites

Yes, no functional difference at all.

 

However, if you do want to use "counterNext" more than once, it will tell synthesis tool that you want only one adder. Although it may not follow the advice.

 

 

3. And sometimes, when working on something tricky, I've found it easier to understand if I separate the synchronous and asynchronous parts.

 

Not always true. Actually, I find the opposite much more readable and understanding, if you follow some rules/conventions.

 

What I often do is this:

-- Inputssignal ina, inb: std_logic;-- outputssignal outa, outb: std_logic;type sync_elements_type is record a: std_logic; b: std_logic;end record;signal r: sync_elements_type;process( clk, r, ina, inb )  variable w: sync_elements_type;begin  w := r; -- copy regs into variable  if ina=1 then     w.a := '1'; -- Synchronous.     outa <= '0'; -- Asynchronous    outb <= '1';  elsif inb='1' then    w.b :='1'; -- Synchronous.     outb <= '0'; -- Asynchronous.    outa <= '1';  else    outa <= '1';    outb <= '1';  end if;  if rising_edge(clk) then    r <= w; -- Update synchronous elements.  end if;end process;

Alvie

 

[Edit: it posted before I finished]

1 person likes this

Share this post


Link to post
Share on other sites

Thanks again,

So for the most part it's just a stylistic difference, then I will continue just putting the + in the process unless I need access to it in multiple locations.

I find it easy to pick up the syntax of new languages, but understanding idiomatic usage takes time, having a lot of fun with the papilio, I think a lot of programmers would get something out of implementing all the basic building blocks. Certainly building the DRAM controller was a great way to reinforce the way DRAM behaves.

Share this post


Link to post
Share on other sites

I realize now I misphrased my #3; when I said "if I separate the synchronous and asynchronous parts" I should have said "if I separate the sequential and combinational" parts.  That is, the part where a value is put in a register, and the part where it's computed.  Which, anyway, isn't something I always do -- only when it seems to help.

Share this post


Link to post
Share on other sites

Thanks, that t least gives me a starting point for building some sort of mental model. I had another question I often see code that does something like the following 

counterNext <= counter + 1;someProc : process (clock) begin    if rising_edge (clock)        counter <= counterNext;    end if;end process;

My assumption is this is done to reduce the skew on the counter relative to the clock because it moves the add outside of the synchronous process. Is my assumption correct here? or is there some other reason to write it this way rather than putting the add inside the process?

 

Thanks 

 

I read it is for a synchronous system :

post-38656-0-34481800-1430853989_thumb.p

post-38656-0-42305200-1430853998_thumb.p

 

text from book

binary counter example (after table 4.1)

 

some more text

 

Filip.

Share this post


Link to post
Share on other sites

One thing you can use is the RTL viewer that comes with ISE.

 

It will give you some insight about how the synthesizer understood your "code".

 

The technology viewer, however, will have everything mapped into LUT's and it's rather hard to understand how mapping was done.

 

Alvie

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now