Commit c917e02c authored by Maciej Lipinski's avatar Maciej Lipinski

Merge branch 'sevensols-wr_starting_kit_update' into 'master'

Sevensols wr starting kit update

See merge request !1
parents 97a2d883 eea7bfc8
## .gitignore file
# OS generated #
####################
*.bak
*.*\#
\#*
.\#*
*.*~
*.swp
*.cache
Thumbs.db
# Compiled source #
###################
*.bit
*.exe
*.o
*.a
*.so
*.wlf
*.vstf
*.vcd
*.pyc
*.d
*.ko
# Eclipse #
###################
.library_mapping.xml
.project
.cproject
.settings/*
# Visual S. Code #
###################
/.vscode/
# VIM files #
####################
*.swo
*.swn
# Kernel Specific #
###################
.*.o.cmd
.*.ko.cmd
.cache.mk
*.o.ur-safe
Module.symvers
modules.order
# Project Specifi #
###################
wr-dio.mod*
[submodule "hdl/ip_cores/wr-cores"]
path = hdl/ip_cores/wr-cores
url = https://ohwr.org/project/wr-cores.git
[submodule "hdl/ip_cores/etherbone-core"]
path = hdl/ip_cores/etherbone-core
url = https://ohwr.org/project/etherbone-core.git
[submodule "hdl/ip_cores/general-cores"]
path = hdl/ip_cores/general-cores
url = https://ohwr.org/project/general-cores.git
[submodule "hdl/ip_cores/gn4124-core"]
path = hdl/ip_cores/gn4124-core
url = https://ohwr.org/project/gn4124-core.git
[submodule "sw/fmc-bus"]
path = sw/fmc-bus
url = https://ohwr.org/project/fmc-bus.git
all:
$(MAKE) -C sw
install:
$(MAKE) -C sw install
clean:
$(MAKE) -C sw clean
FMC DIO 5ch TTLa Documentation
==============================
This folder contains all files related to the documentation of the FMC DIO 5ch TTLa project.
*.*\#
\#*
.\#*
*~
*.wlf
modelsim.ini
transcript
*.vstf
*.bak
*.vcd
*.pyc
work
syn
!syn/dio-nic/Manifest.py
!syn/dio-etherbone/Manifest.py
!syn/dio-ext-nic-etherbone/Manifest.py
0o.*.o0/
/.library_mapping.xml
/.project
/.settings/*
fetchto = "ip_cores"
modules = { "local" : ["modules/wr_dio",
"ip_cores/wr-cores",
"ip_cores/wr-cores/board/spec",
"ip_cores/general-cores",
"ip_cores/gn4124-core/hdl/gn4124core/rtl",
"ip_cores/etherbone-core"]
}
FMC DIO 5ch TTLa Gateware
=========================
This folder contains all files related to the gateware of the FMC DIO 5ch TTLa project.
Subproject commit f19220ffa3c5e526f66ebbded5e0e1e789e7255d
Subproject commit f73bc3d2959bdaab52adf910d99ed90cabab11ab
Subproject commit 10cd74b06a094c5b6c1a566676785e1814001404
Subproject commit 4e5e3dfc01e395a81d9403bd1e150560972685f7
files = ["wr_dio_wb.vhd",
"xwr_dio.vhd",
"wr_dio.vhd",
"wr_dio_pkg.vhd",
"pulse_gen_pl.vhd",
"immed_pulse_counter.vhd",
"dummy_time.vhd" ]
#!/bin/bash
wbgen2 -D wr_dio_wb.htm -V wr_dio_wb.vhd --cstyle defines --lang vhdl -K ../../sim/dio_timing_regs.vh wr_dio.wb
-------------------------------------------------------------------------------
-- Entity: dummy_time
-- File: dummy_time.vhd
-- Description: ¿?
-- Author: Javier Diaz (jdiaz@atc.ugr.es)
-- Date: 8 March 2012
-- Version: 0.01
-- To do:
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- -----------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version.
-- This source is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
-- for more details. You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
--use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_unsigned.all;
entity dummy_time is
port(clk_sys : in std_logic; -- data output reference clock 125MHz
rst_n : in std_logic; -- system reset
-- utc time in seconds
tm_utc : out std_logic_vector(39 downto 0);
-- number of clk_ref_i cycles
tm_cycles : out std_logic_vector(27 downto 0));
end dummy_time;
architecture Behavioral of dummy_time is
signal OneSecond : std_logic;
signal init_time : std_logic;
signal tm_cycles_Aux : std_logic_vector(27 downto 0);
signal tm_utc_Aux : std_logic_vector(39 downto 0);
constant MaxCountcycles1 : std_logic_vector(27 downto 0) := "0111011100110101100100111111"; --125.000.000-1
constant MaxCountcycles2 : std_logic_vector(27 downto 0) := "0111011100110101100101000000"; --125.000.000
constant AllOnesUTC : std_logic_vector(39 downto 0) := (others => '1');
begin
---------------------------------------
-- Process to count cycles in a second
---------------------------------------
P_CountTM_cycles :
process(rst_n, clk_sys)
begin
if(rst_n = '0') then
tm_cycles_Aux <= (others => '0');
oneSecond <= '0';
init_time <= '0';
elsif(rising_Edge(Clk_sys)) then
if (Tm_cycles_Aux /= MaxCountcycles2) then
tm_cycles_Aux <= tm_cycles_Aux + 1;
else
tm_cycles_Aux <= (others => '0');
end if;
if(Tm_cycles_Aux = MaxCountcycles1) then
OneSecond <= '1';
else
OneSecond <= '0';
end if;
init_time <= '1';
end if;
end process P_CountTM_cycles;
P_CountTM_UTC :
process(rst_n, clk_sys)
begin
if(rst_n = '0') then
tm_utc_Aux <= (others => '0');
elsif(rising_edge(Clk_sys)) then
if (OneSecond = '1') then
if (tm_utc_Aux /= AllOnesUTC) then
tm_utc_Aux <= tm_utc_Aux + 1;
else
tm_utc_Aux <= (others => '0');
end if;
end if;
end if;
end process P_CountTM_UTC;
tm_cycles <= tm_cycles_Aux when init_time = '1' else (others => '1');
tm_utc <= tm_utc_Aux when init_time = '1' else (others => '1');
end Behavioral;
-------------------------------------------------------------------------------
-- Entity: immed_pulse counter
-- File: immed_pulse counter.vhd
-- Description: a simple synchronous output based on asynchronous strobe inputs that produces a N-ticks
-- length pulse.
-- Author: Javier Díaz (jdiaz@atc.ugr.es)
-- Date: 9 July 2012
-- Version: 0.01
-- Properties:
-- TBD
-- Todo:
-- TBD
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- -----------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version.
-- This source is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
-- for more details. You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity immed_pulse_counter is
generic (
-- reference clock frequency
pulse_length_width : integer := 28
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic; -- asynchronous system reset
pulse_start_i : in std_logic; -- asynchronous strobe for pulse generation
pulse_length_i : in std_logic_vector(pulse_length_width-1 downto 0); -- asynchronous signal
pulse_output_o : out std_logic
);
end immed_pulse_counter;
architecture rtl of immed_pulse_counter is
-- Internal registers to hold pulse duration
signal counter : unsigned (pulse_length_width-1 downto 0);
-- Signals for states
type counter_state is (WAIT_ST, COUNTING);
signal state : counter_state;
-- Signal for synchronization (in fact they are not so necessary for current system...)
signal pulse_start_d0, pulse_start_d1, pulse_start_d2, pulse_start_d3 : std_logic;
signal nozerolength, nozerolength_aux : boolean;
-- Aux
constant zeros : std_logic_vector(pulse_length_width-1 downto 0) := (others => '0');
begin -- architecture rtl
synchronization : process(clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
pulse_start_d0 <= '0';
pulse_start_d1 <= '0';
pulse_start_d2 <= '0';
pulse_start_d3 <= '0';
elsif rising_edge(clk_i) then
pulse_start_d0 <= pulse_start_i;
pulse_start_d1 <= pulse_start_d0;
pulse_start_d2 <= pulse_start_d1;
pulse_start_d3 <= pulse_start_d2;
nozerolength_aux <= pulse_length_i /= zeros;
if (pulse_start_d2 = '1' and pulse_start_d1 = '0') then
nozerolength <= nozerolength_aux;
end if;
end if;
end process;
state_process : process(clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
counter <= (others => '0');
state <= WAIT_ST;
elsif rising_edge(clk_i) then
case state is
when WAIT_ST =>
if pulse_start_d3 = '1' and nozerolength then
state <= COUNTING;
counter <= unsigned(pulse_length_i)-1;
else
state <= WAIT_ST;
end if;
when COUNTING =>
if (counter = 0) then
state <= WAIT_ST;
else
state <= COUNTING;
counter <= counter-1;
end if;
when others =>
state <= WAIT_ST;
end case;
end if;
end process;
output_process : process(counter, state)
begin
if (rst_n_i = '0') then
pulse_output_o <= '0';
else
case state is
when WAIT_ST =>
pulse_output_o <= '0';
when COUNTING =>
pulse_output_o <= '1';
when others =>
pulse_output_o <= '0';
end case;
end if;
end process;
end architecture rtl;
-------------------------------------------------------------------------------
-- Entity: pulse_gen_pl
-- File: pulse_gen_pl.vhd
-- Description: a pulse generator which produces a N-ticks length pulse in its
-- output when the time passed to it through a vector equals a
-- pre-programmed time.
-- Author: Javier Díaz (jdiaz@atc.ugr.es)
-- Based on the pulse_gen code of Javier Serrano (Javier.Serrano@cern.ch)
-- Date: 6 July 2012
-- Version: 0.02
-- Properties:
-- 1) After arming the trigger, new trigger values are not possible during for 13 clk_sys
-- ticks (208 ns for a 62,5 MHz clock, trig_ready_o<='0') --> not MESURABLE BY PC-SOFTWARE.
-- 2) Minimum of 7 clk_refs ticks are needed between trigger_time and its activation
-- (trig_valid_p1 = 1)
-- Trigger values can be overwritten when trig_ready_o without generate current assigment output
-- Todo: Substitute ready_for_trig process by a state machine.
-- Factor out synchronizer in a separate reusable block.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
-- -----------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version.
-- This source is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
-- for more details. You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it from
-- http://www.gnu.org/licenses/lgpl-2.1.html
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity pulse_gen_pl is
generic (
-- reference clock frequency
g_ref_clk_rate : integer := 125000000);
port (
clk_ref_i : in std_logic; -- timing reference clock
clk_sys_i : in std_logic; -- data output reference clock
rst_n_i : in std_logic; -- system reset
pulse_o : out std_logic; -- pulse output
-------------------------------------------------------------------------------
-- Timing input (from WRPC), clk_ref_i domain
------------------------------------------------------------------------------
-- 1: time given on tm_utc_i and tm_cycles_i is valid (otherwise, don't
-- produce pulses and keep trig_ready_o line permamaently active)
tm_time_valid_i : in std_logic;
-- number of seconds
tm_utc_i : in std_logic_vector(39 downto 0);
-- number of clk_ref_i cycles
tm_cycles_i : in std_logic_vector(27 downto 0);
---------------------------------------------------------------------------
-- Time tag output (clk_sys_i domain)
---------------------------------------------------------------------------
-- 1: input is ready to accept next trigger time tag
trig_ready_o : out std_logic;
-- time at which the pulse will be produced + a single-cycle strobe to
-- latch it in
trig_utc_i : in std_logic_vector(39 downto 0);
trig_cycles_i : in std_logic_vector(27 downto 0);
trig_valid_p1_i : in std_logic;
pulse_length_i : in std_logic_vector(27 downto 0)
);
end pulse_gen_pl;
architecture rtl of pulse_gen_pl is
-- Internal registers to hold trigger time and pulse duration
signal trig_utc, trig_utc_ref : std_logic_vector(39 downto 0);
signal trig_cycles, trig_cycles_ref : std_logic_vector(27 downto 0);
signal pulse_length, pulse_length_ref : std_logic_vector(27 downto 0);
-- Signals for the synchronizer
signal trig_valid_sys_d1, trig_valid_sys_d2 : std_logic;
signal rst_from_sync, rst_from_sync_d1 : std_logic;
signal trig_valid_ref : std_logic_vector(2 downto 0);
signal trig_valid_back : std_logic_vector(2 downto 0);
signal trig_valid_ref_p1 : std_logic;
-- Aux
constant zeros : std_logic_vector(27 downto 0) := (others => '0');
signal counter : unsigned (27 downto 0);
signal nozerolength : boolean;
begin -- architecture rtl
-- Get trigger time into internal registers
trig_regs : process (clk_sys_i) is
begin -- process trig_regs
if clk_sys_i'event and clk_sys_i = '1' then
if rst_n_i = '0' then
trig_utc <= (others => '0');
trig_cycles <= (others => '0');
pulse_length <= (others => '0');
elsif trig_valid_p1_i = '1' then
trig_utc <= trig_utc_i;
trig_cycles <= trig_cycles_i;
pulse_length <= pulse_length_i;
end if;
end if;
end process trig_regs;
-- Synchronizer to pass UTC register data to the reference clock domain
-- This synchronizer is made with the following four processes
-- First one FF with async reset, still in the clk_sys_i domain
sync_first_ff : process (clk_sys_i, rst_n_i, rst_from_sync)
begin
if rst_n_i = '0' or rst_from_sync = '1' then
trig_valid_sys_d1 <= '0';
elsif clk_sys_i'event and clk_sys_i = '1' then
if trig_valid_p1_i = '1' then
trig_valid_sys_d1 <= '1';
end if;
end if;
end process sync_first_ff;
-- OK this is just for the UTC and cycle registers to have time to settle
-- in the pathological case of a very fast ref clock and very long
-- combinational delays in the UTC and cycle registers
delay_sys : process (clk_sys_i)
begin
if clk_sys_i'event and clk_sys_i = '1' then
trig_valid_sys_d2 <= trig_valid_sys_d1;
end if;
end process delay_sys;
-- Then three FFs to take the strobe safely into the clk_ref_i domain
sync_ref : process (clk_ref_i)
begin
if clk_ref_i'event and clk_ref_i = '1' then
trig_valid_ref <= trig_valid_ref(1 downto 0) & trig_valid_sys_d2;
trig_valid_ref_p1 <= trig_valid_ref(1) and not trig_valid_ref(2);
end if;
end process sync_ref;
-- And then back into the clk_sys_i domain
sync_sys : process (clk_sys_i)
begin
if clk_sys_i'event and clk_sys_i = '1' then
trig_valid_back <= trig_valid_back(1 downto 0) & trig_valid_ref(2);
rst_from_sync <= trig_valid_back(2);
rst_from_sync_d1 <= rst_from_sync;
end if;
end process sync_sys;
-- Now get the trig registers into the clk_ref_i domain
trig_regs_ref : process (clk_ref_i)
begin
if clk_ref_i'event and clk_ref_i = '1' then
if trig_valid_ref_p1 = '1' then
trig_utc_ref <= trig_utc;
trig_cycles_ref <= trig_cycles;
pulse_length_ref <= pulse_length;
nozerolength <= pulse_length /= zeros;
end if;
end if;
end process trig_regs_ref;
-- Notify we're ready to receive another trigger time write
-- Having the reset set trig_ready_o to '1' is a kludge.
-- A proper state machine would be better.
ready_for_trig : process (rst_n_i, clk_sys_i)
begin
if rst_n_i = '0' then
trig_ready_o <= '1';
elsif clk_sys_i'event and clk_sys_i = '1' then
if trig_valid_p1_i = '1' then
trig_ready_o <= '0';
elsif rst_from_sync_d1 = '1' and rst_from_sync = '0' then
-- falling edge of reset_from_sync
trig_ready_o <= '1';
end if;
end if;
end process ready_for_trig;
-- Produce output
-- Note rst_n_i is used as an async reset because it comes from the
-- clk_sys_i domain. Not the most elegant but it ensures no glitches
-- in the output after startup.
-- This block actually creates a pulse pulse_length ticks when the programmed
-- time matches the current time.
gen_out : process (rst_n_i, clk_ref_i)
begin
if rst_n_i = '0' then
pulse_o <= '0';
elsif clk_ref_i'event and clk_ref_i = '1' then
if tm_time_valid_i = '0' then
pulse_o <= '0';
elsif tm_utc_i = trig_utc_ref and tm_cycles_i = trig_cycles_ref and nozerolength then
pulse_o <= '1';
counter <= unsigned(pulse_length_ref)-1;
elsif counter /= 0 then
counter <= counter-1;
else
pulse_o <= '0';
end if;
end if;
end process gen_out;
end architecture rtl;
-------------------------------------------------------------------------------
-- Title : DIO Core
-- Project : White Rabbit Network Interface
-------------------------------------------------------------------------------
-- File : wr_dio.vhd
-- Author : Javier Díaz
-- Company : Seven Solutions
-- Created : 2012-07-25
-- Last update: 2019-08-27
-- Platform : FPGA-generic
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description: Simulation file for the xwr_dio.vhd file
--
-------------------------------------------------------------------------------
-- TODO:
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2012-07-25 0.1 JDiaz Created
-- 2013-05-23 0.2 Ben.R Adding PPS
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.wr_fabric_pkg.all;
entity wr_dio is
generic (
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD
);
port (
clk_sys_i : in std_logic;
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
dio_clk_i : in std_logic;
dio_pps_i : in std_logic;
dio_in_i : in std_logic_vector(4 downto 0);
dio_out_o : out std_logic_vector(4 downto 0);
dio_oe_n_o : out std_logic_vector(4 downto 0);
dio_term_en_o : out std_logic_vector(4 downto 0);
dio_onewire_b : inout std_logic;
dio_sdn_n_o : out std_logic;
dio_sdn_ck_n_o : out std_logic;
dio_led_top_o : out std_logic;
dio_led_bot_o : out std_logic;
dio_scl_b : inout std_logic;
dio_sda_b : inout std_logic;
dio_ga_o : out std_logic_vector(1 downto 0);
dio_int : out std_logic;
tm_time_valid_i : in std_logic;
tm_seconds_i : in std_logic_vector(39 downto 0);
tm_cycles_i : in std_logic_vector(27 downto 0);
-------------------------------------------------------------------------------
-- Wishbone bus
-------------------------------------------------------------------------------
wb_cyc_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_sel_i : in std_logic_vector(c_wishbone_data_width/8-1 downto 0);
wb_adr_i : in std_logic_vector(c_wishbone_address_width-1 downto 0);
wb_dat_i : in std_logic_vector(c_wishbone_data_width-1 downto 0);
wb_dat_o : out std_logic_vector(c_wishbone_data_width-1 downto 0);
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
wb_irq_o : out std_logic;
-- Debug signals for chipscope
TRIG0 : out std_logic_vector(31 downto 0);
TRIG1 : out std_logic_vector(31 downto 0);
TRIG2 : out std_logic_vector(31 downto 0);
TRIG3 : out std_logic_vector(31 downto 0)
);
end wr_dio;
architecture rtl of wr_dio is
-- DIO core
component xwr_dio
generic (
g_interface_mode : t_wishbone_interface_mode := CLASSIC;
g_address_granularity : t_wishbone_address_granularity := WORD
);
port (
clk_sys_i : in std_logic;
clk_ref_i : in std_logic;
rst_n_i : in std_logic;
dio_clk_i : in std_logic;
dio_pps_i : in std_logic;
dio_in_i : in std_logic_vector(4 downto 0);
dio_out_o : out std_logic_vector(4 downto 0);
dio_oe_n_o : out std_logic_vector(4 downto 0);
dio_term_en_o : out std_logic_vector(4 downto 0);
dio_onewire_b : inout std_logic;
dio_sdn_n_o : out std_logic;
dio_sdn_ck_n_o : out std_logic;
dio_led_top_o : out std_logic;
dio_led_bot_o : out std_logic;