Commit 5eb3d86a authored by David Cussans's avatar David Cussans

Moving minitlu firmware to subdirectory

parent e5bcc2ba
Introduction to AIDA FMC Mini-TLU {#mainpage}
=================================
The TLU provides different parts of a Particle Physics Beam-Test
system with the information they need to synchronize data taken with
different detectors. The detectors are also refered to as Devices
Under Test (DUT).
Functions of TLU
----------------
- Trigger.
The TLU can combine signals from detectors in the beam-line ( often
scintillation detectors ) to produce a trigger that is sent to the
different DUT. Each DUT can indicate to the TLU that it is busy and
unable to take any further data.
- Particle Timestamping
The arrival time of every pulse from the beam-detectors is recorded.
- Clock and Synchronization Signals.
The TLU produces clock and synchronization signals that allow the
internal counters of different DUT to be sychronized.
N.B. Not all the functions of the TLU may be used in a given beam-test
system. For example, it is common to only use the Trigger/Busy
function of the TLU.
Firmare Structure
-----------------
The firmware is almost exclusively written in VHDL. The top level
entitity is [top_extphy](top_extphy_struct)
The HDL-Designer package by Mentor graphics has been used to develop
some of the code, mainly the top-level structure. However, is is not
necessary to use HDL-Designer to build the firmware. In fact the VHDL
files produced by HDL-Designer can also be edited "by hand" without
using the tool.
A block diagram, generated by HDL-Designer, is [here](http://www.ohwr.org/attachments/2710/hdl_designer_test_print_2.pdf)
Building Firmware
-----------------
Instructions on building the firmware are found
[here](http://www.ohwr.org/projects/fmc-mtlu/wiki/FirmwareBuild).
project open fmc-mtlu
puts "Regenerating cores"
cd $::env(FW_WORKSPACE)/workspace/ipcore_dir
catch {exec coregen -r -b tri_mode_eth_mac_v5_4.xco -p coregen.cgp}
catch {exec coregen -r -b mac_fifo_axi4.xco -p coregen.cgp}
catch {exec coregen -r -b tlu_event_fifo.xco -p coregen.cgp}
catch {exec coregen -r -b FIFO.xco -p coregen.cgp}
# catch {exec coregen -r -b CounterUp.xco -p coregen.cgp}
catch {exec coregen -r -b internalTriggerGenerator.xco -p coregen.cgp}
process run "Synthesize"
process run "Translate"
process run "Map"
process run "Place & Route"
process run "Generate Programming File"
project close
SET busformat = BusFormatAngleBracketNotRipped
SET designentry = VHDL
SET device = xc6slx16
SET devicefamily = spartan6
SET flowvendor = Other
SET package = csg324
SET speedgrade = -3
SET verilogsim = false
SET vhdlsim = true
hdl ipbus/firmware/example_designs/hdl/clocks_s6_extphy.vhd
include ipbus/firmware/ethernet/cfg/file_list_s6_extphy
include ipbus/firmware/ipbus_core/cfg/file_list
project new fmc-mtlu
project set family spartan6
project set device xc6slx16
project set package csg324
project set speed -3
project set "Enable Multi-Threading" "2" -process "Map"
project set "Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs" -process "Map"
project set "Enable Multi-Threading" "2" -process "Place & Route"
project set "Enable BitStream Compression" TRUE -process "Generate Programming File"
project set "Preferred Language" "VHDL"
# source $::env(REPOS_FW_DIR)/firmware/example_designs/scripts/addfiles.tcl
# Just list files by hand for now. Can't get addfiles.tcl to work.
#xfile add ipbus/firmware/example_designs/hdl/clocks_s6_extphy.vhd
# IPBus Ethernet for gig_eth_pcs_pma_v11_5
xfile add ipbus/firmware/ethernet/hdl/eth_s6_gmii.vhd
xfile add ipbus/firmware/ethernet/hdl/emac_hostbus_decl.vhd
puts "Adding and Regenerating Ethernet cores"
# Add cores for Ethernet
exec cp ipbus/firmware/ethernet/coregen/tri_mode_eth_mac_v5_4.xco ipcore_dir
exec cp ipbus/firmware/ethernet/coregen/mac_fifo_axi4.xco ipcore_dir
xfile add ipcore_dir/tri_mode_eth_mac_v5_4.xco
xfile add ipcore_dir/mac_fifo_axi4.xco
# Don't regenerate cores for now...
#cd ipcore_dir
#catch {exec coregen -r -b tri_mode_eth_mac_v5_4.xco -p coregen.cgp}
#catch {exec coregen -r -b mac_fifo_axi4.xco -p coregen.cgp}
#cd ..
puts "Adding IPBus files"
# Xilinx ISE setup fragment for ipbus core
xfile add ipbus/firmware/ipbus_core/hdl/ipbus_package.vhd
xfile add ipbus/firmware/ipbus_core/hdl/ipbus_trans_decl.vhd
xfile add ipbus/firmware/ipbus_core/hdl/ipbus_ctrl.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_if_flat.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_buffer_selector.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_arp.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_payload.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_ping.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_resend.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_status.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_byte_sum.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_clock_crossing_if.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_do_rx_reset.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_dualportram.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_dualportram_rx.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_dualportram_tx.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_ipaddr_block.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_packet_parser.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_rarp_block.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_rxram_mux.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_rxram_shim.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_rxtransactor_if_simple.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_status_buffer.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_tx_mux.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_txtransactor_if_simple.vhd
xfile add ipbus/firmware/ipbus_core/hdl/trans_arb.vhd
xfile add ipbus/firmware/ipbus_core/hdl/transactor.vhd
xfile add ipbus/firmware/ipbus_core/hdl/transactor_if.vhd
xfile add ipbus/firmware/ipbus_core/hdl/transactor_sm.vhd
xfile add ipbus/firmware/ipbus_core/hdl/transactor_cfg.vhd
xfile add ipbus/firmware/ipbus_core/hdl/stretcher.vhd
xfile add ipbus/firmware/ipbus_core/hdl/ipbus_fabric.vhd
xfile add ipbus/firmware/example_designs/hdl/clock_div.vhd
xfile add ipbus/firmware/slaves/hdl/ipbus_reg_types.vhd
xfile add ipbus/firmware/slaves/hdl/ipbus_reg_v.vhd
xfile add ipbus/firmware/slaves/hdl/ipbus_ctrlreg_v.vhd
#xfile add ipbus/firmware/slaves/hdl/syncreg_r.vhd
#xfile add ipbus/firmware/slaves/hdl/syncreg_w.vhd
#xfile add ipbus/firmware/slaves/hdl/ipbus_syncreg_v.vhd
xfile add ipbus/firmware/slaves/hdl/ipbus_ctrlreg_v.vhd
# Add Opencores files for i2c interface
xfile add external/opencores_i2c/i2c_master_bit_ctrl.vhd
xfile add external/opencores_i2c/i2c_master_byte_ctrl.vhd
xfile add external/opencores_i2c/i2c_master_registers.vhd
xfile add external/opencores_i2c/i2c_master_top.vhd
# Add TLU cores....
# Add cores for Ethernet
puts "Adding and Regenerating TLU cores"
exec cp fmc-mtlu/firmware/ise/ipcore_dir/tlu_event_fifo.xco ipcore_dir
exec cp fmc-mtlu/firmware/ise/ipcore_dir/FIFO.xco ipcore_dir
exec cp fmc-mtlu/firmware/ise/ipcore_dir/CounterUp.xco ipcore_dir
exec cp fmc-mtlu/firmware/ise/ipcore_dir/internalTriggerGenerator.xco ipcore_dir
xfile add ipcore_dir/tlu_event_fifo.xco
xfile add ipcore_dir/FIFO.xco
# xfile add ipcore_dir/CounterUp.xco
xfile add ipcore_dir/internalTriggerGenerator.xco
# Don't regenerate cores for now...
#cd ipcore_dir
#catch {exec coregen -r -b tlu_event_fifo.xco -p coregen.cgp}
#catch {exec coregen -r -b FIFO.xco -p coregen.cgp}
#catch {exec coregen -r -b CounterUp.xco -p coregen.cgp}
#catch {exec coregen -r -b internalTriggerGenerator.xco -p coregen.cgp}
#cd ..
puts "Adding TLU Files "
# Add FMC-MTLU files. First the hand-written VHDL
xfile add fmc-mtlu/firmware/hdl/common/dualSERDES_1to4_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/DUTInterfaces_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/eventBuffer_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/eventFormatter_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/i2c_master_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/ipbus_addr_decode.vhd
xfile add fmc-mtlu/firmware/hdl/common/IPBusInterface_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/ipbus_ver.vhd
xfile add fmc-mtlu/firmware/hdl/common/logic_clocks_rtl.vhd
#xfile add fmc-mtlu/firmware/hdl/common/pulseClockDomainCrossing_rtl.vhd
#xfile add fmc-mtlu/firmware/hdl/common/Reg_2clks.vhd
xfile add fmc-mtlu/firmware/hdl/common/registerCounter_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/synchronizeRegisters_rtl.vhd
# xfile add fmc-mtlu/firmware/hdl/common/serdes_1_to_n_SDR.vhd
xfile add fmc-mtlu/firmware/hdl/common/serdesCalibrateFSM_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/triggerInputs_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/triggerLogic_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/clocks_s6_extphy.vhd
xfile add fmc-mtlu/firmware/hdl/common/arrivalTimeLUT_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/test/clock_divider_s6.v
xfile add fmc-mtlu/firmware/hdl/common/counterWithReset_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/synchronizeRegisters_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/handshakes_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/TPx3Logic_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/GPP_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/counterDown.vhd
# Then add the HDL-Designer generated files..
xfile add fmc-mtlu/firmware/hdl_designer/fmc_mTLU/fmc_mTLU_lib/hdl/top_extphy_struct.vhd
xfile add fmc-mtlu/firmware/hdl_designer/fmc_mTLU/fmc_mTLU_lib/hdl/fmcTLU_pkg_body.vhd
xfile add fmc-mtlu/firmware/hdl_designer/fmc_mTLU/fmc_mTLU_lib/hdl/fmcTLU_pkg.vhd
# Add user constraints file
# UCF for TLU with FMC connector wrong way round.
#xfile add fmc-mtlu/firmware/ucf/sp601_FMC_mTLU.ucf
# bug-fixed TLU:
xfile add fmc-mtlu/firmware/ucf/sp601_FMC_mTLU_v1a.ucf
project close
puts "Successfully finished building project file"
project open fmc-mtlu
puts "Regenerating cores"
cd $::env(FW_WORKSPACE)/workspace/ipcore_dir
catch {exec coregen -r -b tri_mode_eth_mac_v5_4.xco -p coregen.cgp}
catch {exec coregen -r -b mac_fifo_axi4.xco -p coregen.cgp}
catch {exec coregen -r -b tlu_event_fifo.xco -p coregen.cgp}
catch {exec coregen -r -b FIFO.xco -p coregen.cgp}
# catch {exec coregen -r -b CounterUp.xco -p coregen.cgp}
catch {exec coregen -r -b internalTriggerGenerator.xco -p coregen.cgp}
process run "Synthesize"
process run "Translate"
process run "Map"
process run "Place & Route"
process run "Generate Programming File"
project close
SET busformat = BusFormatAngleBracketNotRipped
SET designentry = VHDL
SET device = xc6slx45t
SET devicefamily = spartan6
SET flowvendor = Other
SET package = fgg484
SET speedgrade = -3
SET verilogsim = false
SET vhdlsim = true
hdl ipbus/firmware/example_designs/hdl/clocks_s6_extphy.vhd
include ipbus/firmware/ethernet/cfg/file_list_s6_extphy
include ipbus/firmware/ipbus_core/cfg/file_list
project new fmc-mtlu
project set family spartan6
project set device xc6slx45t
project set package fgg484
project set speed -3
project set "Enable Multi-Threading" "2" -process "Map"
project set "Pack I/O Registers/Latches into IOBs" "For Inputs and Outputs" -process "Map"
project set "Enable Multi-Threading" "2" -process "Place & Route"
project set "Enable BitStream Compression" TRUE -process "Generate Programming File"
project set "Preferred Language" "VHDL"
project set "Set SPI Configuration Bus Width spartan6" 4
# source $::env(REPOS_FW_DIR)/firmware/example_designs/scripts/addfiles.tcl
# Just list files by hand for now. Can't get addfiles.tcl to work.
#xfile add ipbus/firmware/example_designs/hdl/clocks_s6_extphy.vhd
# IPBus Ethernet for gig_eth_pcs_pma_v11_5
xfile add ipbus/firmware/ethernet/hdl/eth_s6_gmii.vhd
xfile add ipbus/firmware/ethernet/hdl/emac_hostbus_decl.vhd
puts "Adding and Regenerating Ethernet cores"
# Add cores for Ethernet
exec cp ipbus/firmware/ethernet/coregen/tri_mode_eth_mac_v5_4.xco ipcore_dir
exec cp ipbus/firmware/ethernet/coregen/mac_fifo_axi4.xco ipcore_dir
xfile add ipcore_dir/tri_mode_eth_mac_v5_4.xco
xfile add ipcore_dir/mac_fifo_axi4.xco
# Don't regenerate cores for now...
#cd ipcore_dir
#catch {exec coregen -r -b tri_mode_eth_mac_v5_4.xco -p coregen.cgp}
#catch {exec coregen -r -b mac_fifo_axi4.xco -p coregen.cgp}
#cd ..
puts "Adding IPBus files"
# Xilinx ISE setup fragment for ipbus core
xfile add ipbus/firmware/ipbus_core/hdl/ipbus_package.vhd
xfile add ipbus/firmware/ipbus_core/hdl/ipbus_trans_decl.vhd
xfile add ipbus/firmware/ipbus_core/hdl/ipbus_ctrl.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_if_flat.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_buffer_selector.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_arp.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_payload.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_ping.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_resend.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_build_status.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_byte_sum.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_clock_crossing_if.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_do_rx_reset.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_dualportram.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_dualportram_rx.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_dualportram_tx.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_ipaddr_block.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_packet_parser.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_rarp_block.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_rxram_mux.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_rxram_shim.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_rxtransactor_if_simple.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_status_buffer.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_tx_mux.vhd
xfile add ipbus/firmware/ipbus_core/hdl/udp_txtransactor_if_simple.vhd
xfile add ipbus/firmware/ipbus_core/hdl/trans_arb.vhd
xfile add ipbus/firmware/ipbus_core/hdl/transactor.vhd
xfile add ipbus/firmware/ipbus_core/hdl/transactor_if.vhd
xfile add ipbus/firmware/ipbus_core/hdl/transactor_sm.vhd
xfile add ipbus/firmware/ipbus_core/hdl/transactor_cfg.vhd
xfile add ipbus/firmware/ipbus_core/hdl/stretcher.vhd
xfile add ipbus/firmware/ipbus_core/hdl/ipbus_fabric.vhd
xfile add ipbus/firmware/example_designs/hdl/clock_div.vhd
xfile add ipbus/firmware/slaves/hdl/ipbus_reg_types.vhd
#xfile add ipbus/firmware/slaves/hdl/syncreg_r.vhd
#xfile add ipbus/firmware/slaves/hdl/syncreg_w.vhd
#xfile add ipbus/firmware/slaves/hdl/ipbus_syncreg_v.vhd
xfile add ipbus/firmware/slaves/hdl/ipbus_ctrlreg_v.vhd
xfile add ipbus/firmware/slaves/hdl/ipbus_ctrlreg_v.vhd
# Add Opencores files for i2c interface
xfile add external/opencores_i2c/i2c_master_bit_ctrl.vhd
xfile add external/opencores_i2c/i2c_master_byte_ctrl.vhd
xfile add external/opencores_i2c/i2c_master_registers.vhd
xfile add external/opencores_i2c/i2c_master_top.vhd
# Add TLU cores....
# Add cores for Ethernet
puts "Adding and Regenerating TLU cores"
exec cp fmc-mtlu/firmware/ise/ipcore_dir/tlu_event_fifo.xco ipcore_dir
exec cp fmc-mtlu/firmware/ise/ipcore_dir/FIFO.xco ipcore_dir
exec cp fmc-mtlu/firmware/ise/ipcore_dir/CounterUp.xco ipcore_dir
exec cp fmc-mtlu/firmware/ise/ipcore_dir/internalTriggerGenerator.xco ipcore_dir
xfile add ipcore_dir/tlu_event_fifo.xco
xfile add ipcore_dir/FIFO.xco
#xfile add ipcore_dir/CounterUp.xco
xfile add ipcore_dir/internalTriggerGenerator.xco
# Don't regenerate cores for now...
#cd ipcore_dir
#catch {exec coregen -r -b tlu_event_fifo.xco -p coregen.cgp}
#catch {exec coregen -r -b FIFO.xco -p coregen.cgp}
#catch {exec coregen -r -b CounterUp.xco -p coregen.cgp}
#catch {exec coregen -r -b internalTriggerGenerator.xco -p coregen.cgp}
#cd ..
puts "Adding TLU Files "
# Add FMC-MTLU files. First the hand-written VHDL
xfile add fmc-mtlu/firmware/hdl/common/dualSERDES_1to4_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/DUTInterfaces_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/eventBuffer_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/eventFormatter_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/i2c_master_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/ipbus_addr_decode.vhd
xfile add fmc-mtlu/firmware/hdl/common/IPBusInterface_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/ipbus_ver.vhd
xfile add fmc-mtlu/firmware/hdl/common/logic_clocks_rtl.vhd
#xfile add fmc-mtlu/firmware/hdl/common/pulseClockDomainCrossing_rtl.vhd
#xfile add fmc-mtlu/firmware/hdl/common/Reg_2clks.vhd
xfile add fmc-mtlu/firmware/hdl/common/registerCounter_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/IODELAYCal_FSM_rtl.vhd
#xfile add fmc-mtlu/firmware/hdl/common/serdes_1_to_n_SDR.vhd
#xfile add fmc-mtlu/firmware/hdl/common/sync_reg.vhd
xfile add fmc-mtlu/firmware/hdl/common/triggerInputs_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/triggerLogic_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/clocks_s6_extphy.vhd
xfile add fmc-mtlu/firmware/hdl/common/arrivalTimeLUT_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/test/clock_divider_s6.v
xfile add fmc-mtlu/firmware/hdl/common/counterWithReset_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/synchronizeRegisters_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/handshakes_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/TPx3Logic_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/GPP_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/counterDown.vhd
xfile add fmc-mtlu/firmware/hdl/common/handshakes_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/TPx3Logic_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/pulseClockDomainCrossing_rtl.vhd
xfile add fmc-mtlu/firmware/hdl/common/counterDown.vhd
# Then add the HDL-Designer generated files..
xfile add fmc-mtlu/firmware/hdl_designer/fmc_mTLU/fmc_mTLU_lib/hdl/top_extphy_struct.vhd
xfile add fmc-mtlu/firmware/hdl_designer/fmc_mTLU/fmc_mTLU_lib/hdl/fmcTLU_pkg_body.vhd
xfile add fmc-mtlu/firmware/hdl_designer/fmc_mTLU/fmc_mTLU_lib/hdl/fmcTLU_pkg.vhd
# Add user constraints file
xfile add fmc-mtlu/firmware/ucf/sp605_FMC_mTLU_v1a.ucf
project close
puts "Successfully finished building project file"
This diff is collapsed.
--! @file dtype_fds.vhdl
--
-------------------------------------------------------------------------------
-- --
-- (c) University of Bristol, High Energy Physics Group --
-- --
-------------------------------------------------------------------------------
--
--
-- This file is part of IPBus.
--
-- IPBus is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- IPBus 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with IPBus. If not, see <http://www.gnu.org/licenses/>.
--
-- IPBus is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- IPBus 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with IPBus. If not, see <http://www.gnu.org/licenses/>.
--
--
--! Standard library
library IEEE;
-- Standard logic defintions.
use IEEE.STD_LOGIC_1164.all;
--
-- unit name: dtype_fds
--
--! @brief Aims to be the same as the Xilinx "FDS" primitive - D-Type flip-flop
--
--
--! @author David.Cussans@bristol.ac.uk
--
--! @date 7/May/2011
--
--! @version 0.1
--
--! @details -- Modified from D-type example in VHDL book.
--! See Xilinx spartan6_scm.pdf
--! Output goes high when input goes high ( asyncnronous to system clock).
--
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--! <reference one> \n
--! <reference two>
--!
--! <b>Modified by:</b>\n
--! Author: <name>
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! <date> <initials> <log>\n
--! <extended description>
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
-------------------------------------------------------------------------------
This diff is collapsed.
--=============================================================================
--! @file IODELAYCal_FSM_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- UoB , USC
-- --
------------------------------------------------------------------------------- --
--
--! @brief Finite-state machine to control calibration and reset signals to
--! Iserdes, IDelay
--! based on code by Alvaro Dosil\n
--
--! @author Alvaro Dosil
--
--! @date 22/Feb/2014
--
--! @version v0.1
--
--! @details
--
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo Implement a periodic calibration sequence\n
--! <another thing to do> \n
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity IODELAYCal_FSM is
port (
clk_i : in std_logic; --! Global clock
startcal_i : in std_logic; --! Start calibration
busy_i : in std_logic; --! Status of the IDELAY component
calibrate_o : out std_logic; --! Calibration signals to IODELAY
reset_o : out std_logic --! Reset to IODELAY component
);
end entity IODELAYCal_FSM;
architecture rtl of IODELAYCal_FSM is
--! Calibration FSM state values
type state_values is (st0, st1, st2, st3);
signal pres_state, next_state: state_values := st0;
signal s_cal_FSM : std_logic := '0'; -- IODELAY reset
signal s_rst_FSM : std_logic := '0'; -- IODELAY reset
begin -- rtl
--! Calibration FSM register
statereg: process(clk_i)
begin
if rising_edge(clk_i) then
pres_state <= next_state; -- Move to next state
end if;
end process statereg;
--! Calibration FSM combinational block
fsm: process(pres_state, startcal_i, busy_i)
begin
next_state <= pres_state;
-- Default values
s_Rst_FSM <= '0';
s_cal_FSM <= '0';
case pres_state is
-- st0 - IDLE
when st0=>
if ( startcal_i = '1') then
next_state <= st1; -- Next state is "st1 - SEND CALIBRATION SIGNAL"
end if;
-- st1 - SEND CALIBRATION SIGNAL
when st1=>
s_cal_FSM <= '1';
next_state <= st2; -- Next state is "st2 - WAIT BUSY = '0'"
-- st2 - WAIT BUSY = '0'
when st2=>
if busy_i = '0' then
next_state <= st3; -- Next state is "st3 - RESET STATE"
end if;
-- st3 - RESET STATE
when st3=>
s_Rst_FSM <= '1';
next_state <= st0; -- Next state is "st0 - IDLE"
end case;
end process fsm;
calibrate_o <= s_cal_FSM;
reset_o <= s_Rst_FSM;
end rtl;
--=============================================================================
--! @file IPBusInterface_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture fmc_mTLU_lib.IPBusInterface.rtl
--
--! @brief \n
--! \n
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 16:06:57 11/09/12
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
-- Created using using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE work.ipbus.all;
use work.emac_hostbus_decl.all;
ENTITY IPBusInterface IS
GENERIC(
NUM_EXT_SLAVES : positive := 5
);
PORT(
gmii_rx_clk_i : IN std_logic;
gmii_rx_dv_i : IN std_logic;
gmii_rx_er_i : IN std_logic;
gmii_rxd_i : IN std_logic_vector (7 DOWNTO 0);
ipbr_i : IN ipb_rbus_array (NUM_EXT_SLAVES-1 DOWNTO 0); -- ! IPBus read signals
sysclk_n_i : IN std_logic;
sysclk_p_i : IN std_logic; -- ! 200 MHz xtal clock
clocks_locked_o : OUT std_logic;
gmii_gtx_clk_o : OUT std_logic;
gmii_tx_en_o : OUT std_logic;
gmii_tx_er_o : OUT std_logic;
gmii_txd_o : OUT std_logic_vector (7 DOWNTO 0);
ipb_clk_o : OUT std_logic; -- ! IPBus clock to slaves
ipb_rst_o : OUT std_logic; -- ! IPBus reset to slaves
ipbw_o : OUT ipb_wbus_array (NUM_EXT_SLAVES-1 DOWNTO 0); -- ! IBus write signals
onehz_o : OUT std_logic;
phy_rstb_o : OUT std_logic;
dip_switch_i : IN std_logic_vector (3 DOWNTO 0);
clk_logic_xtal_o : OUT std_logic
);
-- Declarations
END ENTITY IPBusInterface ;
--
ARCHITECTURE rtl OF IPBusInterface IS
--! Number of slaves inside the IPBusInterface block.
constant c_NUM_INTERNAL_SLAVES : positive := 1;
signal clk125, locked, rst_125, rst_ipb: STD_LOGIC;
signal mac_txd, mac_rxd : STD_LOGIC_VECTOR(7 downto 0);
signal mac_txdvld, mac_txack, mac_rxclko, mac_rxdvld, mac_rxgoodframe, mac_rxbadframe : STD_LOGIC;
signal ipb_master_out : ipb_wbus;
signal ipb_master_in : ipb_rbus;
signal mac_addr: std_logic_vector(47 downto 0);
signal mac_tx_data, mac_rx_data: std_logic_vector(7 downto 0);
signal mac_tx_valid, mac_tx_last, mac_tx_error, mac_tx_ready, mac_rx_valid, mac_rx_last, mac_rx_error: std_logic;
signal ip_addr: std_logic_vector(31 downto 0);
signal s_ipb_clk : std_logic;
signal s_ipbw_internal: ipb_wbus_array (NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1 DOWNTO 0);
signal s_ipbr_internal: ipb_rbus_array (NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1 DOWNTO 0);
signal s_sysclk : std_logic;
signal pkt_rx, pkt_tx, pkt_rx_led, pkt_tx_led, sys_rst: std_logic;
BEGIN
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clocks_s6_extphy port map(
sysclk_p => sysclk_p_i,
sysclk_n => sysclk_n_i,
clk_logic_xtal_o => clk_logic_xtal_o,
clko_125 => clk125,
clko_ipb => s_ipb_clk,
locked => clocks_locked_o,
rsto_125 => rst_125,
rsto_ipb => rst_ipb,
onehz => onehz_o
);
-- Connect IPBus clock and reset to output ports.
ipb_clk_o <= s_ipb_clk;
ipb_rst_o <= rst_ipb;
-- leds <= ('0', '0', locked, onehz);
-- Ethernet MAC core and PHY interface
-- In this version, consists of hard MAC core and GMII interface to external PHY
-- Can be replaced by any other MAC / PHY combination
eth: entity work.eth_s6_gmii port map(
clk125 => clk125,
rst => rst_125,
gmii_gtx_clk => gmii_gtx_clk_o,
gmii_tx_en => gmii_tx_en_o,
gmii_tx_er => gmii_tx_er_o,
gmii_txd => gmii_txd_o,
gmii_rx_clk => gmii_rx_clk_i,
gmii_rx_dv => gmii_rx_dv_i,
gmii_rx_er => gmii_rx_er_i,
gmii_rxd => gmii_rxd_i,
tx_data => mac_tx_data,
tx_valid => mac_tx_valid,
tx_last => mac_tx_last,
tx_error => mac_tx_error,
tx_ready => mac_tx_ready,
rx_data => mac_rx_data,
rx_valid => mac_rx_valid,
rx_last => mac_rx_last,
rx_error => mac_rx_error
);
phy_rstb_o <= '1';
-- ipbus control logic
ipbus: entity work.ipbus_ctrl
generic map (
BUFWIDTH => 2)
port map(
mac_clk => clk125,
rst_macclk => rst_125,
ipb_clk => s_ipb_clk,
rst_ipb => rst_ipb,
mac_rx_data => mac_rx_data,
mac_rx_valid => mac_rx_valid,
mac_rx_last => mac_rx_last,
mac_rx_error => mac_rx_error,
mac_tx_data => mac_tx_data,
mac_tx_valid => mac_tx_valid,
mac_tx_last => mac_tx_last,
mac_tx_error => mac_tx_error,
mac_tx_ready => mac_tx_ready,
ipb_out => ipb_master_out,
ipb_in => ipb_master_in,
mac_addr => mac_addr,
ip_addr => ip_addr,
pkt_rx => pkt_rx,
pkt_tx => pkt_tx,
pkt_rx_led => pkt_rx_led,
pkt_tx_led => pkt_tx_led
);
mac_addr <= X"020ddba115" & dip_switch_i & X"0"; -- Careful here, arbitrary addresses do not always work
ip_addr <= X"c0a8c8" & dip_switch_i & X"0"; -- 192.168.200.X
fabric: entity work.ipbus_fabric
generic map(NSLV => NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES)
port map(
ipb_in => ipb_master_out,
ipb_out => ipb_master_in,
ipb_to_slaves => s_ipbw_internal,
ipb_from_slaves => s_ipbr_internal
);
ipbw_o <= s_ipbw_internal(NUM_EXT_SLAVES-1 downto 0);
s_ipbr_internal(NUM_EXT_SLAVES-1 downto 0) <= ipbr_i;
-- Slave: firmware ID
firmware_id: entity work.ipbus_ver
port map(
ipbus_in => s_ipbw_internal(NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1),
ipbus_out => s_ipbr_internal(NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1)
);
END ARCHITECTURE rtl;
----------------------------------------------------------------------------------
-- Company: Universidade de Santiago de Compostela
-- Engineer: Alvaro Dosil
--
-- Create Date: 31/07/2012
-- Module Name: Reg_2clks - Behavioral
-- Revision 0.01 - File Created
-- Additional Comments:
----------------------------------------------------------------------------------
-------------------------------------------------------
--! @file
--! @brief Synchronization module 1b
--! @author Alvaro Dosil
-------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Reg_2clks is
port(
clk_i : in std_logic; --! Synchronous clock
async_i : in std_logic; --! Asynchronous input data
sync_o : out std_logic --! Synchronous output data
);
end Reg_2clks;
--! @brief
--! @details Synchronize 1 bit of data
architecture Behavioral of Reg_2clks is
signal sreg : std_logic_vector(1 downto 0);
attribute TIG : string;
attribute IOB : string;
attribute ASYNC_REG : string;
attribute SHIFT_EXTRACT : string;
attribute HBLKNM : string;
attribute TIG of async_i : signal is "TRUE";
attribute IOB of async_i : signal is "FALSE";
attribute ASYNC_REG of sreg : signal is "TRUE";
attribute SHIFT_EXTRACT of sreg : signal is "NO";
attribute HBLKNM of sreg : signal is "sync_reg";
begin
process (clk_i)
begin
if rising_edge(clk_i) then
sync_o <= sreg(1);
sreg <= sreg(0) & async_i;
end if;
end process;
end Behavioral;
--=============================================================================
--! @file TPx3Logic_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Santiago de Compostela, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture fmc_mTLU_lib.TPx3Logic.rtl
--
--! @brief Produces shutters \n
--! IPBus address map:\n
--
--! @author Alvaro Dosil , alvaro.dosil@usc.es
--
--! @date 16:06:19 11/06/14
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by: Alvaro Dosil , alvaro.dosil@usc.es </b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! Move all IPBus stuff into ipbus_syncreg_v , which also handles clock domain
--! crossing. 20/Feb/2014 , David Cussans
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
-- Created using using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE work.ipbus.all;
use work.ipbus_reg_types.all;
ENTITY TPx3Logic IS
GENERIC(
g_IPBUS_WIDTH : positive := 32
);
PORT(
clk_i : IN std_logic; -- ! Rising edge active
Start_T0sync_i : IN std_logic;
T0syncLen_i : IN std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0);
logic_reset_i : IN std_logic; -- active high. Synchronous with clk_4x_logic
Busy_i : IN std_logic;
Veto_i : IN std_logic;
Shutter_o : OUT std_logic;
T0sync_o : OUT std_logic
);
-- Declarations
END ENTITY TPx3Logic ;
--
ARCHITECTURE rtl OF TPx3Logic IS
type state_values is (st0, st1);
signal pres_state, next_state: state_values;
signal s_Enable : std_logic := '0';
signal s_Shutter, s_Shutter_d1f, s_Shutter_d1, s_T0sync, s_T0sync_d1f : std_logic := '0';
signal s_Start_T0sync, s_Start_T0sync_d1, s_Start_T0sync_d2, s_Start_T0sync_d3 : std_logic;
signal Rst_T0sync, T0syncT : std_logic; --Load signal and flag for the T0sync
signal s_RunNumber : unsigned(g_IPBUS_WIDTH-1 downto 0) := (others => '0'); -- ! counters for runs
BEGIN
-----------------------------------------------------------------------------
-- Counters
-----------------------------------------------------------------------------
--T0sync counter
c_T0sync: entity work.CounterDown
generic map(
MAX_WIDTH => g_IPBUS_WIDTH
)
port map(
Clk => clk_i,
Reset => '0',
Load => Rst_T0sync,
InitVal => std_logic_vector(unsigned(T0syncLen_i)-1),
Count => open,
Q => T0syncT
);
-----------------------------------------------------------------------------
-- FSM register
-----------------------------------------------------------------------------
statereg: process(clk_i)
begin
if rising_edge(clk_i) then
pres_state <= next_state; --Move to the next state
end if;
end process statereg;
-----------------------------------------------------------------------------
-- FSM combinational block
-----------------------------------------------------------------------------
fsm: process(pres_state, s_Start_T0sync, T0syncT)
begin
next_state<=pres_state;
s_T0sync <='0';
Rst_T0sync <= '1';
case pres_state is
when st0=>
if s_Start_T0sync = '1' then
next_state <= st1; --Next state is "Whait for end of T0sync signal"
end if;
when st1 =>
Rst_T0sync <='0';
s_T0sync <='1';
if T0syncT = '1' then
next_state<=st0; --Next state is "Whait for end of T0-sync counter"
end if;
when others=>
next_state<=st0; --Next state is "Whait for T0sync start"
end case;
end process fsm;
-----------------------------------------------------------------------------
-- Busy signals
-----------------------------------------------------------------------------
s_Enable <= not Veto_i;
s_Shutter <= not Busy_i and not Veto_i;
--Shutter_o <= s_Shutter;
--T0sync_o <= s_T0sync;
-----------------------------------------------------------------------------
-- Count runs and synchronization
-----------------------------------------------------------------------------
p_run_counter: process (clk_i )
begin -- process p_run_counter
if rising_edge(clk_i) then
s_Start_T0sync_d1 <= Start_T0sync_i;
s_Start_T0sync_d2 <= s_Start_T0sync_d1;
s_Start_T0sync_d3 <= s_Start_T0sync_d2;
s_Start_T0sync <= s_Start_T0sync_d2 and ( not s_Start_T0sync_d3);
s_Shutter_d1 <= s_Shutter;
if logic_reset_i = '1' then
s_RunNumber <= (others => '0');
elsif s_Shutter='1' and s_Shutter_d1='0' then
s_RunNumber <= s_RunNumber + 1;
end if;
end if;
-- Signals synchronous with falling edge clock
if falling_edge(clk_i) then
s_Shutter_d1f <= s_Shutter;
Shutter_o <= s_Shutter_d1f;
s_T0sync_d1f <= s_T0sync;
T0sync_o <= s_T0sync_d1f;
end if;
end process p_run_counter;
END ARCHITECTURE rtl;
This diff is collapsed.
-- clocks_s6_extphy
--
-- Generates a 125MHz ethernet clock and 31MHz ipbus clock from the 200MHz reference
-- Includes reset logic for ipbus
--
-- Dave Newbold, April 2011
--
-- $Id$
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.VComponents.all;
entity clocks_s6_extphy is port(
sysclk_p, sysclk_n: in std_logic;
-- dummy_sysclk : in std_logic;
clk_logic_xtal_o : out std_logic;
clko_125: out std_logic;
clko_ipb: out std_logic;
locked: out std_logic;
rsto_125: out std_logic;
rsto_ipb: out std_logic;
onehz: out std_logic
);
end clocks_s6_extphy;
architecture rtl of clocks_s6_extphy is
signal clk_ipb_i, clk_ipb_b, clk_125_i, clk_125_b, sysclk : std_logic;
-- signal sysclk_in : std_logic;
signal d25, d25_d, dcm_locked: std_logic;
signal rst: std_logic := '1';
signal s_xtal_dcm_locked: std_logic;
signal s_clk_logic_xtal : std_logic;
-- signal clk_400: std_logic;
-- component clock_divider_s6 port(
-- clk: in std_logic;
-- d25: out std_logic;
-- d28: out std_logic
-- );
-- end component;
begin
ibufgds0: IBUFGDS port map(
i => sysclk_p,
ib => sysclk_n,
o => sysclk
);
-- -- Add global clock buffer in sysclk path.
-- bufg_sysclk : BUFG port map (
-- i => sysclk_in,
-- o => sysclk);
bufg_125: BUFG port map(
i => clk_125_i,
o => clk_125_b
);
clko_125 <= clk_125_b;
bufg_ipb: BUFG port map(
i => clk_ipb_i,
o => clk_ipb_b
);
bufg_clk_logic_xtal: BUFG port map(
i => s_clk_logic_xtal,
o => clk_logic_xtal_o
);
clko_ipb <= clk_ipb_b;
dcm0: DCM_CLKGEN
generic map(
CLKIN_PERIOD => 5.0,
CLKFX_MULTIPLY => 5,
CLKFX_DIVIDE => 8,
CLKFXDV_DIVIDE => 4
)
port map(
clkin => sysclk,
clkfx => clk_125_i,
clkfxdv => clk_ipb_i,
locked => dcm_locked,
rst => '0'
);
clkdiv: entity work.clock_divider_s6 port map(
-- clkdiv: entity work.clock_div port map(
clk => sysclk,
-- D17 => open,
d25 => d25,
d28 => onehz
);
process(sysclk)
begin
if rising_edge(sysclk) then
d25_d <= d25;
if d25='1' and d25_d='0' then
rst <= not dcm_locked;
end if;
end if;
end process;
locked <= dcm_locked;
process(clk_ipb_b)
begin
if rising_edge(clk_ipb_b) then
rsto_ipb <= rst;
end if;
end process;
process(clk_125_b)
begin
if rising_edge(clk_125_b) then
rsto_125 <= rst;
end if;
end process;
sys40_gen : BUFIO2
generic map (
DIVIDE => 5, -- DIVCLK divider (1-8)
DIVIDE_BYPASS => FALSE) -- Bypass the divider circuitry (TRUE/FALSE)
port map (
I => SysClk, -- 1-bit input: Clock input (connect to IBUFG)
DIVCLK => s_clk_logic_xtal, -- 1-bit output: Divided clock output
IOCLK => open, -- 1-bit output: I/O output clock
SERDESSTROBE => open); -- 1-bit output: Output SERDES strobe (connect to ISERDES2/OSERDES2)
-- Generate 40MHz clock from 200MHz crystal
-- dcmXTAL: DCM_CLKGEN
-- generic map(
-- CLKIN_PERIOD => 5.0,
-- CLKFX_MULTIPLY => 2,
-- CLKFX_DIVIDE => 10,
-- CLKFXDV_DIVIDE => 2
-- )
-- port map(
-- clkin => sysclk,
-- clkfx => s_clk_logic_xtal,
-- clkfxdv => open,
-- locked => s_xtal_dcm_locked,
-- rst => '0'
-- );
--
end rtl;
--Counter down
--Outputs: Q<='1' while counting
-- Q<='0' if not counting
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
ENTITY CounterDown IS
GENERIC(
MAX_WIDTH: positive := 32
);
PORT(
Clk : in std_logic;
Reset : in std_logic;
Load : in std_logic;
InitVal : in std_logic_vector(MAX_WIDTH-1 downto 0);
Count : out Std_logic_vector(MAX_WIDTH-1 downto 0);
Q : out std_logic
);
END ENTITY CounterDown;
architecture rtl of CounterDown is
signal cnt : std_logic_vector(MAX_WIDTH-1 downto 0);
signal Qtmp : std_logic;
begin
Counter: process (Clk, Reset)
begin
if (Reset='1') then
cnt <= (others =>'0');
elsif rising_edge(Clk) then
if (Load='1') then
cnt <= InitVal;
else
if Qtmp='0' then
cnt <= std_logic_vector(unsigned(cnt) - 1);
end if;
end if;
end if;
end process;
Qtmp <= '1' when cnt=(cnt'range=>'0') else
'0';
Count <= cnt;
Q <= Qtmp;
end rtl;
--=============================================================================
--! @file counterWithReset_rtl.vhd
--=============================================================================
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- unit name: counterWithReset (counterWithReset / rtl)
--
--! @brief Simple counter with synchronous reset
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date Feb\2012
--
--! @version v0.1
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! None
--!
--! <b>References:</b>\n
--! referenced by ipBusMarocTriggerGenerator \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 5/Mar/12 DGC Changed to use numeric_std\n
--! 26/Feb/14 DGC Added registers to output to aid timing closure.
--!
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
---------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for counterWithReset
--============================================================================
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY counterWithReset IS
GENERIC (g_COUNTER_WIDTH : integer := 32; --! Number of bits
g_OUTPUT_REGISTERS : integer := 4 --! Number of output registers. Minumum =1. Aids timing closure.
);
PORT
(
clock_i: IN STD_LOGIC; --! rising edge active clock
reset_i: IN STD_LOGIC; --! Active high. syncronous with rising clk
enable_i: IN STD_LOGIC; --! counts when enable=1
result_o: OUT STD_LOGIC_VECTOR ( g_COUNTER_WIDTH-1 downto 0) --! Unsigned integer output
);
END counterWithReset;
ARCHITECTURE rtl OF counterWithReset IS
type t_register_array is array(natural range <>) of UNSIGNED ( g_COUNTER_WIDTH-1 downto 0) ; -- --! Array of arrays for output register...
signal s_output_registers : t_register_array(g_OUTPUT_REGISTERS downto 0) := ( others => ( others => '0')); -- --! Output registers.
BEGIN
--! Process to count up from zero when enable_i is high.
p_counter: PROCESS (clock_i)
BEGIN
IF rising_edge(clock_i) THEN
IF (reset_i = '1') THEN
s_output_registers(0) <= (others => '0');
ELSIF (enable_i='1') THEN
s_output_registers(0) <= s_output_registers(0) + 1;
END IF;
END IF;
END PROCESS p_counter;
--! Generate some output registers. Number controlled by g_OUTPUT_REGISTERS
generate_registers: for v_register in 1 to g_OUTPUT_REGISTERS generate
--! An individual register
p_outputRegister: process (clock_i)
begin -- process p_outputRegister
if rising_edge(clock_i) then
s_output_registers( v_register) <=
s_output_registers( v_register-1);
end if;
end process p_outputRegister;
end generate generate_registers; -- v_register
--! Copy the (registered) result to the output
result_o <= STD_LOGIC_VECTOR(s_output_registers(g_OUTPUT_REGISTERS));
END rtl;
This diff is collapsed.
--=============================================================================
--! @file eventBuffer_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture fmc_mTLU_lib.eventBuffer.rtl
--
--! @brief Stores input words (64bits) for readout over IPBus. \n
--! Uses a FIFO ( 64bits at input, 32 bits at output )\n
--! Address map:\n
--! 0x0000 - FIFO data\n
--! 0x0001 - FIFO fill level\n
--! 0x0010 - FIFO status/control:\n
--! Writing Bit-0 resets pointers.\n
--! Reading bit-1 returns "prog_full" flag
--
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 15:24:50 11/13/12
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by: Alvaro Dosil , alvaro.dosil@usc.es </b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
-- Created using using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE work.ipbus.all;
ENTITY eventBuffer IS
GENERIC(
g_EVENT_DATA_WIDTH : positive := 64;
g_IPBUS_WIDTH : positive := 32;
g_WRITE_COUNTER_WIDTH : positive := 15;
g_READ_COUNTER_WIDTH : positive := 16
);
PORT(
clk_4x_logic_i : IN std_logic;
data_strobe_i : IN std_logic; -- Indicates data to transfer
event_data_i : IN std_logic_vector (g_EVENT_DATA_WIDTH-1 DOWNTO 0);
ipbus_clk_i : IN std_logic;
ipbus_i : IN ipb_wbus;
ipbus_reset_i : IN std_logic;
strobe_4x_logic_i : IN std_logic;
--trigger_count_i : IN std_logic_vector (g_IPBUS_WIDTH-1 DOWNTO 0); --! Not used yet.
rst_fifo_o : OUT std_logic; --! rst signal to first level fifos
buffer_full_o : OUT std_logic; --! Goes high when event buffer almost full
ipbus_o : OUT ipb_rbus;
logic_reset_i : IN std_logic -- reset buffers when high. Synch withclk_4x_logic
);
-- Declarations
END ENTITY eventBuffer ;
--
ARCHITECTURE rtl OF eventBuffer IS
signal s_rd_data_count : std_logic_vector(g_READ_COUNTER_WIDTH-1 downto 0) := (others =>'0');
signal s_fifo_fill_level : std_logic_vector(g_IPBUS_WIDTH-1 downto 0) := (others =>'0'); -- read-counter - 2*write_count
signal s_write_strobe : std_logic := '0';
signal s_rst_fifo, s_rst_fifo_ipb : std_logic := '0'; -- ! Take high to reset FIFO pointers.
signal s_fifo_prog_full : std_logic := '0'; -- ! Controlled by programmable-full flag of FIFO core
signal s_fifo_rd_en : std_logic := '0'; -- ! Take high to clock data out of FIFO
signal s_fifo_dout : std_logic_vector(g_IPBUS_WIDTH-1 downto 0); -- ! Output from FIFO ( fall-through mode)
signal s_fifo_valid : std_logic := '1'; -- ! High when data in FIFO
signal s_fifo_full, s_fifo_almost_full, s_fifo_empty, s_fifo_almost_empty : std_logic := '0'; -- ! full and empty FIFO flags
signal s_fifo_status_ipb , s_fifo_fill_level_d1 : std_logic_vector(ipbus_o.ipb_rdata'range) := (others => '0'); -- data registered onto IPBus clock
BEGIN
-----------------------------------------------------------------------------
-- IPBus IO
-----------------------------------------------------------------------------
--! Generate FIFO read enable
s_fifo_rd_en <= '1' when ipbus_i.ipb_strobe = '1' and ipbus_i.ipb_write = '0' and ipbus_i.ipb_addr(1 downto 0) = "00" else '0';
s_fifo_valid <= '1';
--! Generate IPBus ACK
ipbus_o.ipb_ack <= (ipbus_i.ipb_strobe and not s_fifo_rd_en) or (s_fifo_valid and s_fifo_rd_en);
ipbus_o.ipb_err <= '0';
--! Multiplex output data.
with ipbus_i.ipb_addr(1 downto 0) select ipbus_o.ipb_rdata <=
s_fifo_dout when "00",
s_fifo_fill_level when "01",
s_fifo_status_ipb when "10",
(others => '1') when others;
ipbus_write: process (ipbus_clk_i)
begin -- process ipbus_write
if rising_edge(ipbus_clk_i) then
s_rst_fifo_ipb <= '0';
if ipbus_i.ipb_strobe = '1' and ipbus_i.ipb_addr(1 downto 0) = "10" and ipbus_i.ipb_write = '1' then
s_rst_fifo_ipb <= '1';
end if;
-- Register data onto IPBus clock domain to ease timing closure.
s_fifo_status_ipb <= X"000000" & "000" & s_fifo_prog_full & s_fifo_full & s_fifo_almost_full & s_fifo_almost_empty & s_fifo_empty;
s_fifo_fill_level <= X"0000" & s_rd_data_count;
end if;
end process ipbus_write;
rst_fifo_o <= s_rst_fifo_ipb;
s_rst_fifo <= s_rst_fifo_ipb or logic_reset_i;
-----------------------------------------------------------------------------
-- FIFO and fill-level calculation
-----------------------------------------------------------------------------
-- Instantiate a buffer to store the data. 64-bit on input, 32-bit on output.
event_fifo : entity work.tlu_event_fifo
PORT MAP (
rst => s_rst_fifo,
wr_clk => clk_4x_logic_i,
rd_clk => ipbus_clk_i,
din => event_data_i,
wr_en => data_strobe_i,
rd_en => s_fifo_rd_en,
dout => s_fifo_dout,
full => s_fifo_full,
almost_full => s_fifo_almost_full,
empty => s_fifo_empty,
almost_empty => s_fifo_almost_empty,
rd_data_count => s_rd_data_count,
prog_full => s_fifo_prog_full
);
buffer_full_o <= s_fifo_prog_full;
END ARCHITECTURE rtl;
This diff is collapsed.
--=============================================================================
--! @file handshakes_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Santiago de Compostela, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture fmc_mTLU_lib.handshakes.rtl
--
--! @brief Handshakes between TLU and DUTs. \n
--
--
--! @author Alvaro Dosil , alvaro.dosil@usc.es
--
--! @date 12:08:30 25/06/14
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by: </b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
-- Created using using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE work.ipbus.all;
use work.ipbus_reg_types.all;
ENTITY handshakes IS
GENERIC(
g_IPBUS_WIDTH : positive := 32
);
PORT(
clk_i : IN std_logic;
Trigger_i : IN std_logic;
ipbus_clk_i : IN std_logic;
ipbus_i : IN ipb_wbus;
ipbus_reset_i : IN std_logic;
ipbus_o : OUT ipb_rbus;
logic_reset_i : IN std_logic;
Busy_i : IN std_logic;
AIDAhandshake_o : OUT std_logic; -- running an AIDA handshake or the old EUDET handshake
Trigger_o : OUT std_logic;
rst_or_clk_o : OUT std_logic -- CONT in schematics
);
-- Declarations
END ENTITY handshakes ;
--
ARCHITECTURE rtl OF handshakes IS
signal s_handshakeEnabled : std_logic_vector(g_IPBUS_WIDTH-1 downto 0);
signal s_Shutter, s_T0sync : std_logic;
signal s_Trigger, s_TrigAux : std_logic := '0';
signal s_Busy, s_Busy_d1, s_Busy_d2, s_Busy_d3 : std_logic;
signal TPx3_T0syncLen : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0) := x"00000004"; --! T0-sync length
signal TPx3_Start_T0sync : std_logic; --! Flag to start the T0-sync signal
signal s_Veto : std_logic := '0';
signal s_WU : std_logic := '0';
signal s_NMaxPulses : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0) := (others=>'0');
signal s_SuDTime : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0) := (others=>'0');
signal s_PulseLen : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0) := x"00000001";
signal s_IpDTime : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0) := x"00000001";
signal s_RearmTime : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0) := x"10000000";
signal s_PulseDelay : std_logic_vector(g_IPBUS_WIDTH-1 DOWNTO 0) := (others=>'0');
signal s_MaxPulses : std_logic;
signal s_pulse : std_logic;
constant c_N_CTRL : positive := 13;
constant c_N_STAT : positive := 13;
signal s_status_to_ipbus, s_sync_status_to_ipbus : ipb_reg_v(c_N_STAT-1 downto 0);
signal s_control_from_ipbus,s_sync_control_from_ipbus : ipb_reg_v(c_N_CTRL-1 downto 0);
BEGIN
-----------------------------------------------------------------------------
-- IPBus interface
-----------------------------------------------------------------------------
ipbus_registers: entity work.ipbus_ctrlreg_v
generic map(
N_CTRL => c_N_CTRL,
N_STAT => c_N_STAT
)
port map(
clk => ipbus_clk_i,
reset=> '0',--ipbus_reset_i ,
ipbus_in=> ipbus_i,
ipbus_out=> ipbus_o,
d=> s_sync_status_to_ipbus,
q=> s_control_from_ipbus,
stb=> open
);
-- Synchronize registers from logic clock to ipbus.
sync_status: entity work.synchronizeRegisters
generic map (
g_NUM_REGISTERS => c_N_STAT )
port map (
clk_input_i => clk_i,
data_i => s_status_to_ipbus,
data_o => s_sync_status_to_ipbus,
clk_output_i => ipbus_clk_i);
-- Synchronize registers from logic clock to ipbus.
sync_ctrl: entity work.synchronizeRegisters
generic map (
g_NUM_REGISTERS => c_N_CTRL )
port map (
clk_input_i => ipbus_clk_i,
data_i => s_control_from_ipbus,
data_o => s_sync_control_from_ipbus,
clk_output_i => clk_i);
-----------------------------------------------------------------------------
-- Logic not ready to use
-----------------------------------------------------------------------------
--Map the control registers
s_handshakeEnabled <= s_sync_control_from_ipbus(0);
s_status_to_ipbus(0) <= s_handshakeEnabled;
-- No handshake registers
s_NMaxPulses <= s_sync_control_from_ipbus(5);
s_SuDTime <= s_sync_control_from_ipbus(6);
s_PulseLen <= s_sync_control_from_ipbus(7);
s_IpDTime <= s_sync_control_from_ipbus(8);
s_RearmTime <= s_sync_control_from_ipbus(9);
s_PulseDelay <= s_sync_control_from_ipbus(10);
s_Veto <= s_sync_control_from_ipbus(11)(0);
s_WU <= s_sync_control_from_ipbus(11)(1);
s_status_to_ipbus(5) <= s_NMaxPulses;
s_status_to_ipbus(6) <= s_SuDTime;
s_status_to_ipbus(7) <= s_PulseLen;
s_status_to_ipbus(8) <= s_IpDTime;
s_status_to_ipbus(9) <= s_RearmTime;
s_status_to_ipbus(10) <= s_PulseDelay;
s_status_to_ipbus(11) <= x"0000000"& "00" & s_WU & s_Veto;
s_status_to_ipbus(12) <= x"0000000"& "000" & s_MaxPulses;
-- TPx3 registers
TPx3_Start_T0sync <= s_sync_control_from_ipbus(1)(0);
TPx3_T0syncLen <= x"00000001" when s_sync_control_from_ipbus(2)<x"000000002" else
s_sync_control_from_ipbus(2);
s_status_to_ipbus(1) <= x"0000000" & "000" & TPx3_Start_T0sync;
s_status_to_ipbus(2) <= TPx3_T0syncLen;
-----------------------------------------------------------------------------
-- Synchronization - Rewrite!!!
-----------------------------------------------------------------------------
p_trigger : process(Trigger_i, s_Trigger)
begin
if Trigger_i = '1' then
s_TrigAux <= '1';
elsif s_Trigger = '1' then
s_TrigAux <= '0';
end if;
end process p_trigger;
p_sync: process (clk_i )
begin -- process p_run_counter
if rising_edge(clk_i) then
s_Trigger <= s_TrigAux;
s_Busy_d1 <= Busy_i;
s_Busy_d2 <= s_Busy_d1;
s_Busy_d3 <= s_Busy_d2;
s_Busy <= s_Busy_d2;
end if;
end process p_sync;
-----------------------------------------------------------------------------
-- I/O
-----------------------------------------------------------------------------
Trigger_o <= s_Trigger when s_handshakeEnabled(1 downto 0) = "00" and s_Busy = '0' else
s_pulse when s_handshakeEnabled(1 downto 0) = "01" else -- No handshake
s_Shutter when s_handshakeEnabled(1 downto 0) = "10" else -- TPx3 handshake
'0';
rst_or_clk_o <= s_T0sync when s_handshakeEnabled(1 downto 0) = "10" else
'0';
AIDAhandshake_o <= not s_handshakeEnabled(3); -- s_handshakeEnabled = x"00001000" => EUDET handshake.
-- All handshakes with s_handshakeEnabled(3)='0' are AIDA handshakes
-- No Handshake (GPP)
No_handshake: entity work.GPP
GENERIC MAP(
g_IPBUS_WIDTH => g_IPBUS_WIDTH)
PORT MAP(
clk_i => clk_i,
Enable_i => not (s_Busy or s_Veto),
Reset_i => logic_reset_i,
RstPulsCnt_i => '0',
Trigger_i => s_Trigger,
NMaxPulses_i => s_NMaxPulses,
SuDTime_i => s_SuDTime,
PulsLen_i => s_PulseLen,
IpDTime_i => s_IpDTime,
RearmTime_i => s_RearmTime,
Force_PullDown_i => s_Busy or s_Veto,
WU_i => s_WU,
PulseDelay_i => s_PulseDelay,
event_number_o => open,
MaxPulses_o => s_MaxPulses,
Pulse_o => s_pulse,
Pulse_d_o => open);
-- TPx3 Handshake
TPx3_logic: entity work.TPx3Logic
PORT MAP(
clk_i => clk_i,
Start_T0sync_i => TPx3_Start_T0sync,
T0syncLen_i => TPx3_T0syncLen,
logic_reset_i => logic_reset_i,
Busy_i => s_Busy,
Veto_i => s_Veto,
Shutter_o => s_Shutter,
T0sync_o => s_T0sync
);
END ARCHITECTURE rtl;
--=============================================================================
--! @file i2c_master_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture work.i2c_master.rtl
--
--! @brief Wraps the Wishbone I2C master in a wrapper where the IPBus signals\n
--! are bundled together in a record\n
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 17:22:12 11/30/12
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
-- Created using using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE work.ipbus.all;
ENTITY i2c_master IS
PORT(
i2c_scl_i : IN std_logic;
i2c_sda_i : IN std_logic;
ipbus_clk_i : IN std_logic;
ipbus_i : IN ipb_wbus; -- Signals from IPBus core to slave
ipbus_reset_i : IN std_logic;
i2c_scl_enb_o : OUT std_logic;
i2c_sda_enb_o : OUT std_logic;
ipbus_o : OUT ipb_rbus -- signals from slave to IPBus core
);
-- Declarations
END ENTITY i2c_master ;
--
ARCHITECTURE rtl OF i2c_master IS
--signal s_i2c_scl, s_i2c_scl_o, s_i2c_scl_enb, s_i2c_sda, s_i2c_sda_enb : std_logic ;
BEGIN
--i2c_scl_b <= s_i2c_scl when (s_i2c_scl_enb = '0') else 'Z';
--i2c_sda_b <= s_i2c_sda when (s_i2c_sda_enb = '0') else 'Z';
i2c_interface: entity work.i2c_master_top port map(
wb_clk_i => ipbus_clk_i,
wb_rst_i => ipbus_reset_i,
arst_i => '1',
wb_adr_i => ipbus_i.ipb_addr(2 downto 0),
wb_dat_i => ipbus_i.ipb_wdata(7 downto 0),
wb_dat_o => ipbus_o.ipb_rdata(7 downto 0),
wb_we_i => ipbus_i.ipb_write,
wb_stb_i => ipbus_i.ipb_strobe,
wb_cyc_i => '1',
wb_ack_o => ipbus_o.ipb_ack,
wb_inta_o => open,
scl_pad_i => i2c_scl_i,
scl_pad_o => open,
scl_padoen_o => i2c_scl_enb_o,
sda_pad_i => i2c_sda_i,
sda_pad_o => open,
sda_padoen_o => i2c_sda_enb_o
);
ipbus_o.ipb_rdata(31 downto 8) <= ( others => '0');
ipbus_o.ipb_err <= '0'; -- never return an error.
END ARCHITECTURE rtl;
-- Address decode logic for ipbus fabric
--
-- This file has been AUTOGENERATED from the address table - do not hand edit
--
-- We assume the synthesis tool is clever enough to recognise exclusive conditions
-- in the if statement.
--
-- Dave Newbold, February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
use work.ipbus.all;
package ipbus_addr_decode is
function ipbus_addr_sel(signal addr : in std_logic_vector(31 downto 0)) return integer;
end ipbus_addr_decode;
package body ipbus_addr_decode is
function ipbus_addr_sel(signal addr : in std_logic_vector(31 downto 0)) return integer is
variable sel : integer;
begin
if std_match(addr, "-----------------------0001-----") then
sel := 0; -- DUTInterfaces / base 00000020 / mask 0000001f
elsif std_match(addr, "-----------------------0010-----") then
sel := 1; -- triggerInputs / base 00000040 / mask 0000001f
elsif std_match(addr, "-----------------------0011-----") then
sel := 2; -- triggerLogic / base 00000060 / mask 0000001f
elsif std_match(addr, "-----------------------0100-----") then
sel := 3; -- eventBuffer / base 00000080 / mask 0000001f
elsif std_match(addr, "-----------------------0101-----") then
sel := 4; -- logic_clocks / base 000000a0 / mask 0000001f
elsif std_match(addr, "-----------------------0110-----") then
sel := 5; -- i2c_master / base 000000c0 / mask 00000007
elsif std_match(addr, "-----------------------0111-----") then
sel := 6; -- Trigger_Generator / base 000000e0 / mask 0000001f
elsif std_match(addr, "-----------------------1000-----") then
sel := 7; -- Shutter_Generator / base 00000100 / mask 0000001f
elsif std_match(addr, "-----------------------1001-----") then
sel := 8; -- Spill_Generator / base 00000120 / mask 0000001f
elsif std_match(addr, "-----------------------1010-----") then
sel := 9; -- Event_Formatter / base 00000140 / mask 0000001f
elsif std_match(addr, "-----------------------1011-----") then
sel := 10; -- Handshakes / base 00000160 / mask 0000001f
elsif std_match(addr, "-----------------------0000-----") then
sel := 11; -- version / base 00000000 / mask 00000000
else
sel := 99;
end if;
return sel;
end ipbus_addr_sel;
end ipbus_addr_decode;
-- Version register, returns a fixed value
--
-- To be replaced by a more coherent versioning mechanism later
--
-- Dave Newbold, August 2011
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
entity ipbus_ver is
port(
ipbus_in: in ipb_wbus;
ipbus_out: out ipb_rbus
);
end ipbus_ver;
architecture rtl of ipbus_ver is
begin
ipbus_out.ipb_rdata <= X"a5ed" & X"1008"; -- Lower 16b are ipbus firmware build ID (temporary arrangement).
ipbus_out.ipb_ack <= ipbus_in.ipb_strobe;
ipbus_out.ipb_err <= '0';
end rtl;
-- Build log
--
-- build 0x1000 : 22/08/11 : Starting build ID
-- build 0x1001 : 29/08/11 : Version for SPI testing
-- build 0x1002 : 27/09/11 : Bug fixes, new transactor code; v1.3 candidate
-- build 0x1003 : buggy
-- build 0x1004 : 18/10/11 : New mini-t top level, bug fixes, 1.3 codebase
-- build 0x1005 : 20/10/11 : ipbus address config testing in mini-t
-- build 0x1006 : 26/10/11 : trying with jumbo frames
-- build 0x1007 : 27/10/11 : new slaves / address map + rhino frames
-- build 0x1008 : 31/10/11 : rhino frames + multibus demo
This diff is collapsed.
--=============================================================================
--! @file pulseClockDomainCrossing_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture worklib.pulseClockDomainCrossing.rtl
--
--! @brief Takes a pulse synchronized with one clock and produces a
--! pulse synchronized to another clock.
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date September/2012
--
--! @version v0.1
--
--! @details A "ring" of D-type flip-flops is used to transfer a strobe
--! from the input clock domain to the output clock domain and then back again.
--! The time taken to transit from input to output is approximately
--! two clock cycles of clock_output_i .
--! After an additional two cycles of clk_input_i another pulse can be sent
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity pulseClockDomainCrossing is
port (
clk_input_i : in std_logic; --! clock for input
pulse_i : in std_logic; --! input pulse. Active high
clk_output_i: in std_logic; --! clock for output
pulse_o : out std_logic --! Single cycle pulse synchronized to clock_output_i
);
end pulseClockDomainCrossing;
architecture rtl of pulseClockDomainCrossing is
signal s_pulse_out , s_pulse_out_d1 , s_pulse_out_d2 , s_pulse_out_d3 , s_pulse_out_d4 , s_pulse_back_d1 , s_pulse_back_d2: std_logic := '0';
begin -- rtl
-- purpose: registers and flip-flop on clk_input_i
p_input_clock_logic: process (clk_input_i)
begin
if rising_edge(clk_input_i) then
-- Register signals coming from output clock domain back to the
-- input clock domain
s_pulse_back_d1 <= s_pulse_out_d2;
s_pulse_back_d2 <= s_pulse_back_d1;
-- JK flip-flop
if (s_pulse_back_d2 = '1') then
s_pulse_out <= '0';
elsif (pulse_i = '1') then
s_pulse_out <= '1';
end if;
end if;
end process p_input_clock_logic;
-- purpose: registers and flip-flop on clk_output_o
p_output_clock_logic: process (clk_output_i)
begin
if rising_edge(clk_output_i) then
-- Register signal on input clock domain onto output clock domain
s_pulse_out_d1 <= s_pulse_out;
s_pulse_out_d2 <= s_pulse_out_d1;
s_pulse_out_d3 <= s_pulse_out_d2;
s_pulse_out_d4 <= s_pulse_out_d3;
-- Generate single clock-cycle pulse on pulse_o
pulse_o <= s_pulse_out_d3 and ( not s_pulse_out_d4 );
end if;
end process p_output_clock_logic;
end rtl;
--=============================================================================
--! @file registerCounter_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture worklib.registerCounter.rtl
--
--! @brief Regularly transfers the input to the output.\n
--! One clock for input , one clock for output\n
--! Can't just put entire bus through a couple of register stages,\n
--! Since this will just swap meta-stability issues for race issues.
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 24/Nov/12
--
--! @version v0.1
--
--! @details A six stage "ring oscillator" is used to generate two strobes.
--! One reads data into a register. The other registers the data to the output
--! Three stages are clocked on clk_write_i , three stages are clocked on clk_read_i
--! We could use gray-scale and put through registers, but this method
--! should work well enough at the expense of latency.\n
--! \n
--! The time taken for an edge to travel round the complete loop is
--! 2 cycles of clk_read_i and 2 cycles of clk_write_i plus two intervals
--! that depend on the relative phase of clk_read_i and clk_write_i
--!
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author:
--! David Cussans, 26/2/14 - Added registers to output to aid timing closure.
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity registerCounter is
generic (
g_DATA_WIDTH : positive := 15); -- ! Width of counter
port (
clk_input_i : in std_logic; -- ! clock for input
data_i : in std_logic_vector(g_DATA_WIDTH-1 downto 0); -- ! data to transfer to output
data_o : out std_logic_vector(g_DATA_WIDTH-1 downto 0); -- ! Data now in clk_read_i domain
clk_output_i : in std_logic); -- ! clock for output
end registerCounter;
architecture rtl of registerCounter is
signal s_ring_d0 , s_ring_d1 , s_ring_d2 , s_ring_d3 , s_ring_d4, s_ring_d5: std_logic := '0'; -- stages in "ring oscillator" used to generate strobes
signal s_registered_data : std_logic_vector(data_i'range) := ( others => '0'); -- ! Register to store data between clock domains
signal s_read_strobe , s_write_strobe : std_logic := '0'; -- ! Strobes high to register data from input and to output
begin -- rtl
-- purpose: part of "ring oscillator" transfering strobe between clock domains
-- type : combinational
-- inputs : clk_read_i
-- outputs:
p_gen_capture_strobe: process (clk_input_i)
begin -- process p_gen_capture_strobe
if rising_edge(clk_input_i) then
s_ring_d0 <= not s_ring_d5;
s_ring_d1 <= s_ring_d0;
s_ring_d2 <= s_ring_d1;
if s_read_strobe = '1' then
s_registered_data <= data_i;
end if;
end if;
end process p_gen_capture_strobe;
s_read_strobe <= s_ring_d1 xor s_ring_d2; --! Generate a strobe with
--width one clk_read_i
-- purpose: part of "ring oscillator" transfering strobe between clock domains
-- type : combinational
-- inputs : clk_output_i
-- outputs:
p_gen_output_strobe: process (clk_output_i)
begin -- process p_gen_output_strobe
if rising_edge(clk_output_i) then
s_ring_d3 <= s_ring_d2;
s_ring_d4 <= s_ring_d3;
s_ring_d5 <= s_ring_d4;
if s_write_strobe = '1' then
data_o <= s_registered_data;
end if;
end if;
end process p_gen_output_strobe;
s_write_strobe <= s_ring_d4 xor s_ring_d5; --! Generate a strobe
--
end rtl;
This diff is collapsed.
----------------------------------------------------------------------------------
-- Company: Universidade de Santiago de Compostela
-- Engineer: Alvaro Dosil
--
-- Create Date: 15/08/2012
-- Module Name: Conf_Regs - Behavioral
-- Revision 1.00 - File Created
-- Additional Comments:
----------------------------------------------------------------------------------
-------------------------------------------------------
--! @file
--! @brief Synchronization module 32b
--! @author Alvaro Dosil
-------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity sync_reg is
generic(g_Data_width : positive := 32);
port(
clk_i : in std_logic; --! synchronous clock
Async_i : in std_logic_vector(g_Data_width-1 downto 0); --! Asynchronous input data
Sync_o : out std_logic_vector(g_Data_width-1 downto 0)); --! Synchronous output data
end sync_reg;
--! @brief
--! @details Synchronize words (n bits)of data
architecture Behavioral of sync_reg is
signal s_async_i : std_logic_vector(g_Data_width-1 downto 0);
signal s_sync_o : std_logic_vector(g_Data_width-1 downto 0);
begin
loop0: for i in 0 to g_Data_width-1 generate
begin
reg: entity work.Reg_2clks
port map(
clk_i => clk_i,
async_i => s_async_i(i),
sync_o => s_sync_o(i));
end generate;
s_async_i <= Async_i;
Sync_o <= s_sync_o;
end Behavioral;
--=============================================================================
--! @file synchronizeRegisters_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture worklib.synchronizeRegisters.rtl
--
--! @brief Regularly transfers the input to the output.\n
--! One clock for input , one clock for output\n
--! Can't just put entire bus through a couple of register stages,\n
--! Since this will just swap meta-stability issues for race issues.
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 24/Nov/12
--
--! @version v0.1
--
--! @details A six stage "ring oscillator" is used to generate two strobes.
--! One reads data into a register. The other registers the data to the output
--! Three stages are clocked on clk_write_i , three stages are clocked on clk_read_i
--! The time taken for an edge to travel round the complete loop is
--! 2 cycles of clk_read_i and 2 cycles of clk_write_i plus two intervals
--! that depend on the relative phase of clk_read_i and clk_write_i
--!
--! Based on registerCounters
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author:
--! David Cussans, 26/2/14 - Added registers to output to aid timing closure.
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
--use work.fmcTLU.all;
use work.ipbus_reg_types.all;
entity synchronizeRegisters is
generic (
--g_DATA_WIDTH : positive := 15;
g_NUM_REGISTERS : positive := 1); -- ! Width of counter
port (
clk_input_i : in std_logic; -- ! clock for input
data_i : in ipb_reg_v(g_NUM_REGISTERS-1 downto 0); -- ! array of registers to transfer to output
data_o : out ipb_reg_v(g_NUM_REGISTERS-1 downto 0); -- ! Data now in clk_output_i domain
clk_output_i : in std_logic); -- ! clock for output
end synchronizeRegisters;
architecture rtl of synchronizeRegisters is
signal s_ring_d0 , s_ring_d1 , s_ring_d2 , s_ring_d3 , s_ring_d4, s_ring_d5: std_logic := '0'; -- stages in "ring oscillator" used to generate strobes
signal s_registered_data : ipb_reg_v(data_i'range) := ( others => ( others => '0')); -- ! Register to store data between clock domains
signal s_read_strobe , s_write_strobe : std_logic := '0'; -- ! Strobes high to register data from input and to output
begin -- rtl
-- purpose: part of "ring oscillator" transfering strobe between clock domains
-- type : combinational
-- inputs : clk_read_i
-- outputs:
p_gen_capture_strobe: process (clk_input_i)
begin -- process p_gen_capture_strobe
if rising_edge(clk_input_i) then
s_ring_d0 <= not s_ring_d5;
s_ring_d1 <= s_ring_d0;
s_ring_d2 <= s_ring_d1;
if s_read_strobe = '1' then
s_registered_data <= data_i;
end if;
end if;
end process p_gen_capture_strobe;
s_read_strobe <= s_ring_d1 xor s_ring_d2; --! Generate a strobe with
--width one clk_read_i
-- purpose: part of "ring oscillator" transfering strobe between clock domains
-- type : combinational
-- inputs : clk_output_i
-- outputs:
p_gen_output_strobe: process (clk_output_i)
begin -- process p_gen_output_strobe
if rising_edge(clk_output_i) then
s_ring_d3 <= s_ring_d2;
s_ring_d4 <= s_ring_d3;
s_ring_d5 <= s_ring_d4;
if s_write_strobe = '1' then
data_o <= s_registered_data;
end if;
end if;
end process p_gen_output_strobe;
s_write_strobe <= s_ring_d4 xor s_ring_d5; --! Generate a strobe
--
end rtl;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
`timescale 1ns / 1ps
module clock_divider_s6(
input clk,
output d25,
output d28
);
wire [6:0] q;
reg [5:0] qr = 0;
reg [2:0] ctr = 0;
//wire unconnected; // horrid hack
assign q[0] = 1'b1;
generate
genvar i;
for(i=1; i<=5; i=i+1) begin: gen_sr
SRLC32E #(
.INIT(32'h80000000)
) sr_0 (
.Q(q[i]),
.A(5'b11111),
.CE(q[i-1] & ~qr[i-1]),
.CLK(clk),
.D(q[i])
);
always @(posedge clk)
begin
qr[i] <= q[i];
end
end
endgenerate
assign d25 = q[5];
always @(posedge clk)
begin
if(q[5] & ~qr[5]) ctr <= ctr + 1;
end
assign d28 = ctr[2];
endmodule
-- clocks_s6_extphy
--
-- Generates a 125MHz ethernet clock and 31MHz ipbus clock from the 200MHz reference
-- Includes reset logic for ipbus
--
-- Dave Newbold, April 2011
--
-- $Id$
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.VComponents.all;
entity clocks_s6_extphy is port(
sysclk_p, sysclk_n: in std_logic;
clko_125: out std_logic;
clko_ipb: out std_logic;
locked: out std_logic;
rsto_125: out std_logic;
rsto_ipb: out std_logic;
onehz: out std_logic
);
end clocks_s6_extphy;
architecture rtl of clocks_s6_extphy is
signal clk_ipb_i, clk_ipb_b, clk_125_i, clk_125_b, sysclk: std_logic;
signal d25, d25_d, dcm_locked: std_logic;
signal rst: std_logic := '1';
component clock_divider_s6 port(
clk: in std_logic;
d25: out std_logic;
d28: out std_logic
);
end component;
begin
ibufgds0: IBUFGDS port map(
i => sysclk_p,
ib => sysclk_n,
o => sysclk
);
bufg_125: BUFG port map(
i => clk_125_i,
o => clk_125_b
);
clko_125 <= clk_125_b;
bufg_ipb: BUFG port map(
i => clk_ipb_i,
o => clk_ipb_b
);
clko_ipb <= clk_ipb_b;
dcm0: DCM_CLKGEN
generic map(
CLKIN_PERIOD => 5.0,
CLKFX_MULTIPLY => 5,
CLKFX_DIVIDE => 8,
CLKFXDV_DIVIDE => 4
)
port map(
clkin => sysclk,
clkfx => clk_125_i,
clkfxdv => clk_ipb_i,
locked => dcm_locked,
rst => '0'
);
clkdiv: clock_divider_s6 port map(
clk => sysclk,
d25 => d25,
d28 => onehz
);
process(sysclk)
begin
if rising_edge(sysclk) then
d25_d <= d25;
if d25='1' and d25_d='0' then
rst <= not dcm_locked;
end if;
end if;
end process;
locked <= dcm_locked;
process(clk_ipb_b)
begin
if rising_edge(clk_ipb_b) then
rsto_ipb <= rst;
end if;
end process;
process(clk_125_b)
begin
if rising_edge(clk_125_b) then
rsto_125 <= rst;
end if;
end process;
end rtl;
This diff is collapsed.
----- CELL dtype_fd -----
--
--@file
--
--@brief Aims to be the same as the Xilinx "FD" primitive -
-- D-Type flip-flop
--
-- Modified from D-type example in VHDL book.
-- See Xilinx spartan6_scm.pdf
--
-- David Cussans, Feb 2011
--
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity dtype_fd is
port(
Q : out std_logic; --! Output
CLK : in std_logic; --! Clock - rising edge active
D : in std_logic --! Input
);
end dtype_fd;
architecture rtl of dtype_fd is
begin
VITALBehavior : process(CLK)
begin
if rising_edge(CLK) then
Q <= D ;
end if;
end process;
end rtl;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/tmp/fmc_tlu/fmc-mtlu/firmware/hdl/common/DUTInterfaces_rtl.vhd
\ No newline at end of file
/tmp/fmc_tlu/fmc-mtlu/firmware/hdl/common/IPBusInterface_rtl.vhd
\ No newline at end of file
/projects/HEP_Instrumentation/cad/designs/fmc-mtlu/trunk/firmware/workspace/IPbusFirmware/firmware/ipbus/hdl/arp.v
\ No newline at end of file
/tmp/fmc_tlu/fmc-mtlu/firmware/hdl/common/arrivalTimeLUT_rtl.vhd
\ No newline at end of file
/projects/HEP_Instrumentation/cad/designs/fmc-mtlu/trunk/firmware/workspace/IPbusFirmware/firmware/ipbus/hdl/bus_arb.vhd
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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