Read in KR

Xilinx Primitives

When developing for FPGAs, you often use libraries provided by the chip vendor for I/O and other specialized hardware. In the case of Xilinx, this is the unisim library. To use it in SCode, you can include xilinx_lib.sh.

Since the unisim library is extensive, xilinx_lib.sh defines only the most commonly used components.

_xilinx_primitives_data = [
    ## name should be capital case
    {'name': 'BUFG', 'input':['I'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'BUFGMUX', 'input':['I0','I1','S'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'BUFGP', 'input':['I'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'IBUF', 'input':['I'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'IBUFG', 'input':['I'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'IBUFDS', 'input':['I','IB'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'IBUFGDS', 'input':['I','IB'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'IOBUF', 'input':['I','T'], 'output':['O'], 'inout':['IO'], 'generic':None},
    {'name': 'OBUF', 'input':['I'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'OBUFDS', 'input':['I'], 'output':['O','OB'], 'inout':None, 'generic':None},
    {'name': 'OBUFT', 'input':['I','T'], 'output':['O'], 'inout':None, 'generic':None},
    {'name': 'OBUFTDS', 'input':['I','T'], 'output':['O','OB'], 'inout':None, 'generic':None},
]

xilinx_unisim_library(_xilinx_primitives_data)

To add more components, simply specify the unisim library name and its I/O in xilinx_lib.sh. One thing to note is that library names must always be defined in uppercase.

When you use these unisim components in an .sc file, SCode automatically adds the following VHDL statements:

library unisim;
use unisim.vcomponents.all;

The example below shows how to take a differential clock input, convert it to a single-ended clock using IBUFGDS, and then use that clock for a counter:

include("xilinx_lib.sh")

inport("clk_p", "clk_n", "reset")
outport("counter[8]")

IBUFGDS(I=clk_p, IB=clk_n, O=logic("clk"))

with sequence(clk):
    counter <= (0, reset, counter + 1)

The resulting VHDL code is as follows:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library unisim;
use unisim.vcomponents.all;

entity test is
    port (
        clk_p               : in std_logic;
        clk_n               : in std_logic;
        reset               : in std_logic;
        counter             : out std_logic_vector(7 downto 0)
    );
end entity;

architecture arch_test of test is
signal clk                  : std_logic;
signal counter_oi           : std_logic_vector(7 downto 0);

begin

    u0_IBUFGDS : IBUFGDS port map (
        I                   => clk_p,
        IB                  => clk_n,
        O                   => clk
    );

    process(clk)
    begin
        if rising_edge(clk) then 
            if reset = '1' then
                counter_oi <= (others=>'0');
            else
                counter_oi <= std_logic_vector(unsigned(counter_oi) + 1);
            end if;
        end if;
    end process;
    counter <= counter_oi;

end architecture;
← All posts