Forcing a LUT to not be optimized

Hi,

I'm trying to create a design that uses a LUT to control routing on a Virtex-II Pro. It's pretty easy to create the LUT in VHDL and feed it into a MUX to select the appropriate output based on the values in the LUT. I'm trying to use this in a partial reconfiguration design so that I can change the values in the LUT with a partial bitstream to change the routing. My problem is that the design is optimized and broken up in to multiple LUTs making it hard to determine what needs to be changed.

Is there any way to force the LUT to be left as a primitive and implement the equations (or initial value) that I set? I would also like to be able to force the LUT to be in known location so that I can find it easily in the NCD file. I've seen plenty of documentation staying this can be done, I can't find any exampled. I believe I can use an RLOC but I'm not sure where the RLOC constraint should be placed.

Thanks for your help,

David

Here's what I know so far:

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating

---- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all;

entity lut_mod is Port ( SW_0 : in STD_LOGIC; --just some simple inputs and SW_1 : in STD_LOGIC; -- outputs for testing SW_3 : in STD_LOGIC; LED_0 : out STD_LOGIC; LED_2 : out STD_LOGIC; LED_3 : out STD_LOGIC); end lut_mod;

architecture Behavioral of lut_mod is

signal LUT_to_MUX : STD_LOGIC;

begin

LED_3 LUT_to_MUX, -- LUT local output I0 => SW_3, -- LUT input I1 => SW_3, -- LUT input I2 => SW_3, -- LUT input I3 => SW_3 -- LUT input );

MUXF5_inst : MUXF5 port map ( O => LED_0, -- Output of MUX to general routing I0 => SW_0, -- Input I1 => SW_1, -- Input S => LUT_to_MUX -- Input select to MUX );

end Behavioral;

Reply to
David
Loading thread data ...

Read The Fine Manual. The Constraints Guide shows examples of RLOCs in both the architecture declaration area for single components and in the declaration area of for generate blocks for primitives created that way. Just John

Reply to
JustJohn

Hi,

I did something similar years ago to change the content of constant multipliers. You can use the LOC, RLOC and BEL constraints. Also, for reconfiguration I used JBits.

Regards,

Ivan

Reply to
salorankatu

The keywords are different for different synthesis tools. Look up the user guide of your synthesis tool for words like "keep", "preserve", "prune", etc. Once you find the right keyword, you can then attach it as an attribute to your instance. eg attribute SYN_NOPRUNE of my_lut : label is TRUE;

Also the LOCK_PINS constraint may be useful.

Cheers, Jim

formatting link

Reply to
Jim Wu

I put together some Verilog code to send in to the Xilinx hotline just the other day to demonstrate a problem with FPGA Editor. I digested my code down to the single LUT where I was having problems swapping pins. I manually instantiate the LUT whose function is to select the short routing path or the longer routing path for a fine-tuned delay.

I had problems keeping the Xilinx tools from optimizing the LUT back to a single pass-through rather than my mux of 2 versions of the same signal until I hit upon the "right" constraint.

LOCK_PINS as Jim Wu mentioned.

In the Xilinx User Constraints File (.ucf) you can specify everything you need in one line to have an explicit location and not have your INIT values optimized for you.

INST MyLut LOC = SLICE_X15Y34 | BEL = G | LOCK_PINS=ALL;

The LOC and BEL give you explicit placement to the same LUT compile after compile. The LOCK_PINS=ALL keeps the optimizer from undoing your hand crafted details. I even go as far as to use a LUT4 to specify a LUT3 function and leave one input out of the INIT values allowing me to use G1, G3, and G4 pins without using the G2, for instance. I do my pin placement in the LUT instantiation rather than LOCK_PINS=A1:F2 type of syntax that gave me troubles early on.

Keep in mind you can also change the LUT contents by defining an SRL instead. You still have fixed inputs (no LOCK_PINS required to keep the SRL in the right place) and you can reload the LUT over 16 clocks later on. I considered this approach to get up to 4 different delays "tuned" to the silicon for one LUT but ended up sticking with a MUX of 2 values because I couldn't handle the 16 clocks of configuration. An SRL with the same INIT as a LUT4 has the exact same function as the LUT4.

- John_H

David wrote:

Reply to
John_H

Thank you all for your posts. John_h, the combination of LOC BEL and LOCK_PINS works great for my application.

Reply to
David

In the past I've had to create LUTs and this bit of code allows you to do it with an equation, rather than figuring the init values out for yourself:

--

-- Typical usage:

--

-- signal a,b,c,d,x : std_logic;

--

-- LU: VLut4 generic map ( ExprStr => "((I0*I1)@(I2*~I3))" )

-- port map (I0=>a, I1=>b, I2=>c, I3=>d, O=>x );

--

-- This evaluates the following expression:

--

-- x

Reply to
Martin Thompson

Another option is to replace the LUT with an SRL16E. The SRL16E behaves exactly like a LUT when the WE input is low, with the advantage of having the pins inherently locked. Additionally, it can be reloaded without having to use the FPGA configuration logic, i.e. it provides a poor-man's reconfigurability for the logic. I've used this for years for reloading coefficients in DA FIR filters.

By keeping the "reconfiguration" within the operational part of the FPGA, you save yourself a ton of heartache. The logic required to reconfigure an SRL16E LUT is pretty simple too.

Reply to
Ray Andraka

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.