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;