test/spec: first commit of the already working tests

NOTE: it is needed to change paths and some minor work on the python files.
Signed-off-by: 's avatarSamuel Iglesias Gonsalvez <samuel.iglesias.gonsalvez@cern.ch>
parent 33591dd6
-------------------------------------------------------------------------------
-------------------------------- TEST 1 ---------------------------------
-------------------------------------------------------------------------------
1.- WHAT IS INCLUDED
A.- A top VHDL in which 3 wishbone slaves can be addressed. Only the first
two are used. This two wishbone slaves correspond to the I2C master that
connect to i2c devices in fmc-carrier-tester: I2C_A, I2C_B.
Its wishbone mappings are
- I2C_A: 0x40000
- I2C_B: 0x80000
B.- "test00.bin" which is the bitstream for programming spec FPGA with the
aforementioned configuration.
C.- "test00.py" that it's a python test which is an aggregate of the rest
of python code.
This test checks the voltage values of the power supply pins on the FMC.
--------------------------------------------------------------------------------
--
-- CERN BE-CO-HT Top level entity for Simple PCIe FMC Carrier
-- http://www.ohwr.org/projects/spec
--------------------------------------------------------------------------------
--
-- unit name: spec_ddr_test_top (spec_ddr_test_top.vhd)
--
-- author: Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 03-02-2011
--
-- version: 0.1
--
-- description: Top entity for SPEC board.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: see svn log.
--------------------------------------------------------------------------------
-- TODO: -
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity spec_top is
generic(
g_SIMULATION : string := "FALSE";
g_CALIB_SOFT_IP : string := "TRUE");
port
(
-- Global ports
clk_20m_vcxo_i : in std_logic; -- 20MHz VCXO clock
--clk_125m_pllref_p_i : in std_logic; -- 125 MHz PLL reference
--clk_125m_pllref_n_i : in std_logic;
-- From GN4124 Local bus
L_CLKp : in std_logic; -- Local bus clock (frequency set in GN4124 config registers)
L_CLKn : in std_logic; -- Local bus clock (frequency set in GN4124 config registers)
L_RST_N : in std_logic; -- Reset from GN4124 (RSTOUT18_N)
-- General Purpose Interface
GPIO : inout std_logic_vector(1 downto 0); -- GPIO[0] -> GN4124 GPIO8
-- GPIO[1] -> GN4124 GPIO9
-- PCIe to Local [Inbound Data] - RX
P2L_RDY : out std_logic; -- Rx Buffer Full Flag
P2L_CLKn : in std_logic; -- Receiver Source Synchronous Clock-
P2L_CLKp : in std_logic; -- Receiver Source Synchronous Clock+
P2L_DATA : in std_logic_vector(15 downto 0); -- Parallel receive data
P2L_DFRAME : in std_logic; -- Receive Frame
P2L_VALID : in std_logic; -- Receive Data Valid
-- Inbound Buffer Request/Status
P_WR_REQ : in std_logic_vector(1 downto 0); -- PCIe Write Request
P_WR_RDY : out std_logic_vector(1 downto 0); -- PCIe Write Ready
RX_ERROR : out std_logic; -- Receive Error
-- Local to Parallel [Outbound Data] - TX
L2P_DATA : out std_logic_vector(15 downto 0); -- Parallel transmit data
L2P_DFRAME : out std_logic; -- Transmit Data Frame
L2P_VALID : out std_logic; -- Transmit Data Valid
L2P_CLKn : out std_logic; -- Transmitter Source Synchronous Clock-
L2P_CLKp : out std_logic; -- Transmitter Source Synchronous Clock+
L2P_EDB : out std_logic; -- Packet termination and discard
-- Outbound Buffer Status
L2P_RDY : in std_logic; -- Tx Buffer Full Flag
L_WR_RDY : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
P_RD_D_RDY : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
TX_ERROR : in std_logic; -- Transmit Error
VC_RDY : in std_logic_vector(1 downto 0); -- Channel ready
-- Font panel LEDs
LED_RED : out std_logic;
LED_GREEN : out std_logic;
-- I2C interface
SDA1_b : inout std_logic;
SCL1_b : inout std_logic;
FPGA_SDA : inout std_logic;
FPGA_SCL : inout std_logic
-- GPIO ports
-- THESE PORT CORRESPOND TO
-- LA33_N : inout std_logic;
-- LA33_P : inout std_logic;
-- LA32_N : inout std_logic;
-- LA16_P : inout std_logic;
-- LA15_N : inout std_logic;
-- LA15_P : inout std_logic;
-- LA13_P : inout std_logic;
-- LA13_N : inout std_logic;
--
-- LA17_P : inout std_logic;
-- LA14_P : inout std_logic;
-- LA14_N : inout std_logic;
-- LA20_N : inout std_logic;
-- LA20_P : inout std_logic;
-- LA19_P : inout std_logic;
-- LA19_N : inout std_logic;
-- LA17_N : inout std_logic
-- LA33_N : in std_logic;
-- LA33_P : in std_logic;
-- LA32_N : in std_logic;
-- LA16_P : in std_logic;
-- LA15_N : in std_logic;
-- LA15_P : in std_logic;
-- LA13_P : in std_logic;
-- LA13_N : in std_logic;
--
-- LA17_P : in std_logic;
-- LA14_P : in std_logic;
-- LA14_N : in std_logic;
-- LA20_N : in std_logic;
-- LA20_P : in std_logic;
-- LA19_P : in std_logic;
-- LA19_N : in std_logic;
-- LA17_N : in std_logic
-- LA33_N : out std_logic;
-- LA33_P : out std_logic;
-- LA32_N : out std_logic;
-- LA16_P : out std_logic;
-- LA15_N : out std_logic;
-- LA15_P : out std_logic;
-- LA13_P : out std_logic;
-- LA13_N : out std_logic;
--
-- LA17_P : out std_logic;
-- LA14_P : out std_logic;
-- LA14_N : out std_logic;
-- LA20_N : out std_logic;
-- LA20_P : out std_logic;
-- LA19_P : out std_logic;
-- LA19_N : out std_logic;
-- LA17_N : out std_logic
);
end spec_top;
architecture rtl of spec_top is
------------------------------------------------------------------------------
-- Components declaration
------------------------------------------------------------------------------
component gn4124_core
generic(
g_BAR0_APERTURE : integer := 20; -- BAR0 aperture, defined in GN4124 PCI_BAR_CONFIG register (0x80C)
-- => number of bits to address periph on the board
g_CSR_WB_SLAVES_NB : integer := 3; -- Number of CSR wishbone slaves
g_DMA_WB_SLAVES_NB : integer := 1; -- Number of DMA wishbone slaves
g_DMA_WB_ADDR_WIDTH : integer := 26 -- DMA wishbone address bus width
);
port
(
---------------------------------------------------------
-- Control and status
--
-- Asynchronous reset from GN4124
rst_n_a_i : in std_logic;
-- P2L clock PLL locked
p2l_pll_locked : out std_logic;
-- Debug ouputs
debug_o : out std_logic_vector(7 downto 0);
---------------------------------------------------------
-- P2L Direction
--
-- Source Sync DDR related signals
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i : in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
-- P2L Control
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
---------------------------------------------------------
-- L2P Direction
--
-- Source Sync DDR related signals
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o : out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
-- L2P Control
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Channel ready
---------------------------------------------------------
-- Interrupt interface
dma_irq_o : out std_logic_vector(1 downto 0); -- Interrupts sources to IRQ manager
irq_p_i : in std_logic; -- Interrupt request pulse from IRQ manager
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
---------------------------------------------------------
-- Target interface (CSR wishbone master)
wb_clk_i : in std_logic;
wb_adr_o : out std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_CSR_WB_SLAVES_NB+1)-1 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic;
wb_we_o : out std_logic;
wb_cyc_o : out std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
wb_dat_i : in std_logic_vector((32*g_CSR_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
---------------------------------------------------------
-- DMA interface (Pipelined wishbone master)
dma_clk_i : in std_logic;
dma_adr_o : out std_logic_vector(31 downto 0);
dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
dma_stb_o : out std_logic;
dma_we_o : out std_logic;
dma_cyc_o : out std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_dat_i : in std_logic_vector((32*g_DMA_WB_SLAVES_NB)-1 downto 0); -- Data in
dma_ack_i : in std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_stall_i : in std_logic--_vector(g_DMA_WB_SLAVES_NB-1 downto 0) -- for pipelined Wishbone
);
end component; -- gn4124_core
-- I2C
component i2c_master_top is
generic(
ARST_LVL : std_logic := '0' -- asynchronous reset level
);
port (
-- wishbone signals
wb_clk_i : in std_logic; -- master clock input
wb_rst_i : in std_logic := '0'; -- synchronous active high reset
arst_i : in std_logic := not ARST_LVL; -- asynchronous reset
wb_adr_i : in std_logic_vector(2 downto 0); -- lower address bits
wb_dat_i : in std_logic_vector(7 downto 0); -- Databus input
wb_dat_o : out std_logic_vector(7 downto 0); -- Databus output
wb_we_i : in std_logic; -- Write enable input
wb_stb_i : in std_logic; -- Strobe signals / core select signal
wb_cyc_i : in std_logic; -- Valid bus cycle input
wb_ack_o : out std_logic; -- Bus cycle acknowledge output
wb_inta_o : out std_logic; -- interrupt request output signal
-- i2c lines
scl_pad_i : in std_logic; -- i2c clock line input
scl_pad_o : out std_logic; -- i2c clock line output
scl_padoen_o : out std_logic; -- i2c clock line output enable, active low
sda_pad_i : in std_logic; -- i2c data line input
sda_pad_o : out std_logic; -- i2c data line output
sda_padoen_o : out std_logic -- i2c data line output enable, active low
);
end component; -- i2c_master_top
component monostable is
generic(
g_INPUT_POLARITY : std_logic := '1'; --! trigger_i polarity
--! ('0'=negative, 1=positive)
g_OUTPUT_POLARITY : std_logic := '1'; --! pulse_o polarity
--! ('0'=negative, 1=positive)
g_OUTPUT_RETRIG : boolean := false; --! Retriggerable output monostable
g_OUTPUT_LENGTH : natural := 1 --! pulse_o lenght (in clk_i ticks)
);
port (
rst_n_i : in std_logic; --! Reset (active low)
clk_i : in std_logic; --! Clock
trigger_i : in std_logic; --! Trigger input pulse
pulse_o : out std_logic --! Monostable output pulse
);
end component;
------------------------------------------------------------------------------
-- Constants declaration
------------------------------------------------------------------------------
constant c_BAR0_APERTURE : integer := 20;
constant c_CSR_WB_SLAVES_NB : integer := 3;
constant c_DMA_WB_SLAVES_NB : integer := 1;
constant c_DMA_WB_ADDR_WIDTH : integer := 26;
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
-- System clock
signal sys_clk_in : std_logic;
signal sys_clk_50_buf : std_logic;
signal sys_clk_200_buf : std_logic;
signal sys_clk_50 : std_logic;
signal sys_clk_200 : std_logic;
signal sys_clk_fb : std_logic;
signal sys_clk_pll_locked : std_logic;
-- LCLK from GN4124 used as system clock
signal l_clk : std_logic;
-- P2L clock PLL status
signal p2l_pll_locked : std_logic;
-- Reset
signal rst : std_logic;
-- CSR wishbone bus
signal wb_adr : std_logic_vector(c_BAR0_APERTURE-log2_ceil(c_CSR_WB_SLAVES_NB+1)-1 downto 0);
signal wb_dat_i : std_logic_vector((32*c_CSR_WB_SLAVES_NB)-1 downto 0);
signal wb_dat_o : std_logic_vector(31 downto 0);
signal wb_sel : std_logic_vector(3 downto 0);
signal wb_cyc : std_logic_vector(c_CSR_WB_SLAVES_NB-1 downto 0);
signal wb_stb : std_logic;
signal wb_we : std_logic;
signal wb_ack : std_logic_vector(c_CSR_WB_SLAVES_NB-1 downto 0);
signal spi_wb_adr : std_logic_vector(4 downto 0);
-- I2C additional signals
signal scl_fmc_int_in : std_logic;
signal scl_fmc_int_out : std_logic;
signal scl_fmc_int_oe : std_logic;
signal sda_fmc_int_in : std_logic;
signal sda_fmc_int_out : std_logic;
signal sda_fmc_int_oe : std_logic;
signal scl_fmc_int2_in : std_logic;
signal scl_fmc_int2_out : std_logic;
signal scl_fmc_int2_oe : std_logic;
signal sda_fmc_int2_in : std_logic;
signal sda_fmc_int2_out : std_logic;
signal sda_fmc_int2_oe : std_logic;
-- DMA wishbone bus
signal dma_adr : std_logic_vector(31 downto 0);
signal dma_dat_i : std_logic_vector((32*c_DMA_WB_SLAVES_NB)-1 downto 0);
signal dma_dat_o : std_logic_vector(31 downto 0);
signal dma_sel : std_logic_vector(3 downto 0);
signal dma_cyc : std_logic; --_vector(c_DMA_WB_SLAVES_NB-1 downto 0);
signal dma_stb : std_logic;
signal dma_we : std_logic;
signal dma_ack : std_logic; --_vector(c_DMA_WB_SLAVES_NB-1 downto 0);
signal dma_stall : std_logic; --_vector(c_DMA_WB_SLAVES_NB-1 downto 0);
signal ram_we : std_logic_vector(0 downto 0);
signal ddr_dma_adr : std_logic_vector(29 downto 0);
-- Interrupts stuff
signal irq_sources : std_logic_vector(1 downto 0);
signal irq_to_gn4124 : std_logic;
signal irq_sources_2_led : std_logic_vector(1 downto 0);
-- CSR wishbone slaves for test
signal gpio_stat : std_logic_vector(31 downto 0);
signal gpio_ctrl_1 : std_logic_vector(31 downto 0);
signal gpio_ctrl_2 : std_logic_vector(31 downto 0);
signal gpio_ctrl_3 : std_logic_vector(31 downto 0);
signal gpio_led_ctrl : std_logic_vector(31 downto 0);
-- SIG: test leds
signal led_clock : std_logic;
signal led_1 : std_logic := '0';
signal led_2 : std_logic := '1';
begin
------------------------------------------------------------------------------
-- Clocks distribution from 20MHz TCXO
-- 50.000 MHz system clock
-- 200.000 MHz fast system clock
-- 333.333 MHz DDR3 clock
------------------------------------------------------------------------------
cmp_sys_clk_buf : IBUFG
port map (
I => clk_20m_vcxo_i,
O => sys_clk_in);
cmp_sys_clk_pll : PLL_BASE
generic map (
BANDWIDTH => "OPTIMIZED",
CLK_FEEDBACK => "CLKFBOUT",
COMPENSATION => "INTERNAL",
DIVCLK_DIVIDE => 1,
CLKFBOUT_MULT => 50,
CLKFBOUT_PHASE => 0.000,
CLKOUT0_DIVIDE => 20,
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT1_DIVIDE => 5,
CLKOUT1_PHASE => 0.000,
CLKOUT1_DUTY_CYCLE => 0.500,
CLKOUT2_DIVIDE => 3,
CLKOUT2_PHASE => 0.000,
CLKOUT2_DUTY_CYCLE => 0.500,
CLKIN_PERIOD => 50.0,
REF_JITTER => 0.016)
port map (
CLKFBOUT => sys_clk_fb,
CLKOUT0 => sys_clk_50_buf,
CLKOUT1 => open, --sys_clk_200_buf,
CLKOUT2 => open,
CLKOUT3 => open,
CLKOUT4 => open,
CLKOUT5 => open,
LOCKED => sys_clk_pll_locked,
RST => '0',
CLKFBIN => sys_clk_fb,
CLKIN => sys_clk_in);
cmp_clk_50_buf : BUFG
port map (
O => sys_clk_50,
I => sys_clk_50_buf);
--cmp_clk_200_buf : BUFG
-- port map (
-- O => sys_clk_200,
-- I => sys_clk_200_buf);
------------------------------------------------------------------------------
-- Local clock from gennum LCLK
------------------------------------------------------------------------------
cmp_l_clk_buf : IBUFDS
generic map (
DIFF_TERM => false, -- Differential Termination
IBUF_LOW_PWR => true, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "DEFAULT")
port map (
O => l_clk, -- Buffer output
I => L_CLKp, -- Diff_p buffer input (connect directly to top-level port)
IB => L_CLKn -- Diff_n buffer input (connect directly to top-level port)
);
------------------------------------------------------------------------------
-- Active high reset
------------------------------------------------------------------------------
rst <= not(L_RST_N);
------------------------------------------------------------------------------
-- GN4124 interface
------------------------------------------------------------------------------
cmp_gn4124_core : gn4124_core
generic map (
g_BAR0_APERTURE => c_BAR0_APERTURE,
g_CSR_WB_SLAVES_NB => c_CSR_WB_SLAVES_NB,
g_DMA_WB_SLAVES_NB => c_DMA_WB_SLAVES_NB,
g_DMA_WB_ADDR_WIDTH => c_DMA_WB_ADDR_WIDTH)
port map(
---------------------------------------------------------
-- Control and status
--
-- Asynchronous reset from GN4124
rst_n_a_i => L_RST_N,
-- P2L clock PLL locked
p2l_pll_locked => p2l_pll_locked,
-- Debug outputs
debug_o => open,
---------------------------------------------------------
-- P2L Direction
--
-- Source Sync DDR related signals
p2l_clk_p_i => P2L_CLKp,
p2l_clk_n_i => P2L_CLKn,
p2l_data_i => P2L_DATA,
p2l_dframe_i => P2L_DFRAME,
p2l_valid_i => P2L_VALID,
-- P2L Control
p2l_rdy_o => P2L_RDY,
p_wr_req_i => P_WR_REQ,
p_wr_rdy_o => P_WR_RDY,
rx_error_o => RX_ERROR,
---------------------------------------------------------
-- L2P Direction
--
-- Source Sync DDR related signals
l2p_clk_p_o => L2P_CLKp,
l2p_clk_n_o => L2P_CLKn,
l2p_data_o => L2P_DATA,
l2p_dframe_o => L2P_DFRAME,
l2p_valid_o => L2P_VALID,
l2p_edb_o => L2P_EDB,
-- L2P Control
l2p_rdy_i => L2P_RDY,
l_wr_rdy_i => L_WR_RDY,
p_rd_d_rdy_i => P_RD_D_RDY,
tx_error_i => TX_ERROR,
vc_rdy_i => VC_RDY,
---------------------------------------------------------
-- Interrupt interface
dma_irq_o => irq_sources,
irq_p_i => irq_to_gn4124,
irq_p_o => GPIO(0),
---------------------------------------------------------
-- CSR wishbone interface
wb_clk_i => sys_clk_50,
wb_adr_o => wb_adr,
wb_dat_o => wb_dat_o,
wb_sel_o => wb_sel,
wb_stb_o => wb_stb,
wb_we_o => wb_we,
wb_cyc_o => wb_cyc,
wb_dat_i => wb_dat_i,
wb_ack_i => wb_ack,
---------------------------------------------------------
-- DMA wishbone interface (pipelined)
dma_clk_i => sys_clk_50,
dma_adr_o => dma_adr,
dma_dat_o => dma_dat_o,
dma_sel_o => dma_sel,
dma_stb_o => dma_stb,
dma_we_o => dma_we,
dma_cyc_o => dma_cyc,
dma_dat_i => dma_dat_i,
dma_ack_i => dma_ack,
dma_stall_i => dma_stall);
------------------------------------------------------------------------------
-- CSR wishbone bus slaves
-- 0 -> I2C controller
-- 1 -> GPIO port
-- 2 -> Not connected
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- Interrupt stuff
------------------------------------------------------------------------------
-- just forward irq pulses for test
irq_to_gn4124 <= irq_sources(1) or irq_sources(0);
------------------------------------------------------------------------------
-- Assign unused outputs
------------------------------------------------------------------------------
GPIO(1) <= '0';
----------------------------------------------------------
-- I2C master
----------------------------------------------------------
I2C_FMC : i2c_master_top
generic map (
ARST_LVL => '0')
port map (
wb_clk_i => sys_clk_50,
wb_rst_i => rst,
arst_i => '1',
wb_adr_i => wb_adr(2 downto 0),
wb_dat_i => wb_dat_o(7 downto 0),
wb_dat_o => wb_dat_i(39 downto 32),
wb_we_i => wb_we,
wb_stb_i => wb_stb,
wb_cyc_i => wb_cyc(1),
wb_ack_o => wb_ack(1),
wb_inta_o => open,
scl_pad_i => scl_fmc_int2_in,
scl_pad_o => scl_fmc_int2_out,
scl_padoen_o => scl_fmc_int2_oe,
sda_pad_i => sda_fmc_int2_in,
sda_pad_o => sda_fmc_int2_out,
sda_padoen_o => sda_fmc_int2_oe);
SCL1_b <= scl_fmc_int2_out when (scl_fmc_int2_oe = '0') else 'Z';
scl_fmc_int2_in <= SCL1_b;
SDA1_b <= sda_fmc_int2_out when (sda_fmc_int2_oe = '0') else 'Z';
sda_fmc_int2_in <= SDA1_b;
I2C_FMC_2 : i2c_master_top
generic map (
ARST_LVL => '0')
port map (
wb_clk_i => sys_clk_50,
wb_rst_i => rst,
arst_i => '1',
wb_adr_i => wb_adr(2 downto 0),
wb_dat_i => wb_dat_o(7 downto 0),
wb_dat_o => wb_dat_i(7 downto 0),
wb_we_i => wb_we,
wb_stb_i => wb_stb,
wb_cyc_i => wb_cyc(0),
wb_ack_o => wb_ack(0),
wb_inta_o => open,
scl_pad_i => scl_fmc_int_in,
scl_pad_o => scl_fmc_int_out,
scl_padoen_o => scl_fmc_int_oe,
sda_pad_i => sda_fmc_int_in,
sda_pad_o => sda_fmc_int_out,
sda_padoen_o => sda_fmc_int_oe);
FPGA_SCL <= scl_fmc_int_out when (scl_fmc_int_oe = '0') else 'Z';
scl_fmc_int_in <= FPGA_SCL;
FPGA_SDA <= sda_fmc_int_out when (sda_fmc_int_oe = '0') else 'Z';
sda_fmc_int_in <= FPGA_SDA;
end rtl;
#---------------------------------------------------------------------------------------------
# The IO Location Constraints
#---------------------------------------------------------------------------------------------
NET "CLK_20M_VCXO_I" LOC = H12;
NET "CLK_20M_VCXO_I" IOSTANDARD = "LVCMOS25";
#NET "EN_FB_RX" LOC = D5;
#NET "EN_FB_RX" IOSTANDARD = "LVCMOS25";
#NET "EN_FB_TX" LOC = E5;
#NET "EN_FB_TX" IOSTANDARD = "LVCMOS25";
#NET "FB_N" LOC = A18;
#NET "FB_N" IOSTANDARD = "LVDS_25";
#NET "FB_P" LOC = B18;
#NET "FB_P" IOSTANDARD = "LVCMOS25";
#NET "clk_125m_pllref_n_i" LOC = F10;
#NET "clk_125m_pllref_n_i" IOSTANDARD = "LVDS_25";
#NET "clk_125m_pllref_p_i" LOC = G9;
#NET "clk_125m_pllref_p_i" IOSTANDARD = "LVDS_25";
#NET "OE_SI57X" LOC = H13;
#NET "OE_SI57X" IOSTANDARD = "LVCMOS25";
#NET "PG_C2M" LOC = B2;
#NET "PG_C2M" IOSTANDARD = "LVCMOS25";
#NET "dac_cs1_n_o" LOC = A3;
#NET "dac_cs1_n_o" IOSTANDARD = "LVCMOS25";
#NET "dac_cs2_n_o" LOC = B3;
#NET "dac_cs2_n_o" IOSTANDARD = "LVCMOS25";
#NET "dac_clr_n_o" LOC = F7;
#NET "dac_clr_n_o" IOSTANDARD = "LVCMOS25";
#NET "dac_din_o" LOC = C4;
#NET "dac_din_o" IOSTANDARD = "LVCMOS25";
#NET "dac_sclk_o" LOC = A4;
#NET "dac_sclk_o" IOSTANDARD = "LVCMOS25";
#NET "SI57X_CLK_N" LOC = F15;
#NET "SI57X_CLK_N" IOSTANDARD = "LVDS_25";
#NET "SI57X_CLK_P" LOC = F14;
#NET "SI57X_CLK_P" IOSTANDARD = "LVDS_25";
#NET "TDI_TO_FMC" LOC = H11;
#NET "TDI_TO_FMC" IOSTANDARD = "LVCMOS25";
#NET "TDO_FROM_FMC" LOC = F9;
#NET "TDO_FROM_FMC" IOSTANDARD = "LVCMOS25";
#NET "TMS_TO_FMC" LOC = H10;
#NET "TMS_TO_FMC" IOSTANDARD = "LVCMOS25";
#NET "TRST_TO_FMC" LOC = E6;
#NET "TRST_TO_FMC" IOSTANDARD = "LVCMOS25";
#NET "TCK_TO_FMC" LOC = G8;
#NET "TCK_TO_FMC" IOSTANDARD = "LVCMOS25";
#NET "THERMO_ID" LOC = D4;
#NET "THERMO_ID" IOSTANDARD = "LVCMOS25";
#NET "PRSNT_M2C_L" LOC = A2;
#NET "PRSNT_M2C_L" IOSTANDARD = "LVCMOS25";
#NET "SFP_TX_FAULT" LOC = A17;
#NET "SFP_TX_FAULT" IOSTANDARD = "LVCMOS25";
#NET "SFP_TX_DISABLE" LOC = C17;
#NET "SFP_TX_DISABLE" IOSTANDARD = "LVCMOS25";
#NET "SFP_LOS" LOC = D18;
#NET "SFP_LOS" IOSTANDARD = "LVCMOS25";
#NET "scl0_b" LOC = F7;
#NET "scl0_b" IOSTANDARD = "LVCMOS25";
#
NET "FPGA_SCL" LOC = F7;
NET "FPGA_SCL" IOSTANDARD = "LVCMOS25";
#
#NET "sda0_b" LOC = F8;
#NET "sda0_b" IOSTANDARD = "LVCMOS25";
#
NET "FPGA_SDA" LOC = F8;
NET "FPGA_SDA" IOSTANDARD = "LVCMOS25";
############################################################
# SIG: search the correct tag for SATA's pins.
#NET "SATA0_RX_N" LOC = C9;
#NET "SATA0_RX_N" IOSTANDARD = "LVDS_25";
#NET "SATA0_RX_P" LOC = D9;
#NET "SATA0_RX_P" IOSTANDARD = "LVDS_25";
#NET "SATA0_TX_N" LOC = A8;
#NET "SATA0_TX_N" IOSTANDARD = "LVDS_25";
#NET "SATA0_TX_P" LOC = B8;
#NET "SATA0_TX_P" IOSTANDARD = "LVDS_25";
##########################################################3
#NET "SFP_MOD_DEF1" LOC = F17;
#NET "SFP_MOD_DEF1" IOSTANDARD = "LVCMOS25";
#NET "SFP_MOD_DEF0" LOC = G15;
#NET "SFP_MOD_DEF0" IOSTANDARD = "LVCMOS25";
#NET "SFP_MOD_DEF2" LOC = G16;
#NET "SFP_MOD_DEF2" IOSTANDARD = "LVCMOS25";
#NET "SFP_RATE_SELECT" LOC = H14;
#NET "SFP_RATE_SELECT" IOSTANDARD = "LVCMOS25";
NET "L_RST_N" LOC = N20;
NET "L_RST_N" IOSTANDARD = "LVCMOS18";
NET "L2P_CLKN" LOC = K22;
NET "L2P_CLKN" IOSTANDARD = "DIFF_SSTL18_I";
NET "L2P_CLKP" LOC = K21;
NET "L2P_CLKP" IOSTANDARD = "DIFF_SSTL18_I";
NET "L2P_DFRAME" LOC = U22;
NET "L2P_DFRAME" IOSTANDARD = "SSTL18_I";
NET "L2P_EDB" LOC = U20;
NET "L2P_EDB" IOSTANDARD = "SSTL18_I";
NET "L2P_RDY" LOC = U19;
NET "L2P_RDY" IOSTANDARD = "SSTL18_I";
NET "L2P_VALID" LOC = T18;
NET "L2P_VALID" IOSTANDARD = "SSTL18_I";
NET "L_WR_RDY[0]" LOC = R20;
NET "L_WR_RDY[0]" IOSTANDARD = "SSTL18_I";
NET "L_WR_RDY[1]" LOC = T22;
NET "L_WR_RDY[1]" IOSTANDARD = "SSTL18_I";
NET "L_CLKN" LOC = N19;
NET "L_CLKN" IOSTANDARD = "DIFF_SSTL18_I";
NET "L_CLKP" LOC = P20;
NET "L_CLKP" IOSTANDARD = "DIFF_SSTL18_I";
NET "P2L_CLKN" LOC = M19;
NET "P2L_CLKN" IOSTANDARD = "DIFF_SSTL18_I";
NET "P2L_CLKP" LOC = M20;
NET "P2L_CLKP" IOSTANDARD = "DIFF_SSTL18_I";
NET "P2L_DFRAME" LOC = J22;
NET "P2L_DFRAME" IOSTANDARD = "SSTL18_I";
NET "P2L_RDY" LOC = J16;
NET "P2L_RDY" IOSTANDARD = "SSTL18_I";
NET "P2L_VALID" LOC = L19;
NET "P2L_VALID" IOSTANDARD = "SSTL18_I";
NET "P_RD_D_RDY[0]" LOC = N16;
NET "P_RD_D_RDY[0]" IOSTANDARD = "SSTL18_I";
NET "P_RD_D_RDY[1]" LOC = P19;
NET "P_RD_D_RDY[1]" IOSTANDARD = "SSTL18_I";
NET "P_WR_RDY[0]" LOC = L15;
NET "P_WR_RDY[0]" IOSTANDARD = "SSTL18_I";
NET "P_WR_RDY[1]" LOC = K16;
NET "P_WR_RDY[1]" IOSTANDARD = "SSTL18_I";
NET "P_WR_REQ[0]" LOC = M22;
NET "P_WR_REQ[0]" IOSTANDARD = "SSTL18_I";
NET "P_WR_REQ[1]" LOC = M21;
NET "P_WR_REQ[1]" IOSTANDARD = "SSTL18_I";
NET "RX_ERROR" LOC = J17;
NET "RX_ERROR" IOSTANDARD = "SSTL18_I";
NET "TX_ERROR" LOC = M17;
NET "TX_ERROR" IOSTANDARD = "SSTL18_I";
NET "VC_RDY[0]" LOC = B21;
NET "VC_RDY[0]" IOSTANDARD = "SSTL18_I";
NET "VC_RDY[1]" LOC = B22;
NET "VC_RDY[1]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[0]" LOC = P16;
NET "L2P_DATA[0]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[1]" LOC = P21;
NET "L2P_DATA[1]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[2]" LOC = P18;
NET "L2P_DATA[2]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[3]" LOC = T20;
NET "L2P_DATA[3]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[4]" LOC = V21;
NET "L2P_DATA[4]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[5]" LOC = V19;
NET "L2P_DATA[5]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[6]" LOC = W22;
NET "L2P_DATA[6]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[7]" LOC = Y22;
NET "L2P_DATA[7]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[8]" LOC = P22;
NET "L2P_DATA[8]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[9]" LOC = R22;
NET "L2P_DATA[9]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[10]" LOC = T21;
NET "L2P_DATA[10]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[11]" LOC = T19;
NET "L2P_DATA[11]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[12]" LOC = V22;
NET "L2P_DATA[12]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[13]" LOC = V20;
NET "L2P_DATA[13]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[14]" LOC = W20;
NET "L2P_DATA[14]" IOSTANDARD = "SSTL18_I";
NET "L2P_DATA[15]" LOC = Y21;
NET "L2P_DATA[15]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[0]" LOC = K20;
NET "P2L_DATA[0]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[1]" LOC = H22;
NET "P2L_DATA[1]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[2]" LOC = H21;
NET "P2L_DATA[2]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[3]" LOC = L17;
NET "P2L_DATA[3]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[4]" LOC = K17;
NET "P2L_DATA[4]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[5]" LOC = G22;
NET "P2L_DATA[5]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[6]" LOC = G20;
NET "P2L_DATA[6]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[7]" LOC = K18;
NET "P2L_DATA[7]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[8]" LOC = K19;
NET "P2L_DATA[8]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[9]" LOC = H20;
NET "P2L_DATA[9]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[10]" LOC = J19;
NET "P2L_DATA[10]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[11]" LOC = E22;
NET "P2L_DATA[11]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[12]" LOC = E20;
NET "P2L_DATA[12]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[13]" LOC = F22;
NET "P2L_DATA[13]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[14]" LOC = F21;
NET "P2L_DATA[14]" IOSTANDARD = "SSTL18_I";
NET "P2L_DATA[15]" LOC = H19;
NET "P2L_DATA[15]" IOSTANDARD = "SSTL18_I";
NET "GPIO[0]" LOC = U16;
NET "GPIO[0]" IOSTANDARD = "LVCMOS25";
NET "GPIO[1]" LOC = AB19;
NET "GPIO[1]" IOSTANDARD = "LVCMOS25";
#NET "CLK0_M2C_P" LOC = E16;
##NET "CLK0_M2C_P" IOSTANDARD = "LVDS_25";
#NET "CLK0_M2C_P" IOSTANDARD = "LVCMOS25";
#NET "CLK0_M2C_N" LOC = F16;
##NET "CLK0_M2C_N" IOSTANDARD = "LVDS_25";
#NET "CLK0_M2C_N" IOSTANDARD = "LVCMOS25";
##NET "CLK1_M2C_P" LOC = L20;
#NET "CLK1_M2C_P" IOSTANDARD = "LVDS_25";
##NET "CLK1_M2C_P" IOSTANDARD = "LVCMOS25";
#NET "CLK1_M2C_N" LOC = L22;
#NET "CLK1_M2C_N" IOSTANDARD = "LVDS_25";
##NET "CLK1_M2C_N" IOSTANDARD = "LVCMOS25";
# SIG: I2C carrier tester VADJ
NET "SDA1_b" LOC = Y6;
NET "SDA1_b" IOSTANDARD = "LVCMOS25";
NET "SCL1_b" LOC = W6;
NET "SCL1_b" IOSTANDARD = "LVCMOS25";
#NET "LA00_N" LOC = AB11;
#NET "LA00_N" IOSTANDARD = "LVCMOS25";
#NET "LA00_P" LOC = Y11;
#NET "LA00_P" IOSTANDARD = "LVCMOS25";
#NET "LA01_N" LOC = AB12;
#NET "LA01_N" IOSTANDARD = "LVCMOS25";
#NET "LA01_P" LOC = AA12;
#NET "LA01_P" IOSTANDARD = "LVCMOS25";
#NET "LA02_N" LOC = Y6;
#NET "LA02_N" IOSTANDARD = "LVCMOS25";
#NET "LA02_P" LOC = W6;
#NET "LA02_P" IOSTANDARD = "LVCMOS25";
#NET "LA03_N" LOC = W8;
#NET "LA03_N" IOSTANDARD = "LVCMOS25";
#NET "LA03_P" LOC = V7;
#NET "LA03_P" IOSTANDARD = "LVCMOS25";
#NET "LA04_N" LOC = U8;
#NET "LA04_N" IOSTANDARD = "LVCMOS25";
#NET "LA04_P" LOC = T8;
#NET "LA04_P" IOSTANDARD = "LVCMOS25";
#NET "LA05_N" LOC = AB6;
#NET "LA05_N" IOSTANDARD = "LVCMOS25";
#NET "LA05_P" LOC = AA6;
#NET "LA05_P" IOSTANDARD = "LVCMOS25";
#NET "LA06_N" LOC = AB5;
#NET "LA06_N" IOSTANDARD = "LVCMOS25";
#NET "LA06_P" LOC = Y5;
#NET "LA06_P" IOSTANDARD = "LVCMOS25";
#NET "LA07_N" LOC = V9;
#NET "LA07_N" IOSTANDARD = "LVCMOS25";
#NET "LA07_P" LOC = U9;
#NET "LA07_P" IOSTANDARD = "LVCMOS25";
#NET "LA08_N" LOC = R8;
#NET "LA08_N" IOSTANDARD = "LVCMOS25";
#NET "LA08_P" LOC = R9;
#NET "LA08_P" IOSTANDARD = "LVCMOS25";
#NET "LA09_N" LOC = AB7;
#NET "LA09_N" IOSTANDARD = "LVCMOS25";
#NET "LA09_P" LOC = Y7;
#NET "LA09_P" IOSTANDARD = "LVCMOS25";
#NET "LA10_N" LOC = AB8;
#NET "LA10_N" IOSTANDARD = "LVCMOS25";
#NET "LA10_P" LOC = AA8;
#NET "LA10_P" IOSTANDARD = "LVCMOS25";
#NET "LA11_N" LOC = Y10;
#NET "LA11_N" IOSTANDARD = "LVCMOS25";
#NET "LA11_P" LOC = W10;
#NET "LA11_P" IOSTANDARD = "LVCMOS25";
#NET "LA12_N" LOC = U10;
#NET "LA12_N" IOSTANDARD = "LVCMOS25";
#NET "LA12_P" LOC = T10;
#NET "LA12_P" IOSTANDARD = "LVCMOS25";
#NET "LA13_N" LOC = AB9;
#NET "LA13_N" IOSTANDARD = "LVCMOS25";
#NET "LA13_P" LOC = Y9;
#NET "LA13_P" IOSTANDARD = "LVCMOS25";
#NET "LA14_N" LOC = AB4;
#NET "LA14_N" IOSTANDARD = "LVCMOS25";
#NET "LA14_P" LOC = AA4;
#NET "LA14_P" IOSTANDARD = "LVCMOS25";
#NET "LA15_N" LOC = W11;
#NET "LA15_N" IOSTANDARD = "LVCMOS25";
#NET "LA15_P" LOC = V11;
#NET "LA15_P" IOSTANDARD = "LVCMOS25";
#NET "LA16_N" LOC = AB15;
#NET "LA16_N" IOSTANDARD = "LVCMOS25";
#NET "LA16_P" LOC = Y15;
#NET "LA16_P" IOSTANDARD = "LVCMOS25";
#NET "LA17_N" LOC = AB13;
#NET "LA17_N" IOSTANDARD = "LVCMOS25";
#NET "LA17_P" LOC = Y13;
#NET "LA17_P" IOSTANDARD = "LVCMOS25";
#NET "LA18_N" LOC = U12;
#NET "LA18_N" IOSTANDARD = "LVCMOS25";
#NET "LA18_P" LOC = T12;
#NET "LA18_P" IOSTANDARD = "LVCMOS25";
#NET "LA19_N" LOC = Y12;
#NET "LA19_N" IOSTANDARD = "LVCMOS25";
#NET "LA19_P" LOC = W12;
#NET "LA19_P" IOSTANDARD = "LVCMOS25";
#NET "LA20_N" LOC = T11;
#NET "LA20_N" IOSTANDARD = "LVCMOS25";
#NET "LA20_P" LOC = R11;
#NET "LA20_P" IOSTANDARD = "LVCMOS25";
#NET "LA21_N" LOC = W13;
#NET "LA21_N" IOSTANDARD = "LVCMOS25";
#NET "LA21_P" LOC = V13;
#NET "LA21_P" IOSTANDARD = "LVCMOS25";
#NET "LA22_N" LOC = T14;
#NET "LA22_N" IOSTANDARD = "LVCMOS25";
#NET "LA22_P" LOC = R13;
#NET "LA22_P" IOSTANDARD = "LVCMOS25";
#NET "LA23_N" LOC = AB16;
#NET "LA23_N" IOSTANDARD = "LVCMOS25";
#NET "LA23_P" LOC = AA16;
#NET "LA23_P" IOSTANDARD = "LVCMOS25";
#NET "LA24_N" LOC = Y14;
#NET "LA24_N" IOSTANDARD = "LVCMOS25";
#NET "LA24_P" LOC = W14;
#NET "LA24_P" IOSTANDARD = "LVCMOS25";
#NET "LA25_N" LOC = U15;
#NET "LA25_N" IOSTANDARD = "LVCMOS25";
#NET "LA25_P" LOC = T15;
#NET "LA25_P" IOSTANDARD = "LVCMOS25";
#NET "LA26_N" LOC = AB17;
#NET "LA26_N" IOSTANDARD = "LVCMOS25";
#NET "LA26_P" LOC = Y17;
#NET "LA26_P" IOSTANDARD = "LVCMOS25";
#NET "LA27_N" LOC = AB18;
#NET "LA27_N" IOSTANDARD = "LVCMOS25";
#NET "LA27_P" LOC = AA18;
#NET "LA27_P" IOSTANDARD = "LVCMOS25";
#NET "LA28_N" LOC = W15;
#NET "LA28_N" IOSTANDARD = "LVCMOS25";
#NET "LA28_P" LOC = Y16;
#NET "LA28_P" IOSTANDARD = "LVCMOS25";
#NET "LA29_N" LOC = Y18;
#NET "LA29_N" IOSTANDARD = "LVCMOS25";
#NET "LA29_P" LOC = W17;
#NET "LA29_P" IOSTANDARD = "LVCMOS25";
#NET "LA30_N" LOC = W18;
#NET "LA30_N" IOSTANDARD = "LVCMOS25";
#NET "LA30_P" LOC = V17;
#NET "LA30_P" IOSTANDARD = "LVCMOS25";
#NET "LA31_N" LOC = C18;
#NET "LA31_N" IOSTANDARD = "LVCMOS25";
#NET "LA31_P" LOC = D17;
#NET "LA31_P" IOSTANDARD = "LVCMOS25";
#NET "LA32_N" LOC = A20;
#NET "LA32_N" IOSTANDARD = "LVCMOS25";
#NET "LA32_P" LOC = B20;
#NET "LA32_P" IOSTANDARD = "LVCMOS25";
#NET "LA33_N" LOC = A19;
#NET "LA33_N" IOSTANDARD = "LVCMOS25";
#NET "LA33_P" LOC = C19;
#NET "LA33_P" IOSTANDARD = "LVCMOS25";
#NET "SI57X_SCL" LOC = AA14;
#NET "SI57X_SCL" IOSTANDARD = "LVCMOS25";
#NET "SI57X_SDA" LOC = AB14;
#NET "SI57X_SDA" IOSTANDARD = "LVCMOS25";
#NET "LED_RED" LOC = T6;
#NET "LED_RED" IOSTANDARD = "LVCMOS15";
#NET "LED_GREEN" LOC = Y3;
#NET "LED_GREEN" IOSTANDARD = "LVCMOS15";
#NET "PCB_VER[0]" LOC = P5;
#NET "PCB_VER[0]" IOSTANDARD = "LVCMOS15";
#NET "PCB_VER[1]" LOC = P4;
#NET "PCB_VER[1]" IOSTANDARD = "LVCMOS15";
#NET "PCB_VER[2]" LOC = AA2;
#NET "PCB_VER[2]" IOSTANDARD = "LVCMOS15";
#NET "PCB_VER[3]" LOC = AA1;
#NET "PCB_VER[3]" IOSTANDARD = "LVCMOS15";
#NET "PCB_VER[4]" LOC = N6;
#NET "PCB_VER[4]" IOSTANDARD = "LVCMOS15";
#NET "PCB_VER[5]" LOC = N7;
#NET "PCB_VER[5]" IOSTANDARD = "LVCMOS15";
#NET "PCB_VER[6]" LOC = U4;
#NET "PCB_VER[6]" IOSTANDARD = "LVCMOS15";
#NET "PCB_VER[7]" LOC = T4;
#NET "PCB_VER[7]" IOSTANDARD = "LVCMOS15";
#NET "DDR3_CAS_N" LOC = M4;
#NET "DDR3_CAS_N" IOSTANDARD = "SSTL15_II";
#NET "DDR3_CK_N" LOC = K3;
#NET "DDR3_CK_N" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_CK_P" LOC = K4;
#NET "DDR3_CK_P" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_CKE" LOC = F2;
#NET "DDR3_CKE" IOSTANDARD = "SSTL15_II";
#NET "DDR3_LDM" LOC = N4;
#NET "DDR3_LDM" IOSTANDARD = "SSTL15_II";
#NET "DDR3_LDQS_N" LOC = N1;
#NET "DDR3_LDQS_N" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_LDQS_P" LOC = N3;
#NET "DDR3_LDQS_P" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_ODT" LOC = L6;
#NET "DDR3_ODT" IOSTANDARD = "SSTL15_II";
#NET "DDR3_RAS_N" LOC = M5;
#NET "DDR3_RAS_N" IOSTANDARD = "SSTL15_II";
#NET "DDR3_RESET_N" LOC = E3;
#NET "DDR3_RESET_N" IOSTANDARD = "SSTL15_II";
#NET "DDR3_UDM" LOC = P3;
#NET "DDR3_UDM" IOSTANDARD = "SSTL15_II";
#NET "DDR3_UDQS_N" LOC = V1;
#NET "DDR3_UDQS_N" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_UDQS_P" LOC = V2;
#NET "DDR3_UDQS_P" IOSTANDARD = "DIFF_SSTL15_II";
#NET "DDR3_WE_N" LOC = H2;
#NET "DDR3_WE_N" IOSTANDARD = "SSTL15_II";
#NET "DDR3_RZQ" LOC = K7;
#NET "DDR3_RZQ" IOSTANDARD = "SSTL15_II";
#NET "DDR3_ZIO" LOC = M7;
#NET "DDR3_ZIO" IOSTANDARD = "SSTL15_II";
#
#NET "DDR3_A[0]" LOC = K2;
#NET "DDR3_A[0]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[1]" LOC = K1;
#NET "DDR3_A[1]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[2]" LOC = K5;
#NET "DDR3_A[2]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[3]" LOC = M6;
#NET "DDR3_A[3]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[4]" LOC = H3;
#NET "DDR3_A[4]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[5]" LOC = M3;
#NET "DDR3_A[5]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[6]" LOC = L4;
#NET "DDR3_A[6]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[7]" LOC = K6;
#NET "DDR3_A[7]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[8]" LOC = G3;
#NET "DDR3_A[8]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[9]" LOC = G1;
#NET "DDR3_A[9]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[10]" LOC = J4;
#NET "DDR3_A[10]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[11]" LOC = E1;
#NET "DDR3_A[11]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[12]" LOC = F1;
#NET "DDR3_A[12]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_A[13]" LOC = J6;
#NET "DDR3_A[13]" IOSTANDARD = "SSTL15_II";
##NET "DDR3_A[14]" LOC = H5;
##NET "DDR3_A[14]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_BA[0]" LOC = J3;
#NET "DDR3_BA[0]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_BA[1]" LOC = J1;
#NET "DDR3_BA[1]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_BA[2]" LOC = H1;
#NET "DDR3_BA[2]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[0]" LOC = R3;
#NET "DDR3_DQ[0]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[1]" LOC = R1;
#NET "DDR3_DQ[1]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[2]" LOC = P2;
#NET "DDR3_DQ[2]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[3]" LOC = P1;
#NET "DDR3_DQ[3]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[4]" LOC = L3;
#NET "DDR3_DQ[4]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[5]" LOC = L1;
#NET "DDR3_DQ[5]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[6]" LOC = M2;
#NET "DDR3_DQ[6]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[7]" LOC = M1;
#NET "DDR3_DQ[7]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[8]" LOC = T2;
#NET "DDR3_DQ[8]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[9]" LOC = T1;
#NET "DDR3_DQ[9]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[10]" LOC = U3;
#NET "DDR3_DQ[10]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[11]" LOC = U1;
#NET "DDR3_DQ[11]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[12]" LOC = W3;
#NET "DDR3_DQ[12]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[13]" LOC = W1;
#NET "DDR3_DQ[13]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[14]" LOC = Y2;
#NET "DDR3_DQ[14]" IOSTANDARD = "SSTL15_II";
#NET "DDR3_DQ[15]" LOC = Y1;
#NET "DDR3_DQ[15]" IOSTANDARD = "SSTL15_II";
#---------------------------------------------------------------------------------------------
# IOBs
#---------------------------------------------------------------------------------------------
INST "cmp_gn4124_core/l2p_rdy_t" IOB=FALSE;
#INST "cmp_gn4124_core/l_wr_rdy_t*" IOB=FALSE;
#---------------------------------------------------------------------------------------------
# Terminations
#---------------------------------------------------------------------------------------------
# DDR3
#NET "DDR3_DQ[*]" IN_TERM = NONE;
#NET "DDR3_LDQS_P" IN_TERM = NONE;
#NET "DDR3_LDQS_N" IN_TERM = NONE;
#NET "DDR3_UDQS_P" IN_TERM = NONE;
#NET "DDR3_UDQS_N" IN_TERM = NONE;
#---------------------------------------------------------------------------------------------
# Clock constraints
#---------------------------------------------------------------------------------------------
# GN4124
NET "L_CLKp" TNM_NET = "l_clkp_grp";
TIMESPEC TS_l_clkp = PERIOD "l_clkp_grp" 10 ns HIGH 50%;
NET "P2L_CLKp" TNM_NET = "p2l_clkp_grp";
TIMESPEC TS_p2l_clkp = PERIOD "p2l_clkp_grp" 10 ns HIGH 50%;
NET "P2L_CLKn" TNM_NET = "p2l_clkn_grp";
TIMESPEC TS_p2l_clkn = PERIOD "p2l_clkn_grp" 10 ns HIGH 50%;
# System clock
NET "clk_20m_vcxo_i" TNM_NET = "clk_20m_vcxo_i_grp";
TIMESPEC TS_clk_20m_vcxo_i = PERIOD "clk_20m_vcxo_i_grp" 50 ns HIGH 50%;
# DDR3
#NET "cmp_ddr_ctrl/cmp_ddr_controller/memc3_infrastructure_inst/sys_clk_ibufg" TNM_NET = "SYS_CLK5";
#TIMESPEC "TS_SYS_CLK5" = PERIOD "SYS_CLK5" 3.0 ns HIGH 50 %;
#---------------------------------------------------------------------------------------------
# False Path
#---------------------------------------------------------------------------------------------
# GN4124
NET "l_rst_n" TIG;
NET "cmp_gn4124_core/rst_*" TIG;
# DDR3
#NET "cmp_ddr_ctrl/cmp_ddr_controller/memc3_wrapper_inst/memc3_mcb_raw_wrapper_inst/selfrefresh_mcb_mode" TIG;
#NET "cmp_ddr_ctrl/cmp_ddr_controller/c3_pll_lock" TIG;
#NET "cmp_ddr_ctrl/cmp_ddr_controller/memc3_wrapper_inst/memc3_mcb_raw_wrapper_inst/hard_done_cal" TIG;
#!/usr/bin/python
import sys
import rr
import time
class CCSR:
def __init__(self, bus, base_addr):
self.base_addr = base_addr;
self.bus = bus;
def wr_reg(self, addr, val):
#print(" wr:%.8X reg:%.8X")%(val,(self.base_addr+addr))
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self, addr):
reg = self.bus.iread(0, self.base_addr + addr, 4)
#print(" reg:%.8X value:%.8X")%((self.base_addr+addr), reg)
return reg
def wr_bit(self, addr, bit, value):
reg = self.rd_reg(addr)
if(0==value):
reg &= ~(1<<bit)
else:
reg |= (1<<bit)
self.wr_reg(addr, reg)
def rd_bit(self, addr, bit):
if(self.rd_reg(addr) & (1<<bit)):
return 1
else:
return 0
AAAA AAAAAAAA
AAAA AAAAAAAA
AAAA AAAAAAAA
AAAA AAAAAAAA
AAAA AAAAAAAA
AAAA AAAAAAAA
#!/usr/bin/python
import sys
import rr
import time
import csr
class CGN4124:
# Host registers (BAR12), for DMA items storage
HOST_BAR = 0xC
HOST_DMA_CARRIER_START_ADDR = 0x00
HOST_DMA_HOST_START_ADDR_L = 0x04
HOST_DMA_HOST_START_ADDR_H = 0x08
HOST_DMA_LENGTH = 0x0C
HOST_DMA_NEXT_ITEM_ADDR_L = 0x10
HOST_DMA_NEXT_ITEM_ADDR_H = 0x14
HOST_DMA_ATTRIB = 0x18
# GN4124 chip registers (BAR4)
GN4124_BAR = 0x4
R_CLK_CSR = 0x808
R_INT_CFG0 = 0x820
R_GPIO_DIR_MODE = 0xA04
R_GPIO_INT_MASK_CLR = 0xA18
R_GPIO_INT_MASK_SET = 0xA1C
R_GPIO_INT_STATUS = 0xA20
R_GPIO_INT_VALUE = 0xA28
CLK_CSR_DIVOT_MASK = 0x3F0
INT_CFG0_GPIO = 15
GPIO_INT_SRC = 8
# GN4124 core registers (BAR0)
R_DMA_CTL = 0x00
R_DMA_STA = 0x04
R_DMA_CARRIER_START_ADDR = 0x08
R_DMA_HOST_START_ADDR_L = 0x0C
R_DMA_HOST_START_ADDR_H = 0x10
R_DMA_LENGTH = 0x14
R_DMA_NEXT_ITEM_ADDR_L = 0x18
R_DMA_NEXT_ITEM_ADDR_H = 0x1C
R_DMA_ATTRIB = 0x20
DMA_CTL_START = 0
DMA_CTL_ABORT = 1
DMA_CTL_SWAP = 2
DMA_STA = ['Idle','Done','Busy','Error','Aborted']
DMA_ATTRIB_LAST = 0
DMA_ATTRIB_DIR = 1
def rd_reg(self, bar, addr):
return self.bus.iread(bar, addr, 4)
def wr_reg(self, bar, addr, value):
self.bus.iwrite(bar, addr, 4, value)
def __init__(self, bus, csr_addr):
self.bus = bus
self.dma_csr = csr.CCSR(bus, csr_addr)
self.dma_item_cnt = 0
# Get page list
self.pages = self.bus.getplist()
# Shift by 12 to get the 32-bit physical addresses
self.pages = [addr << 12 for addr in self.pages]
self.set_interrupt_config()
# Enable interrupt from gn4124
self.bus.irqena()
# Set local bus frequency
def set_local_bus_freq(self, freq):
# freq in MHz
# LCLK = (25MHz*(DIVFB+1))/(DIVOT+1)
# DIVFB = 31
# DIVOT = (800/LCLK)-1
divot = int(round((800/freq)-1,0))
#print '%d' % divot
data = 0xe001f00c + (divot << 4)
#print '%.8X' % data
#print 'Set local bus freq to %dMHz' % int(round(800/(divot+1),0))
self.wr_reg(self.GN4124_BAR, self.R_CLK_CSR, data)
# Get local bus frequency
# return: frequency in MHz
def get_local_bus_freq(self):
reg = self.rd_reg(self.GN4124_BAR, self.R_CLK_CSR)
divot = ((reg & self.CLK_CSR_DIVOT_MASK)>>4)
return (800/(divot + 1))
# Get physical addresses of the pages allocated to GN4124
def get_physical_addr(self):
return self.pages
# Wait for interrupt
def wait_irq(self):
# Add here reading of the interrupt source (once the irq core will be present)
return self.bus.irqwait()
# GN4124 interrupt configuration
def set_interrupt_config(self):
# Set interrupt line from FPGA (GPIO8) as input
self.wr_reg(self.GN4124_BAR, self.R_GPIO_DIR_MODE, (1<<self.GPIO_INT_SRC))
# Set interrupt mask for all GPIO except for GPIO8
self.wr_reg(self.GN4124_BAR, self.R_GPIO_INT_MASK_SET, ~(1<<self.GPIO_INT_SRC))
# Make sure the interrupt mask is cleared for GPIO8
self.wr_reg(self.GN4124_BAR, self.R_GPIO_INT_MASK_CLR, (1<<self.GPIO_INT_SRC))
# Interrupt on rising edge of GPIO8
self.wr_reg(self.GN4124_BAR, self.R_GPIO_INT_VALUE, (1<<self.GPIO_INT_SRC))
# GPIO as interrupt 0 source
self.wr_reg(self.GN4124_BAR, self.R_INT_CFG0, (1<<self.INT_CFG0_GPIO))
# Get DMA controller status
def get_dma_status(self):
reg = self.dma_csr.rd_reg(self.R_DMA_STA)
if(reg > len(self.DMA_STA)):
print("DMA status register : %.8X") % reg
raise Exception('Invalid DMA status')
else:
return self.DMA_STA[reg]
# Configure DMA byte swapping
# 0 = A1 B2 C3 D4 (straight)
# 1 = B2 A1 D4 C3 (swap bytes in words)
# 2 = C3 D4 A1 B2 (swap words)
# 3 = D4 C3 B2 A1 (invert bytes)
def set_dma_swap(self, swap):
if(swap > 3):
raise Exception('Invalid swapping configuration : %d') % swap
else:
self.dma_csr.wr_reg(self.R_CTL, (swap << self.DMA_CTL_SWAP))
# Add DMA item (first item is on the board, the following in the host memory)
# carrier_addr, host_addr, length and next_item_addr are in bytes
# dma_dir = 1 -> PCIe to carrier
# dma_dir = 0 -> carrier to PCIe
# dma_last = 0 -> last item in the transfer
# dma_last = 1 -> more item in the transfer
# Only supports 32-bit host address
def add_dma_item(self, carrier_addr, host_addr, length, dma_dir, last_item):
if(0 == self.dma_item_cnt):
# write the first DMA item in the carrier
self.dma_csr.wr_reg(self.R_DMA_CARRIER_START_ADDR, carrier_addr)
self.dma_csr.wr_reg(self.R_DMA_HOST_START_ADDR_L, (host_addr & 0xFFFFFFFF))
self.dma_csr.wr_reg(self.R_DMA_HOST_START_ADDR_H, (host_addr >> 32))
self.dma_csr.wr_reg(self.R_DMA_LENGTH, length)
self.dma_csr.wr_reg(self.R_DMA_NEXT_ITEM_ADDR_L, (self.pages[0] & 0xFFFFFFFF))
self.dma_csr.wr_reg(self.R_DMA_NEXT_ITEM_ADDR_H, 0x0)
attrib = (dma_dir << self.DMA_ATTRIB_DIR) + (last_item << self.DMA_ATTRIB_LAST)
self.dma_csr.wr_reg(self.R_DMA_ATTRIB, attrib)
else:
# write nexy DMA item(s) in host memory
# uses page 0 to store DMA items
# current and next item addresses are automatically set
current_item_addr = (self.dma_item_cnt-1)*0x20
next_item_addr = (self.dma_item_cnt)*0x20
self.wr_reg(self.HOST_BAR, self.HOST_DMA_CARRIER_START_ADDR + current_item_addr, carrier_addr)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_HOST_START_ADDR_L + current_item_addr, host_addr)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_HOST_START_ADDR_H + current_item_addr, 0x0)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_LENGTH + current_item_addr, length)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_NEXT_ITEM_ADDR_L + current_item_addr,
self.pages[0] + next_item_addr)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_NEXT_ITEM_ADDR_H + current_item_addr, 0x0)
attrib = (dma_dir << self.DMA_ATTRIB_DIR) + (last_item << self.DMA_ATTRIB_LAST)
self.wr_reg(self.HOST_BAR, self.HOST_DMA_ATTRIB + current_item_addr, attrib)
self.dma_item_cnt += 1
# Start DMA transfer
def start_dma(self):
self.dma_item_cnt = 0
self.dma_csr.wr_bit(self.R_DMA_CTL, self.DMA_CTL_START, 1)
# The following two lines should be removed
# when the GN4124 vhdl core will implement auto clear of start bit
#while(('Idle' == self.get_dma_status()) or
# ('Busy' == self.get_dma_status())):
# pass
self.dma_csr.wr_bit(self.R_DMA_CTL, self.DMA_CTL_START, 0)
# Abort DMA transfer
def abort_dma(self):
self.dma_item_cnt = 0
self.dma_csr.wr_bit(self.R_DMA_CTL, self.DMA_CTL_ABORT, 1)
# The following two lines should be removed
# when the GN4124 vhdl core will implement auto clear of start bit
while('Aborted' != self.get_dma_status()):
pass
self.dma_csr.wr_bit(self.R_DMA_CTL, self.DMA_CTL_ABORT, 0)
# Get memory page
def get_memory_page(self, page_nb):
data = []
for i in range(2**10):
data.append(self.rd_reg(self.HOST_BAR, (page_nb<<12)+(i<<2)))
return data
# Set memory page
def set_memory_page(self, page_nb, pattern):
for i in range(2**10):
self.wr_reg(self.HOST_BAR, (page_nb<<12)+(i<<2), pattern)
#!/usr/bin/python
import sys
import rr
import time
class COpenCoresI2C:
# OpenCores I2C registers description
R_PREL = 0x0
R_PREH = 0x4
R_CTR = 0x8
R_TXR = 0xC
R_RXR = 0xC
R_CR = 0x10
R_SR = 0x10
CTR_EN = (1<<7)
CR_STA = (1<<7)
CR_STO = (1<<6)
CR_RD = (1<<5)
CR_WR = (1<<4)
CR_ACK = (1<<3)
SR_RXACK = (1<<7)
SR_TIP = (1<<1)
def wr_reg(self, addr, val):
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self,addr):
return self.bus.iread(0, self.base_addr + addr, 4)
# Function called during object creation
# bus = host bus (PCIe, VME, etc...)
# base_addr = I2C core base address
# prescaler = SCK prescaler, prescaler = (Fsys/(5*Fsck))-1
def __init__(self, bus, base_addr, prescaler):
self.bus = bus
self.base_addr = base_addr
self.wr_reg(self.R_CTR, 0)
#print("prescaler: %.4X") % prescaler
self.wr_reg(self.R_PREL, (prescaler & 0xff))
#print("PREL: %.2X") % self.rd_reg(self.R_PREL)
self.wr_reg(self.R_PREH, (prescaler >> 8))
#print("PREH: %.2X") % self.rd_reg(self.R_PREH)
self.wr_reg(self.R_CTR, self.CTR_EN)
#print("CTR: %.2X") % self.rd_reg(self.R_CTR)
if(not(self.rd_reg(self.R_CTR) & self.CTR_EN)):
print "Warning! I2C core is not enabled!"
def wait_busy(self):
while(self.rd_reg(self.R_SR) & self.SR_TIP):
pass
def start(self, addr, write_mode):
addr = addr << 1
if(write_mode == False):
addr = addr | 1
self.wr_reg(self.R_TXR, addr)
#print("R_TXR: %.2X") % self.rd_reg(self.R_TXR)
self.wr_reg(self.R_CR, self.CR_STA | self.CR_WR)
self.wait_busy()
if(self.rd_reg(self.R_SR) & self.SR_RXACK):
raise Exception('No ACK upon address (device 0x%x not connected?)' % addr)
return "nack"
else:
return "ack"
def write(self, data, last):
self.wr_reg(self.R_TXR, data)
cmd = self.CR_WR
if(last):
cmd = cmd | self.CR_STO
self.wr_reg(self.R_CR, cmd)
self.wait_busy()
if(self.rd_reg(self.R_SR) & self.SR_RXACK):
raise Exception('No ACK upon write')
def read(self, last):
cmd = self.CR_RD
if(last):
cmd = cmd | self.CR_STO | self.CR_ACK
self.wr_reg(self.R_CR, cmd)
self.wait_busy()
return self.rd_reg(self.R_RXR)
def scan(self):
for i in range(0,128):
addr = i << 1
addr |= 1
self.wr_reg(self.R_TXR, addr)
self.wr_reg(self.R_CR, self.CR_STA | self.CR_WR)
self.wait_busy()
if(not(self.rd_reg(self.R_SR) & self.SR_RXACK)):
print("Device found at address: %.2X") % i
self.wr_reg(self.R_TXR, 0)
self.wr_reg(self.R_CR, self.CR_STO | self.CR_WR)
self.wait_busy()
##########################################
# Usage example
#gennum = rr.Gennum();
#i2c = COpenCoresI2C(gennum, 0x80000, 500);
#i2c.scan()
#!/usr/bin/python
import sys
import rr
import time
class COpenCoresSPI:
R_RX = [0x00, 0x04, 0x08, 0x0C]
R_TX = [0x00, 0x04, 0x08, 0x0C]
R_CTRL = 0x10
R_DIV = 0x14
R_SS = 0x18
LGH_MASK = (0x7F)
CTRL_GO = (1<<8)
CTRL_BSY = (1<<8)
CTRL_RXNEG = (1<<9)
CTRL_TXNEG = (1<<10)
CTRL_LSB = (1<<11)
CTRL_IE = (1<<12)
CTRL_ASS = (1<<13)
DIV_MASK = (0xFFFF)
SS_SEL = [0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40]
conf = 0x0
def wr_reg(self, addr, val):
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self, addr):
return self.bus.iread(0, self.base_addr + addr, 4)
def __init__(self, bus, base_addr, divider):
self.bus = bus;
self.base_addr = base_addr;
self.wr_reg(self.R_DIV, (divider & self.DIV_MASK));
# default configuration
self.conf = self.CTRL_ASS | self.CTRL_TXNEG
def wait_busy(self):
while(self.rd_reg(self.R_CTRL) & self.CTRL_BSY):
pass
def config(self, ass, rx_neg, tx_neg, lsb, ie):
self.conf = 0
if(ass):
self.conf |= self.CTRL_ASS
if(tx_neg):
self.conf |= self.CTRL_TXNEG
if(rx_neg):
self.conf |= self.CTRL_RXNEG
if(lsb):
self.conf |= self.CTRL_LSB
if(ie):
self.conf |= self.CTRL_IE
# slave = slave number (0 to 7)
# data = byte data array to send, in case if read fill with dummy data of the right size
def transaction(self, slave, data):
txrx = [0x00000000, 0x00000000, 0x00000000, 0x00000000]
for i in range(0,len(data)):
txrx[i/4] += (data[i]<<((i%4)*8))
#print("tx[%d]=%.8X data[%d]=%.2X") %(i,txrx[i/4],i,data[i])
for i in range(0, len(txrx)):
self.wr_reg(self.R_TX[i], txrx[i])
self.wr_reg(self.R_SS, self.SS_SEL[slave])
self.wr_reg(self.R_CTRL, (self.LGH_MASK & (len(data)<<3)) | self.CTRL_GO | self.conf)
self.wait_busy()
for i in range(0, len(txrx)):
txrx[i] = self.rd_reg(self.R_RX[i])
#print("rx[%d]=%.8X") %(i,txrx[i])
return txrx
#gennum = rr.Gennum();
#spi = COpenCoresSPI(gennum, 0x80000, 500);
#!/acc/src/dsc/drivers/cohtdrep/siglesia/Python-2.7/python
import sys
import rr
import time
import os
from tpsexcept import *
BASE_GPIO = 0x40000
BASE_MINIC = 0xc0000
GPIO_CODR = 0x0
GPIO_SODR = 0x4
GPIO_PSR = 0xc
class COpenCoresI2C:
R_PREL = 0x0
R_PREH = 0x4
R_CTR = 0x8
R_TXR = 0xC
R_RXR = 0xC
R_CR = 0x10
R_SR = 0x10
CTR_EN = (1<<7)
CR_STA = (1<<7)
CR_STO = (1<<6)
CR_WR = (1<<4)
CR_RD = (1<<5)
CR_NACK = (1<<3)
SR_RXACK = (1<<7)
SR_TIP = (1<<1)
def wr_reg(self, addr, val):
self.bus.iwrite(0, self.base + addr, 4, val)
def rd_reg(self,addr):
return self.bus.iread(0, self.base + addr, 4)
def __init__(self, bus, base, prescaler):
self.bus = bus;
self.base =base;
self.wr_reg(self.R_CTR, 0);
self.wr_reg(self.R_PREL, (prescaler & 0xff))
self.wr_reg(self.R_PREH, (prescaler >> 8))
self.wr_reg(self.R_CTR, self.CTR_EN);
def wait_busy(self):
while(self.rd_reg(self.R_SR) & self.SR_TIP):
pass
def start(self, addr, write_mode):
addr = addr << 1
if(write_mode == False):
addr = addr | 1;
self.wr_reg(self.R_TXR, addr);
self.wr_reg(self.R_CR, self.CR_STA | self.CR_WR);
self.wait_busy()
if(self.rd_reg(self.R_SR) & self.SR_RXACK):
raise Exception('No ACK upon address (device 0x%x not connected?)' % addr)
def write(self, data, last):
self.wr_reg(self.R_TXR, data);
cmd = self.CR_WR;
if(last):
cmd = cmd | self.CR_STO;
self.wr_reg(self.R_CR, cmd);
self.wait_busy();
if(self.rd_reg(self.R_SR) & self.SR_RXACK):
raise Exception('No ACK upon write')
def read(self, last):
cmd = self.CR_RD;
if(last):
cmd = cmd | self.CR_STO | self.CR_NACK;
self.wr_reg(self.R_CR, cmd);
self.wait_busy();
return self.rd_reg(self.R_RXR);
class ADC_AD7997:
CONVER_R = 0x00;
CONFIG_R = 0x02;
CH8 = (1 << 11);
CH7 = (1 << 10);
CH6 = (1 << 9);
CH5 = (1 << 8);
CH4 = (1 << 7);
CH3 = (1 << 6);
CH2 = (1 << 5);
CH1 = (1 << 4);
def __init__(self, i2c, addr):
self.i2c = i2c;
self.addr = addr;
def wr_reg16(self, addr, value):
self.i2c.start(self.addr, True);
self.i2c.write(addr, False);
tmp = (value >> 8) & 0xFF;
self.i2c.write(value, False);
tmp = value & 0xFF;
self.i2c.write(value, True)
def wr_reg8(self, addr, value):
self.i2c.start(self.addr, True); # write cycle
self.i2c.write(addr, False);
self.i2c.write(value, True);
def rd_reg16(self, addr):
self.i2c.start(self.addr, True);
self.i2c.write(addr, False);
self.i2c.start(self.addr, False);
tmp_MSB = self.i2c.read(False);
tmp_LSB = self.i2c.read(True);
value = (tmp_MSB << 8) | tmp_LSB;
return value;
def rd_reg8(self, addr):
self.i2c.start(self.addr, True);
self.i2c.write(addr, False);
self.i2c.start(self.addr, False);
return self.i2c.read(True);
def adc_value(value) :
return str(2.495 * (0x3FF & (value >> 2)) / 1024); # 10 bits
def main ():
bitstream_name = 'test_voltage_fmc.bin'
os.system('/user/siglesia/vhdl/gennum/fpga_loader/gnurabbit/user/fpga_loader_test /user/siglesia/vhdl/gennum/fpga_loader/gnurabbit/user/'+bitstream_name);
time.sleep(1);
gennum = rr.Gennum();
i2c = COpenCoresI2C(gennum, 0x40000, 99); # Prescaler value calculated using 50 MHz clock
# The address of the AD7997 is 0x23, pin 15 connected to GND.
adc = ADC_AD7997(i2c, 0x23);
value8 = adc_value(adc.rd_reg16(0xF0));
value7 = adc_value(adc.rd_reg16(0xE0));
value6 = adc_value(adc.rd_reg16(0xD0));
value5 = adc_value(adc.rd_reg16(0xC0));
value4 = adc_value(adc.rd_reg16(0xB0));
value3 = adc_value(adc.rd_reg16(0xA0));
value2 = adc_value(adc.rd_reg16(0x90));
value1 = adc_value(adc.rd_reg16(0x80));
# Check the values of the ADC.
if(float(value8) < 2.0) :
raise TpsError ("Error in VS_VADJ, value " + value8 + " < 2.0")
print "VS_VADJ = " + value8
if(float(value7) < 2.0) :
raise TpsError ("Error in VS_P12V_x, value " + value7 + " < 2.0")
print "VS_P12V_x = " + value7
if(float(value6) < 1.57) :
raise TpsError ("Error in VS_P3V3_x, value " + value6 + " < 1.57")
print "VS_P3V3_x = " + value6
if(float(value5) < 2.52) :
raise TpsWarning ("Error in P5V_BI, value " + value5 + " < 2.52")
print "P5V_BI = " + value5
if(float(value4) > 2.0) :
raise TpsWarning ("Error in M2V_BI, value " + value4 + " > 2.0")
print "M2V_BI = " + value4
if(float(value3) > 2.28) :
raise TpsWarning ("Error in M5V2_BI, value " + value3 + " > 2.28")
print "M5V2_BI = " + value3
if(float(value2) > 2.4) :
raise TpsWarning ("Error in M12V_BI, value " + value2 + " > 2.4")
print "M12V_BI = " + value2
if(float(value1) < 2.0) :
raise TpsWarning( "Error in P12V_BI, value " + value1 + " < 2.0")
print "P12V_BI = " + value1
#!/acc/src/dsc/drivers/cohtdrep/siglesia/Python-2.7/python
# It needs Python 2.7 or higher!
import sys
import rr
import time
import os
class EEPROM_GENNUM:
LB_CTL = 0x804;
TWI_CTRL = 0x900;
TWI_STATUS = 0x904;
TWI_IRT_STATUS = 0x910;
I2C_ADDR = 0x908;
I2C_DATA = 0x90C;
def __init__ (self, gennum):
self.gennum = gennum;
def i2c_read(self, i2c_addr, offset, length, read_data):
"""Read from I2C
"""
# Shut off EEPROM_INIT state machine if not done so */
tmp = self.gennum.iread(4, self.LB_CTL, 4)
#print 'LB_CTL=%.8X' % tmp
if tmp & 0x10000 == 0:
tmp |= 0x10000
self.gennum.iwrite(4, self.LB_CTL, 4, tmp)
# Init I2C clock Fpci/(22*Fscl)=(DIV_A+1)*(DIV_B+1)
# CLR_FIFO=1, SLVMON=0, HOLD=0, ACKEN=1, NEA=1, MS=1, RW=0
self.gennum.iwrite(4, self.TWI_CTRL, 4, 0x384E)
# Read back from register to guarantee the mode change
tmp = self.gennum.iread(4, self.TWI_CTRL, 4)
# Wait until I2C bus is idle
i=2000000
while i > 0:
i-=1
tmp = self.gennum.iread(4, self.TWI_STATUS, 4)
#print 'TWI_STATUS=%.8X' % tmp
#time.sleep(.5)
if tmp & 0x100 == 0:
#print 'I2C bus is idle'
break
# Read to clear TWI_IRT_STATUS
tmp = self.gennum.iread(4, self.TWI_IRT_STATUS, 4)
# Write word offset
tmp=(0xFF & offset)
self.gennum.iwrite(4, self.I2C_DATA, 4, tmp)
# Write device address
tmp=(0x7F & i2c_addr)
self.gennum.iwrite(4, self.I2C_ADDR, 4, tmp)
# Wait for transfer complete status
i=2000000
while i > 0:
tmp = self.gennum.iread(4, self.TWI_IRT_STATUS, 4)
if tmp & 0x1:
break
elif tmp & 0xC:
raise TpsError ('NACK detected or TIMEOUT, IRT_STATUS = 0x%x!!' % tmp)
sys.exit()
i-=1
if i == 0:
raise TpsError ('ERROR, completion status not detected!!')
sys.exit()
# Change to read mode
self.gennum.iwrite(4, self.TWI_CTRL, 4, 0x384F)
# Perform sequential page read from the start address
error_flag=0
total_transfer=0
while length > 0 and error_flag == 0:
# Transfer bigger than I2C fifo (8 bytes) are split
if length > 8:
transfer_len = 8
length -= 8
else:
transfer_len = length
length = 0
# Update expected receive data size
self.gennum.iwrite(4, 0x914, 4, transfer_len)
# Write device address
self.gennum.iwrite(4, self.I2C_ADDR, 4, (0x7F & i2c_addr))
# Wait until transfer is completed
j=2000000
while j > 0:
tmp = self.gennum.iread(4, self.TWI_IRT_STATUS, 4)
if tmp & 0x1:
#print 'Transfer completed'
break
j-=1
if j == 0:
error_flag = 1
raise TpsWarning('ERROR, completion status not detected!!')
# Read data from fifo
while transfer_len > 0:
read_data.append(0xFF & self.gennum.iread(4, self.I2C_DATA, 4))
transfer_len-=1
total_transfer+=1
# End of read
return total_transfer
#
def i2c_write(self, i2c_addr, offset, length, write_data):
"""Write to I2C
"""
# Shut off EEPROM_INIT state machine if not done so */
tmp = self.gennum.iread(4, self.LB_CTL, 4)
if tmp & 0x10000 == 0:
tmp |= 0x10000
self.gennum.iwrite(4, self.LB_CTL, 4, tmp)
# Read to clear TWI_IRT_STATUS
self.gennum.iread(4, self.TWI_IRT_STATUS, 4)
# Read to clear TWI_STATUS
self.gennum.iread(4, self.TWI_STATUS, 4)
# Init I2C clock Fpci/(22*Fscl)=(DIV_A+1)*(DIV_B+1)
# CLR_FIFO=1, SLVMON=0, HOLD=0, ACKEN=1, NEA=1, MS=1, RW=0
self.gennum.iwrite(4, self.TWI_CTRL, 4, 0x384E)
# Read back from register to guarantee the mode change
self.gennum.iread(4, self.TWI_CTRL, 4)
# Wait until I2C bus is idle
i=2000000
while i > 0:
i-=1
tmp = self.gennum.iread(4, self.TWI_STATUS, 4)
if tmp & 0x100 == 0:
break
# Perform sequential page write from the start address
error_flag=0
total_transfer=0
while length > 0 and error_flag == 0:
# Write word offset
self.gennum.iwrite(4, self.I2C_DATA, 4, (0xFF & offset))
i=6 # fifo size - 2
while i > 0 and length > 0:
tmp = (0xFF & write_data[total_transfer])
self.gennum.iwrite(4, self.I2C_DATA, 4, tmp)
total_transfer+=1
offset+=1
i-=1
length-=1
# Reaches the page write address boundary, thus need to start
# the offset at the next page (page size = 8)
if offset & 7 == 0:
break
# Write device address
self.gennum.iwrite(4, self.I2C_ADDR, 4, (0x7F & i2c_addr))
#print 'Write I2C address'
# Wait until transfer is completed
i=2000000
while i > 0:
tmp = self.gennum.iread(4, self.TWI_IRT_STATUS, 4)
time.sleep(0.01)
if tmp & 0x1:
#print 'Transfer completed!'
tmp = self.gennum.iread(4, 0x914, 4)
#print 'TR_SIZE=%d' % tmp
break
elif tmp & 0xC:
raise TpsWarning ('NACK detected or TIMEOUT, IRT_STATUS = 0x%x!!' % tmp)
tmp = self.gennum.iread(4, 0x914, 4)
return total_transfer
i-=1
return total_transfer
def eeprom_dump_to_screen(self):
""" Dump the content of the EEPROM to the screen
"""
eeprom_data=[]
nb_rec=42
self.i2c_read(0x56, 0, nb_rec*6, eeprom_data)
for i in range(0,nb_rec*6,6):
addr=eeprom_data[i] + (eeprom_data[i+1] << 8)
data=eeprom_data[i+2] + (eeprom_data[i+3] << 8) + (eeprom_data[i+4] << 16) + (eeprom_data[i+5] << 24)
if addr == 0xFFFF:
break
print '[%.2d]=%.4X %.8X' %(i/6,addr,data)
print ''
for i in range(0,len(eeprom_data)):
print '[%.2d]=%.2X' %(i,eeprom_data[i])
if eeprom_data[i+1] == 0xFF and eeprom_data[i+2] == 0xFF:
break
return 0
def eeprom_dump_to_file(self, file_name):
"""Dump the content of the EEPROM to a file
"""
if file_name == "":
file_name = "eeprom.dat"
file = open(file_name, 'w+')
eeprom_data=[]
nb_rec=100
self.i2c_read(0x56, 0, nb_rec*6, eeprom_data)
for i in range(0,nb_rec*6,6):
addr=eeprom_data[i] + (eeprom_data[i+1] << 8)
data=eeprom_data[i+2] + (eeprom_data[i+3] << 8) + (eeprom_data[i+4] << 16) + (eeprom_data[i+5] << 24)
print >>file,'%.4X %.8X' %(addr,data)
if addr == 0xFFFF:
break
return 0
def file_dump_to_screen(self, file_name):
"""Dump the content of a file to the screen
"""
if file_name == "":
file_name = "eeprom.dat"
file = open(file_name, 'r+')
file_data=[]
for line in file:
addr,data = line.split()
print addr+' '+data
for i in range(2,0,-1):
#print addr[(i-1)*2:(i-1)*2+2]
file_data.append(int(addr[(i-1)*2:(i-1)*2+2],16))
for i in range(4,0,-1):
#print data[(i-1)*2:(i-1)*2+2]
file_data.append(int(data[(i-1)*2:(i-1)*2+2],16))
print ''
for i in range(0,len(file_data)):
print '[%.2d]=%.2X' %(i,file_data[i])
return 0
def file_dump_to_eeprom(self, file_name):
"""Dump the content of a file to the EEPROM
"""
if file_name == "":
file_name = "eeprom.dat"
file = open(file_name, 'r+')
file_data=[]
# Read file
for line in file:
addr,data = line.split()
for i in range(2,0,-1):
#print addr[(i-1)*2:(i-1)*2+2]
file_data.append(int(addr[(i-1)*2:(i-1)*2+2],16))
for i in range(4,0,-1):
#print data[(i-1)*2:(i-1)*2+2]
file_data.append(int(data[(i-1)*2:(i-1)*2+2],16))
# Write EEPROM
#print len(file_data)
#print file_data
written = self.i2c_write(0x56, 0, len(file_data), file_data)
if written == len(file_data):
print 'EEPROM written with '+file_name+' content!'
else :
raise TpsUser ("ERROR writting to the EEPROM: Written lenght doesn't correspond with the length of the file.")
return 0
def compare_eeprom_with_file(self, file_name):
"""Compare the content of a file to the EEPROM
"""
if file_name == "":
file_name = "eeprom.dat"
file = open(file_name, 'r+')
file_data=[]
eeprom_data=[]
nb_rec=0
# Read file
for line in file:
addr,data = line.split()
for i in range(2,0,-1):
#print addr[(i-1)*2:(i-1)*2+2]
file_data.append(int(addr[(i-1)*2:(i-1)*2+2],16))
for i in range(4,0,-1):
#print data[(i-1)*2:(i-1)*2+2]
file_data.append(int(data[(i-1)*2:(i-1)*2+2],16))
nb_rec+=1
# Read EEPROM
self.i2c_read(0x56, 0, (nb_rec+1)*6, eeprom_data)
# Compare
for i in range(0,len(file_data)):
if file_data[i] == eeprom_data[i]:
print 'EEPROM= %.2X, FILE= %.2X => OK' %(eeprom_data[i],file_data[i])
else :
raise TpsUser('EEPROM= %.2X, FILE= %.2X => ERROR' %(eeprom_data[i],file_data[i]))
def main ():
bitstream_name = 'test_ddr.bin'
os.system('/user/siglesia/vhdl/gennum/fpga_loader/gnurabbit/user/fpga_loader_test /user/siglesia/vhdl/gennum/fpga_loader/gnurabbit/user/'+bitstream_name);
time.sleep(1);
gennum = rr.Gennum();
eeprom = EEPROM_GENNUM(gennum);
# eeprom.eeprom_dump_to_screen();
eeprom.eeprom_dump_to_file("/tmp/eeprom.dat"); #
# f_test = open("/tmp/eeprom_test.dat","w+");
# with open("/tmp/eeprom.dat") as f:
# for line in f:
# f_test.write(line);
# f.close();
# f_test.seek(-14, os.SEEK_END);
# f_test.write("FFFF FFFFFFFF");
# f_test.close();
eeprom.file_dump_to_eeprom("test/eeprom_test_A.dat");
eeprom.eeprom_dump_to_screen();
eeprom.compare_eeprom_with_file("test/eeprom_test_A.dat");
eeprom.file_dump_to_eeprom("/tmp/eeprom.dat");
eeprom.eeprom_dump_to_screen();
eeprom.compare_eeprom_with_file("/tmp/eeprom.dat");
#!/acc/src/dsc/drivers/cohtdrep/siglesia/Python-2.7/python
# It needs Python 2.7 or higher!
import sys
import rr
import time
import os
from ctypes import *
from tpsexcept import *
class CGennumFlash :
GENNUM_FLASH = 1;
GENNUM_FPGA = 2;
FPGA_FLASH = 3;
def __init__ (self, bus):
self.bus = bus;
self.lib = cdll.LoadLibrary("libfpga_loader.so");
self.lib.rr_init();
self.lib.gpio_init();
def main():
gennum = rr.Gennum();
flash = CGennumFlash(gennum);
start = time.time();
flash.lib.gpio_bootselect(flash.GENNUM_FLASH);
version = hex(flash.lib.flash_read_id());
if (version != "0x202016"):
raise TpsError('Error: version of the flash is not correct: ' + version);
# Load a new firmware to the Flash memory.
print "Starting the process to load a FW into Flash memory"
flash.lib.load_mcs_to_flash("./test_flash.bin");
time.sleep(1);
print "Forcing to load FW from Flash memory to FPGA"
# Force the FPGA to load the FW from the Flash memory
flash.lib.force_load_fpga_from_flash();
finish = time.time();
print "Time elapsed: " + str(finish - start) + " seconds"
ask = "";
tmp_stdout = sys.stdout;
sys.stdout = sys.__stdout__;
tmp_stdin = sys.stdin;
sys.stdin = sys.__stdin__;
while ((ask != "Y") and (ask != "N")) :
ask = raw_input("Are the LEDs blinking? [Y/N]")
sys.stdout = tmp_stdout;
sys.stdin = tmp_stdin;
if (ask == "N") :
raise TpsError("Error loading FW through the Flash memory");
#!/acc/src/dsc/drivers/cohtdrep/siglesia/Python-2.7/python
# coding: utf8
import sys
import rr
import random
import time
import spi
import i2c
import gn4124
import os
GN4124_CSR = 0x0
def main():
bitstream_name = 'test_ddr.bin'
os.system('/user/siglesia/vhdl/gennum/fpga_loader/gnurabbit/user/fpga_loader_test /user/siglesia/vhdl/gennum/fpga_loader/gnurabbit/user/'+bitstream_name);
time.sleep(1);
# Objects declaration
spec = rr.Gennum() # bind to the SPEC board
gennum = gn4124.CGN4124(spec, GN4124_CSR)
print '\n### Configuration ###'
# Set local bus frequency
gennum.set_local_bus_freq(160)
print("GN4124 local bus frequency: %d") % gennum.get_local_bus_freq()
print '\nStart test'
# Get host memory pages physical address
pages = gennum.get_physical_addr()
num_addr_lines = 64;
num_data_lines = 16;
if (len(pages) < (num_addr_lines + 2)) :
raise Exception("Not enough pages");
# Clear memory pages
gennum.set_memory_page(0, 0x0)
gennum.set_memory_page(1, 0xBABEFACE)
gennum.set_memory_page(2, 0x0)
dma_length = 0x400 # DMA length in bytes
t1 = time.time();
print "Test Address lines"
error = 0;
for i in range(num_addr_lines) :
if (i==0) :
continue;
for j in range(num_addr_lines/2) :
t3 = time.time();
if (i != 2*j) :
gennum.add_dma_item((1 << 2*j), pages[2], dma_length, 1, 1)
gennum.add_dma_item((1 << 2*j), pages[3+2*j], dma_length, 0, 0)
gennum.start_dma()
gennum.wait_irq()
if ((2*j+1) != i) :
gennum.add_dma_item((1 << (2*j+1)), pages[2], dma_length, 1, 1)
gennum.add_dma_item((1 << (2*j+1)), pages[3+(2*j+1)], dma_length, 0, 0)
gennum.start_dma()
gennum.wait_irq()
gennum.add_dma_item((1 << i), pages[1], dma_length, 1, 1)
gennum.add_dma_item((1 << i), pages[3+i], dma_length, 0, 0)
gennum.start_dma()
gennum.wait_irq()
page_data = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
for j in range(num_addr_lines):
page_data[j] = gennum.get_memory_page(3+j)
if (j == i) :
if (page_data[j][0] != 0xDEADFACE):
print("\n### Compare error @ addr line:0x%.8X wr:0x%.8X rd:0x%.8X") % (j,0xDEADFACE, page_data[j][0])
error = 1;
else :
if(page_data[j][0] != 0x0):
print("\n### Compare error @ addr line:0x%.8X wr:0x%.8X rd:0x%.8X") % (j,0x0, page_data[j][0])
error = 1;
if (error) :
print "RESULT: [FAILED]"
else :
print "RESULT: [OK]"
print "Test Data lines"
error = 0;
for i in range(num_data_lines) :
gennum.set_memory_page(1, (1<<i))
gennum.add_dma_item(0, pages[1], dma_length, 1, 1)
gennum.add_dma_item(0, pages[2], dma_length, 0, 0)
gennum.start_dma()
gennum.wait_irq()
page_data = gennum.get_memory_page(2);
if (page_data[0] != (1 << i)) :
print("### Compare error @ data line:0x%.8X wr:0x%.8X rd:0x%.8X") % (i,(1 << i), page_data[0])
error = 1;
if (error) :
print "RESULT: [FAILED]"
else :
print "RESULT: [OK]"
t2 = time.time();
print 'End of test'
print 'Time DDR test: ' + str(t2-t1) + ' seconds'
#!/usr/bin/python
import sys
import os
import rr
import time
import math
import os.path
from tpsexcept import * # jdgc
""" SPEC test for two clock domains.
This tests checks the 20 MHz system clock and the output of the CDC5662 PLL
"""
# jdgc: path dependencies
firmware_loader_path = 'tests/fpga_loader_test '
test_clk_path = './log/test_clk/' # jdgc
clk_test_bitstream = 'tests/test_clk.bin'
# test_clk_path = '/tmp'
# firmware_loader_path = 'fpga_loader_test '
# clk_test_bitstream = 'test_clk.bin'
TEST_TIME_SLOW = 0.25
TOTAL_OF_TESTS = 10
GENNUM_ADDRESS_SPACE = 0x100000
VHDL_WB_SLAVES = 3
VHDL_WB_SLAVE_NUMBER_COUNTER = 0
VHDL_WB_SLAVE_NUMBER_SPI = 1
def wb_addr(vhdl_wb_slave_number):
return (vhdl_wb_slave_number+1) * (GENNUM_ADDRESS_SPACE >> int(math.ceil(math.log(VHDL_WB_SLAVES + 1,2))))
BASE_WB_2CLK_COUNTER = wb_addr(VHDL_WB_SLAVE_NUMBER_COUNTER)
BASE_WB_SPI = wb_addr(VHDL_WB_SLAVE_NUMBER_SPI)
#def vprint(msg):
# if (global_mod)
class COpenCoresSPI:
R_RX = [0x00, 0x04, 0x08, 0x0C]
R_TX = [0x00, 0x04, 0x08, 0x0C]
R_CTRL = 0x10
R_DIV = 0x14
R_SS = 0x18
LGH_MASK = (0x7F)
CTRL_GO = (1<<8)
CTRL_BSY = (1<<8)
CTRL_RXNEG = (1<<9)
CTRL_TXNEG = (1<<10)
CTRL_LSB = (1<<11)
CTRL_IE = (1<<12)
CTRL_ASS = (1<<13)
DIV_MASK = (0xFFFF)
SS_SEL = [0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40]
conf = 0x0
def wr_reg(self, addr, val):
self.bus.iwrite(0, self.base_addr + addr, 4, val)
def rd_reg(self, addr):
return self.bus.iread(0, self.base_addr + addr, 4)
def __init__(self, bus, base_addr, divider):
self.bus = bus;
self.base_addr = base_addr;
self.wr_reg(self.R_DIV, (divider & self.DIV_MASK));
# default configuration
self.conf = self.CTRL_ASS # | self.CTRL_TXNEG
def wait_busy(self):
while(self.rd_reg(self.R_CTRL) & self.CTRL_BSY):
pass
def config(self, ass, rx_neg, tx_neg, lsb, ie):
self.conf = 0
if(ass):
self.conf |= self.CTRL_ASS
if(tx_neg):
self.conf |= self.CTRL_TXNEG
if(rx_neg):
self.conf |= self.CTRL_RXNEG
if(lsb):
self.conf |= self.CTRL_LSB
if(ie):
self.conf |= self.CTRL_IE
# slave = slave number (0 to 7)
# data = byte data array to send, in case if read fill with dummy data of the right size
# This transaction has been modified for this test!!
def transaction(self, slave, data):
self.wr_reg(self.R_SS, self.SS_SEL[slave])
txrx = [0x00000000, 0x00000000, 0x00000000, 0x00000000]
txrx[0] = 0x00FFFFFF & data
self.wr_reg(self.R_TX[0], txrx[0])
ctrl_reg = self.CTRL_ASS | self.CTRL_GO | 24
self.wr_reg(self.R_CTRL, 2018)
self.wr_reg(self.R_CTRL, 2118)
tmp = (self.rd_reg(self.R_CTRL) >> 8) & 0x00000001
while(tmp == 1):
tmp = (self.rd_reg(self.R_CTRL) >> 8) & 0x00000001
#print self.rd_reg(self.R_CTRL)
pass
return txrx
class WB_2CLK_COUNTER:
CTRL_REG = 0x0
SLOW_MAX_VALUE_REG = 0x8
SLOW_CNT_VALUE_REG = 0xC
FAST_MAX_VALUE_REG = 0x10
FAST_CNT_VALUE_REG = 0x14
BAD_REG = 0x4
INT_O_FAST = 6
RUN_FAST = 5
RST_FAST = 4
INT_O_SLOW = 2
RUN_SLOW = 1
RST_SLOW = 0
SLOW_CLK_FREQ = 20 # MHz
FAST_CLK_FREQ = 125.01 #200 # MHz
SLOW_CLK_PPM = 100
# RAKON IVT3200 25 MHz stability specs
# Nominal frequency tolerance 2 ppm
# Frquency stability over temperature 5 ppm
# Frequency slope against temperature 1 ppm/2degC
# Static temperature hysteresis 0.6 ppm
# Supply voltage stability 0.1 ppm
# Load sensitivity 0.2 ppm
# Long term stability 2 ppm
# RAKON IVT3200 CONTROL VOLTAGE
# Control voltage range 0.5V to 2.8V
# Frequency shift 6 to 50 ppm
# Kv = 2.3/44 ppm/V (+ 6 ppm)
FAST_RAKON_CLK_KV = 2.3/44
# CDCM61004 grants 100 ppm after setting up
FAST_CLK_PPM = 30
MAX_CYCLES = 0xFFFFFFFF
def __init__(self, bus, base):
self.bus = bus;
self.base = base;
self.bus.iwrite(0, self.base + self.CTRL_REG, 4, 0x000000F1)
self.results = []
# FAIL: Bad first bit
def set_ctrl_reg(self, value):
self.bus.iwrite(0, self.base + self.CTRL_REG, 4, value)
def rd_ctrl_reg(self):
return self.bus.iread(0, self.base + self.CTRL_REG, 4)
# OK
def set_slow_max_value(self, value):
self.bus.iwrite(0, self.base + self.SLOW_MAX_VALUE_REG, 4, value)
# OK
def rd_slow_max_value(self):
return self.bus.iread(0, self.base + self.SLOW_MAX_VALUE_REG, 4)
# OK
def set_fast_max_value(self, value):
self.bus.iwrite(0, self.base + self.FAST_MAX_VALUE_REG, 4, value)
# OK
def rd_fast_max_value(self):
return self.bus.iread(0, self.base + self.FAST_MAX_VALUE_REG, 4)
def rd_slow_counter(self):
return self.bus.iread(0, self.base + self.SLOW_CNT_VALUE_REG, 4)
def rd_fast_counter(self):
return self.bus.iread(0, self.base + self.FAST_CNT_VALUE_REG, 4)
def translate_to_slow_clk_cycles(self, seconds):
tmp = seconds*WB_2CLK_COUNTER.SLOW_CLK_FREQ*(10**6)
if (tmp > WB_2CLK_COUNTER.MAX_CYCLES):
raise Exception("Bad setting up of the slow clk cycles: Please put a smaller slow clock value")
return int(tmp)
def translate_to_fast_clk_cycles(self, seconds):
tmp = int(math.ceil(seconds*WB_2CLK_COUNTER.FAST_CLK_FREQ*(10**6)))
if (tmp > WB_2CLK_COUNTER.MAX_CYCLES):
raise Exception("Bad setting up of the slow clk cycles: Please put a smaller fast clock value\n\tFAST_CLOCK_CYCLES:\t" + "%0.8X"%tmp)
return int(tmp)
def rd_bad_reg(self):
return self.bus.iread(0, self.base + self.BAD_REG, 4)
def wr_reg(self, REG_ADDR):
self.bus.iwrite(0, self.base + REG_ADDR, 4, value)
def rd_reg(self, REG_ADDR):
return self.bus.iread(0, self.base + REG_ADDR, 4)
def run_test(self, test_time_slow):
global double_counter
test_time_fast = int(test_time_slow*WB_2CLK_COUNTER.FAST_CLK_FREQ/WB_2CLK_COUNTER.SLOW_CLK_FREQ*1.05)
double_counter.set_ctrl_reg(0x00000011)
#print " CTRL REG\t" + "%.8X"%double_counter.rd_ctrl_reg() + "\tResetting up"
time.sleep(0.05)
double_counter.set_ctrl_reg(0x00000000)
time.sleep(0.05)
# Then, we fix the max value of the clocks
# Slow clock is 25MHz
# Fast clock is 125MHz
slow_cycles = double_counter.translate_to_slow_clk_cycles(test_time_slow)
fast_cycles = double_counter.translate_to_fast_clk_cycles(test_time_fast)
# We put a larger value fo test for fast clock so as to avoid problems
double_counter.set_slow_max_value(slow_cycles) # We have to put long values so as to be precises
double_counter.set_fast_max_value(fast_cycles) # It has to be bigger than the slow_max_value (in test seconds)
#print " Slow max value\t" + "%.8X"%double_counter.rd_slow_max_value()
#print " Fast max value\t" + "%.8X"%double_counter.rd_fast_max_value()
#print "Wishbone clock comparator ready to go\n"
#print "Test start!"
double_counter.set_ctrl_reg(0x00000022)
initial_time = time.localtime().tm_sec;
time.sleep(test_time_slow * 1.1)
counter_slow_test_value = double_counter.rd_slow_counter()
counter_fast_test_value = double_counter.rd_fast_counter()
#print ""
print "Slow counter value\t" + "%.8X"%counter_slow_test_value
print "Fast counter value\t" + "%.8X"%(counter_fast_test_value - 2) # We substract 2 cycles because of the VHDL CDC
# counter_fast_test_value += 0x10000 # cause a failure!!! jdgc
double_counter.clocks_check(counter_slow_test_value, counter_fast_test_value)
# Needs some rework
def clocks_check(self, ticks_slow, ticks_fast):
lower_threshold_n = (1 - self.FAST_CLK_PPM*10**(-6))/(1 + self.SLOW_CLK_PPM*10**(-6))
upper_threshold_n = (1 + self.FAST_CLK_PPM*10**(-6))/(1 - self.SLOW_CLK_PPM*10**(-6))
lower_threshold = ticks_slow * self.FAST_CLK_FREQ /self.SLOW_CLK_FREQ * lower_threshold_n
upper_threshold = ticks_slow * self.FAST_CLK_FREQ /self.SLOW_CLK_FREQ * upper_threshold_n
print "\tlower_threshold:\t" + "%0.8X"%lower_threshold
print "\tupper_threshold:\t" + "%0.8X"%upper_threshold
print "Test checked " + str(len(double_counter.results))
# print "Threshold\t\t[" + "%0.8X"%lower_threshold + ", " + "%0.8X"%upper_threshold + "]"
if (ticks_fast < lower_threshold or ticks_fast > upper_threshold):
# print "Clocks are working badly!"
self.results.append(False)
else:
# print "Clocks are working nicely!"
self.results.append(True)
def write_report (self):
if not os.path.exists('./log/'):
print "There"
os.mkdir('./log')
if not os.path.exists('./log/test_clk/'):
os.mkdir('./log/test_clk')
filename = "test_clk.txt"
file = open(os.path.join(test_clk_path, filename), 'w')
tmp_str = "-------------------------------------------------------------------\n"
tmp_str += "-- SPEC V.1.1 Clocks testing --\n"
tmp_str += "-- - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - --\n"
for i in xrange(len(double_counter.results)):
tmp_str += "\tTest " + str(i) + "\t"
if(double_counter.results[i] == False):
tmp_str += "FAIL\n"
else:
tmp_str += "PASS\n"
file.write(tmp_str)
class AD5662_1:
PD0 = 16
PD1 = 17
OM_NORMAL = 0
OM_1K = 1
OM_100K = 2
OM_TRISTATE = 3
V_REF = 3.3
def __init__(self, spi):
self.dac_value = 0x0000
self.op = self.OM_NORMAL
self.spi = spi
def set_dac_voltage(self, voltage):
if (voltage >= self.V_REF):
"FAIL: please set a valid AD5662_1 voltage"
value = int(voltage / self.V_REF * 65536)
self.dac_value = value
def operation_mode(self, op):
self.op = op
def update_output(self):
data = (self.op << 16) + (self.dac_value)
self.spi.transaction(0, data)
def main():
global double_counter
bitstream_name = clk_test_bitstream
os.system(firmware_loader_path + ' ' + bitstream_name);
time.sleep(2); # Take it easy yo'! Reducing this time can produce unexpected outputs
gennum = rr.Gennum();
double_counter = WB_2CLK_COUNTER(gennum, BASE_WB_2CLK_COUNTER)
print "-------------------------------------------------------------------"
print "-- SPEC V.1.1 Clocks testing --"
print "-- - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - --"
print " CERN BE-CO-HT Visit us! www.ohwr.org "
print " "
print " This test is intended for testing the system clock (20 MHz) and "
print " the PLL clock (CDCM61004)"
print " The following circuits are tested as well:"
print " - IC3 AD5662BRMZ-1"
print " - OSC1 IVT3205CR 25.0MHz"
print "-- - - - - - - - - - - - - - - - --"
print " TEST PARAMS"
print "-- - - - - - - - - - - - - - - - --"
print "Wishbone counter address\t" + "%.8X"%BASE_WB_2CLK_COUNTER
print "Wishbone SPI address\t\t" + "%.8X"%BASE_WB_SPI
print "Number of tests\t\t\t" + str(TOTAL_OF_TESTS)
print "Elapsed time per test\t\t" + str(TEST_TIME_SLOW)
spi_device = COpenCoresSPI(gennum, BASE_WB_SPI, 0x0004) # Configuring with a 4 means a SCLK frequency of 5 MHz
dac = AD5662_1(spi_device)
dac.operation_mode(dac.OM_NORMAL)
dac.set_dac_voltage(1.65)
dac.update_output()
print "* AD5662_1 set up for PLL reference clock\tOK"
for i in range (0, TOTAL_OF_TESTS):
double_counter.run_test(TEST_TIME_SLOW)
for i in range (0, len(double_counter.results)):
if (double_counter.results[i] == False):
print "Test " + str(i) +":\tFAIL"
raise TpsCritical("Mismatch between expected fast cycles and expected ones")
else:
print "Test " + str(i) +":\tPASS"
double_counter.write_report()
if __name__ == '__main__':
main()
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment