Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16556 Discussions

How to control routing in Altera Cyclone V FPGA

M0ysez
Beginner
361 Views

I am trying to implement a Time-to-Digital Converter on Cyclone V FPGA. I am using Quartus Prime 17.1 lite edition (No license). I have trouble manipulating the placing and routing. The connection that I want to achieve is depicted in image 1. The idea is that a reference signal (Propogated Signal) is delayed through embedded adders using carry chain connections. I want to latch such a signal indirectly by capturing the outputs of the adders on the falling and rising clock edge with two different FFDs where the routing path among all adders (around 300) and FFDs is equal. For the Falling edge, I want to use one FFD (FF0 for the upper adder and FF2 for the lower adder); similarly, For the Rising edge, I want to use FF1 for the upper adder and FF3 for the lower adder.

 

inkscape_bcfGcNonWu.png

Image 1

 

The code that I am using for describing adders cascades is:

 

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity unsigned_adder is
    generic
    (DATA_WIDTH : natural := 8  );
    port 
    (   input_signal : in std_logic;
        a      : in std_logic_vector  ((DATA_WIDTH-1) downto 0);
        b      : in std_logic_vector  ((DATA_WIDTH-1) downto 0);
        result : out std_logic_vector ((DATA_WIDTH-1) downto 0)
    );
end entity;

architecture rtl of unsigned_adder is
begin
    result <= a + b + input_signal;
end rtl;

 

 

 

 

To generate the set of FFD, I have tried three different methods for describing FFDS; the first one is using a code style shown in Recommended HDL Coding Styles within the Quartus II handbook, which match with physically existing FFD in Cyclone V architecture. The second uses DFFEAS primitive, and the third is a general style to describe an FFD. The code is as follows:

 

    library ieee;
use ieee.std_logic_1164.all;

-- Add the library and use clauses before the design unit declaration
library altera; 
use altera.altera_primitives_components.all;

entity FFX is
    generic(capture_edge : integer := 1 -- Rising => 1 -- Falling => 0 
    ); 
    port 
    (iclk : in std_logic;
    irst : in std_logic;
     ien  : in std_logic;
     D_data : in std_logic;
     Q_data : out std_logic

    );
end entity;

architecture rtl of FFX is

