UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer krhandfield
Observer
1,363 Views
Registered: ‎09-28-2015

attribute DIRECT_ENABLE still doesn’t work.

I need to force the Vivado synthesis tool to use the register CE pin so I can place registers in IOB cells, instead Vivado synthesis thinks I can do a better job and loops the output of the register round to the D input via a LUT that merges the enable logic, as soon as this is done the register can no longer be placed in a IOB cell.  The DIRECT_ENABLE attribute designed specifically for this does nothing and neither does a DONT_TOUCH  attribute.  I even tried a MARK_DEBUG attribute on the net thinking synthesis would have to leave the net as designed in order to connect to it for debug but all attempts failed.

 

I see this has come up before in these two subjects:

The only way to get a synthesis result I want is to instantiate the registers manually.

 

  -- Registers should be placed in IOB.
  -- DDS_CE_O needs a DIRECT_ENABLE attribute applied as the synthesis tool merges the
  -- DDS_CE_Mux with D port input logic, the logic then uses the register output to
  -- maintain the value when DDS_CE_O is low, this forces the register from the IOB
  -- cell.
  G_Inferred_Output_Register : if not INSTANTIATED_OUTPUT_REGISTER generate
    P_Outputs :
    process (DDS_Clk) is
    begin
      if Rising_Edge(DDS_Clk) then
        if DDS_CE_O = '1' then
          DDS_FUD <= DDS_FUD_O;
          DDS_PS  <= DDS_PS_O;
        end if;
      end if;
    end process;
  end generate G_Inferred_Output_Register;


  G_Instantiated_Output_Register : if INSTANTIATED_OUTPUT_REGISTER generate
    constant OUTPUT_REGISTERS : natural := DDS_PS'length + 1;
    --
    signal D : std_logic_vector(OUTPUT_REGISTERS - 1 downto 0);
    signal Q : std_logic_vector(D'range);
  begin
    G_Output_Registers : for n in D'range generate
      FDRE_I : FDRE
      generic map
      (
         INIT          => '0',
         IS_C_INVERTED => '0',
         IS_D_INVERTED => '0',
         IS_R_INVERTED => '0'
      )
      port map
      (
         C  => DDS_Clk,
         R  => '0',
         CE => DDS_CE_O,
         D  => D(n),
         Q  => Q(n)
      );
    end generate G_Output_Registers;
    --
    D <= DDS_PS_O & DDS_FUD_O;
    DDS_FUD <= Q(0);
    DDS_PS  <= Q(2 downto 1);
  end generate G_Instantiated_Output_Register;


  DDS_CE_Mux    : DDS_CE_O  <= DDS_CE(0)        when AD9910_nAD9858 = '1' else DDS_CE(1);
  DDS_FUD_Mux   : DDS_FUD_O <= AD9910_DDS_FUD   when AD9910_nAD9858 = '1' else AD9858_DDS_FUD;  
  DDS_PS_Mux    : DDS_PS_O  <= AD9910_DDS_PS    when AD9910_nAD9858 = '1' else AD9858_DDS_PS;
Tags (1)
8 Replies
Voyager
Voyager
1,303 Views
Registered: ‎06-20-2017

Re: attribute DIRECT_ENABLE still doesn’t work.

Did you try

 

 

attribute IOB : string;
attribute IOB of Q: signal is "TRUE";

See UG912.

 

 

Adaptable Processing coming to an IP address near you.
0 Kudos
Observer krhandfield
Observer
1,280 Views
Registered: ‎09-28-2015

Re: attribute DIRECT_ENABLE still doesn’t work.

I already have:

set_property IOB TRUE [all_outputs]
set_property IOB TRUE [all_inputs]

Main problem is synthesis is not doing what the user has asked, direct instantiation I have found is the only way to work around the problem but it is not elegant.

 

In my experience when a problem strongly suggests a bug in the tool there is little comment from Xilinx employees in a thread.

Voyager
Voyager
1,246 Views
Registered: ‎06-20-2017

Re: attribute DIRECT_ENABLE still doesn’t work.


@krhandfield wrote:

I already have:

set_property IOB TRUE [all_outputs]
set_property IOB TRUE [all_inputs]

Main problem is synthesis is not doing what the user has asked, direct instantiation I have found is the only way to work around the problem but it is not elegant.

 

In my experience when a problem strongly suggests a bug in the tool there is little comment from Xilinx employees in a thread.


try this (which worked on a xcku040)

library ieee;
use ieee.std_logic_1164.all;
Library UNISIM;
use UNISIM.vcomponents.FDCE; -- for component declaration
use UNISIM.vcomponents.LUT3; -- for component declaration
entity extract_en is
  port (
    iClk  : IN  std_logic;
    iEn   : IN  std_logic;
    iD    : IN  std_logic;
    oQ    : OUT std_logic
  );
end entity extract_en;

architecture EXTRACT_ENABLE_ARCH of extract_en is
  signal    Qfirst                : std_logic := '0';
  signal    Qinner                : std_logic := '0';
  signal    Q                     : std_logic := '0';
  attribute extract_enable        : string;
  attribute extract_enable of iEn : signal is "NO";
  attribute IOB                   : string;
  attribute IOB of Q              : signal is "TRUE";
  attribute IOB of Qfirst         : signal is "TRUE";
begin -- architecture

  process(iClk)
    begin
      if rising_edge(iClk) then
        if iEn = '1' then
          Qfirst <= iD;
          Qinner <= Qfirst;
          Q <= Qinner;
        end if;
      end if;
  end process;
  oQ <= Q;

end architecture EXTRACT_ENABLE_ARCH;

I hope this gets you to where you want to be.

 

Now onto some other advice that may serve others in the future who find this thread while trying to force a register with an enable into the IO slice, and find the tools a reluctant partner.

 

Whenever the synthesizer does not do what I want, I remember some advice I once received, and I start thinking about "why might that be?" 

 

A number of engineers are advocates for forcing registers into the IOB with the reasoning that it helps keep t_c2q timing from one build to the next a little more consistent. 

 

But I prefer to do my input and output delay constraints rigorously and correctly, and then let the tools do whatever it thinks is necessary to solve the mundane and tedious problem of meeting those requirements. Static timing accounting is a monotonous task, and I am perfectly happy to let the tools do that task.

 

Maybe the tools can more easily meet all the constraints by not putting the register in the IOB, for example.  Maybe I don't know better than the tool in all cases.  This is certainly true, because I cannot put my brain up against a sophisticated tool with a lot of thought and energy behind it, running on a 4 GHz CPU.  It can run through many more what if scenarios than I can in the same amount of time.

 

Put it this way, when I write a program in C, I don't spend frustrating hours trying to specify exactly which optimizations to use, micromanaging when this or that optimization should be used as C is converted into assembly, unless it is absolutely necessary.  And it is almost never necessary.

 

Likewise, if I specify my design constraints properly (functionality through testing, timing through constraints), and the tools meet those requirements, why would I want to micromanage where a particular register is placed?

 

Whether I am direct instantiating, or adding attributes like above, there really isn't much difference in practice. 

 

If I force the tools hand, I'm telling the synthesizer I know better in this particular application.  Toward that end, what difference does elegance make?  It makes a little with regard to portability, and a little with regard to pride in workmanship, but both methods are only portable so long as the attributes or the primitives continue to be supported, and neither is as important as getting a sound design to market in the planned market window.   Besides, portability is not guaranteed whether I'm using vendor specific attributes or family/vendor specific primitive instantiation.  So now I'm down to pride in writing higher level code decorated with constraints that eliminate tool flexibility. 

 

But ever since I learned how to use the set_output_delay constraint, and the value in doing so, I have more time to spend with my family, and my personal life is a lot more pleasant.  But it does have a cost--Ihave to spend time gather data so that I can write correct constraints. 

 

Whether any of this applies to this post, I have no clue, but I have certainly met a number of engineers who insist on putting their registers in IOBs because they think it helps meet timing.

Adaptable Processing coming to an IP address near you.
Observer krhandfield
Observer
1,221 Views
Registered: ‎09-28-2015

Re: attribute DIRECT_ENABLE still doesn’t work.

Thank you for your response.

 

I accept your reasoning for delay constraints but in my case my signals are part of a timing critical small bus.  If I applied delay constraints you have added variation to builds, yes it will meet your specification by applied constraints but the variation is there.  If I design suitable pipelining to the intended output registers (which can be as simple as a row of registers) I don’t need to calculate and apply a delay constraint on the output as I have achieved the best possible minimum delay (in logic placement terms) and reduced skew between my bus bits to a minimum.  Xilinx recognises the need for the attribute as they have provided the facility to use it, my problem is the optimiser is effectively overriding the designers override.  I also agree that probably something close to 99% of a design can be left to the place and router, but I have found sometimes it needs a little prompting to get the desired results.

 

Thank you for the ‘extract_enable’ prompt, this must be a fairly new attribute as I could not find reference of it in my local copy of UG901 ‘Vivado Design Suite User Guide - Synthesis’.  I have downloaded the latest document and there it is (I have a feeling this might not work with our current version of tools, we are using Vivado 2016.2 on the current SoC project).

 

I came across this when trying to track down a reference for ‘extract_enable’ which might be of use to others.

https://forums.xilinx.com/t5/Synthesis/What-is-the-disparity-between-DIRECT-ENABLE-and-EXTRACT-ENABLE/m-p/835862

0 Kudos
Voyager
Voyager
1,214 Views
Registered: ‎06-20-2017

Re: attribute DIRECT_ENABLE still doesn’t work.

Okay, I'm glad it was well received.

 

See also set_bus_skew constraint, if you want to control bus skew

Adaptable Processing coming to an IP address near you.
0 Kudos
Moderator
Moderator
1,144 Views
Registered: ‎07-21-2014

Re: attribute DIRECT_ENABLE still doesn’t work.

@krhandfield

 

DIRECT_ENABLE should be able to push logic on control pin. Can you please share the complete test case for me to reproduce the issue?

 

Thanks,

Anusheel

Thanks
Anusheel
0 Kudos
Observer krhandfield
Observer
1,134 Views
Registered: ‎09-28-2015

Re: attribute DIRECT_ENABLE still doesn’t work.

@anusheel

 

Well this issue has become more intriguing.  I have tried to reproduce the error in a small cut down project which then doesn’t exhibit the problem.  I then expanded the project to a full sub-module with modules not of interest built as black boxes and again the attribute appeared to work as intended.  The attribute appears to work in certain conditions, it therefore implies something else is effecting the attribute being applied which I have yet to identify that occurs in the whole FPGA design.  I am not sure I will be able to share the whole FPGA design outside the company and do not have the time to investigate further at the moment.  I will have to come back to this at a later date.

 

Thanks.

0 Kudos
Moderator
Moderator
1,131 Views
Registered: ‎07-21-2014

Re: attribute DIRECT_ENABLE still doesn’t work.

@krhandfield

 

Just check if anything is blocking the attribute(other attributes or hierarchy based properties) when you are using this attribute in your main design. 

Sure, let us know if you have a test case in future for us to reproduce the issue.

 

Thanks,

Anusheel

Thanks
Anusheel
0 Kudos