BEGIN
-- --FIRST METHOD -------------------------------------------------------
--Rising_sel : if capture_edge = 1 generate 
--  PROCESS (clk, aclr, sload, sdata)
--  BEGIN
--      IF (aclr = '1') THEN
--          q <= '0';
--      ELSE
--          IF (clk = '1' AND clk'event) THEN
--              IF (ena ='1') THEN
--                  IF (sclr = '1') THEN
--                      q <= '0';
--                  ELSIF (sload = '1') THEN
--                      q <= sdata;
--                  ELSE
--                      q <= data;
--                  END IF;
--              END IF;
--          END IF;
--      END IF;
--  END PROCESS;
--end generate; 
--
--Falling_sel : if capture_edge = 0 generate 
--  PROCESS (clk, aclr, sload, sdata)
--  BEGIN
--      IF (aclr = '1') THEN
--          q <= '0';
--      ELSE
--          IF (clk = '0' AND clk'event) THEN
--              IF (ena ='1') THEN
--                  IF (sclr = '1') THEN
--                      q <= '0';
--                  ELSIF (sload = '1') THEN
--                      q <= sdata;
--                  ELSE
--                      q <= data;
--                  END IF;
--              END IF;
--          END IF;
--      END IF;
--  END PROCESS;
--end generate; 

-- --SECOND METHOD -------------------------------------------------------
    Rising_sel : if capture_edge = 1 generate 
    SRFFE_R : DFFEAS
    port map (
            d => D_data,
            clk => iclk,
            clrn => '1',
            prn => '1',
            ena => ien,
            asdata => '0',
            aload => '0',
            sclr => irst,
            sload => '0',
            q => Q_data
            );
    end generate;   
    
    Falling_sel : if capture_edge = 0 generate 
        SRFFE_F : DFFEAS
        port map (
                d => D_data,
                clk => not iclk,
                clrn => '1',
                prn => '1',
                ena => ien,
                asdata => '0',
                aload => '0',
                sclr => irst,
                sload => '0',
                q => Q_data
                );
    end generate;   

-- --THIRD METHOD -------------------------------------------------------
--  Rising_sel : if capture_edge = 1 generate 
--      process(irst, iclk) begin
--          if irst = '0' then
--              if rising_edge(iclk) then
--                  if ien = '1' then
--                      Q_data <= D_data;
--                  end if;
--              end if;
--          else
--              Q_data <= '0';
--          end if;
--      end process;
--  end generate;   
--  
--  Falling_sel : if capture_edge = 0 generate 
--      process(irst, iclk) begin
--          if irst = '0' then
--              if falling_edge(iclk) then
--                  if ien = '1' then
--                      Q_data <= D_data;
--                  end if;
--              end if;
--          else
--              Q_data <= '0';
--          end if;
--      end process;
--  end generate;   

end rtl;

 

 

I am using a component where FFDs triggered with falling and rising edges are instantiated. The parameter "No_bits" equals to the number of adders:

 

library ieee;
    use ieee.std_logic_1164.all;
    
    entity Capture_Array is
        generic(No_bits : integer := 8
        ); 
        port 
        (iclk : in std_logic;
         D_data : in std_logic_vector(No_bits-1 downto 0);
         Q_dataRising  : out std_logic_vector(No_bits-1 downto 0);
         Q_dataFalling : out std_logic_vector(No_bits-1 downto 0)
        );
    end entity;
    
    architecture rtl of Capture_Array is
    
    component FFX is
        generic(capture_edge : integer := 1 -- Rising => 1 -- Falling => 0 
        ); 
        port 
        (iclk : in std_logic;
        irst : in std_logic;
         ien  : in std_logic;
         D_data : in std_logic;
         Q_data : out std_logic
        );
    END component;
    
    signal xDFF_Rising, xQFF_Rising : std_logic_vector(No_bits-1 downto 0);
    signal xDFF_Falling, xQFF_Falling : std_logic_vector(No_bits-1 downto 0);
    
    begin
    
        FFR_FFDs : for i in 0 to No_bits-1 generate
            FFX_cmp1 : FFX generic map (capture_edge => 1)
                            port map    (iclk   => iclk,
                                             irst   => '0',
                                             ien    => '1', 
                                             D_data => xDFF_Rising(i),
                                             Q_data => xQFF_Rising(i)
    
                                            );
        end generate;                                   
    
    
        FFF_FFDs : for i in 0 to No_bits-1 generate
            FFX_cmp0 : FFX generic map (capture_edge => 0)
                            port map    (iclk   => iclk,
                                             irst   => '0',
                                             ien    => '1', 
                                             D_data => xDFF_Falling(i),
                                             Q_data => xQFF_Falling(i)
    
                                            );
        end generate;                                   
    
    xDFF_Rising <= D_data;
    Q_dataRising <= xQFF_Rising;
    
    
    xDFF_Falling <= D_data;
    Q_dataFalling <= xQFF_Falling;                                      
    
    end rtl;

 

Finally, I connect the adders component with the FFDs component as follows:

 

Delay_cmp : unsigned_adder  generic map (DATA_WIDTH => Length_delay
                                                    )
                           port map (   
                                       input_signal => xLaunchedSignal,
                                       a      => (others => '0'),
                                       b      => (others => '1'),
                                       result => xresult
                                         );

 Captures_cmp : for i in 0 to No_captures-1 generate
     Capture_Array_cmp : Capture_Array generic map (No_bits => Length_delay
                                                    ) 
                     port map  (iclk => icaptures(i),
                                D_data => xresult,
                                Q_dataRising  => oFine_Measurements_R(i),
                                Q_dataFalling => oFine_Measurements_F(i)
                                 );
 end generate;  

 

 

For the purpose of the doubt, "for generate" can be despised. Now, what I currently have achieved using the drag and drop method in the "chip planner" tool is the connection shown in image 2. The tool does not let me connect my elements just like in image 1; this is due to (I think) there is exist “~fedder logic” (image 3), which is something that I want to eliminate. I do not know how (and why) this logic is created and how to suppress it.

inkscape_IhSkDhdeNS.png

Image 2

  

FStzj.png

Image 3

 

Additionally, I have tried the TCL command in the .qsf file for placement, but it creates heterogeneous routing due to feeders. An example of the TCL commands that I am using considering only ten adders are the following:

 

set_location_assignment LABCELL_X13_Y6_N0 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|unsigned_adder:Delay_cmp|result[0]"

set_location_assignment FF_X13_Y6_N1 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:0:FFX_cmp0"
set_location_assignment FF_X13_Y6_N4 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:1:FFX_cmp0"
set_location_assignment FF_X13_Y6_N7 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:2:FFX_cmp0"
set_location_assignment FF_X13_Y6_N10 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:3:FFX_cmp0"
set_location_assignment FF_X13_Y6_N13 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:4:FFX_cmp0"
set_location_assignment FF_X13_Y6_N16 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:5:FFX_cmp0"
set_location_assignment FF_X13_Y6_N19 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:6:FFX_cmp0"
set_location_assignment FF_X13_Y6_N22 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:7:FFX_cmp0"
set_location_assignment FF_X13_Y6_N25 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:8:FFX_cmp0"
set_location_assignment FF_X13_Y6_N28 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFF_FFDs:9:FFX_cmp0"
    
set_location_assignment FF_X14_Y6_N2 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:0:FFX_cmp1"
set_location_assignment FF_X14_Y6_N5 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:1:FFX_cmp1"
set_location_assignment FF_X14_Y6_N8 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:2:FFX_cmp1"
set_location_assignment FF_X14_Y6_N11 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:3:FFX_cmp1"
set_location_assignment FF_X14_Y6_N14 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:4:FFX_cmp1"
set_location_assignment FF_X14_Y6_N17 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:5:FFX_cmp1"
set_location_assignment FF_X14_Y6_N20 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:6:FFX_cmp1"
set_location_assignment FF_X14_Y6_N23 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:7:FFX_cmp1"
set_location_assignment FF_X14_Y6_N26 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:8:FFX_cmp1"
set_location_assignment FF_X14_Y6_N29 -to "ChannelNTDC:\\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\\Captures_cmp:0:Capture_Array_cmp|FFX:\\FFR_FFDs:9:FFX_cmp1"

 

If I try to force the placement of all FFDs in the same ALM column through the TCL commands, i.e., changing the coordinates FF_X14_... by FF_X13_... , I receive error messages:

 

Error (170208): Cannot place 5 nodes into a single ALM
    Info (170017): Cannot place nodes in a single ALM -- the ALM would be illegal because not all of the LUT and FF inputs are routable.
    Info (170072): List of 5 nodes in the ALM
        Info (170000): Node "ChannelNTDC:\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|unsigned_adder:Delay_cmp|result[0]"
        Info (170000): Node "ChannelNTDC:\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\Captures_cmp:0:Capture_Array_cmp|FFX:\FFF_FFDs:0:FFX_cmp0|\Falling_sel:SRFFE_F"
        Info (170000): Node "ChannelNTDC:\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\Captures_cmp:0:Capture_Array_cmp|FFX:\FFR_FFDs:0:FFX_cmp1|\Rising_sel:SRFFE_R"
        Info (170000): Node "ChannelNTDC:\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\Captures_cmp:0:Capture_Array_cmp|FFX:\FFF_FFDs:1:FFX_cmp0|\Falling_sel:SRFFE_F"
        Info (170000): Node "ChannelNTDC:\Channels:0:ChannelNTDC_cmp|Fine_interpolator:Fine_interpolator_cmp|Capture_Array:\Captures_cmp:0:Capture_Array_cmp|FFX:\FFR_FFDs:1:FFX_cmp1|\Rising_sel:SRFFE_R"
Error (11802): Can't fit design in device. Modify your design to reduce resources, or choose a larger device. The Intel FPGA Knowledge Database contains many articles with specific details on how to resolve this error. Visit the Knowledge Database at https://www.altera.com/support/support-resources/knowledge-base/search.html and search for this specific error message number.

 

Are connection shown in image 1 achievable? How I can eliminate "feeder logic"? and what is the strategy/tool used for manually manipulating the routing?

 

0 Kudos
0 Replies
Reply