Commit b4d12c32 authored by penacoba's avatar penacoba

First versions for hardware test



git-svn-id: http://svn.ohwr.org/fmc-tdc@32 85dfdc96-de2c-444c-878d-45b388be74a9
parent 4c9264e1
# DO NOT EDIT -- automatically generated design data file -- DO NOT EDIT!!!
list \
workdir {/afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/sim} \
cdslib {/afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/sim/cds.lib} \
worklib {worklib} \
mode {0} \
filters {*} \
sesslist {} \
ToolOption_NCVhdl {-logfile ncvhdl.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog/AMS {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog/SV {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_irun {-gui {} +linedebug +access rwc -q} \
ToolOption_NCElab {-logfile ncelab.log -errormax 15 -status -access +wc} \
ToolOption_NCSim {-gui -logfile ncsim.log -errormax 15 -status} \
ToolOption_NCSdfc {-logfile ncsdfc.log -compile -status} \
ToolOption_HAL {-logfile hal.log} \
ToolOption_SimVision {} \
ToolOption_Update {-errormax 15 -force} \
ToolOption_Comparescan {} \
ToolOption_NCBrowse {} \
ToolOption_HALDefEdit {} \
ToolOption_PLI Wizard {} \
ToolOption_NCShell {-view shell -logfile ncshell.log -errormax 15 -suffix .v} \
ToolOption_NCProtect {-logfile ncprotect.log} \
ToolOption_NCDC {-logfile ncdc.log -messages -status} \
ToolOption_DBUtil {} \
ToolOption_NCVhdl {-logfile ncvhdl.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog/AMS {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog/SV {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_irun {-gui {} +linedebug +access rwc -q} \
ToolOption_NCElab {-logfile ncelab.log -errormax 15 -status -access +wc} \
ToolOption_NCSim {-gui -logfile ncsim.log -errormax 15 -status} \
ToolOption_NCSdfc {-logfile ncsdfc.log -compile -status} \
ToolOption_HAL {-logfile hal.log} \
ToolOption_SimVision {} \
ToolOption_Update {-errormax 15 -force} \
ToolOption_Comparescan {} \
ToolOption_NCBrowse {} \
ToolOption_HALDefEdit {} \
ToolOption_PLI Wizard {} \
ToolOption_NCShell {-view shell -logfile ncshell.log -errormax 15 -suffix .v} \
ToolOption_NCProtect {-logfile ncprotect.log} \
ToolOption_NCDC {-logfile ncdc.log -messages -status} \
ToolOption_DBUtil {} \
# DO NOT EDIT -- automatically generated design data file -- DO NOT EDIT!!!
list \
workdir {/afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/sim} \
cdslib {/afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/sim/cds.lib} \
worklib {worklib} \
mode {0} \
filters {*} \
sesslist {} \
ToolOption_NCVhdl {-logfile ncvhdl.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog/AMS {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog/SV {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_irun {-gui {} +linedebug +access rwc -q} \
ToolOption_NCElab {-logfile ncelab.log -errormax 15 -status -access +wc} \
ToolOption_NCSim {-gui -logfile ncsim.log -errormax 15 -status} \
ToolOption_NCSdfc {-logfile ncsdfc.log -compile -status} \
ToolOption_HAL {-logfile hal.log} \
ToolOption_SimVision {} \
ToolOption_Update {-errormax 15 -force} \
ToolOption_Comparescan {} \
ToolOption_NCBrowse {} \
ToolOption_HALDefEdit {} \
ToolOption_PLI Wizard {} \
ToolOption_NCShell {-view shell -logfile ncshell.log -errormax 15 -suffix .v} \
ToolOption_NCProtect {-logfile ncprotect.log} \
ToolOption_NCDC {-logfile ncdc.log -messages -status} \
ToolOption_DBUtil {} \
ToolOption_NCVhdl {-logfile ncvhdl.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog/AMS {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_NCVlog/SV {-logfile ncvlog.log -errormax 15 -update -linedebug -status} \
ToolOption_irun {-gui {} +linedebug +access rwc -q} \
ToolOption_NCElab {-logfile ncelab.log -errormax 15 -status -access +wc} \
ToolOption_NCSim {-gui -logfile ncsim.log -errormax 15 -status} \
ToolOption_NCSdfc {-logfile ncsdfc.log -compile -status} \
ToolOption_HAL {-logfile hal.log} \
ToolOption_SimVision {} \
ToolOption_Update {-errormax 15 -force} \
ToolOption_Comparescan {} \
ToolOption_NCBrowse {} \
ToolOption_HALDefEdit {} \
ToolOption_PLI Wizard {} \
ToolOption_NCShell {-view shell -logfile ncshell.log -errormax 15 -suffix .v} \
ToolOption_NCProtect {-logfile ncprotect.log} \
ToolOption_NCDC {-logfile ncdc.log -messages -status} \
ToolOption_DBUtil {} \
Thu 07 Jul 2011 06:32:13 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:54 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:54 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:54 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:54 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:54 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:54 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:54 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:54 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:55 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:55 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:55 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:55 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:56 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:56 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:57 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 06:32:57 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 07:32:59 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Thu 07 Jul 2011 07:32:59 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Fri 08 Jul 2011 03:05:19 PM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:04:27 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:05:27 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:05:30 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:06:31 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:06:31 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:06:32 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:06:32 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:06:32 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:40:01 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:40:01 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
Mon 11 Jul 2011 11:40:42 AM CEST
visadev: *F,DLNOLK: Failed to get a shared lock on library 'worklib' (Resource temporarily unavailable).
include $CDS_INST_DIR/tools/inca/files/cds.lib
define worklib /afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/sim/INCA_libs/worklib
DEFINE unimacro /afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/sim/INCA_libs/unimacro
DEFINE unisim /afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/sim/INCA_libs/unisim
DEFINE xilinxcorelib /afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/sim/INCA_libs/xilinxcorelib
-------------------------------------------------------------------------------
-- acam_test.vec
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model 0
-- Initialize the BFM to its default state
init
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 0000000000000000 00100000 0 7 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 0000000040000000 20000000
bfm_bar 1 0000000020000000 20000000
-- Drive reset to the FPGA
reset %d320
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d50000
-- Drive reset to the FPGA
reset %d320
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d20000
-------------------------------------------------------------------------------
-- Access the tdc core register space
-------------------------------------------------------------------------------
-- the following writes will go out in a single packet
wr 0000000000000000 F 0000AFA1
wait %d1
wr 0000000000080004 F 1000AFA2
1300 us,1,5 us
6 us,2,505 ns
162 ps,3,505 ns
840 us,4,505 ns
1400 ps,5,505 ns
400 ps,1,505 ns
define WORK worklib
include $CDS_INST_DIR/tools/inca/files/hdl.var
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/gn4124_core_pkg_s6.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/ip_cores/fifo_32x512.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/ip_cores/fifo_64x512.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/serdes_n_to_1_s2_diff.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/serdes_n_to_1_s2_se.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/l2p_ser_s6.vhd
ncvhdl -controlrelax NLSTEX -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/serdes_1_to_n_data_s2_se.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/p2l_des_s6.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/serdes_1_to_n_clk_pll_s2_diff.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/p2l_decode32.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/wbmaster32.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/dma_controller_wb_slave.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/dma_controller.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/l2p_dma_master.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/p2l_dma_master.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/l2p_arbiter.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/gnum_core/gn4124_core_s6.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/tdc_core_pkg.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/free_counter.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/incr_counter.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/countdown_counter.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/clk_rst_managr.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/one_hz_gen.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/start_nb_offset_gen.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/data_formatting.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/acam_timecontrol_interface.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/acam_databus_interface.vhd
#ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/top_tdc.vhd
#ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/test_tdc_acam/top_test_acam.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/design/test_tdc_pll/top_test_pll.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/gnum_model/util.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/gnum_model/textutil.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/gnum_model/mem_model.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/gnum_model/cmd_router1.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/gnum_model/cmd_router.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/gnum_model/gn412x_bfm.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/acam_timing_model.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/acam_fifo_model.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/acam_data_model.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/acam_model.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/start_stop_gen.vhd
ncvhdl -nocopyright -nolog -messages -linedebug -v93 -cdslib ./cds.lib -work worklib ../src/test_bench/tb_tdc.vhd
ncelab -nocopyright -nolog -messages -access +wc -messages -v93 -cdslib ./cds.lib -work worklib worklib.tb_tdc:behavioral
#ncelab -nocopyright -nolog -messages -access +wc -messages -v93 -cdslib ./cds.lib -work worklib worklib.tdc_top:rtl
#ncsim -gui -cdslib ./cds.lib -nocopyright -nolog -nokey worklib.tb_tdc:behavioral -input waves.tcl
probe -create -shm -waveform :spec_clk_i
probe -create -shm -waveform :dut:por_reset
probe -create -shm -waveform :dut:internal_reset
probe -create -shm -waveform :dut:clk
probe -create -shm -waveform :dut:acam_refclk
probe -create -shm -waveform :dut:gnum_reset
probe -create -shm -waveform :dut:general_reset
#probe -create -shm -waveform :dut:clocks_and_resets_management_block:half_clk
probe -create -shm -waveform :dut:clocks_and_resets_management_block:cs
#probe -create -shm -waveform :dut:clocks_and_resets_management_block:bit_index
probe -create -shm -waveform :dut:clocks_and_resets_management_block:byte_index
probe -create -shm -waveform :dut:clocks_and_resets_management_block:bit_being_sent
probe -create -shm -waveform :dut:clocks_and_resets_management_block:byte_being_sent
probe -create -shm -waveform :dut:clocks_and_resets_management_block:pll_init_st
probe -create -shm -waveform :dut:clocks_and_resets_management_block:gral_incr
probe -create -shm -waveform :dut:clocks_and_resets_management_block:inv_reset
probe -create -shm -waveform :dut:clocks_and_resets_management_block:general_power_on_reset:current_value
#probe -create -shm -waveform :dut:clocks_and_resets_management_block:nxt_pll_init_st
probe -create -shm -waveform :spec_led_green
probe -create -shm -waveform :spec_led_red
probe -create -shm -waveform :tdc_led_status
probe -create -shm -waveform :dut:tdc_led_count_done
probe -create -shm -waveform :dut:spec_led_count_done
#probe -create -shm -waveform :RSTINn
#probe -create -shm -waveform :RSTOUT18n
#probe -create -shm -waveform :RSTOUT33n
#probe -create -shm -waveform :LCLK
#probe -create -shm -waveform :LCLKn
probe -create -shm -waveform :P2L_CLKp
probe -create -shm -waveform :P2L_CLKn
probe -create -shm -waveform :P2L_DATA
probe -create -shm -waveform :P2L_DATA_32
probe -create -shm -waveform :P2L_DFRAME
probe -create -shm -waveform :P2L_VALID
probe -create -shm -waveform :P2L_RDY
probe -create -shm -waveform :P_WR_REQ
probe -create -shm -waveform :P_WR_RDY
probe -create -shm -waveform :RX_ERROR
probe -create -shm -waveform :VC_RDY
#probe -create -shm -waveform :L2P_CLKp, L2P_CLKn
#probe -create -shm -waveform :L2P_DATA
#probe -create -shm -waveform :L2P_DATA_32
#probe -create -shm -waveform :L2P_DFRAME
#probe -create -shm -waveform :L2P_VALID
#probe -create -shm -waveform :L2P_EDB
#probe -create -shm -waveform :L2P_RDY
#probe -create -shm -waveform :L_WR_RDY
#probe -create -shm -waveform :P_RD_D_RDY
#probe -create -shm -waveform :TX_ERROR
probe -create -shm -waveform :GPIO
#probe -create -shm -waveform :dut:acm_adr
#probe -create -shm -waveform :dut:acm_cyc
#probe -create -shm -waveform :dut:acm_dat_w
#probe -create -shm -waveform :dut:acm_stb
#probe -create -shm -waveform :dut:acm_we
#probe -create -shm -waveform :dut:acm_ack
#probe -create -shm -waveform :dut:acm_dat_r
probe -create -shm -waveform :dut:csr_clk
probe -create -shm -waveform :dut:csr_cyc
probe -create -shm -waveform :dut:csr_sel
probe -create -shm -waveform :dut:csr_adr
probe -create -shm -waveform :dut:csr_dat_r
probe -create -shm -waveform :dut:csr_dat_w
probe -create -shm -waveform :dut:csr_stb
probe -create -shm -waveform :dut:csr_ack
probe -create -shm -waveform :dut:csr_we
probe -create -shm -waveform :dut:acam_data_block:acam_data_st
probe -create -shm -waveform :dut:acam_data_block:nxt_acam_data_st
probe -create -shm -waveform :dut:data_bus_io
probe -create -shm -waveform :dut:address_o
probe -create -shm -waveform :dut:cs_n_o
probe -create -shm -waveform :dut:oe_n_o
probe -create -shm -waveform :dut:rd_n_o
probe -create -shm -waveform :dut:wr_n_o
#probe -create -shm -waveform :acam:data_block:wr_falling_time
#probe -create -shm -waveform :acam:data_block:wr_rising_time
#probe -create -shm -waveform :dut:one_second_block:acam_refclk_i
#probe -create -shm -waveform :dut:one_second_block:s_acam_refclk
#probe -create -shm -waveform :dut:one_second_block:refclk_edge
#probe -create -shm -waveform :dut:one_second_block:onesec_counter_en
#probe -create -shm -waveform :dut:one_second_block:total_delay
#probe -create -shm -waveform :dut:one_second_block:one_hz_p_pre
#probe -create -shm -waveform :dut:one_second_block:one_hz_p_post
probe -create -shm -waveform :dut:one_second_block:one_hz_p_o
#probe -create -shm -waveform :dut:acam_timing_block:counter_reset
#probe -create -shm -waveform :dut:acam_timing_block:window_inverted
#probe -create -shm -waveform :dut:acam_timing_block:start_window
#probe -create -shm -waveform :dut:acam_timing_block:start_dis_o
#probe -create -shm -waveform :dut:acam_timing_block:int_flag_i
#probe -create -shm -waveform :dut:start_nb_block:acam_irflag_p_i
#probe -create -shm -waveform :dut:start_nb_block:start_nb_offset_o
#probe -create -shm -waveform :start_dis_o
probe -create -shm -waveform :start_from_fpga_o
probe -create -shm -waveform :acam_refclk_i
#probe -create -shm -waveform :stop_dis_o
probe -create -shm -waveform :tstop1
probe -create -shm -waveform :tstop2
probe -create -shm -waveform :tstop3
probe -create -shm -waveform :tstop4
probe -create -shm -waveform :tstop5
#probe -create -shm -waveform :pulses_generator:pulse_channel
#probe -create -shm -waveform :pulses_generator:sequence:pulse_ch
#probe -create -shm -waveform :acam:timing_block:timestamp_for_fifo1
#probe -create -shm -waveform :acam:timing_block:timestamp_for_fifo2
#probe -create -shm -waveform :acam:timing_block:tstart
#probe -create -shm -waveform :acam:timing_block:tstop1
#probe -create -shm -waveform :acam:timing_block:tstop2
#probe -create -shm -waveform :acam:timing_block:tstop3
#probe -create -shm -waveform :acam:timing_block:tstop4
#probe -create -shm -waveform :acam:timing_block:tstop5
#probe -create -shm -waveform :acam:data_block:interface_fifo1:fifo
#probe -create -shm -waveform :acam:data_block:interface_fifo1:fifo[0]
#probe -create -shm -waveform :acam:data_block:interface_fifo1:fifo[1]
#probe -create -shm -waveform :acam:data_block:interface_fifo1:fifo[2]
#probe -create -shm -waveform :acam:data_block:interface_fifo1:fifo[3]
#probe -create -shm -waveform :acam:data_block:interface_fifo1:fifo[4]
#probe -create -shm -waveform :acam:data_block:interface_fifo2:fifo
#probe -create -shm -waveform :acam:data_block:interface_fifo2:fifo[0]
#probe -create -shm -waveform :acam:data_block:interface_fifo2:fifo[1]
#probe -create -shm -waveform :acam:data_block:interface_fifo2:fifo[2]
#probe -create -shm -waveform :acam:data_block:interface_fifo2:fifo[3]
#probe -create -shm -waveform :acam:data_block:interface_fifo2:fifo[4]
#probe -create -shm -waveform :acam:timing_block:start_trig
#probe -create -shm -waveform :acam:timing_block:stop1_trig
#probe -create -shm -waveform :acam:timing_block:stop1
#probe -create -shm -waveform :acam:timing_block:stop2_trig
#probe -create -shm -waveform :acam:timing_block:stop2
#probe -create -shm -waveform :acam:timing_block:stop3_trig
#probe -create -shm -waveform :acam:timing_block:stop3
#probe -create -shm -waveform :acam:timing_block:stop4_trig
#probe -create -shm -waveform :acam:timing_block:stop4
#probe -create -shm -waveform :acam:timing_block:stop5_trig
#probe -create -shm -waveform :acam:timing_block:stop5
probe -create -shm -waveform :acam:timing_block:start01
probe -create -shm -waveform :acam:timing_block:start_retrig_p
probe -create -shm -waveform :acam:timing_block:start_retrig_nb
#probe -create -shm -waveform :acam:timing_block:int_flag_o
#probe -create -shm -waveform :acam:timing_block:start_nb1
#probe -create -shm -waveform :acam:timing_block:start_nb2
#probe -create -shm -waveform :acam:timing_block:start_nb3
#probe -create -shm -waveform :acam:timing_block:start_nb4
#probe -create -shm -waveform :acam:timing_block:start_nb5
set intovf_severity_level warning
run 1 ms
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: clock_generator_ddr_s2_diff.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: BUFIO2 Based DDR clock generator. Takes in a differential clock
-- and instantiates two sets of 2 BUFIO2s, one for each half bank
--
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity clock_generator_ddr_s2_diff is
generic (
S : integer := 2; -- Parameter to set the serdes factor
DIFF_TERM : boolean := false) ; -- Enable or disable internal differential termination
port (
clkin_p, clkin_n : in std_logic; -- differential clock input
ioclkap : out std_logic; -- A P ioclock from BUFIO2
ioclkan : out std_logic; -- A N ioclock from BUFIO2
serdesstrobea : out std_logic; -- A serdes strobe from BUFIO2
ioclkbp : out std_logic; -- B P ioclock from BUFIO2 - leave open if not required
ioclkbn : out std_logic; -- B N ioclock from BUFIO2 - leave open if not required
serdesstrobeb : out std_logic; -- B serdes strobe from BUFIO2 - leave open if not required
gclk : out std_logic) ; -- global clock output from BUFIO2
end clock_generator_ddr_s2_diff;
architecture arch_clock_generator_ddr_s2_diff of clock_generator_ddr_s2_diff is
signal clkint : std_logic; --
signal gclk_int : std_logic; --
signal freqgen_in_p : std_logic; --
signal tx_bufio2_x1 : std_logic; --
begin
gclk <= gclk_int;
iob_freqgen_in : IBUFGDS generic map(
DIFF_TERM => DIFF_TERM)
port map (
I => clkin_p,
IB => clkin_n,
O => freqgen_in_p);
bufio2_inst1 : BUFIO2 generic map(
DIVIDE => S, -- The DIVCLK divider divide-by value; default 1
I_INVERT => false, --
DIVIDE_BYPASS => false, --
USE_DOUBLER => true) --
port map (
I => freqgen_in_p, -- Input source clock 0 degrees
IOCLK => ioclkap, -- Output Clock for IO
DIVCLK => tx_bufio2_x1, -- Output Divided Clock
SERDESSTROBE => serdesstrobea) ; -- Output SERDES strobe (Clock Enable)
bufio2_inst2 : BUFIO2 generic map(
I_INVERT => true, --
DIVIDE_BYPASS => false, --
USE_DOUBLER => false) --
port map (
I => freqgen_in_p, -- N_clk input from IDELAY
IOCLK => ioclkan, -- Output Clock
DIVCLK => open, -- Output Divided Clock
SERDESSTROBE => open) ; -- Output SERDES strobe (Clock Enable)
bufio2_inst3 : BUFIO2 generic map(
DIVIDE => S, -- The DIVCLK divider divide-by value; default 1
I_INVERT => false, --
DIVIDE_BYPASS => false, --
USE_DOUBLER => true) --
port map (
I => freqgen_in_p, -- Input source clock 0 degrees
IOCLK => ioclkbp, -- Output Clock for IO
DIVCLK => open, -- Output Divided Clock
SERDESSTROBE => serdesstrobeb) ; -- Output SERDES strobe (Clock Enable)
bufio2_inst4 : BUFIO2 generic map(
I_INVERT => true, --
DIVIDE_BYPASS => false, --
USE_DOUBLER => false) --
port map (
I => freqgen_in_p, -- N_clk input from IDELAY
IOCLK => ioclkbn, -- Output Clock
DIVCLK => open, -- Output Divided Clock
SERDESSTROBE => open) ; -- Output SERDES strobe (Clock Enable)
bufg_tx : BUFG port map (I => tx_bufio2_x1, O => gclk_int);
end arch_clock_generator_ddr_s2_diff;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: clock_generator_pll_s2_diff.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: PLL Based clock generator. Takes in a differential clock and multiplies it
-- by the amount specified. Instantiates a BUFIO2, BUFPLL and a PLL using
-- INTERNAL feedback
--
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity clock_generator_pll_s2_diff is
generic (
PLLD : integer := 1; -- Parameter to set the division factor in the PLL
PLLX : integer := 2; -- Parameter to set the multiplication factor in the PLL
S : integer := 2; -- Parameter to set the serdes factor 1..8
CLKIN_PERIOD : real := 5.000; -- clock period (ns) of input clock on clkin_p
DIFF_TERM : boolean := false) ; -- Enable or disable internal differential termination
port (
reset : in std_logic; -- reset (active high)
clkin_p, clkin_n : in std_logic; -- differential clock input
ioclk : out std_logic; -- ioclock from BUFPLL
serdesstrobe : out std_logic; -- serdes strobe from BUFPLL
gclk : out std_logic; -- global clock output from BUFG x1
bufpll_lckd : out std_logic) ; -- Locked output from BUFPLL
end clock_generator_pll_s2_diff;
architecture arch_clock_generator_pll_s2_diff of clock_generator_pll_s2_diff is
signal clkint : std_logic; --
signal clkintb : std_logic; --
signal dummy : std_logic; --
signal pllout_xs : std_logic; --
signal pllout_x1 : std_logic; --
signal pll_lckd : std_logic; --
signal gclk_int : std_logic; --
signal buf_pll_lckd : std_logic;
begin
gclk <= gclk_int;
iob_freqgen_in : IBUFGDS generic map(
DIFF_TERM => DIFF_TERM)
port map (
I => clkin_p,
IB => clkin_n,
O => clkint);
bufio2_inst : BUFIO2 generic map(
DIVIDE => 1, -- The DIVCLK divider divide-by value; default 1
I_INVERT => false,
DIVIDE_BYPASS => true,
USE_DOUBLER => false)
port map (
I => clkint, -- Input source clock 0 degrees
IOCLK => open, -- Output Clock for IO
DIVCLK => clkintb, -- Output Divided Clock
SERDESSTROBE => open) ; -- Output SERDES strobe (Clock Enable)
tx_pll_adv_inst : PLL_ADV generic map(
BANDWIDTH => "OPTIMIZED", -- "high", "low" or "optimized"
CLKFBOUT_MULT => PLLX, -- multiplication factor for all output clocks
CLKFBOUT_PHASE => 0.0, -- phase shift (degrees) of all output clocks
CLKIN1_PERIOD => CLKIN_PERIOD, -- clock period (ns) of input clock on clkin1
CLKIN2_PERIOD => CLKIN_PERIOD, -- clock period (ns) of input clock on clkin2
CLKOUT0_DIVIDE => 1, -- division factor for clkout0 (1 to 128)
CLKOUT0_DUTY_CYCLE => 0.5, -- duty cycle for clkout0 (0.01 to 0.99)
CLKOUT0_PHASE => 0.0, -- phase shift (degrees) for clkout0 (0.0 to 360.0)
CLKOUT1_DIVIDE => 1, -- division factor for clkout1 (1 to 128)
CLKOUT1_DUTY_CYCLE => 0.5, -- duty cycle for clkout1 (0.01 to 0.99)
CLKOUT1_PHASE => 0.0, -- phase shift (degrees) for clkout1 (0.0 to 360.0)
CLKOUT2_DIVIDE => S, -- division factor for clkout2 (1 to 128)
CLKOUT2_DUTY_CYCLE => 0.5, -- duty cycle for clkout2 (0.01 to 0.99)
CLKOUT2_PHASE => 0.0, -- phase shift (degrees) for clkout2 (0.0 to 360.0)
CLKOUT3_DIVIDE => S, -- division factor for clkout3 (1 to 128)
CLKOUT3_DUTY_CYCLE => 0.5, -- duty cycle for clkout3 (0.01 to 0.99)
CLKOUT3_PHASE => 0.0, -- phase shift (degrees) for clkout3 (0.0 to 360.0)
CLKOUT4_DIVIDE => S, -- division factor for clkout4 (1 to 128)
CLKOUT4_DUTY_CYCLE => 0.5, -- duty cycle for clkout4 (0.01 to 0.99)
CLKOUT4_PHASE => 0.0, -- phase shift (degrees) for clkout4 (0.0 to 360.0)
CLKOUT5_DIVIDE => S, -- division factor for clkout5 (1 to 128)
CLKOUT5_DUTY_CYCLE => 0.5, -- duty cycle for clkout5 (0.01 to 0.99)
CLKOUT5_PHASE => 0.0, -- phase shift (degrees) for clkout5 (0.0 to 360.0)
COMPENSATION => "INTERNAL", -- "SYSTEM_SYNCHRONOUS", "SOURCE_SYNCHRONOUS", "INTERNAL", "EXTERNAL", "DCM2PLL", "PLL2DCM"
DIVCLK_DIVIDE => PLLD, -- division factor for all clocks (1 to 52)
REF_JITTER => 0.100) -- input reference jitter (0.000 to 0.999 ui%)
port map (
CLKFBDCM => open, -- output feedback signal used when pll feeds a dcm
CLKFBOUT => dummy, -- general output feedback signal
CLKOUT0 => pllout_xs, -- x7 clock for transmitter
CLKOUT1 => open, --
CLKOUT2 => pllout_x1, -- x1 clock for BUFG
CLKOUT3 => open, -- x2 clock for BUFG
CLKOUT4 => open, -- one of six general clock output signals
CLKOUT5 => open, -- one of six general clock output signals
CLKOUTDCM0 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM1 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM2 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM3 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM4 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM5 => open, -- one of six clock outputs to connect to the dcm
DO => open, -- dynamic reconfig data output (16-bits)
DRDY => open, -- dynamic reconfig ready output
LOCKED => pll_lckd, -- active high pll lock signal
CLKFBIN => dummy, -- clock feedback input
CLKIN1 => clkintb, -- primary clock input
CLKIN2 => '0', -- secondary clock input
CLKINSEL => '1', -- selects '1' = clkin1, '0' = clkin2
DADDR => "00000", -- dynamic reconfig address input (5-bits)
DCLK => '0', -- dynamic reconfig clock input
DEN => '0', -- dynamic reconfig enable input
DI => "0000000000000000", -- dynamic reconfig data input (16-bits)
DWE => '0', -- dynamic reconfig write enable input
RST => reset, -- asynchronous pll reset
REL => '0') ; -- used to force the state of the PFD outputs (test only)
bufg_tx_x1 : BUFG port map (I => pllout_x1, O => gclk_int);
tx_bufpll_inst : BUFPLL generic map(
DIVIDE => S) -- PLLIN0 divide-by value to produce SERDESSTROBE (1 to 8); default 1
port map (
PLLIN => pllout_xs, -- PLL Clock input
GCLK => gclk_int, -- Global Clock input
LOCKED => pll_lckd, -- Clock0 locked input
IOCLK => ioclk, -- Output PLL Clock
LOCK => buf_pll_lckd, -- BUFPLL Clock and strobe locked
SERDESSTROBE => serdesstrobe) ; -- Output SERDES strobe
bufpll_lckd <= buf_pll_lckd and pll_lckd;
end arch_clock_generator_pll_s2_diff;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: DMA controller (dma_controller.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 0.2
--
-- description: Manages the DMA transfers.
--
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: 30-09-2010 (mcattin) Add status, error and abort
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity dma_controller is
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Interrupt request
dma_ctrl_irq_o : out std_logic_vector(1 downto 0);
---------------------------------------------------------
-- To the L2P DMA master and P2L DMA master
dma_ctrl_carrier_addr_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_o : out std_logic_vector(31 downto 0);
dma_ctrl_len_o : out std_logic_vector(31 downto 0);
dma_ctrl_start_l2p_o : out std_logic; -- To the L2P DMA master
dma_ctrl_start_p2l_o : out std_logic; -- To the P2L DMA master
dma_ctrl_start_next_o : out std_logic; -- To the P2L DMA master
dma_ctrl_byte_swap_o : out std_logic_vector(1 downto 0);
dma_ctrl_abort_o : out std_logic;
dma_ctrl_done_i : in std_logic;
dma_ctrl_error_i : in std_logic;
---------------------------------------------------------
-- From P2L DMA master
next_item_carrier_addr_i : in std_logic_vector(31 downto 0);
next_item_host_addr_h_i : in std_logic_vector(31 downto 0);
next_item_host_addr_l_i : in std_logic_vector(31 downto 0);
next_item_len_i : in std_logic_vector(31 downto 0);
next_item_next_l_i : in std_logic_vector(31 downto 0);
next_item_next_h_i : in std_logic_vector(31 downto 0);
next_item_attrib_i : in std_logic_vector(31 downto 0);
next_item_valid_i : in std_logic;
---------------------------------------------------------
-- Wishbone slave interface
wb_clk_i : in std_logic; -- Bus clock
wb_adr_i : in std_logic_vector(3 downto 0); -- Adress
wb_dat_o : out std_logic_vector(31 downto 0); -- Data in
wb_dat_i : in std_logic_vector(31 downto 0); -- Data out
wb_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wb_cyc_i : in std_logic; -- Read or write cycle
wb_stb_i : in std_logic; -- Read or write strobe
wb_we_i : in std_logic; -- Write
wb_ack_o : out std_logic -- Acknowledge
);
end dma_controller;
architecture behaviour of dma_controller is
------------------------------------------------------------------------------
-- Wishbone slave component declaration
------------------------------------------------------------------------------
component dma_controller_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(3 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
clk_i : in std_logic;
-- Port for std_logic_vector field: 'DMA engine control' in reg: 'DMACTRLR'
dma_ctrl_o : out std_logic_vector(31 downto 0);
dma_ctrl_i : in std_logic_vector(31 downto 0);
dma_ctrl_load_o : out std_logic;
-- Port for std_logic_vector field: 'DMA engine status' in reg: 'DMASTATR'
dma_stat_o : out std_logic_vector(31 downto 0);
dma_stat_i : in std_logic_vector(31 downto 0);
dma_stat_load_o : out std_logic;
-- Port for std_logic_vector field: 'DMA start address in the carrier' in reg: 'DMACSTARTR'
dma_cstart_o : out std_logic_vector(31 downto 0);
dma_cstart_i : in std_logic_vector(31 downto 0);
dma_cstart_load_o : out std_logic;
-- Port for std_logic_vector field: 'DMA start address (low) in the host' in reg: 'DMAHSTARTLR'
dma_hstartl_o : out std_logic_vector(31 downto 0);
dma_hstartl_i : in std_logic_vector(31 downto 0);
dma_hstartl_load_o : out std_logic;
-- Port for std_logic_vector field: 'DMA start address (high) in the host' in reg: 'DMAHSTARTHR'
dma_hstarth_o : out std_logic_vector(31 downto 0);
dma_hstarth_i : in std_logic_vector(31 downto 0);
dma_hstarth_load_o : out std_logic;
-- Port for std_logic_vector field: 'DMA read length in bytes' in reg: 'DMALENR'
dma_len_o : out std_logic_vector(31 downto 0);
dma_len_i : in std_logic_vector(31 downto 0);
dma_len_load_o : out std_logic;
-- Port for std_logic_vector field: 'Pointer (low) to next item in list' in reg: 'DMANEXTLR'
dma_nextl_o : out std_logic_vector(31 downto 0);
dma_nextl_i : in std_logic_vector(31 downto 0);
dma_nextl_load_o : out std_logic;
-- Port for std_logic_vector field: 'Pointer (high) to next item in list' in reg: 'DMANEXTHR'
dma_nexth_o : out std_logic_vector(31 downto 0);
dma_nexth_i : in std_logic_vector(31 downto 0);
dma_nexth_load_o : out std_logic;
-- Port for std_logic_vector field: 'DMA chain control' in reg: 'DMAATTRIBR'
dma_attrib_o : out std_logic_vector(31 downto 0);
dma_attrib_i : in std_logic_vector(31 downto 0);
dma_attrib_load_o : out std_logic
);
end component dma_controller_wb_slave;
------------------------------------------------------------------------------
-- Constants declaration
------------------------------------------------------------------------------
constant c_IDLE : std_logic_vector(2 downto 0) := "000";
constant c_DONE : std_logic_vector(2 downto 0) := "001";
constant c_BUSY : std_logic_vector(2 downto 0) := "010";
constant c_ERROR : std_logic_vector(2 downto 0) := "011";
constant c_ABORT : std_logic_vector(2 downto 0) := "100";
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
-- DMA controller registers
signal dma_ctrl : std_logic_vector(31 downto 0);
signal dma_stat : std_logic_vector(31 downto 0);
signal dma_cstart : std_logic_vector(31 downto 0);
signal dma_hstartl : std_logic_vector(31 downto 0);
signal dma_hstarth : std_logic_vector(31 downto 0);
signal dma_len : std_logic_vector(31 downto 0);
signal dma_nextl : std_logic_vector(31 downto 0);
signal dma_nexth : std_logic_vector(31 downto 0);
signal dma_attrib : std_logic_vector(31 downto 0);
signal dma_ctrl_load : std_logic;
signal dma_stat_load : std_logic;
signal dma_cstart_load : std_logic;
signal dma_hstartl_load : std_logic;
signal dma_hstarth_load : std_logic;
signal dma_len_load : std_logic;
signal dma_nextl_load : std_logic;
signal dma_nexth_load : std_logic;
signal dma_attrib_load : std_logic;
signal dma_ctrl_reg : std_logic_vector(31 downto 0);
signal dma_stat_reg : std_logic_vector(31 downto 0);
signal dma_cstart_reg : std_logic_vector(31 downto 0);
signal dma_hstartl_reg : std_logic_vector(31 downto 0);
signal dma_hstarth_reg : std_logic_vector(31 downto 0);
signal dma_len_reg : std_logic_vector(31 downto 0);
signal dma_nextl_reg : std_logic_vector(31 downto 0);
signal dma_nexth_reg : std_logic_vector(31 downto 0);
signal dma_attrib_reg : std_logic_vector(31 downto 0);
-- DMA controller FSM
type dma_ctrl_state_type is (DMA_IDLE, DMA_START_TRANSFER, DMA_TRANSFER,
DMA_START_CHAIN, DMA_CHAIN,
DMA_ERROR, DMA_ABORT);
signal dma_ctrl_current_state : dma_ctrl_state_type;
-- status signals
signal dma_status : std_logic_vector(2 downto 0);
signal dma_error_irq : std_logic;
signal dma_done_irq : std_logic;
begin
------------------------------------------------------------------------------
-- Wishbone slave instanciation
------------------------------------------------------------------------------
dma_controller_wb_slave_0 : dma_controller_wb_slave port map (
rst_n_i => rst_n_i,
wb_clk_i => wb_clk_i,
wb_addr_i => wb_adr_i,
wb_data_i => wb_dat_i,
wb_data_o => wb_dat_o,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_ack_o => wb_ack_o,
clk_i => clk_i,
dma_ctrl_o => dma_ctrl,
dma_ctrl_i => dma_ctrl_reg,
dma_ctrl_load_o => dma_ctrl_load,
dma_stat_o => open,
dma_stat_i => dma_stat_reg,
dma_stat_load_o => open,
dma_cstart_o => dma_cstart,
dma_cstart_i => dma_cstart_reg,
dma_cstart_load_o => dma_cstart_load,
dma_hstartl_o => dma_hstartl,
dma_hstartl_i => dma_hstartl_reg,
dma_hstartl_load_o => dma_hstartl_load,
dma_hstarth_o => dma_hstarth,
dma_hstarth_i => dma_hstarth_reg,
dma_hstarth_load_o => dma_hstarth_load,
dma_len_o => dma_len,
dma_len_i => dma_len_reg,
dma_len_load_o => dma_len_load,
dma_nextl_o => dma_nextl,
dma_nextl_i => dma_nextl_reg,
dma_nextl_load_o => dma_nextl_load,
dma_nexth_o => dma_nexth,
dma_nexth_i => dma_nexth_reg,
dma_nexth_load_o => dma_nexth_load,
dma_attrib_o => dma_attrib,
dma_attrib_i => dma_attrib_reg,
dma_attrib_load_o => dma_attrib_load
);
------------------------------------------------------------------------------
-- DMA controller registers
------------------------------------------------------------------------------
p_regs : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
dma_ctrl_reg <= (others => '0');
dma_stat_reg <= (others => '0');
dma_cstart_reg <= (others => '0');
dma_hstartl_reg <= (others => '0');
dma_hstarth_reg <= (others => '0');
dma_len_reg <= (others => '0');
dma_nextl_reg <= (others => '0');
dma_nexth_reg <= (others => '0');
dma_attrib_reg <= (others => '0');
elsif rising_edge(clk_i) then
-- Control register
if (dma_ctrl_load = '1') then
dma_ctrl_reg <= dma_ctrl;
end if;
-- Status register
dma_stat_reg(2 downto 0) <= dma_status;
dma_stat_reg(31 downto 3) <= (others => '0');
-- Target start address
if (dma_cstart_load = '1') then
dma_cstart_reg <= dma_cstart;
end if;
-- Host start address lowest 32-bit
if (dma_hstartl_load = '1') then
dma_hstartl_reg <= dma_hstartl;
end if;
-- Host start address highest 32-bit
if (dma_hstarth_load = '1') then
dma_hstarth_reg <= dma_hstarth;
end if;
-- DMA transfer length in byte
if (dma_len_load = '1') then
dma_len_reg <= dma_len;
end if;
-- next item address lowest 32-bit
if (dma_nextl_load = '1') then
dma_nextl_reg <= dma_nextl;
end if;
-- next item address highest 32-bit
if (dma_nexth_load = '1') then
dma_nexth_reg <= dma_nexth;
end if;
-- Chained DMA control
if (dma_attrib_load = '1') then
dma_attrib_reg <= dma_attrib;
end if;
-- next item received => start a new transfer
if (next_item_valid_i = '1') then
dma_ctrl_reg(0) <= '1';
dma_cstart_reg <= next_item_carrier_addr_i;
dma_hstartl_reg <= next_item_host_addr_l_i;
dma_hstarth_reg <= next_item_host_addr_h_i;
dma_len_reg <= next_item_len_i;
dma_nextl_reg <= next_item_next_l_i;
dma_nexth_reg <= next_item_next_h_i;
dma_attrib_reg <= next_item_attrib_i;
end if;
-- Start DMA, 1 tick pulse
if (dma_ctrl_reg(0) = '1') then
dma_ctrl_reg(0) <= '0';
end if;
end if;
end process p_regs;
dma_ctrl_byte_swap_o <= dma_ctrl_reg(3 downto 2);
------------------------------------------------------------------------------
-- IRQ output assignement
------------------------------------------------------------------------------
dma_ctrl_irq_o <= dma_error_irq & dma_done_irq;
------------------------------------------------------------------------------
-- DMA controller FSM
------------------------------------------------------------------------------
p_fsm : process (clk_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
dma_ctrl_current_state <= DMA_IDLE;
dma_ctrl_carrier_addr_o <= (others => '0');
dma_ctrl_host_addr_h_o <= (others => '0');
dma_ctrl_host_addr_l_o <= (others => '0');
dma_ctrl_len_o <= (others => '0');
dma_ctrl_start_l2p_o <= '0';
dma_ctrl_start_p2l_o <= '0';
dma_ctrl_start_next_o <= '0';
dma_status <= c_IDLE;
dma_error_irq <= '0';
dma_done_irq <= '0';
dma_ctrl_abort_o <= '0';
elsif rising_edge(clk_i) then
case dma_ctrl_current_state is
when DMA_IDLE =>
-- Clear done irq to make it 1 tick pulse
dma_done_irq <= '0';
if(dma_ctrl_reg(0) = '1') then
-- Starts a new transfer
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when DMA_START_TRANSFER =>
-- Clear abort signal
dma_ctrl_abort_o <= '0';
if (unsigned(dma_len_reg(31 downto 2)) = 0) then
-- Requesting a DMA of 0 word length gives a error
dma_ctrl_current_state <= DMA_ERROR;
else
-- Start the DMA if the length is not 0
if (dma_attrib_reg(1) = '0') then
-- L2P transfer (from target to PCIe)
dma_ctrl_start_l2p_o <= '1';
elsif (dma_attrib_reg(1) = '1') then
-- P2L transfer (from PCIe to target)
dma_ctrl_start_p2l_o <= '1';
end if;
dma_ctrl_current_state <= DMA_TRANSFER;
dma_ctrl_carrier_addr_o <= dma_cstart_reg;
dma_ctrl_host_addr_h_o <= dma_hstarth_reg;
dma_ctrl_host_addr_l_o <= dma_hstartl_reg;
dma_ctrl_len_o <= dma_len_reg;
dma_status <= c_BUSY;
end if;
when DMA_TRANSFER =>
-- Clear start signals, to make them 1 tick pulses
dma_ctrl_start_l2p_o <= '0';
dma_ctrl_start_p2l_o <= '0';
if (dma_ctrl_reg(1) = '1') then
-- Transfer aborted
dma_ctrl_current_state <= DMA_ABORT;
elsif(dma_ctrl_error_i = '1') then
-- An error occurs !
dma_error_irq <= '1';
dma_ctrl_current_state <= DMA_ERROR;
elsif(dma_ctrl_done_i = '1') then
-- End of DMA transfer
if(dma_attrib_reg(0) = '1') then
-- More transfer in chained DMA
dma_ctrl_current_state <= DMA_START_CHAIN;
else
-- Was the last transfer
dma_status <= c_DONE;
dma_done_irq <= '1';
dma_ctrl_current_state <= DMA_IDLE;
end if;
end if;
when DMA_START_CHAIN =>
-- Catch the next item in host memory
dma_ctrl_current_state <= DMA_CHAIN;
dma_ctrl_host_addr_h_o <= dma_nexth_reg;
dma_ctrl_host_addr_l_o <= dma_nextl_reg;
dma_ctrl_len_o <= X"0000001C";
dma_ctrl_start_next_o <= '1';
when DMA_CHAIN =>
-- Clear start next signal, to make it 1 tick pulse
dma_ctrl_start_next_o <= '0';
if (dma_ctrl_reg(1) = '1') then
-- Transfer aborted
dma_ctrl_current_state <= DMA_ABORT;
elsif(dma_ctrl_error_i = '1') then
-- An error occurs !
dma_error_irq <= '1';
dma_ctrl_current_state <= DMA_ERROR;
elsif (next_item_valid_i = '1') then
-- next item received
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when DMA_ERROR =>
dma_status <= c_ERROR;
-- Clear error irq to make it 1 tick pulse
dma_error_irq <= '0';
if(dma_ctrl_reg(0) = '1') then
-- Starts a new transfer
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when DMA_ABORT =>
dma_status <= c_ABORT;
dma_ctrl_abort_o <= '1';
if(dma_ctrl_reg(0) = '1') then
-- Starts a new transfer
dma_ctrl_current_state <= DMA_START_TRANSFER;
end if;
when others =>
dma_ctrl_current_state <= DMA_IDLE;
dma_ctrl_carrier_addr_o <= (others => '0');
dma_ctrl_host_addr_h_o <= (others => '0');
dma_ctrl_host_addr_l_o <= (others => '0');
dma_ctrl_len_o <= (others => '0');
dma_ctrl_start_l2p_o <= '0';
dma_ctrl_start_p2l_o <= '0';
dma_ctrl_start_next_o <= '0';
dma_status <= (others => '0');
dma_error_irq <= '0';
dma_done_irq <= '0';
dma_ctrl_abort_o <= '0';
end case;
end if;
end process p_fsm;
end behaviour;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for GN4124 core DMA controller
---------------------------------------------------------------------------------------
-- File : async_regs.vhd
-- Author : auto-generated by wbgen2 from async_regs.wb
-- Created : Wed Oct 6 15:30:35 2010
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE async_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dma_controller_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(3 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
clk_i : in std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'DMA engine control' in reg: 'DMACTRLR'
dma_ctrl_o : out std_logic_vector(31 downto 0);
dma_ctrl_i : in std_logic_vector(31 downto 0);
dma_ctrl_load_o : out std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'DMA engine status' in reg: 'DMASTATR'
dma_stat_o : out std_logic_vector(31 downto 0);
dma_stat_i : in std_logic_vector(31 downto 0);
dma_stat_load_o : out std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'DMA start address in the carrier' in reg: 'DMACSTARTR'
dma_cstart_o : out std_logic_vector(31 downto 0);
dma_cstart_i : in std_logic_vector(31 downto 0);
dma_cstart_load_o : out std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'DMA start address (low) in the host' in reg: 'DMAHSTARTLR'
dma_hstartl_o : out std_logic_vector(31 downto 0);
dma_hstartl_i : in std_logic_vector(31 downto 0);
dma_hstartl_load_o : out std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'DMA start address (high) in the host' in reg: 'DMAHSTARTHR'
dma_hstarth_o : out std_logic_vector(31 downto 0);
dma_hstarth_i : in std_logic_vector(31 downto 0);
dma_hstarth_load_o : out std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'DMA read length in bytes' in reg: 'DMALENR'
dma_len_o : out std_logic_vector(31 downto 0);
dma_len_i : in std_logic_vector(31 downto 0);
dma_len_load_o : out std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'Pointer (low) to next item in list' in reg: 'DMANEXTLR'
dma_nextl_o : out std_logic_vector(31 downto 0);
dma_nextl_i : in std_logic_vector(31 downto 0);
dma_nextl_load_o : out std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'Pointer (high) to next item in list' in reg: 'DMANEXTHR'
dma_nexth_o : out std_logic_vector(31 downto 0);
dma_nexth_i : in std_logic_vector(31 downto 0);
dma_nexth_load_o : out std_logic;
-- Ports for asynchronous (clock: clk_i) std_logic_vector field: 'DMA chain control' in reg: 'DMAATTRIBR'
dma_attrib_o : out std_logic_vector(31 downto 0);
dma_attrib_i : in std_logic_vector(31 downto 0);
dma_attrib_load_o : out std_logic
);
end dma_controller_wb_slave;
architecture syn of dma_controller_wb_slave is
signal dma_ctrl_int_read : std_logic_vector(31 downto 0);
signal dma_ctrl_int_write : std_logic_vector(31 downto 0);
signal dma_ctrl_lw : std_logic ;
signal dma_ctrl_lw_delay : std_logic ;
signal dma_ctrl_lw_read_in_progress : std_logic ;
signal dma_ctrl_lw_s0 : std_logic ;
signal dma_ctrl_lw_s1 : std_logic ;
signal dma_ctrl_lw_s2 : std_logic ;
signal dma_ctrl_rwsel : std_logic ;
signal dma_stat_int_read : std_logic_vector(31 downto 0);
signal dma_stat_int_write : std_logic_vector(31 downto 0);
signal dma_stat_lw : std_logic ;
signal dma_stat_lw_delay : std_logic ;
signal dma_stat_lw_read_in_progress : std_logic ;
signal dma_stat_lw_s0 : std_logic ;
signal dma_stat_lw_s1 : std_logic ;
signal dma_stat_lw_s2 : std_logic ;
signal dma_stat_rwsel : std_logic ;
signal dma_cstart_int_read : std_logic_vector(31 downto 0);
signal dma_cstart_int_write : std_logic_vector(31 downto 0);
signal dma_cstart_lw : std_logic ;
signal dma_cstart_lw_delay : std_logic ;
signal dma_cstart_lw_read_in_progress : std_logic ;
signal dma_cstart_lw_s0 : std_logic ;
signal dma_cstart_lw_s1 : std_logic ;
signal dma_cstart_lw_s2 : std_logic ;
signal dma_cstart_rwsel : std_logic ;
signal dma_hstartl_int_read : std_logic_vector(31 downto 0);
signal dma_hstartl_int_write : std_logic_vector(31 downto 0);
signal dma_hstartl_lw : std_logic ;
signal dma_hstartl_lw_delay : std_logic ;
signal dma_hstartl_lw_read_in_progress : std_logic ;
signal dma_hstartl_lw_s0 : std_logic ;
signal dma_hstartl_lw_s1 : std_logic ;
signal dma_hstartl_lw_s2 : std_logic ;
signal dma_hstartl_rwsel : std_logic ;
signal dma_hstarth_int_read : std_logic_vector(31 downto 0);
signal dma_hstarth_int_write : std_logic_vector(31 downto 0);
signal dma_hstarth_lw : std_logic ;
signal dma_hstarth_lw_delay : std_logic ;
signal dma_hstarth_lw_read_in_progress : std_logic ;
signal dma_hstarth_lw_s0 : std_logic ;
signal dma_hstarth_lw_s1 : std_logic ;
signal dma_hstarth_lw_s2 : std_logic ;
signal dma_hstarth_rwsel : std_logic ;
signal dma_len_int_read : std_logic_vector(31 downto 0);
signal dma_len_int_write : std_logic_vector(31 downto 0);
signal dma_len_lw : std_logic ;
signal dma_len_lw_delay : std_logic ;
signal dma_len_lw_read_in_progress : std_logic ;
signal dma_len_lw_s0 : std_logic ;
signal dma_len_lw_s1 : std_logic ;
signal dma_len_lw_s2 : std_logic ;
signal dma_len_rwsel : std_logic ;
signal dma_nextl_int_read : std_logic_vector(31 downto 0);
signal dma_nextl_int_write : std_logic_vector(31 downto 0);
signal dma_nextl_lw : std_logic ;
signal dma_nextl_lw_delay : std_logic ;
signal dma_nextl_lw_read_in_progress : std_logic ;
signal dma_nextl_lw_s0 : std_logic ;
signal dma_nextl_lw_s1 : std_logic ;
signal dma_nextl_lw_s2 : std_logic ;
signal dma_nextl_rwsel : std_logic ;
signal dma_nexth_int_read : std_logic_vector(31 downto 0);
signal dma_nexth_int_write : std_logic_vector(31 downto 0);
signal dma_nexth_lw : std_logic ;
signal dma_nexth_lw_delay : std_logic ;
signal dma_nexth_lw_read_in_progress : std_logic ;
signal dma_nexth_lw_s0 : std_logic ;
signal dma_nexth_lw_s1 : std_logic ;
signal dma_nexth_lw_s2 : std_logic ;
signal dma_nexth_rwsel : std_logic ;
signal dma_attrib_int_read : std_logic_vector(31 downto 0);
signal dma_attrib_int_write : std_logic_vector(31 downto 0);
signal dma_attrib_lw : std_logic ;
signal dma_attrib_lw_delay : std_logic ;
signal dma_attrib_lw_read_in_progress : std_logic ;
signal dma_attrib_lw_s0 : std_logic ;
signal dma_attrib_lw_s1 : std_logic ;
signal dma_attrib_lw_s2 : std_logic ;
signal dma_attrib_rwsel : std_logic ;
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(3 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (wb_clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
dma_ctrl_lw <= '0';
dma_ctrl_lw_delay <= '0';
dma_ctrl_lw_read_in_progress <= '0';
dma_ctrl_rwsel <= '0';
dma_ctrl_int_write <= "00000000000000000000000000000000";
dma_stat_lw <= '0';
dma_stat_lw_delay <= '0';
dma_stat_lw_read_in_progress <= '0';
dma_stat_rwsel <= '0';
dma_stat_int_write <= "00000000000000000000000000000000";
dma_cstart_lw <= '0';
dma_cstart_lw_delay <= '0';
dma_cstart_lw_read_in_progress <= '0';
dma_cstart_rwsel <= '0';
dma_cstart_int_write <= "00000000000000000000000000000000";
dma_hstartl_lw <= '0';
dma_hstartl_lw_delay <= '0';
dma_hstartl_lw_read_in_progress <= '0';
dma_hstartl_rwsel <= '0';
dma_hstartl_int_write <= "00000000000000000000000000000000";
dma_hstarth_lw <= '0';
dma_hstarth_lw_delay <= '0';
dma_hstarth_lw_read_in_progress <= '0';
dma_hstarth_rwsel <= '0';
dma_hstarth_int_write <= "00000000000000000000000000000000";
dma_len_lw <= '0';
dma_len_lw_delay <= '0';
dma_len_lw_read_in_progress <= '0';
dma_len_rwsel <= '0';
dma_len_int_write <= "00000000000000000000000000000000";
dma_nextl_lw <= '0';
dma_nextl_lw_delay <= '0';
dma_nextl_lw_read_in_progress <= '0';
dma_nextl_rwsel <= '0';
dma_nextl_int_write <= "00000000000000000000000000000000";
dma_nexth_lw <= '0';
dma_nexth_lw_delay <= '0';
dma_nexth_lw_read_in_progress <= '0';
dma_nexth_rwsel <= '0';
dma_nexth_int_write <= "00000000000000000000000000000000";
dma_attrib_lw <= '0';
dma_attrib_lw_delay <= '0';
dma_attrib_lw_read_in_progress <= '0';
dma_attrib_rwsel <= '0';
dma_attrib_int_write <= "00000000000000000000000000000000";
elsif rising_edge(wb_clk_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
ack_in_progress <= '0';
else
dma_ctrl_lw <= dma_ctrl_lw_delay;
dma_ctrl_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_ctrl_lw_read_in_progress = '1')) then
dma_ctrl_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_ctrl_int_read;
end if;
dma_stat_lw <= dma_stat_lw_delay;
dma_stat_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_stat_lw_read_in_progress = '1')) then
dma_stat_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_stat_int_read;
end if;
dma_cstart_lw <= dma_cstart_lw_delay;
dma_cstart_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_cstart_lw_read_in_progress = '1')) then
dma_cstart_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_cstart_int_read;
end if;
dma_hstartl_lw <= dma_hstartl_lw_delay;
dma_hstartl_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_hstartl_lw_read_in_progress = '1')) then
dma_hstartl_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_hstartl_int_read;
end if;
dma_hstarth_lw <= dma_hstarth_lw_delay;
dma_hstarth_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_hstarth_lw_read_in_progress = '1')) then
dma_hstarth_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_hstarth_int_read;
end if;
dma_len_lw <= dma_len_lw_delay;
dma_len_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_len_lw_read_in_progress = '1')) then
dma_len_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_len_int_read;
end if;
dma_nextl_lw <= dma_nextl_lw_delay;
dma_nextl_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_nextl_lw_read_in_progress = '1')) then
dma_nextl_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_nextl_int_read;
end if;
dma_nexth_lw <= dma_nexth_lw_delay;
dma_nexth_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_nexth_lw_read_in_progress = '1')) then
dma_nexth_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_nexth_int_read;
end if;
dma_attrib_lw <= dma_attrib_lw_delay;
dma_attrib_lw_delay <= '0';
if ((ack_sreg(1) = '1') and (dma_attrib_lw_read_in_progress = '1')) then
dma_attrib_lw_read_in_progress <= '0';
rddata_reg(31 downto 0) <= dma_attrib_int_read;
end if;
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(3 downto 0) is
when "0000" =>
if (wb_we_i = '1') then
dma_ctrl_int_write <= wrdata_reg(31 downto 0);
dma_ctrl_lw <= '1';
dma_ctrl_lw_delay <= '1';
dma_ctrl_lw_read_in_progress <= '0';
dma_ctrl_rwsel <= '1';
else
dma_ctrl_lw <= '1';
dma_ctrl_lw_delay <= '1';
dma_ctrl_lw_read_in_progress <= '1';
dma_ctrl_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when "0001" =>
if (wb_we_i = '1') then
dma_stat_int_write <= wrdata_reg(31 downto 0);
dma_stat_lw <= '1';
dma_stat_lw_delay <= '1';
dma_stat_lw_read_in_progress <= '0';
dma_stat_rwsel <= '1';
else
dma_stat_lw <= '1';
dma_stat_lw_delay <= '1';
dma_stat_lw_read_in_progress <= '1';
dma_stat_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when "0010" =>
if (wb_we_i = '1') then
dma_cstart_int_write <= wrdata_reg(31 downto 0);
dma_cstart_lw <= '1';
dma_cstart_lw_delay <= '1';
dma_cstart_lw_read_in_progress <= '0';
dma_cstart_rwsel <= '1';
else
dma_cstart_lw <= '1';
dma_cstart_lw_delay <= '1';
dma_cstart_lw_read_in_progress <= '1';
dma_cstart_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when "0011" =>
if (wb_we_i = '1') then
dma_hstartl_int_write <= wrdata_reg(31 downto 0);
dma_hstartl_lw <= '1';
dma_hstartl_lw_delay <= '1';
dma_hstartl_lw_read_in_progress <= '0';
dma_hstartl_rwsel <= '1';
else
dma_hstartl_lw <= '1';
dma_hstartl_lw_delay <= '1';
dma_hstartl_lw_read_in_progress <= '1';
dma_hstartl_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when "0100" =>
if (wb_we_i = '1') then
dma_hstarth_int_write <= wrdata_reg(31 downto 0);
dma_hstarth_lw <= '1';
dma_hstarth_lw_delay <= '1';
dma_hstarth_lw_read_in_progress <= '0';
dma_hstarth_rwsel <= '1';
else
dma_hstarth_lw <= '1';
dma_hstarth_lw_delay <= '1';
dma_hstarth_lw_read_in_progress <= '1';
dma_hstarth_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when "0101" =>
if (wb_we_i = '1') then
dma_len_int_write <= wrdata_reg(31 downto 0);
dma_len_lw <= '1';
dma_len_lw_delay <= '1';
dma_len_lw_read_in_progress <= '0';
dma_len_rwsel <= '1';
else
dma_len_lw <= '1';
dma_len_lw_delay <= '1';
dma_len_lw_read_in_progress <= '1';
dma_len_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when "0110" =>
if (wb_we_i = '1') then
dma_nextl_int_write <= wrdata_reg(31 downto 0);
dma_nextl_lw <= '1';
dma_nextl_lw_delay <= '1';
dma_nextl_lw_read_in_progress <= '0';
dma_nextl_rwsel <= '1';
else
dma_nextl_lw <= '1';
dma_nextl_lw_delay <= '1';
dma_nextl_lw_read_in_progress <= '1';
dma_nextl_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when "0111" =>
if (wb_we_i = '1') then
dma_nexth_int_write <= wrdata_reg(31 downto 0);
dma_nexth_lw <= '1';
dma_nexth_lw_delay <= '1';
dma_nexth_lw_read_in_progress <= '0';
dma_nexth_rwsel <= '1';
else
dma_nexth_lw <= '1';
dma_nexth_lw_delay <= '1';
dma_nexth_lw_read_in_progress <= '1';
dma_nexth_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when "1000" =>
if (wb_we_i = '1') then
dma_attrib_int_write <= wrdata_reg(31 downto 0);
dma_attrib_lw <= '1';
dma_attrib_lw_delay <= '1';
dma_attrib_lw_read_in_progress <= '0';
dma_attrib_rwsel <= '1';
else
dma_attrib_lw <= '1';
dma_attrib_lw_delay <= '1';
dma_attrib_lw_read_in_progress <= '1';
dma_attrib_rwsel <= '0';
end if;
ack_sreg(5) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- DMA engine control
-- asynchronous std_logic_vector register : DMA engine control (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_ctrl_lw_s0 <= '0';
dma_ctrl_lw_s1 <= '0';
dma_ctrl_lw_s2 <= '0';
dma_ctrl_o <= "00000000000000000000000000000000";
dma_ctrl_load_o <= '0';
dma_ctrl_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_ctrl_lw_s0 <= dma_ctrl_lw;
dma_ctrl_lw_s1 <= dma_ctrl_lw_s0;
dma_ctrl_lw_s2 <= dma_ctrl_lw_s1;
if ((dma_ctrl_lw_s2 = '0') and (dma_ctrl_lw_s1 = '1')) then
if (dma_ctrl_rwsel = '1') then
dma_ctrl_o <= dma_ctrl_int_write;
dma_ctrl_load_o <= '1';
else
dma_ctrl_load_o <= '0';
dma_ctrl_int_read <= dma_ctrl_i;
end if;
else
dma_ctrl_load_o <= '0';
end if;
end if;
end process;
-- DMA engine status
-- asynchronous std_logic_vector register : DMA engine status (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_stat_lw_s0 <= '0';
dma_stat_lw_s1 <= '0';
dma_stat_lw_s2 <= '0';
dma_stat_o <= "00000000000000000000000000000000";
dma_stat_load_o <= '0';
dma_stat_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_stat_lw_s0 <= dma_stat_lw;
dma_stat_lw_s1 <= dma_stat_lw_s0;
dma_stat_lw_s2 <= dma_stat_lw_s1;
if ((dma_stat_lw_s2 = '0') and (dma_stat_lw_s1 = '1')) then
if (dma_stat_rwsel = '1') then
dma_stat_o <= dma_stat_int_write;
dma_stat_load_o <= '1';
else
dma_stat_load_o <= '0';
dma_stat_int_read <= dma_stat_i;
end if;
else
dma_stat_load_o <= '0';
end if;
end if;
end process;
-- DMA start address in the carrier
-- asynchronous std_logic_vector register : DMA start address in the carrier (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_cstart_lw_s0 <= '0';
dma_cstart_lw_s1 <= '0';
dma_cstart_lw_s2 <= '0';
dma_cstart_o <= "00000000000000000000000000000000";
dma_cstart_load_o <= '0';
dma_cstart_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_cstart_lw_s0 <= dma_cstart_lw;
dma_cstart_lw_s1 <= dma_cstart_lw_s0;
dma_cstart_lw_s2 <= dma_cstart_lw_s1;
if ((dma_cstart_lw_s2 = '0') and (dma_cstart_lw_s1 = '1')) then
if (dma_cstart_rwsel = '1') then
dma_cstart_o <= dma_cstart_int_write;
dma_cstart_load_o <= '1';
else
dma_cstart_load_o <= '0';
dma_cstart_int_read <= dma_cstart_i;
end if;
else
dma_cstart_load_o <= '0';
end if;
end if;
end process;
-- DMA start address (low) in the host
-- asynchronous std_logic_vector register : DMA start address (low) in the host (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_hstartl_lw_s0 <= '0';
dma_hstartl_lw_s1 <= '0';
dma_hstartl_lw_s2 <= '0';
dma_hstartl_o <= "00000000000000000000000000000000";
dma_hstartl_load_o <= '0';
dma_hstartl_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_hstartl_lw_s0 <= dma_hstartl_lw;
dma_hstartl_lw_s1 <= dma_hstartl_lw_s0;
dma_hstartl_lw_s2 <= dma_hstartl_lw_s1;
if ((dma_hstartl_lw_s2 = '0') and (dma_hstartl_lw_s1 = '1')) then
if (dma_hstartl_rwsel = '1') then
dma_hstartl_o <= dma_hstartl_int_write;
dma_hstartl_load_o <= '1';
else
dma_hstartl_load_o <= '0';
dma_hstartl_int_read <= dma_hstartl_i;
end if;
else
dma_hstartl_load_o <= '0';
end if;
end if;
end process;
-- DMA start address (high) in the host
-- asynchronous std_logic_vector register : DMA start address (high) in the host (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_hstarth_lw_s0 <= '0';
dma_hstarth_lw_s1 <= '0';
dma_hstarth_lw_s2 <= '0';
dma_hstarth_o <= "00000000000000000000000000000000";
dma_hstarth_load_o <= '0';
dma_hstarth_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_hstarth_lw_s0 <= dma_hstarth_lw;
dma_hstarth_lw_s1 <= dma_hstarth_lw_s0;
dma_hstarth_lw_s2 <= dma_hstarth_lw_s1;
if ((dma_hstarth_lw_s2 = '0') and (dma_hstarth_lw_s1 = '1')) then
if (dma_hstarth_rwsel = '1') then
dma_hstarth_o <= dma_hstarth_int_write;
dma_hstarth_load_o <= '1';
else
dma_hstarth_load_o <= '0';
dma_hstarth_int_read <= dma_hstarth_i;
end if;
else
dma_hstarth_load_o <= '0';
end if;
end if;
end process;
-- DMA read length in bytes
-- asynchronous std_logic_vector register : DMA read length in bytes (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_len_lw_s0 <= '0';
dma_len_lw_s1 <= '0';
dma_len_lw_s2 <= '0';
dma_len_o <= "00000000000000000000000000000000";
dma_len_load_o <= '0';
dma_len_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_len_lw_s0 <= dma_len_lw;
dma_len_lw_s1 <= dma_len_lw_s0;
dma_len_lw_s2 <= dma_len_lw_s1;
if ((dma_len_lw_s2 = '0') and (dma_len_lw_s1 = '1')) then
if (dma_len_rwsel = '1') then
dma_len_o <= dma_len_int_write;
dma_len_load_o <= '1';
else
dma_len_load_o <= '0';
dma_len_int_read <= dma_len_i;
end if;
else
dma_len_load_o <= '0';
end if;
end if;
end process;
-- Pointer (low) to next item in list
-- asynchronous std_logic_vector register : Pointer (low) to next item in list (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_nextl_lw_s0 <= '0';
dma_nextl_lw_s1 <= '0';
dma_nextl_lw_s2 <= '0';
dma_nextl_o <= "00000000000000000000000000000000";
dma_nextl_load_o <= '0';
dma_nextl_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_nextl_lw_s0 <= dma_nextl_lw;
dma_nextl_lw_s1 <= dma_nextl_lw_s0;
dma_nextl_lw_s2 <= dma_nextl_lw_s1;
if ((dma_nextl_lw_s2 = '0') and (dma_nextl_lw_s1 = '1')) then
if (dma_nextl_rwsel = '1') then
dma_nextl_o <= dma_nextl_int_write;
dma_nextl_load_o <= '1';
else
dma_nextl_load_o <= '0';
dma_nextl_int_read <= dma_nextl_i;
end if;
else
dma_nextl_load_o <= '0';
end if;
end if;
end process;
-- Pointer (high) to next item in list
-- asynchronous std_logic_vector register : Pointer (high) to next item in list (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_nexth_lw_s0 <= '0';
dma_nexth_lw_s1 <= '0';
dma_nexth_lw_s2 <= '0';
dma_nexth_o <= "00000000000000000000000000000000";
dma_nexth_load_o <= '0';
dma_nexth_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_nexth_lw_s0 <= dma_nexth_lw;
dma_nexth_lw_s1 <= dma_nexth_lw_s0;
dma_nexth_lw_s2 <= dma_nexth_lw_s1;
if ((dma_nexth_lw_s2 = '0') and (dma_nexth_lw_s1 = '1')) then
if (dma_nexth_rwsel = '1') then
dma_nexth_o <= dma_nexth_int_write;
dma_nexth_load_o <= '1';
else
dma_nexth_load_o <= '0';
dma_nexth_int_read <= dma_nexth_i;
end if;
else
dma_nexth_load_o <= '0';
end if;
end if;
end process;
-- DMA chain control
-- asynchronous std_logic_vector register : DMA chain control (type RW/WO, clk_i <-> wb_clk_i)
process (clk_i, rst_n_i)
begin
if (rst_n_i = '0') then
dma_attrib_lw_s0 <= '0';
dma_attrib_lw_s1 <= '0';
dma_attrib_lw_s2 <= '0';
dma_attrib_o <= "00000000000000000000000000000000";
dma_attrib_load_o <= '0';
dma_attrib_int_read <= "00000000000000000000000000000000";
elsif rising_edge(clk_i) then
dma_attrib_lw_s0 <= dma_attrib_lw;
dma_attrib_lw_s1 <= dma_attrib_lw_s0;
dma_attrib_lw_s2 <= dma_attrib_lw_s1;
if ((dma_attrib_lw_s2 = '0') and (dma_attrib_lw_s1 = '1')) then
if (dma_attrib_rwsel = '1') then
dma_attrib_o <= dma_attrib_int_write;
dma_attrib_load_o <= '1';
else
dma_attrib_load_o <= '0';
dma_attrib_int_read <= dma_attrib_i;
end if;
else
dma_attrib_load_o <= '0';
end if;
end if;
end process;
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Dummy control registers
---------------------------------------------------------------------------------------
-- File : ../../GN4124_core/hdl/gn4124core/design/rtl/dummy_ctrl_regs.vhd
-- Author : auto-generated by wbgen2 from ../../GN4124_core/hdl/gn4124core/design/wb_gen/dummy_ctrl_regs_wb_slave.wb
-- Created : Wed Nov 10 14:40:05 2010
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ../../GN4124_core/hdl/gn4124core/design/wb_gen/dummy_ctrl_regs_wb_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dummy_ctrl_regs_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- Port for std_logic_vector field: 'Dummy register 1' in reg: 'DUMMY_1'
dummy_reg_1_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 2' in reg: 'DUMMY_2'
dummy_reg_2_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 3' in reg: 'DUMMY_3'
dummy_reg_3_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register for LED control' in reg: 'DUMMY_LED'
dummy_reg_led_o : out std_logic_vector(31 downto 0)
);
end dummy_ctrl_regs_wb_slave;
architecture syn of dummy_ctrl_regs_wb_slave is
signal dummy_reg_1_int : std_logic_vector(31 downto 0);
signal dummy_reg_2_int : std_logic_vector(31 downto 0);
signal dummy_reg_3_int : std_logic_vector(31 downto 0);
signal dummy_reg_led_int : std_logic_vector(31 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
dummy_reg_1_int <= "00000000000000000000000000000000";
dummy_reg_2_int <= "00000000000000000000000000000000";
dummy_reg_3_int <= "00000000000000000000000000000000";
dummy_reg_led_int <= "00000000000000000000000000000000";
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
dummy_reg_1_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_1_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
dummy_reg_2_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_2_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
dummy_reg_3_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_3_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
dummy_reg_led_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_led_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- Dummy register 1
dummy_reg_1_o <= dummy_reg_1_int;
-- Dummy register 2
dummy_reg_2_o <= dummy_reg_2_int;
-- Dummy register 3
dummy_reg_3_o <= dummy_reg_3_int;
-- Dummy register for LED control
dummy_reg_led_o <= dummy_reg_led_int;
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Dummy status registers
---------------------------------------------------------------------------------------
-- File : ../../GN4124_core/hdl/gn4124core/design/rtl/dummy_stat_regs.vhd
-- Author : auto-generated by wbgen2 from ../../GN4124_core/hdl/gn4124core/design/wb_gen/dummy_stat_regs_wb_slave.wb
-- Created : Wed Nov 10 14:42:59 2010
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ../../GN4124_core/hdl/gn4124core/design/wb_gen/dummy_stat_regs_wb_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dummy_stat_regs_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- Port for std_logic_vector field: 'Dummy register 1' in reg: 'DUMMY_1'
dummy_stat_reg_1_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 2' in reg: 'DUMMY_2'
dummy_stat_reg_2_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 3' in reg: 'DUMMY_3'
dummy_stat_reg_3_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register for switch status' in reg: 'DUMMY_SWITCH'
dummy_stat_reg_switch_i : in std_logic_vector(31 downto 0)
);
end dummy_stat_regs_wb_slave;
architecture syn of dummy_stat_regs_wb_slave is
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_1_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_2_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_3_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_switch_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- Dummy register 1
-- Dummy register 2
-- Dummy register 3
-- Dummy register for switch status
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: Gn4124 core main block (gn4124-core.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 0.3
--
-- description: GN4124 core top level.
--
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: see svn log
--------------------------------------------------------------------------------
-- TODO: - DMA wishbone bus address map
-- - reset and clock signals
-- - wishbone timeout generic ??
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
--==============================================================================
-- Entity declaration for GN4124 core (gn4124_core)
--==============================================================================
entity gn4124_core is
generic(
g_IS_SPARTAN6 : boolean := false; -- This generic is used to instanciate spartan6 specific primitives
g_BAR0_APERTURE : integer := 20; -- BAR0 aperture, defined in GN4124 PCI_BAR_CONFIG register (0x80C)
-- => number of bits to address periph on the board
g_CSR_WB_SLAVES_NB : integer := 1; -- Number of CSR wishbone slaves
g_DMA_WB_SLAVES_NB : integer := 1; -- Number of DMA wishbone slaves
g_DMA_WB_ADDR_WIDTH : integer := 26 -- DMA wishbone address bus width
);
port
(
---------------------------------------------------------
-- Asynchronous reset from GN4124
rst_n_a_i : in std_logic;
---------------------------------------------------------
-- P2L Direction
--
-- Source Sync DDR related signals
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i : in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
-- P2L Control
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
---------------------------------------------------------
-- L2P Direction
--
-- Source Sync DDR related signals
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o : out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
-- L2P Control
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
---------------------------------------------------------
-- Interrupt interface
dma_irq_o : out std_logic_vector(1 downto 0); -- Interrupts sources to IRQ manager
irq_p_i : in std_logic; -- Interrupt request pulse from IRQ manager
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
---------------------------------------------------------
-- Target interface (CSR wishbone master)
wb_clk_i : in std_logic;
wb_adr_o : out std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_CSR_WB_SLAVES_NB+1)-1 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic;
wb_we_o : out std_logic;
wb_cyc_o : out std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
wb_dat_i : in std_logic_vector((32*g_CSR_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
---------------------------------------------------------
-- DMA interface (Pipelined wishbone master)
dma_clk_i : in std_logic;
dma_adr_o : out std_logic_vector(31 downto 0);
dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
dma_stb_o : out std_logic;
dma_we_o : out std_logic;
dma_cyc_o : out std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_dat_i : in std_logic_vector((32*g_DMA_WB_SLAVES_NB)-1 downto 0); -- Data in
dma_ack_i : in std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_stall_i : in std_logic--_vector(g_DMA_WB_SLAVES_NB-1 downto 0) -- for pipelined Wishbone
);
end gn4124_core;
--==============================================================================
-- Architecture declaration for GN4124 core (gn4124_core)
--==============================================================================
architecture rtl of gn4124_core is
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
-- Clock
signal clk_p : std_logic;
signal clk_n : std_logic;
signal clk_p_buf : std_logic;
signal clk_n_buf : std_logic;
-- Reset for all clk_p logic
signal rst_reg : std_logic;
signal rst_n : std_logic;
-------------------------------------------------------------
-- P2L DataPath (from deserializer to packet decoder)
-------------------------------------------------------------
signal des_pd_valid : std_logic;
signal des_pd_dframe : std_logic;
signal des_pd_data : std_logic_vector(31 downto 0);
-- Local bus control
signal p_wr_rdy : std_logic;
signal p2l_rdy_wbm : std_logic;
signal p2l_rdy_pdm : std_logic;
-------------------------------------------------------------
-- P2L DataPath (from packet decoder to Wishbone master and P2L DMA master)
-------------------------------------------------------------
signal p2l_hdr_start : std_logic;
signal p2l_hdr_length : std_logic_vector(9 downto 0);
signal p2l_hdr_cid : std_logic_vector(1 downto 0);
signal p2l_hdr_last : std_logic;
signal p2l_hdr_stat : std_logic_vector(1 downto 0);
signal p2l_target_mrd : std_logic;
signal p2l_target_mwr : std_logic;
signal p2l_master_cpld : std_logic;
signal p2l_master_cpln : std_logic;
signal p2l_d_valid : std_logic;
signal p2l_d_last : std_logic;
signal p2l_d : std_logic_vector(31 downto 0);
signal p2l_be : std_logic_vector(3 downto 0);
signal p2l_addr : std_logic_vector(31 downto 0);
signal p2l_addr_start : std_logic;
-------------------------------------------------------------
-- L2P DataPath (from arbiter to serializer)
-------------------------------------------------------------
signal arb_ser_valid : std_logic;
signal arb_ser_dframe : std_logic;
signal arb_ser_data : std_logic_vector(31 downto 0);
-- Local bus control
signal l_wr_rdy_t : std_logic_vector(1 downto 0);
signal l_wr_rdy : std_logic_vector(1 downto 0);
signal p_rd_d_rdy_t : std_logic_vector(1 downto 0);
signal p_rd_d_rdy : std_logic_vector(1 downto 0);
signal l2p_rdy_t : std_logic;
signal l2p_rdy : std_logic;
-------------------------------------------------------------
-- CSR wishbone master to arbiter
-------------------------------------------------------------
signal wbm_arb_valid : std_logic;
signal wbm_arb_dframe : std_logic;
signal wbm_arb_data : std_logic_vector(31 downto 0);
signal wbm_arb_req : std_logic;
signal arb_wbm_gnt : std_logic;
-------------------------------------------------------------
-- L2P DMA master to arbiter
-------------------------------------------------------------
signal ldm_arb_req : std_logic;
signal arb_ldm_gnt : std_logic;
signal ldm_arb_valid : std_logic;
signal ldm_arb_dframe : std_logic;
signal ldm_arb_data : std_logic_vector(31 downto 0);
-------------------------------------------------------------
-- P2L DMA master to arbiter
-------------------------------------------------------------
signal pdm_arb_valid : std_logic;
signal pdm_arb_dframe : std_logic;
signal pdm_arb_data : std_logic_vector(31 downto 0);
signal pdm_arb_req : std_logic;
signal arb_pdm_gnt : std_logic;
-------------------------------------------------------------
-- DMA controller
-------------------------------------------------------------
signal dma_ctrl_carrier_addr : std_logic_vector(31 downto 0);
signal dma_ctrl_host_addr_h : std_logic_vector(31 downto 0);
signal dma_ctrl_host_addr_l : std_logic_vector(31 downto 0);
signal dma_ctrl_len : std_logic_vector(31 downto 0);
signal dma_ctrl_start_l2p : std_logic;
signal dma_ctrl_start_p2l : std_logic;
signal dma_ctrl_start_next : std_logic;
signal dma_ctrl_done : std_logic;
signal dma_ctrl_error : std_logic;
signal dma_ctrl_l2p_done : std_logic;
signal dma_ctrl_l2p_error : std_logic;
signal dma_ctrl_p2l_done : std_logic;
signal dma_ctrl_p2l_error : std_logic;
signal dma_ctrl_byte_swap : std_logic_vector(1 downto 0);
signal dma_ctrl_abort : std_logic;
signal next_item_carrier_addr : std_logic_vector(31 downto 0);
signal next_item_host_addr_h : std_logic_vector(31 downto 0);
signal next_item_host_addr_l : std_logic_vector(31 downto 0);
signal next_item_len : std_logic_vector(31 downto 0);
signal next_item_next_l : std_logic_vector(31 downto 0);
signal next_item_next_h : std_logic_vector(31 downto 0);
signal next_item_attrib : std_logic_vector(31 downto 0);
signal next_item_valid : std_logic;
------------------------------------------------------------------------------
-- CSR wishbone bus
------------------------------------------------------------------------------
signal wb_adr : std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_CSR_WB_SLAVES_NB+1)-1 downto 0);
signal wb_dat_s2m : std_logic_vector((32*(g_CSR_WB_SLAVES_NB+1))-1 downto 0);
signal wb_dat_m2s : std_logic_vector(31 downto 0);
signal wb_sel : std_logic_vector(3 downto 0);
signal wb_cyc : std_logic_vector(g_CSR_WB_SLAVES_NB downto 0);
signal wb_stb : std_logic;
signal wb_we : std_logic;
signal wb_ack : std_logic_vector(g_CSR_WB_SLAVES_NB downto 0);
signal wb_ack_dma_ctrl : std_logic;
signal wb_dat_s2m_dma_ctrl : std_logic_vector(31 downto 0);
------------------------------------------------------------------------------
-- DMA wishbone bus
------------------------------------------------------------------------------
signal l2p_dma_adr : std_logic_vector(31 downto 0);
signal l2p_dma_dat_s2m : std_logic_vector(31 downto 0);
signal l2p_dma_dat_m2s : std_logic_vector(31 downto 0);
signal l2p_dma_sel : std_logic_vector(3 downto 0);
signal l2p_dma_cyc : std_logic;
signal l2p_dma_stb : std_logic;
signal l2p_dma_we : std_logic;
signal l2p_dma_ack : std_logic;
signal l2p_dma_stall : std_logic;
signal p2l_dma_adr : std_logic_vector(31 downto 0);
signal p2l_dma_dat_s2m : std_logic_vector(31 downto 0);
signal p2l_dma_dat_m2s : std_logic_vector(31 downto 0);
signal p2l_dma_sel : std_logic_vector(3 downto 0);
signal p2l_dma_cyc : std_logic;
signal p2l_dma_stb : std_logic;
signal p2l_dma_we : std_logic;
signal p2l_dma_ack : std_logic;
signal p2l_dma_stall : std_logic;
--==============================================================================
-- Architecture begin (gn4124_core)
--==============================================================================
begin
-----------------------------------------------------------------------------
-- The Internal Core Clock is Derived from the P2L_CLK
-----------------------------------------------------------------------------
CLK_ibuf : IBUFGDS
port map(
I => p2l_clk_p_i,
IB => p2l_clk_n_i,
O => clk_p_buf);
CLK_bufg : BUFG
port map(
I => clk_p_buf,
O => clk_p);
CLKn_ibuf : IBUFGDS
port map(
I => p2l_clk_n_i,
IB => p2l_clk_p_i,
O => clk_n_buf);
CLKn_bufg : BUFG
port map(
I => clk_n_buf,
O => clk_n);
------------------------------------------------------------------------------
-- Reset aligned to core clock
------------------------------------------------------------------------------
p_core_rst : process (clk_p, rst_n_a_i)
begin
if rst_n_a_i = c_RST_ACTIVE then
rst_reg <= c_RST_ACTIVE;
elsif rising_edge(clk_p) then
rst_reg <= not(c_RST_ACTIVE);
end if;
end process p_core_rst;
gen_rst : if g_IS_SPARTAN6 = false generate
cmp_rst_buf : BUFG
port map (
I => rst_reg,
O => rst_n
);
end generate gen_rst;
gen_rst_s6 : if g_IS_SPARTAN6 = true generate
rst_n <= rst_reg;
end generate gen_rst_s6;
------------------------------------------------------------------------------
-- IRQ pulse forward to GN4124 GPIO
------------------------------------------------------------------------------
irq_p_o <= irq_p_i;
--============================================================================
-- P2L DataPath
--============================================================================
-----------------------------------------------------------------------------
-- p2l_des: Deserialize the P2L DDR inputs
-----------------------------------------------------------------------------
cmp_p2l_des : p2l_des
generic map (
g_IS_SPARTAN6 => g_IS_SPARTAN6
)
port map
(
---------------------------------------------------------
-- Raw unprocessed reset from the GN412x
rst_n_i => rst_n,
clk_p_i => clk_p,
clk_n_i => clk_n,
---------------------------------------------------------
-- P2L Clock Domain
--
-- P2L Inputs
p2l_valid_i => p2l_valid_i,
p2l_dframe_i => p2l_dframe_i,
p2l_data_i => p2l_data_i,
---------------------------------------------------------
-- Core Clock Domain
--
-- DeSerialized Output
p2l_valid_o => des_pd_valid,
p2l_dframe_o => des_pd_dframe,
p2l_data_o => des_pd_data
);
------------------------------------------------------------------------------
-- P2L local bus control signals
------------------------------------------------------------------------------
-- de-asserted to pause transfer from GN4124
p2l_rdy_o <= p2l_rdy_wbm and p2l_rdy_pdm;
-----------------------------------------------------------------------------
-- p2l_decode32: Decode the output of the p2l_des
-----------------------------------------------------------------------------
cmp_p2l_decode32 : p2l_decode32
port map
(
---------------------------------------------------------
-- Clock/Reset
clk_i => clk_p,
rst_n_i => rst_n,
---------------------------------------------------------
-- Input from the Deserializer
--
des_p2l_valid_i => des_pd_valid,
des_p2l_dframe_i => des_pd_dframe,
des_p2l_data_i => des_pd_data,
---------------------------------------------------------
-- Decoder Outputs
--
-- Header
p2l_hdr_start_o => p2l_hdr_start,
p2l_hdr_length_o => p2l_hdr_length,
p2l_hdr_cid_o => p2l_hdr_cid,
p2l_hdr_last_o => p2l_hdr_last,
p2l_hdr_stat_o => p2l_hdr_stat,
p2l_target_mrd_o => p2l_target_mrd,
p2l_target_mwr_o => p2l_target_mwr,
p2l_master_cpld_o => p2l_master_cpld,
p2l_master_cpln_o => p2l_master_cpln,
--
-- Address
p2l_addr_start_o => p2l_addr_start,
p2l_addr_o => p2l_addr,
--
-- Data
p2l_d_valid_o => p2l_d_valid,
p2l_d_last_o => p2l_d_last,
p2l_d_o => p2l_d,
p2l_be_o => p2l_be
);
--===========================================================================
-- Core Logic Blocks
--===========================================================================
-----------------------------------------------------------------------------
-- Wishbone master
-----------------------------------------------------------------------------
cmp_wbmaster32 : wbmaster32
generic map
(
g_BAR0_APERTURE => g_BAR0_APERTURE,
g_WB_SLAVES_NB => (g_CSR_WB_SLAVES_NB + 1) -- +1 for the DMA controller (wb slave always present)
)
port map
(
---------------------------------------------------------
-- Clock/Reset
clk_i => clk_p,
rst_n_i => rst_n,
---------------------------------------------------------
-- From P2L Decoder
--
-- Header
pd_wbm_hdr_start_i => p2l_hdr_start,
pd_wbm_hdr_length_i => p2l_hdr_length,
pd_wbm_hdr_cid_i => p2l_hdr_cid,
pd_wbm_target_mrd_i => p2l_target_mrd,
pd_wbm_target_mwr_i => p2l_target_mwr,
--
-- Address
pd_wbm_addr_start_i => p2l_addr_start,
pd_wbm_addr_i => p2l_addr,
--
-- Data
pd_wbm_data_valid_i => p2l_d_valid,
pd_wbm_data_last_i => p2l_d_last,
pd_wbm_data_i => p2l_d,
pd_wbm_be_i => p2l_be,
---------------------------------------------------------
-- P2L Control
p_wr_rdy_o => p_wr_rdy_o,
p2l_rdy_o => p2l_rdy_wbm,
p_rd_d_rdy_i => p_rd_d_rdy,
---------------------------------------------------------
-- To the L2P Interface
wbm_arb_valid_o => wbm_arb_valid,
wbm_arb_dframe_o => wbm_arb_dframe,
wbm_arb_data_o => wbm_arb_data,
wbm_arb_req_o => wbm_arb_req,
arb_wbm_gnt_i => arb_wbm_gnt,
---------------------------------------------------------
-- Wishbone Interface
wb_clk_i => wb_clk_i,
wb_adr_o => wb_adr,
wb_dat_i => wb_dat_s2m,
wb_dat_o => wb_dat_m2s,
wb_sel_o => wb_sel,
wb_cyc_o => wb_cyc,
wb_stb_o => wb_stb,
wb_we_o => wb_we,
wb_ack_i => wb_ack
);
wb_adr_o <= wb_adr;
wb_dat_s2m <= wb_dat_i & wb_dat_s2m_dma_ctrl;
wb_dat_o <= wb_dat_m2s;
wb_sel_o <= wb_sel;
wb_cyc_o <= wb_cyc(g_CSR_WB_SLAVES_NB downto 1); -- wb_cyc(0) is for DMA controller
wb_stb_o <= wb_stb;
wb_we_o <= wb_we;
wb_ack <= wb_ack_i & wb_ack_dma_ctrl;
-----------------------------------------------------------------------------
-- DMA controller
-----------------------------------------------------------------------------
cmp_dma_controller : dma_controller
port map
(
clk_i => clk_p,
rst_n_i => rst_n,
dma_ctrl_irq_o => dma_irq_o,
dma_ctrl_carrier_addr_o => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_o => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_o => dma_ctrl_host_addr_l,
dma_ctrl_len_o => dma_ctrl_len,
dma_ctrl_start_l2p_o => dma_ctrl_start_l2p,
dma_ctrl_start_p2l_o => dma_ctrl_start_p2l,
dma_ctrl_start_next_o => dma_ctrl_start_next,
dma_ctrl_done_i => dma_ctrl_done,
dma_ctrl_error_i => dma_ctrl_error,
dma_ctrl_byte_swap_o => dma_ctrl_byte_swap,
dma_ctrl_abort_o => dma_ctrl_abort,
next_item_carrier_addr_i => next_item_carrier_addr,
next_item_host_addr_h_i => next_item_host_addr_h,
next_item_host_addr_l_i => next_item_host_addr_l,
next_item_len_i => next_item_len,
next_item_next_l_i => next_item_next_l,
next_item_next_h_i => next_item_next_h,
next_item_attrib_i => next_item_attrib,
next_item_valid_i => next_item_valid,
wb_clk_i => wb_clk_i,
wb_adr_i => wb_adr(3 downto 0),
wb_dat_o => wb_dat_s2m_dma_ctrl,
wb_dat_i => wb_dat_m2s,
wb_sel_i => wb_sel,
wb_cyc_i => wb_cyc(0),
wb_stb_i => wb_stb,
wb_we_i => wb_we,
wb_ack_o => wb_ack_dma_ctrl
);
-- Status signals from DMA masters
dma_ctrl_done <= dma_ctrl_l2p_done or dma_ctrl_p2l_done;
dma_ctrl_error <= dma_ctrl_l2p_error or dma_ctrl_p2l_error;
-----------------------------------------------------------------------------
-- L2P DMA master
-----------------------------------------------------------------------------
cmp_l2p_dma_master : l2p_dma_master
port map
(
clk_i => clk_p,
rst_n_i => rst_n,
dma_ctrl_target_addr_i => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_i => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_i => dma_ctrl_host_addr_l,
dma_ctrl_len_i => dma_ctrl_len,
dma_ctrl_start_l2p_i => dma_ctrl_start_l2p,
dma_ctrl_done_o => dma_ctrl_l2p_done,
dma_ctrl_error_o => dma_ctrl_l2p_error,
dma_ctrl_byte_swap_i => dma_ctrl_byte_swap,
dma_ctrl_abort_i => dma_ctrl_abort,
ldm_arb_valid_o => ldm_arb_valid,
ldm_arb_dframe_o => ldm_arb_dframe,
ldm_arb_data_o => ldm_arb_data,
ldm_arb_req_o => ldm_arb_req,
arb_ldm_gnt_i => arb_ldm_gnt,
l2p_edb_o => l2p_edb_o,
l_wr_rdy_i => l_wr_rdy,
l2p_rdy_i => l2p_rdy,
l2p_dma_clk_i => dma_clk_i,
l2p_dma_adr_o => l2p_dma_adr,
l2p_dma_dat_i => l2p_dma_dat_s2m,
l2p_dma_dat_o => l2p_dma_dat_m2s,
l2p_dma_sel_o => l2p_dma_sel,
l2p_dma_cyc_o => l2p_dma_cyc,
l2p_dma_stb_o => l2p_dma_stb,
l2p_dma_we_o => l2p_dma_we,
l2p_dma_ack_i => l2p_dma_ack,
l2p_dma_stall_i => l2p_dma_stall
);
-----------------------------------------------------------------------------
-- P2L DMA master
-----------------------------------------------------------------------------
cmp_p2l_dma_master : p2l_dma_master
port map
(
clk_i => clk_p,
rst_n_i => rst_n,
dma_ctrl_carrier_addr_i => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_i => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_i => dma_ctrl_host_addr_l,
dma_ctrl_len_i => dma_ctrl_len,
dma_ctrl_start_p2l_i => dma_ctrl_start_p2l,
dma_ctrl_start_next_i => dma_ctrl_start_next,
dma_ctrl_done_o => dma_ctrl_p2l_done,
dma_ctrl_error_o => dma_ctrl_p2l_error,
dma_ctrl_byte_swap_i => dma_ctrl_byte_swap,
dma_ctrl_abort_i => dma_ctrl_abort,
pd_pdm_hdr_start_i => p2l_hdr_start,
pd_pdm_hdr_length_i => p2l_hdr_length,
pd_pdm_hdr_cid_i => p2l_hdr_cid,
pd_pdm_master_cpld_i => p2l_master_cpld,
pd_pdm_master_cpln_i => p2l_master_cpln,
pd_pdm_data_valid_i => p2l_d_valid,
pd_pdm_data_last_i => p2l_d_last,
pd_pdm_data_i => p2l_d,
pd_pdm_be_i => p2l_be,
p2l_rdy_o => p2l_rdy_pdm,
rx_error_o => rx_error_o,
pdm_arb_valid_o => pdm_arb_valid,
pdm_arb_dframe_o => pdm_arb_dframe,
pdm_arb_data_o => pdm_arb_data,
pdm_arb_req_o => pdm_arb_req,
arb_pdm_gnt_i => arb_pdm_gnt,
p2l_dma_clk_i => dma_clk_i,
p2l_dma_adr_o => p2l_dma_adr,
p2l_dma_dat_i => p2l_dma_dat_s2m,
p2l_dma_dat_o => p2l_dma_dat_m2s,
p2l_dma_sel_o => p2l_dma_sel,
p2l_dma_cyc_o => p2l_dma_cyc,
p2l_dma_stb_o => p2l_dma_stb,
p2l_dma_we_o => p2l_dma_we,
p2l_dma_ack_i => p2l_dma_ack,
p2l_dma_stall_i => p2l_dma_stall,
next_item_carrier_addr_o => next_item_carrier_addr,
next_item_host_addr_h_o => next_item_host_addr_h,
next_item_host_addr_l_o => next_item_host_addr_l,
next_item_len_o => next_item_len,
next_item_next_l_o => next_item_next_l,
next_item_next_h_o => next_item_next_h,
next_item_attrib_o => next_item_attrib,
next_item_valid_o => next_item_valid
);
p_dma_wb_mux : process (p2l_dma_cyc, l2p_dma_cyc, l2p_dma_we, p2l_dma_we,
l2p_dma_stb, p2l_dma_stb, l2p_dma_sel, p2l_dma_sel,
l2p_dma_dat_m2s, p2l_dma_dat_m2s, l2p_dma_adr, p2l_dma_adr)
begin
if (l2p_dma_cyc = '1') then
dma_adr_o <= l2p_dma_adr;
dma_dat_o <= l2p_dma_dat_m2s;
dma_sel_o <= l2p_dma_sel;
dma_cyc_o <= l2p_dma_cyc;
dma_stb_o <= l2p_dma_stb;
dma_we_o <= l2p_dma_we;
elsif (p2l_dma_cyc = '1') then
dma_adr_o <= p2l_dma_adr;
dma_dat_o <= p2l_dma_dat_m2s;
dma_sel_o <= p2l_dma_sel;
dma_cyc_o <= p2l_dma_cyc;
dma_stb_o <= p2l_dma_stb;
dma_we_o <= p2l_dma_we;
else
dma_adr_o <= (others => 'X');
dma_dat_o <= (others => 'X');
dma_sel_o <= (others => 'X');
dma_cyc_o <= '0';
dma_stb_o <= '0';
dma_we_o <= 'X';
end if;
end process p_dma_wb_mux;
l2p_dma_dat_s2m <= dma_dat_i;
p2l_dma_dat_s2m <= dma_dat_i;
l2p_dma_ack <= dma_ack_i;
p2l_dma_ack <= dma_ack_i;
l2p_dma_stall <= dma_stall_i;
p2l_dma_stall <= dma_stall_i;
--===========================================================================
-- L2P DataPath
--===========================================================================
-----------------------------------------------------------------------------
-- Resync GN412x L2P status signals
-----------------------------------------------------------------------------
p_l2p_status_sync : process (clk_p, rst_n)
begin
if(rst_n = c_RST_ACTIVE) then
l_wr_rdy_t <= "00";
l_wr_rdy <= "00";
p_rd_d_rdy_t <= "00";
p_rd_d_rdy <= "00";
l2p_rdy_t <= '0';
l2p_rdy <= '0';
elsif rising_edge(clk_p) then
-- must be checked before l2p_dma_master issues a master write
l_wr_rdy_t <= l_wr_rdy_i;
l_wr_rdy <= l_wr_rdy_t;
-- must be checked before wbmaster32 sends read completion with data
p_rd_d_rdy_t <= p_rd_d_rdy_i;
p_rd_d_rdy <= p_rd_d_rdy_t;
-- when de-asserted, l2p_dma_master must stop sending data (de-assert l2p_valid) within 3 (or 7 ?) clock cycles
l2p_rdy_t <= l2p_rdy_i;
l2p_rdy <= l2p_rdy_t;
end if;
end process p_l2p_status_sync;
-----------------------------------------------------------------------------
-- L2P arbiter, arbitrates access to GN4124
-----------------------------------------------------------------------------
cmp_l2p_arbiter : l2p_arbiter
port map
(
---------------------------------------------------------
-- Clock/Reset
clk_i => clk_p,
rst_n_i => rst_n,
---------------------------------------------------------
-- From Wishbone master (wbm) to arbiter (arb)
wbm_arb_valid_i => wbm_arb_valid,
wbm_arb_dframe_i => wbm_arb_dframe,
wbm_arb_data_i => wbm_arb_data,
wbm_arb_req_i => wbm_arb_req,
arb_wbm_gnt_o => arb_wbm_gnt,
---------------------------------------------------------
-- From DMA controller (pdm) to arbiter (arb)
pdm_arb_valid_i => pdm_arb_valid,
pdm_arb_dframe_i => pdm_arb_dframe,
pdm_arb_data_i => pdm_arb_data,
pdm_arb_req_i => pdm_arb_req,
arb_pdm_gnt_o => arb_pdm_gnt,
---------------------------------------------------------
-- From P2L DMA master (pdm) to arbiter (arb)
ldm_arb_valid_i => ldm_arb_valid,
ldm_arb_dframe_i => ldm_arb_dframe,
ldm_arb_data_i => ldm_arb_data,
ldm_arb_req_i => ldm_arb_req,
arb_ldm_gnt_o => arb_ldm_gnt,
---------------------------------------------------------
-- From arbiter (arb) to serializer (ser)
arb_ser_valid_o => arb_ser_valid,
arb_ser_dframe_o => arb_ser_dframe,
arb_ser_data_o => arb_ser_data
);
-----------------------------------------------------------------------------
-- L2P_SER: Generate the L2P DDR Outputs
-----------------------------------------------------------------------------
cmp_l2p_ser : l2p_ser
generic map (
g_IS_SPARTAN6 => g_IS_SPARTAN6
)
port map
(
---------------------------------------------------------
-- clk_p Clock Domain Inputs
clk_p_i => clk_p,
clk_n_i => clk_n,
rst_n_i => rst_n,
---------------------------------------------------------
-- DeSerialized Output
l2p_valid_i => arb_ser_valid,
l2p_dframe_i => arb_ser_dframe,
l2p_data_i => arb_ser_data,
---------------------------------------------------------
-- SER Outputs
--
-- P2L Inputs
l2p_clk_p_o => l2p_clk_p_o,
l2p_clk_n_o => l2p_clk_n_o,
l2p_valid_o => l2p_valid_o,
l2p_dframe_o => l2p_dframe_o,
l2p_data_o => l2p_data_o
);
end rtl;
--==============================================================================
-- Architecture end (gn4124_core)
--==============================================================================
--==============================================================================
--! @file gn4124_core_pkg.vhd
--==============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Package for gn4124 core
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--! @brief
--! Package for components declaration and core wide constants
--------------------------------------------------------------------------------
--! @version
--! 0.1 | mc | 01.09.2010 | File creation and Doxygen comments
--!
--! @author
--! mc : Matthieu Cattin, CERN (BE-CO-HT)
--------------------------------------------------------------------------------
--==============================================================================
--! Package declaration
--==============================================================================
package gn4124_core_pkg is
--==============================================================================
--! Constants declaration
--==============================================================================
constant c_RST_ACTIVE : std_logic := '0'; -- Active low reset
--==============================================================================
--! Functions declaration
--==============================================================================
function f_byte_swap (
constant enable : boolean;
signal din : std_logic_vector(31 downto 0);
signal byte_swap : std_logic_vector(1 downto 0))
return std_logic_vector;
function log2_ceil(N : natural) return positive;
--==============================================================================
--! Components declaration
--==============================================================================
-----------------------------------------------------------------------------
component p2l_des
generic (
g_IS_SPARTAN6 : boolean := false
);
port
(
---------------------------------------------------------
-- Reset and clock
rst_n_i : in std_logic;
clk_p_i : in std_logic;
clk_n_i : in std_logic;
---------------------------------------------------------
-- P2L Clock Domain
--
-- P2L Inputs
p2l_valid_i : in std_logic;
p2l_dframe_i : in std_logic;
p2l_data_i : in std_logic_vector(15 downto 0);
---------------------------------------------------------
-- Core Clock Domain
--
-- DeSerialized Output
p2l_valid_o : out std_logic;
p2l_dframe_o : out std_logic;
p2l_data_o : out std_logic_vector(31 downto 0)
);
end component; -- p2l_des
-----------------------------------------------------------------------------
component p2l_decode32
port
(
---------------------------------------------------------
-- Clock/Reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Input from the Deserializer
des_p2l_valid_i : in std_logic;
des_p2l_dframe_i : in std_logic;
des_p2l_data_i : in std_logic_vector(31 downto 0);
---------------------------------------------------------
-- Decoder Outputs
--
-- Header
p2l_hdr_start_o : out std_logic; -- Indicates Header start cycle
p2l_hdr_length_o : out std_logic_vector(9 downto 0); -- Latched LENGTH value from header
p2l_hdr_cid_o : out std_logic_vector(1 downto 0); -- Completion ID
p2l_hdr_last_o : out std_logic; -- Indicates Last packet in a completion
p2l_hdr_stat_o : out std_logic_vector(1 downto 0); -- Completion Status
p2l_target_mrd_o : out std_logic; -- Target memory read
p2l_target_mwr_o : out std_logic; -- Target memory write
p2l_master_cpld_o : out std_logic; -- Master completion with data
p2l_master_cpln_o : out std_logic; -- Master completion without data
--
-- Address
p2l_addr_start_o : out std_logic; -- Indicates Address Start
p2l_addr_o : out std_logic_vector(31 downto 0); -- Latched Address that will increment with data
--
-- Data
p2l_d_valid_o : out std_logic; -- Indicates Data is valid
p2l_d_last_o : out std_logic; -- Indicates end of the packet
p2l_d_o : out std_logic_vector(31 downto 0); -- Data
p2l_be_o : out std_logic_vector(3 downto 0) -- Byte Enable for data
);
end component; -- p2l_decode32
-----------------------------------------------------------------------------
component l2p_ser
generic (
g_IS_SPARTAN6 : boolean := false
);
port
(
---------------------------------------------------------
-- ICLK Clock Domain Inputs
clk_p_i : in std_logic;
clk_n_i : in std_logic;
rst_n_i : in std_logic;
l2p_valid_i : in std_logic;
l2p_dframe_i : in std_logic;
l2p_data_i : in std_logic_vector(31 downto 0);
---------------------------------------------------------
-- SER Outputs
l2p_clk_p_o : out std_logic;
l2p_clk_n_o : out std_logic;
l2p_valid_o : out std_logic;
l2p_dframe_o : out std_logic;
l2p_data_o : out std_logic_vector(15 downto 0)
);
end component; -- l2p_ser
-----------------------------------------------------------------------------
component wbmaster32
generic
(
g_BAR0_APERTURE : integer := 20; -- BAR0 aperture, defined in GN4124 PCI_BAR_CONFIG register (0x80C)
-- => number of bits to address periph on the board
g_WB_SLAVES_NB : integer := 2
);
port
(
---------------------------------------------------------
-- Clock/Reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From P2L Decoder
--
-- Header
pd_wbm_hdr_start_i : in std_logic; -- Indicates Header start cycle
pd_wbm_hdr_length_i : in std_logic_vector(9 downto 0); -- Latched LENGTH value from header
pd_wbm_hdr_cid_i : in std_logic_vector(1 downto 0); -- Completion ID
pd_wbm_target_mrd_i : in std_logic; -- Target memory read
pd_wbm_target_mwr_i : in std_logic; -- Target memory write
--
-- Address
pd_wbm_addr_start_i : in std_logic; -- Indicates Address Start
pd_wbm_addr_i : in std_logic_vector(31 downto 0); -- Latched Address that will increment with data
--
-- Data
pd_wbm_data_valid_i : in std_logic; -- Indicates Data is valid
pd_wbm_data_last_i : in std_logic; -- Indicates end of the packet
pd_wbm_data_i : in std_logic_vector(31 downto 0); -- Data
pd_wbm_be_i : in std_logic_vector(3 downto 0); -- Byte Enable for data
---------------------------------------------------------
-- P2L Control
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- Ready to accept target write
p2l_rdy_o : out std_logic; -- De-asserted to pause transfer already in progress
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- Asserted when GN4124 ready to accept read completion with data
---------------------------------------------------------
-- To the L2P Interface
wbm_arb_valid_o : out std_logic; -- Read completion signals
wbm_arb_dframe_o : out std_logic; -- Toward the arbiter
wbm_arb_data_o : out std_logic_vector(31 downto 0);
wbm_arb_req_o : out std_logic;
arb_wbm_gnt_i : in std_logic;
---------------------------------------------------------
-- CSR wishbone interface
wb_clk_i : in std_logic; -- Wishbone bus clock
wb_adr_o : out std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0); -- Address
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic; -- Strobe
wb_we_o : out std_logic; -- Write
wb_cyc_o : out std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Cycle
wb_dat_i : in std_logic_vector((32*g_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0) -- Acknowledge
);
end component; -- wbmaster32
-----------------------------------------------------------------------------
component dma_controller
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Interrupt request
dma_ctrl_irq_o : out std_logic_vector(1 downto 0);
---------------------------------------------------------
-- To the L2P DMA master and P2L DMA master
dma_ctrl_carrier_addr_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_o : out std_logic_vector(31 downto 0);
dma_ctrl_len_o : out std_logic_vector(31 downto 0);
dma_ctrl_start_l2p_o : out std_logic; -- To the L2P DMA master
dma_ctrl_start_p2l_o : out std_logic; -- To the P2L DMA master
dma_ctrl_start_next_o : out std_logic; -- To the P2L DMA master
dma_ctrl_done_i : in std_logic;
dma_ctrl_error_i : in std_logic;
dma_ctrl_byte_swap_o : out std_logic_vector(1 downto 0);
dma_ctrl_abort_o : out std_logic;
---------------------------------------------------------
-- From P2L DMA MASTER
next_item_carrier_addr_i : in std_logic_vector(31 downto 0);
next_item_host_addr_h_i : in std_logic_vector(31 downto 0);
next_item_host_addr_l_i : in std_logic_vector(31 downto 0);
next_item_len_i : in std_logic_vector(31 downto 0);
next_item_next_l_i : in std_logic_vector(31 downto 0);
next_item_next_h_i : in std_logic_vector(31 downto 0);
next_item_attrib_i : in std_logic_vector(31 downto 0);
next_item_valid_i : in std_logic;
---------------------------------------------------------
-- Wishbone Slave Interface
wb_clk_i : in std_logic; -- Bus clock
wb_adr_i : in std_logic_vector(3 downto 0); -- Adress
wb_dat_o : out std_logic_vector(31 downto 0); -- Data in
wb_dat_i : in std_logic_vector(31 downto 0); -- Data out
wb_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wb_cyc_i : in std_logic; -- Read or write cycle
wb_stb_i : in std_logic; -- Read or write strobe
wb_we_i : in std_logic; -- Write
wb_ack_o : out std_logic -- Acknowledge
);
end component; -- dma_controller
-----------------------------------------------------------------------------
component l2p_dma_master
generic (
-- Enable byte swap module (if false, no swap)
g_BYTE_SWAP : boolean := false
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From the DMA controller
dma_ctrl_target_addr_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_i : in std_logic_vector(31 downto 0);
dma_ctrl_len_i : in std_logic_vector(31 downto 0);
dma_ctrl_start_l2p_i : in std_logic;
dma_ctrl_done_o : out std_logic;
dma_ctrl_error_o : out std_logic;
dma_ctrl_byte_swap_i : in std_logic_vector(1 downto 0);
dma_ctrl_abort_i : in std_logic;
---------------------------------------------------------
-- To the L2P Interface (send the DMA data)
ldm_arb_valid_o : out std_logic; -- Read completion signals
ldm_arb_dframe_o : out std_logic; -- Toward the arbiter
ldm_arb_data_o : out std_logic_vector(31 downto 0);
ldm_arb_req_o : out std_logic;
arb_ldm_gnt_i : in std_logic;
---------------------------------------------------------
-- L2P channel control
l2p_edb_o : out std_logic; -- Asserted when transfer is aborted
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Asserted when GN4124 is ready to receive master write
l2p_rdy_i : in std_logic; -- De-asserted to pause transfer already in progress
---------------------------------------------------------
-- DMA Interface (Pipelined Wishbone)
l2p_dma_clk_i : in std_logic; -- Bus clock
l2p_dma_adr_o : out std_logic_vector(31 downto 0); -- Adress
l2p_dma_dat_i : in std_logic_vector(31 downto 0); -- Data in
l2p_dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
l2p_dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
l2p_dma_cyc_o : out std_logic; -- Read or write cycle
l2p_dma_stb_o : out std_logic; -- Read or write strobe
l2p_dma_we_o : out std_logic; -- Write
l2p_dma_ack_i : in std_logic; -- Acknowledge
l2p_dma_stall_i : in std_logic -- for pipelined Wishbone
);
end component; -- l2p_dma_master
-----------------------------------------------------------------------------
component p2l_dma_master
generic (
-- Enable byte swap module (if false, no swap)
g_BYTE_SWAP : boolean := false
);
port
(
---------------------------------------------------------
-- Clock/Reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From the DMA controller
dma_ctrl_carrier_addr_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_i : in std_logic_vector(31 downto 0);
dma_ctrl_len_i : in std_logic_vector(31 downto 0);
dma_ctrl_start_p2l_i : in std_logic;
dma_ctrl_start_next_i : in std_logic;
dma_ctrl_done_o : out std_logic;
dma_ctrl_error_o : out std_logic;
dma_ctrl_byte_swap_i : in std_logic_vector(1 downto 0);
dma_ctrl_abort_i : in std_logic;
---------------------------------------------------------
-- From P2L Decoder (receive the read completion)
--
-- Header
pd_pdm_hdr_start_i : in std_logic; -- Indicates Header start cycle
pd_pdm_hdr_length_i : in std_logic_vector(9 downto 0); -- Latched LENGTH value from header
pd_pdm_hdr_cid_i : in std_logic_vector(1 downto 0); -- Completion ID
pd_pdm_master_cpld_i : in std_logic; -- Master read completion with data
pd_pdm_master_cpln_i : in std_logic; -- Master read completion without data
--
-- Data
pd_pdm_data_valid_i : in std_logic; -- Indicates Data is valid
pd_pdm_data_last_i : in std_logic; -- Indicates end of the packet
pd_pdm_data_i : in std_logic_vector(31 downto 0); -- Data
pd_pdm_be_i : in std_logic_vector(3 downto 0); -- Byte Enable for data
---------------------------------------------------------
-- P2L control
p2l_rdy_o : out std_logic; -- De-asserted to pause transfer already in progress
rx_error_o : out std_logic; -- Asserted when transfer is aborted
---------------------------------------------------------
-- To the L2P Interface (send the DMA Master Read request)
pdm_arb_valid_o : out std_logic; -- Read completion signals
pdm_arb_dframe_o : out std_logic; -- Toward the arbiter
pdm_arb_data_o : out std_logic_vector(31 downto 0);
pdm_arb_req_o : out std_logic;
arb_pdm_gnt_i : in std_logic;
---------------------------------------------------------
-- DMA Interface (Pipelined Wishbone)
p2l_dma_clk_i : in std_logic; -- Bus clock
p2l_dma_adr_o : out std_logic_vector(31 downto 0); -- Adress
p2l_dma_dat_i : in std_logic_vector(31 downto 0); -- Data in
p2l_dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
p2l_dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
p2l_dma_cyc_o : out std_logic; -- Read or write cycle
p2l_dma_stb_o : out std_logic; -- Read or write strobe
p2l_dma_we_o : out std_logic; -- Write
p2l_dma_ack_i : in std_logic; -- Acknowledge
p2l_dma_stall_i : in std_logic; -- for pipelined Wishbone
---------------------------------------------------------
-- From P2L DMA MASTER
next_item_carrier_addr_o : out std_logic_vector(31 downto 0);
next_item_host_addr_h_o : out std_logic_vector(31 downto 0);
next_item_host_addr_l_o : out std_logic_vector(31 downto 0);
next_item_len_o : out std_logic_vector(31 downto 0);
next_item_next_l_o : out std_logic_vector(31 downto 0);
next_item_next_h_o : out std_logic_vector(31 downto 0);
next_item_attrib_o : out std_logic_vector(31 downto 0);
next_item_valid_o : out std_logic
);
end component; -- p2l_dma_master
-----------------------------------------------------------------------------
component l2p_arbiter
port (
---------------------------------------------------------
-- Clock/Reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From Wishbone master (wbm) to arbiter (arb)
wbm_arb_valid_i : in std_logic;
wbm_arb_dframe_i : in std_logic;
wbm_arb_data_i : in std_logic_vector(31 downto 0);
wbm_arb_req_i : in std_logic;
arb_wbm_gnt_o : out std_logic;
---------------------------------------------------------
-- From DMA controller (pdm) to arbiter (arb)
pdm_arb_valid_i : in std_logic;
pdm_arb_dframe_i : in std_logic;
pdm_arb_data_i : in std_logic_vector(31 downto 0);
pdm_arb_req_i : in std_logic;
arb_pdm_gnt_o : out std_logic;
---------------------------------------------------------
-- From P2L DMA master (ldm) to arbiter (arb)
ldm_arb_valid_i : in std_logic;
ldm_arb_dframe_i : in std_logic;
ldm_arb_data_i : in std_logic_vector(31 downto 0);
ldm_arb_req_i : in std_logic;
arb_ldm_gnt_o : out std_logic;
---------------------------------------------------------
-- From arbiter (arb) to serializer (ser)
arb_ser_valid_o : out std_logic;
arb_ser_dframe_o : out std_logic;
arb_ser_data_o : out std_logic_vector(31 downto 0)
);
end component; -- l2p_arbiter
-----------------------------------------------------------------------------
component fifo_32x512
port (
rst : in std_logic;
wr_clk : in std_logic;
rd_clk : in std_logic;
din : in std_logic_vector(31 downto 0);
wr_en : in std_logic;
rd_en : in std_logic;
prog_full_thresh_assert : in std_logic_vector(8 downto 0);
prog_full_thresh_negate : in std_logic_vector(8 downto 0);
dout : out std_logic_vector(31 downto 0);
full : out std_logic;
empty : out std_logic;
valid : out std_logic;
prog_full : out std_logic);
end component;
-----------------------------------------------------------------------------
component fifo_64x512
port (
rst : in std_logic;
wr_clk : in std_logic;
rd_clk : in std_logic;
din : in std_logic_vector(63 downto 0);
wr_en : in std_logic;
rd_en : in std_logic;
prog_full_thresh_assert : in std_logic_vector(8 downto 0);
prog_full_thresh_negate : in std_logic_vector(8 downto 0);
dout : out std_logic_vector(63 downto 0);
full : out std_logic;
empty : out std_logic;
valid : out std_logic;
prog_full : out std_logic);
end component;
end gn4124_core_pkg;
package body gn4124_core_pkg is
-----------------------------------------------------------------------------
-- Byte swap function
--
-- enable | byte_swap | din | dout
-- false | XX | ABCD | ABCD
-- true | 00 | ABCD | ABCD
-- true | 01 | ABCD | BADC
-- true | 10 | ABCD | CDAB
-- true | 11 | ABCD | DCBA
-----------------------------------------------------------------------------
function f_byte_swap (
constant enable : boolean;
signal din : std_logic_vector(31 downto 0);
signal byte_swap : std_logic_vector(1 downto 0))
return std_logic_vector is
variable dout : std_logic_vector(31 downto 0) := din;
begin
if (enable = true) then
case byte_swap is
when "00" =>
dout := din;
when "01" =>
dout := din(23 downto 16)
& din(31 downto 24)
& din(7 downto 0)
& din(15 downto 8);
when "10" =>
dout := din(15 downto 0)
& din(31 downto 16);
when "11" =>
dout := din(7 downto 0)
& din(15 downto 8)
& din(23 downto 16)
& din(31 downto 24);
when others =>
dout := din;
end case;
else
dout := din;
end if;
return dout;
end function f_byte_swap;
-----------------------------------------------------------------------------
-- Returns log of 2 of a natural number
-----------------------------------------------------------------------------
function log2_ceil(N : natural) return positive is
begin
if N < 2 then
return 1;
else
return 1 + log2_ceil(N/2);
end if;
end;
end gn4124_core_pkg;
--==============================================================================
--! @file gn4124_core_pkg_s6.vhd
--==============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Package for gn4124 core
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--! @brief
--! Package for components declaration and core wide constants.
--! Spartan6 FPGAs version.
--------------------------------------------------------------------------------
--! @version
--! 0.1 | mc | 01.09.2010 | File creation and Doxygen comments
--!
--! @author
--! mc : Matthieu Cattin, CERN (BE-CO-HT)
--------------------------------------------------------------------------------
--==============================================================================
--! Package declaration
--==============================================================================
package gn4124_core_pkg is
--==============================================================================
--! Constants declaration
--==============================================================================
constant c_RST_ACTIVE : std_logic := '0'; -- Active low reset
--==============================================================================
--! Functions declaration
--==============================================================================
function f_byte_swap (
constant enable : boolean;
signal din : std_logic_vector(31 downto 0);
signal byte_swap : std_logic_vector(1 downto 0))
return std_logic_vector;
function log2_ceil(N : natural) return positive;
--==============================================================================
--! Components declaration
--==============================================================================
-----------------------------------------------------------------------------
component p2l_des
port
(
---------------------------------------------------------
-- Reset and clock
rst_n_i : in std_logic;
sys_clk_i : in std_logic;
io_clk_i : in std_logic;
serdes_strobe_i : in std_logic;
---------------------------------------------------------
-- P2L DDR inputs
p2l_valid_i : in std_logic;
p2l_dframe_i : in std_logic;
p2l_data_i : in std_logic_vector(15 downto 0);
---------------------------------------------------------
-- P2L SDR outputs
p2l_valid_o : out std_logic;
p2l_dframe_o : out std_logic;
p2l_data_o : out std_logic_vector(31 downto 0)
);
end component; -- p2l_des
-----------------------------------------------------------------------------
component p2l_decode32
port
(
---------------------------------------------------------
-- Clock/Reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Input from the Deserializer
des_p2l_valid_i : in std_logic;
des_p2l_dframe_i : in std_logic;
des_p2l_data_i : in std_logic_vector(31 downto 0);
---------------------------------------------------------
-- Decoder Outputs
--
-- Header
p2l_hdr_start_o : out std_logic; -- Indicates Header start cycle
p2l_hdr_length_o : out std_logic_vector(9 downto 0); -- Latched LENGTH value from header
p2l_hdr_cid_o : out std_logic_vector(1 downto 0); -- Completion ID
p2l_hdr_last_o : out std_logic; -- Indicates Last packet in a completion
p2l_hdr_stat_o : out std_logic_vector(1 downto 0); -- Completion Status
p2l_target_mrd_o : out std_logic; -- Target memory read
p2l_target_mwr_o : out std_logic; -- Target memory write
p2l_master_cpld_o : out std_logic; -- Master completion with data
p2l_master_cpln_o : out std_logic; -- Master completion without data
--
-- Address
p2l_addr_start_o : out std_logic; -- Indicates Address Start
p2l_addr_o : out std_logic_vector(31 downto 0); -- Latched Address that will increment with data
--
-- Data
p2l_d_valid_o : out std_logic; -- Indicates Data is valid
p2l_d_last_o : out std_logic; -- Indicates end of the packet
p2l_d_o : out std_logic_vector(31 downto 0); -- Data
p2l_be_o : out std_logic_vector(3 downto 0) -- Byte Enable for data
);
end component; -- p2l_decode32
-----------------------------------------------------------------------------
component l2p_ser
port
(
---------------------------------------------------------
-- Reset and clock
rst_n_i : in std_logic;
sys_clk_i : in std_logic;
io_clk_i : in std_logic;
serdes_strobe_i : in std_logic;
---------------------------------------------------------
-- L2P SDR inputs
l2p_valid_i : in std_logic;
l2p_dframe_i : in std_logic;
l2p_data_i : in std_logic_vector(31 downto 0);
---------------------------------------------------------
-- L2P DDR outputs
l2p_clk_p_o : out std_logic;
l2p_clk_n_o : out std_logic;
l2p_valid_o : out std_logic;
l2p_dframe_o : out std_logic;
l2p_data_o : out std_logic_vector(15 downto 0)
);
end component; -- l2p_ser
-----------------------------------------------------------------------------
component wbmaster32
generic
(
g_BAR0_APERTURE : integer := 20; -- BAR0 aperture, defined in GN4124 PCI_BAR_CONFIG register (0x80C)
-- => number of bits to address periph on the board
g_WB_SLAVES_NB : integer := 2
);
port
(
---------------------------------------------------------
-- Clock/Reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From P2L Decoder
--
-- Header
pd_wbm_hdr_start_i : in std_logic; -- Indicates Header start cycle
pd_wbm_hdr_length_i : in std_logic_vector(9 downto 0); -- Latched LENGTH value from header
pd_wbm_hdr_cid_i : in std_logic_vector(1 downto 0); -- Completion ID
pd_wbm_target_mrd_i : in std_logic; -- Target memory read
pd_wbm_target_mwr_i : in std_logic; -- Target memory write
--
-- Address
pd_wbm_addr_start_i : in std_logic; -- Indicates Address Start
pd_wbm_addr_i : in std_logic_vector(31 downto 0); -- Latched Address that will increment with data
--
-- Data
pd_wbm_data_valid_i : in std_logic; -- Indicates Data is valid
pd_wbm_data_last_i : in std_logic; -- Indicates end of the packet
pd_wbm_data_i : in std_logic_vector(31 downto 0); -- Data
pd_wbm_be_i : in std_logic_vector(3 downto 0); -- Byte Enable for data
---------------------------------------------------------
-- P2L Control
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- Ready to accept target write
p2l_rdy_o : out std_logic; -- De-asserted to pause transfer already in progress
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- Asserted when GN4124 ready to accept read completion with data
---------------------------------------------------------
-- To the L2P Interface
wbm_arb_valid_o : out std_logic; -- Read completion signals
wbm_arb_dframe_o : out std_logic; -- Toward the arbiter
wbm_arb_data_o : out std_logic_vector(31 downto 0);
wbm_arb_req_o : out std_logic;
arb_wbm_gnt_i : in std_logic;
---------------------------------------------------------
-- CSR wishbone interface
wb_clk_i : in std_logic; -- Wishbone bus clock
wb_adr_o : out std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0); -- Address
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic; -- Strobe
wb_we_o : out std_logic; -- Write
wb_cyc_o : out std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Cycle
wb_dat_i : in std_logic_vector((32*g_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0) -- Acknowledge
);
end component; -- wbmaster32
-----------------------------------------------------------------------------
component dma_controller
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Interrupt request
dma_ctrl_irq_o : out std_logic_vector(1 downto 0);
---------------------------------------------------------
-- To the L2P DMA master and P2L DMA master
dma_ctrl_carrier_addr_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_o : out std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_o : out std_logic_vector(31 downto 0);
dma_ctrl_len_o : out std_logic_vector(31 downto 0);
dma_ctrl_start_l2p_o : out std_logic; -- To the L2P DMA master
dma_ctrl_start_p2l_o : out std_logic; -- To the P2L DMA master
dma_ctrl_start_next_o : out std_logic; -- To the P2L DMA master
dma_ctrl_done_i : in std_logic;
dma_ctrl_error_i : in std_logic;
dma_ctrl_byte_swap_o : out std_logic_vector(1 downto 0);
dma_ctrl_abort_o : out std_logic;
---------------------------------------------------------
-- From P2L DMA MASTER
next_item_carrier_addr_i : in std_logic_vector(31 downto 0);
next_item_host_addr_h_i : in std_logic_vector(31 downto 0);
next_item_host_addr_l_i : in std_logic_vector(31 downto 0);
next_item_len_i : in std_logic_vector(31 downto 0);
next_item_next_l_i : in std_logic_vector(31 downto 0);
next_item_next_h_i : in std_logic_vector(31 downto 0);
next_item_attrib_i : in std_logic_vector(31 downto 0);
next_item_valid_i : in std_logic;
---------------------------------------------------------
-- Wishbone Slave Interface
wb_clk_i : in std_logic; -- Bus clock
wb_adr_i : in std_logic_vector(3 downto 0); -- Adress
wb_dat_o : out std_logic_vector(31 downto 0); -- Data in
wb_dat_i : in std_logic_vector(31 downto 0); -- Data out
wb_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wb_cyc_i : in std_logic; -- Read or write cycle
wb_stb_i : in std_logic; -- Read or write strobe
wb_we_i : in std_logic; -- Write
wb_ack_o : out std_logic -- Acknowledge
);
end component; -- dma_controller
-----------------------------------------------------------------------------
component l2p_dma_master
generic (
-- Enable byte swap module (if false, no swap)
g_BYTE_SWAP : boolean := false
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From the DMA controller
dma_ctrl_target_addr_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_i : in std_logic_vector(31 downto 0);
dma_ctrl_len_i : in std_logic_vector(31 downto 0);
dma_ctrl_start_l2p_i : in std_logic;
dma_ctrl_done_o : out std_logic;
dma_ctrl_error_o : out std_logic;
dma_ctrl_byte_swap_i : in std_logic_vector(1 downto 0);
dma_ctrl_abort_i : in std_logic;
---------------------------------------------------------
-- To the L2P Interface (send the DMA data)
ldm_arb_valid_o : out std_logic; -- Read completion signals
ldm_arb_dframe_o : out std_logic; -- Toward the arbiter
ldm_arb_data_o : out std_logic_vector(31 downto 0);
ldm_arb_req_o : out std_logic;
arb_ldm_gnt_i : in std_logic;
---------------------------------------------------------
-- L2P channel control
l2p_edb_o : out std_logic; -- Asserted when transfer is aborted
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Asserted when GN4124 is ready to receive master write
l2p_rdy_i : in std_logic; -- De-asserted to pause transfer already in progress
---------------------------------------------------------
-- DMA Interface (Pipelined Wishbone)
l2p_dma_clk_i : in std_logic; -- Bus clock
l2p_dma_adr_o : out std_logic_vector(31 downto 0); -- Adress
l2p_dma_dat_i : in std_logic_vector(31 downto 0); -- Data in
l2p_dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
l2p_dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
l2p_dma_cyc_o : out std_logic; -- Read or write cycle
l2p_dma_stb_o : out std_logic; -- Read or write strobe
l2p_dma_we_o : out std_logic; -- Write
l2p_dma_ack_i : in std_logic; -- Acknowledge
l2p_dma_stall_i : in std_logic; -- for pipelined Wishbone
p2l_dma_cyc_i : in std_logic -- P2L dma wb cycle (for bus arbitration)
);
end component; -- l2p_dma_master
-----------------------------------------------------------------------------
component p2l_dma_master
generic (
-- Enable byte swap module (if false, no swap)
g_BYTE_SWAP : boolean := false
);
port
(
---------------------------------------------------------
-- Clock/Reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From the DMA controller
dma_ctrl_carrier_addr_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_i : in std_logic_vector(31 downto 0);
dma_ctrl_len_i : in std_logic_vector(31 downto 0);
dma_ctrl_start_p2l_i : in std_logic;
dma_ctrl_start_next_i : in std_logic;
dma_ctrl_done_o : out std_logic;
dma_ctrl_error_o : out std_logic;
dma_ctrl_byte_swap_i : in std_logic_vector(1 downto 0);
dma_ctrl_abort_i : in std_logic;
---------------------------------------------------------
-- From P2L Decoder (receive the read completion)
--
-- Header
pd_pdm_hdr_start_i : in std_logic; -- Indicates Header start cycle
pd_pdm_hdr_length_i : in std_logic_vector(9 downto 0); -- Latched LENGTH value from header
pd_pdm_hdr_cid_i : in std_logic_vector(1 downto 0); -- Completion ID
pd_pdm_master_cpld_i : in std_logic; -- Master read completion with data
pd_pdm_master_cpln_i : in std_logic; -- Master read completion without data
--
-- Data
pd_pdm_data_valid_i : in std_logic; -- Indicates Data is valid
pd_pdm_data_last_i : in std_logic; -- Indicates end of the packet
pd_pdm_data_i : in std_logic_vector(31 downto 0); -- Data
pd_pdm_be_i : in std_logic_vector(3 downto 0); -- Byte Enable for data
---------------------------------------------------------
-- P2L control
p2l_rdy_o : out std_logic; -- De-asserted to pause transfer already in progress
rx_error_o : out std_logic; -- Asserted when transfer is aborted
---------------------------------------------------------
-- To the L2P Interface (send the DMA Master Read request)
pdm_arb_valid_o : out std_logic; -- Read completion signals
pdm_arb_dframe_o : out std_logic; -- Toward the arbiter
pdm_arb_data_o : out std_logic_vector(31 downto 0);
pdm_arb_req_o : out std_logic;
arb_pdm_gnt_i : in std_logic;
---------------------------------------------------------
-- DMA Interface (Pipelined Wishbone)
p2l_dma_clk_i : in std_logic; -- Bus clock
p2l_dma_adr_o : out std_logic_vector(31 downto 0); -- Adress
p2l_dma_dat_i : in std_logic_vector(31 downto 0); -- Data in
p2l_dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
p2l_dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
p2l_dma_cyc_o : out std_logic; -- Read or write cycle
p2l_dma_stb_o : out std_logic; -- Read or write strobe
p2l_dma_we_o : out std_logic; -- Write
p2l_dma_ack_i : in std_logic; -- Acknowledge
p2l_dma_stall_i : in std_logic; -- for pipelined Wishbone
l2p_dma_cyc_i : in std_logic; -- L2P dma wb cycle (for bus arbitration)
---------------------------------------------------------
-- From P2L DMA MASTER
next_item_carrier_addr_o : out std_logic_vector(31 downto 0);
next_item_host_addr_h_o : out std_logic_vector(31 downto 0);
next_item_host_addr_l_o : out std_logic_vector(31 downto 0);
next_item_len_o : out std_logic_vector(31 downto 0);
next_item_next_l_o : out std_logic_vector(31 downto 0);
next_item_next_h_o : out std_logic_vector(31 downto 0);
next_item_attrib_o : out std_logic_vector(31 downto 0);
next_item_valid_o : out std_logic
);
end component; -- p2l_dma_master
-----------------------------------------------------------------------------
component l2p_arbiter
port (
---------------------------------------------------------
-- Clock/Reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From Wishbone master (wbm) to arbiter (arb)
wbm_arb_valid_i : in std_logic;
wbm_arb_dframe_i : in std_logic;
wbm_arb_data_i : in std_logic_vector(31 downto 0);
wbm_arb_req_i : in std_logic;
arb_wbm_gnt_o : out std_logic;
---------------------------------------------------------
-- From DMA controller (pdm) to arbiter (arb)
pdm_arb_valid_i : in std_logic;
pdm_arb_dframe_i : in std_logic;
pdm_arb_data_i : in std_logic_vector(31 downto 0);
pdm_arb_req_i : in std_logic;
arb_pdm_gnt_o : out std_logic;
---------------------------------------------------------
-- From P2L DMA master (ldm) to arbiter (arb)
ldm_arb_valid_i : in std_logic;
ldm_arb_dframe_i : in std_logic;
ldm_arb_data_i : in std_logic_vector(31 downto 0);
ldm_arb_req_i : in std_logic;
arb_ldm_gnt_o : out std_logic;
---------------------------------------------------------
-- From arbiter (arb) to serializer (ser)
arb_ser_valid_o : out std_logic;
arb_ser_dframe_o : out std_logic;
arb_ser_data_o : out std_logic_vector(31 downto 0)
);
end component; -- l2p_arbiter
-----------------------------------------------------------------------------
component fifo_32x512
port (
rst : in std_logic;
wr_clk : in std_logic;
rd_clk : in std_logic;
din : in std_logic_vector(31 downto 0);
wr_en : in std_logic;
rd_en : in std_logic;
prog_full_thresh_assert : in std_logic_vector(8 downto 0);
prog_full_thresh_negate : in std_logic_vector(8 downto 0);
dout : out std_logic_vector(31 downto 0);
full : out std_logic;
empty : out std_logic;
valid : out std_logic;
prog_full : out std_logic);
end component;
-----------------------------------------------------------------------------
component fifo_64x512
port (
rst : in std_logic;
wr_clk : in std_logic;
rd_clk : in std_logic;
din : in std_logic_vector(63 downto 0);
wr_en : in std_logic;
rd_en : in std_logic;
prog_full_thresh_assert : in std_logic_vector(8 downto 0);
prog_full_thresh_negate : in std_logic_vector(8 downto 0);
dout : out std_logic_vector(63 downto 0);
full : out std_logic;
empty : out std_logic;
valid : out std_logic;
prog_full : out std_logic);
end component;
end gn4124_core_pkg;
package body gn4124_core_pkg is
-----------------------------------------------------------------------------
-- Byte swap function
--
-- enable | byte_swap | din | dout
-- false | XX | ABCD | ABCD
-- true | 00 | ABCD | ABCD
-- true | 01 | ABCD | BADC
-- true | 10 | ABCD | CDAB
-- true | 11 | ABCD | DCBA
-----------------------------------------------------------------------------
function f_byte_swap (
constant enable : boolean;
signal din : std_logic_vector(31 downto 0);
signal byte_swap : std_logic_vector(1 downto 0))
return std_logic_vector is
variable dout : std_logic_vector(31 downto 0) := din;
begin
if (enable = true) then
case byte_swap is
when "00" =>
dout := din;
when "01" =>
dout := din(23 downto 16)
& din(31 downto 24)
& din(7 downto 0)
& din(15 downto 8);
when "10" =>
dout := din(15 downto 0)
& din(31 downto 16);
when "11" =>
dout := din(7 downto 0)
& din(15 downto 8)
& din(23 downto 16)
& din(31 downto 24);
when others =>
dout := din;
end case;
else
dout := din;
end if;
return dout;
end function f_byte_swap;
-----------------------------------------------------------------------------
-- Returns log of 2 of a natural number
-----------------------------------------------------------------------------
function log2_ceil(N : natural) return positive is
begin
if N <= 2 then
return 1;
elsif N mod 2 = 0 then
return 1 + log2_ceil(N/2);
else
return 1 + log2_ceil((N+1)/2);
end if;
end;
end gn4124_core_pkg;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: Gn4124 core main block (gn4124_core_s6.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 0.3
--
-- description: GN4124 core top level.
-- Version for spartan6 FPGAs.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: see svn log
--------------------------------------------------------------------------------
-- TODO: - DMA wishbone bus address map
-- - reset and clock signals
-- - wishbone timeout generic ??
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
--==============================================================================
-- Entity declaration for GN4124 core (gn4124_core)
--==============================================================================
entity gn4124_core is
generic(
g_BAR0_APERTURE : integer := 20; -- BAR0 aperture, defined in GN4124 PCI_BAR_CONFIG register (0x80C)
-- => number of bits to address periph on the board
g_CSR_WB_SLAVES_NB : integer := 1; -- Number of CSR wishbone slaves
g_DMA_WB_SLAVES_NB : integer := 1; -- Number of DMA wishbone slaves
g_DMA_WB_ADDR_WIDTH : integer := 26 -- DMA wishbone address bus width
);
port
(
---------------------------------------------------------
-- Control and status
--
-- Asynchronous reset from GN4124
rst_n_a_i : in std_logic;
-- P2L clock PLL locked
p2l_pll_locked : out std_logic;
-- Debug ouputs
debug_o : out std_logic_vector(7 downto 0);
---------------------------------------------------------
-- P2L Direction
--
-- Source Sync DDR related signals
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i : in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
-- P2L Control
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
---------------------------------------------------------
-- L2P Direction
--
-- Source Sync DDR related signals
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o : out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
-- L2P Control
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
---------------------------------------------------------
-- Interrupt interface
dma_irq_o : out std_logic_vector(1 downto 0); -- Interrupts sources to IRQ manager
irq_p_i : in std_logic; -- Interrupt request pulse from IRQ manager
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
---------------------------------------------------------
-- Target interface (CSR wishbone master)
wb_clk_i : in std_logic;
wb_adr_o : out std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_CSR_WB_SLAVES_NB+1)-1 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic;
wb_we_o : out std_logic;
wb_cyc_o : out std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
wb_dat_i : in std_logic_vector((32*g_CSR_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
---------------------------------------------------------
-- DMA interface (Pipelined wishbone master)
dma_clk_i : in std_logic;
dma_adr_o : out std_logic_vector(31 downto 0);
dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
dma_stb_o : out std_logic;
dma_we_o : out std_logic;
dma_cyc_o : out std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_dat_i : in std_logic_vector((32*g_DMA_WB_SLAVES_NB)-1 downto 0); -- Data in
dma_ack_i : in std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_stall_i : in std_logic--_vector(g_DMA_WB_SLAVES_NB-1 downto 0) -- for pipelined Wishbone
);
end gn4124_core;
--==============================================================================
-- Architecture declaration for GN4124 core (gn4124_core)
--==============================================================================
architecture rtl of gn4124_core is
-----------------------------------------------------------------------------
-- Components declaration
-----------------------------------------------------------------------------
component serdes_1_to_n_clk_pll_s2_diff
generic (
PLLD : integer := 1; -- Parameter to set division for PLL
PLLX : integer := 2; -- Parameter to set multiplier for PLL (2 for DDR)
CLKIN_PERIOD : real := 5.000; -- clock period (ns) of input clock on clkin_p
S : integer := 2; -- Parameter to set the serdes factor 1..8
BS : boolean := false; -- Parameter to enable bitslip TRUE or FALSE
DIFF_TERM : boolean := false) ; -- Enable or disable internal differential termination
port (
clkin_p : in std_logic; -- Input from LVDS receiver pin
clkin_n : in std_logic; -- Input from LVDS receiver pin
reset : in std_logic; -- Reset line
pattern1 : in std_logic_vector(S-1 downto 0); -- Pattern that bitslip should search for
pattern2 : in std_logic_vector(S-1 downto 0); -- Alternate pattern that bitslip should search for
rxioclk : out std_logic; -- IO Clock network
rx_serdesstrobe : out std_logic; -- Parallel data capture strobe
rx_bufg_pll_x1 : out std_logic; -- Global clock
rx_pll_lckd : out std_logic; -- PLL locked - only used if a 2nd BUFPLL is required
rx_pllout_xs : out std_logic; -- Multiplied PLL clock - only used if a 2nd BUFPLL is required
bitslip : out std_logic; -- Bitslip control line
datain : out std_logic_vector(S-1 downto 0); -- Output data
rx_bufpll_lckd : out std_logic); -- BUFPLL locked
end component serdes_1_to_n_clk_pll_s2_diff;
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
-- Clock
signal sys_clk : std_logic;
signal io_clk : std_logic;
signal serdes_strobe : std_logic;
signal pll_locked : std_logic;
-- Reset for all clk_p logic
signal rst_reg : std_logic;
signal rst_n : std_logic;
signal rst : std_logic;
-------------------------------------------------------------
-- P2L DataPath (from deserializer to packet decoder)
-------------------------------------------------------------
signal des_pd_valid : std_logic;
signal des_pd_dframe : std_logic;
signal des_pd_data : std_logic_vector(31 downto 0);
-- Local bus control
signal p_wr_rdy : std_logic;
signal p2l_rdy_wbm : std_logic;
signal p2l_rdy_pdm : std_logic;
-------------------------------------------------------------
-- P2L DataPath (from packet decoder to Wishbone master and P2L DMA master)
-------------------------------------------------------------
signal p2l_hdr_start : std_logic;
signal p2l_hdr_length : std_logic_vector(9 downto 0);
signal p2l_hdr_cid : std_logic_vector(1 downto 0);
signal p2l_hdr_last : std_logic;
signal p2l_hdr_stat : std_logic_vector(1 downto 0);
signal p2l_target_mrd : std_logic;
signal p2l_target_mwr : std_logic;
signal p2l_master_cpld : std_logic;
signal p2l_master_cpln : std_logic;
signal p2l_d_valid : std_logic;
signal p2l_d_last : std_logic;
signal p2l_d : std_logic_vector(31 downto 0);
signal p2l_be : std_logic_vector(3 downto 0);
signal p2l_addr : std_logic_vector(31 downto 0);
signal p2l_addr_start : std_logic;
-------------------------------------------------------------
-- L2P DataPath (from arbiter to serializer)
-------------------------------------------------------------
signal arb_ser_valid : std_logic;
signal arb_ser_dframe : std_logic;
signal arb_ser_data : std_logic_vector(31 downto 0);
-- Local bus control
signal l_wr_rdy_t : std_logic_vector(1 downto 0);
signal l_wr_rdy_t2 : std_logic_vector(1 downto 0);
signal l_wr_rdy : std_logic_vector(1 downto 0);
signal p_rd_d_rdy_t : std_logic_vector(1 downto 0);
signal p_rd_d_rdy_t2 : std_logic_vector(1 downto 0);
signal p_rd_d_rdy : std_logic_vector(1 downto 0);
signal l2p_rdy_t : std_logic;
signal l2p_rdy_t2 : std_logic;
signal l2p_rdy : std_logic;
signal l2p_edb : std_logic;
signal l2p_edb_t : std_logic;
signal l2p_edb_t2 : std_logic;
-------------------------------------------------------------
-- CSR wishbone master to arbiter
-------------------------------------------------------------
signal wbm_arb_valid : std_logic;
signal wbm_arb_dframe : std_logic;
signal wbm_arb_data : std_logic_vector(31 downto 0);
signal wbm_arb_req : std_logic;
signal arb_wbm_gnt : std_logic;
-------------------------------------------------------------
-- L2P DMA master to arbiter
-------------------------------------------------------------
signal ldm_arb_req : std_logic;
signal arb_ldm_gnt : std_logic;
signal ldm_arb_valid : std_logic;
signal ldm_arb_dframe : std_logic;
signal ldm_arb_data : std_logic_vector(31 downto 0);
-------------------------------------------------------------
-- P2L DMA master to arbiter
-------------------------------------------------------------
signal pdm_arb_valid : std_logic;
signal pdm_arb_dframe : std_logic;
signal pdm_arb_data : std_logic_vector(31 downto 0);
signal pdm_arb_req : std_logic;
signal arb_pdm_gnt : std_logic;
-------------------------------------------------------------
-- DMA controller
-------------------------------------------------------------
signal dma_ctrl_carrier_addr : std_logic_vector(31 downto 0);
signal dma_ctrl_host_addr_h : std_logic_vector(31 downto 0);
signal dma_ctrl_host_addr_l : std_logic_vector(31 downto 0);
signal dma_ctrl_len : std_logic_vector(31 downto 0);
signal dma_ctrl_start_l2p : std_logic;
signal dma_ctrl_start_p2l : std_logic;
signal dma_ctrl_start_next : std_logic;
signal dma_ctrl_done : std_logic;
signal dma_ctrl_error : std_logic;
signal dma_ctrl_l2p_done : std_logic;
signal dma_ctrl_l2p_error : std_logic;
signal dma_ctrl_p2l_done : std_logic;
signal dma_ctrl_p2l_error : std_logic;
signal dma_ctrl_byte_swap : std_logic_vector(1 downto 0);
signal dma_ctrl_abort : std_logic;
signal next_item_carrier_addr : std_logic_vector(31 downto 0);
signal next_item_host_addr_h : std_logic_vector(31 downto 0);
signal next_item_host_addr_l : std_logic_vector(31 downto 0);
signal next_item_len : std_logic_vector(31 downto 0);
signal next_item_next_l : std_logic_vector(31 downto 0);
signal next_item_next_h : std_logic_vector(31 downto 0);
signal next_item_attrib : std_logic_vector(31 downto 0);
signal next_item_valid : std_logic;
------------------------------------------------------------------------------
-- CSR wishbone bus
------------------------------------------------------------------------------
signal wb_adr : std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_CSR_WB_SLAVES_NB+1)-1 downto 0);
signal wb_dat_s2m : std_logic_vector((32*(g_CSR_WB_SLAVES_NB+1))-1 downto 0);
signal wb_dat_m2s : std_logic_vector(31 downto 0);
signal wb_sel : std_logic_vector(3 downto 0);
signal wb_cyc : std_logic_vector(g_CSR_WB_SLAVES_NB downto 0);
signal wb_stb : std_logic;
signal wb_we : std_logic;
signal wb_ack : std_logic_vector(g_CSR_WB_SLAVES_NB downto 0);
signal wb_ack_dma_ctrl : std_logic;
signal wb_dat_s2m_dma_ctrl : std_logic_vector(31 downto 0);
------------------------------------------------------------------------------
-- DMA wishbone bus
------------------------------------------------------------------------------
signal l2p_dma_adr : std_logic_vector(31 downto 0);
signal l2p_dma_dat_s2m : std_logic_vector(31 downto 0);
signal l2p_dma_dat_m2s : std_logic_vector(31 downto 0);
signal l2p_dma_sel : std_logic_vector(3 downto 0);
signal l2p_dma_cyc : std_logic;
signal l2p_dma_stb : std_logic;
signal l2p_dma_we : std_logic;
signal l2p_dma_ack : std_logic;
signal l2p_dma_stall : std_logic;
signal p2l_dma_adr : std_logic_vector(31 downto 0);
signal p2l_dma_dat_s2m : std_logic_vector(31 downto 0);
signal p2l_dma_dat_m2s : std_logic_vector(31 downto 0);
signal p2l_dma_sel : std_logic_vector(3 downto 0);
signal p2l_dma_cyc : std_logic;
signal p2l_dma_stb : std_logic;
signal p2l_dma_we : std_logic;
signal p2l_dma_ack : std_logic;
signal p2l_dma_stall : std_logic;
--==============================================================================
-- Architecture begin (gn4124_core)
--==============================================================================
begin
------------------------------------------------------------------------------
-- Debug outputs assignment
------------------------------------------------------------------------------
--debug_o(0) <= io_clk;
--debug_o(1) <= serdes_strobe;
debug_o(7 downto 0) <= (others => '0');
------------------------------------------------------------------------------
-- Clock Input. Generate ioclocks and system clock via BUFPLL
------------------------------------------------------------------------------
cmp_clk_in : serdes_1_to_n_clk_pll_s2_diff
generic map(
CLKIN_PERIOD => 5.000,
PLLD => 1,
PLLX => 2,
S => 2,
BS => false)
port map (
clkin_p => p2l_clk_p_i,
clkin_n => p2l_clk_n_i,
rxioclk => io_clk,
pattern1 => "10",
pattern2 => "10",
rx_serdesstrobe => serdes_strobe,
rx_bufg_pll_x1 => sys_clk,
bitslip => open,
reset => rst,
datain => open,
rx_bufpll_lckd => pll_locked) ;
p2l_pll_locked <= pll_locked;
------------------------------------------------------------------------------
-- Reset aligned to core clock
------------------------------------------------------------------------------
p_core_rst : process (sys_clk, rst_n_a_i)
begin
if rst_n_a_i = c_RST_ACTIVE then
rst_reg <= c_RST_ACTIVE;
elsif rising_edge(sys_clk) then
if pll_locked = '1' then
rst_reg <= not(c_RST_ACTIVE);
end if;
end if;
end process p_core_rst;
rst_n <= rst_reg;
-- Always active high reset for PLL
rst <= not(rst_n_a_i);
------------------------------------------------------------------------------
-- IRQ pulse forward to GN4124 GPIO
------------------------------------------------------------------------------
irq_p_o <= irq_p_i;
--============================================================================
-- P2L DataPath
--============================================================================
-----------------------------------------------------------------------------
-- p2l_des: Deserialize the P2L DDR inputs
-----------------------------------------------------------------------------
cmp_p2l_des : p2l_des
port map
(
---------------------------------------------------------
-- Clocks and reset
rst_n_i => rst_n,
sys_clk_i => sys_clk,
io_clk_i => io_clk,
serdes_strobe_i => serdes_strobe,
---------------------------------------------------------
-- P2L DDR inputs
p2l_valid_i => p2l_valid_i,
p2l_dframe_i => p2l_dframe_i,
p2l_data_i => p2l_data_i,
---------------------------------------------------------
-- P2L SDR outputs
p2l_valid_o => des_pd_valid,
p2l_dframe_o => des_pd_dframe,
p2l_data_o => des_pd_data
);
------------------------------------------------------------------------------
-- P2L local bus control signals
------------------------------------------------------------------------------
-- de-asserted to pause transfer from GN4124
p2l_rdy_o <= p2l_rdy_wbm and p2l_rdy_pdm;
-----------------------------------------------------------------------------
-- p2l_decode32: Decode the output of the p2l_des
-----------------------------------------------------------------------------
cmp_p2l_decode32 : p2l_decode32
port map
(
---------------------------------------------------------
-- Clock/Reset
clk_i => sys_clk,
rst_n_i => rst_n,
---------------------------------------------------------
-- Input from the Deserializer
--
des_p2l_valid_i => des_pd_valid,
des_p2l_dframe_i => des_pd_dframe,
des_p2l_data_i => des_pd_data,
---------------------------------------------------------
-- Decoder Outputs
--
-- Header
p2l_hdr_start_o => p2l_hdr_start,
p2l_hdr_length_o => p2l_hdr_length,
p2l_hdr_cid_o => p2l_hdr_cid,
p2l_hdr_last_o => p2l_hdr_last,
p2l_hdr_stat_o => p2l_hdr_stat,
p2l_target_mrd_o => p2l_target_mrd,
p2l_target_mwr_o => p2l_target_mwr,
p2l_master_cpld_o => p2l_master_cpld,
p2l_master_cpln_o => p2l_master_cpln,
--
-- Address
p2l_addr_start_o => p2l_addr_start,
p2l_addr_o => p2l_addr,
--
-- Data
p2l_d_valid_o => p2l_d_valid,
p2l_d_last_o => p2l_d_last,
p2l_d_o => p2l_d,
p2l_be_o => p2l_be
);
--===========================================================================
-- Core Logic Blocks
--===========================================================================
-----------------------------------------------------------------------------
-- Wishbone master
-----------------------------------------------------------------------------
cmp_wbmaster32 : wbmaster32
generic map
(
g_BAR0_APERTURE => g_BAR0_APERTURE,
g_WB_SLAVES_NB => (g_CSR_WB_SLAVES_NB + 1) -- +1 for the DMA controller (wb slave always present)
)
port map
(
---------------------------------------------------------
-- Clock/Reset
clk_i => sys_clk,
rst_n_i => rst_n,
---------------------------------------------------------
-- From P2L Decoder
--
-- Header
pd_wbm_hdr_start_i => p2l_hdr_start,
pd_wbm_hdr_length_i => p2l_hdr_length,
pd_wbm_hdr_cid_i => p2l_hdr_cid,
pd_wbm_target_mrd_i => p2l_target_mrd,
pd_wbm_target_mwr_i => p2l_target_mwr,
--
-- Address
pd_wbm_addr_start_i => p2l_addr_start,
pd_wbm_addr_i => p2l_addr,
--
-- Data
pd_wbm_data_valid_i => p2l_d_valid,
pd_wbm_data_last_i => p2l_d_last,
pd_wbm_data_i => p2l_d,
pd_wbm_be_i => p2l_be,
---------------------------------------------------------
-- P2L Control
p_wr_rdy_o => p_wr_rdy_o,
p2l_rdy_o => p2l_rdy_wbm,
p_rd_d_rdy_i => p_rd_d_rdy,
---------------------------------------------------------
-- To the L2P Interface
wbm_arb_valid_o => wbm_arb_valid,
wbm_arb_dframe_o => wbm_arb_dframe,
wbm_arb_data_o => wbm_arb_data,
wbm_arb_req_o => wbm_arb_req,
arb_wbm_gnt_i => arb_wbm_gnt,
---------------------------------------------------------
-- Wishbone Interface
wb_clk_i => wb_clk_i,
wb_adr_o => wb_adr,
wb_dat_i => wb_dat_s2m,
wb_dat_o => wb_dat_m2s,
wb_sel_o => wb_sel,
wb_cyc_o => wb_cyc,
wb_stb_o => wb_stb,
wb_we_o => wb_we,
wb_ack_i => wb_ack
);
wb_adr_o <= wb_adr;
wb_dat_s2m <= wb_dat_i & wb_dat_s2m_dma_ctrl;
wb_dat_o <= wb_dat_m2s;
wb_sel_o <= wb_sel;
wb_cyc_o <= wb_cyc(g_CSR_WB_SLAVES_NB downto 1); -- wb_cyc(0) is for DMA controller
wb_stb_o <= wb_stb;
wb_we_o <= wb_we;
wb_ack <= wb_ack_i & wb_ack_dma_ctrl;
-----------------------------------------------------------------------------
-- DMA controller
-----------------------------------------------------------------------------
cmp_dma_controller : dma_controller
port map
(
clk_i => sys_clk,
rst_n_i => rst_n,
dma_ctrl_irq_o => dma_irq_o,
dma_ctrl_carrier_addr_o => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_o => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_o => dma_ctrl_host_addr_l,
dma_ctrl_len_o => dma_ctrl_len,
dma_ctrl_start_l2p_o => dma_ctrl_start_l2p,
dma_ctrl_start_p2l_o => dma_ctrl_start_p2l,
dma_ctrl_start_next_o => dma_ctrl_start_next,
dma_ctrl_done_i => dma_ctrl_done,
dma_ctrl_error_i => dma_ctrl_error,
dma_ctrl_byte_swap_o => dma_ctrl_byte_swap,
dma_ctrl_abort_o => dma_ctrl_abort,
next_item_carrier_addr_i => next_item_carrier_addr,
next_item_host_addr_h_i => next_item_host_addr_h,
next_item_host_addr_l_i => next_item_host_addr_l,
next_item_len_i => next_item_len,
next_item_next_l_i => next_item_next_l,
next_item_next_h_i => next_item_next_h,
next_item_attrib_i => next_item_attrib,
next_item_valid_i => next_item_valid,
wb_clk_i => wb_clk_i,
wb_adr_i => wb_adr(3 downto 0),
wb_dat_o => wb_dat_s2m_dma_ctrl,
wb_dat_i => wb_dat_m2s,
wb_sel_i => wb_sel,
wb_cyc_i => wb_cyc(0),
wb_stb_i => wb_stb,
wb_we_i => wb_we,
wb_ack_o => wb_ack_dma_ctrl
);
-- Status signals from DMA masters
dma_ctrl_done <= dma_ctrl_l2p_done or dma_ctrl_p2l_done;
dma_ctrl_error <= dma_ctrl_l2p_error or dma_ctrl_p2l_error;
-----------------------------------------------------------------------------
-- L2P DMA master
-----------------------------------------------------------------------------
cmp_l2p_dma_master : l2p_dma_master
port map
(
clk_i => sys_clk,
rst_n_i => rst_n,
dma_ctrl_target_addr_i => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_i => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_i => dma_ctrl_host_addr_l,
dma_ctrl_len_i => dma_ctrl_len,
dma_ctrl_start_l2p_i => dma_ctrl_start_l2p,
dma_ctrl_done_o => dma_ctrl_l2p_done,
dma_ctrl_error_o => dma_ctrl_l2p_error,
dma_ctrl_byte_swap_i => dma_ctrl_byte_swap,
dma_ctrl_abort_i => dma_ctrl_abort,
ldm_arb_valid_o => ldm_arb_valid,
ldm_arb_dframe_o => ldm_arb_dframe,
ldm_arb_data_o => ldm_arb_data,
ldm_arb_req_o => ldm_arb_req,
arb_ldm_gnt_i => arb_ldm_gnt,
l2p_edb_o => l2p_edb,
l_wr_rdy_i => l_wr_rdy,
l2p_rdy_i => l2p_rdy,
l2p_dma_clk_i => dma_clk_i,
l2p_dma_adr_o => l2p_dma_adr,
l2p_dma_dat_i => l2p_dma_dat_s2m,
l2p_dma_dat_o => l2p_dma_dat_m2s,
l2p_dma_sel_o => l2p_dma_sel,
l2p_dma_cyc_o => l2p_dma_cyc,
l2p_dma_stb_o => l2p_dma_stb,
l2p_dma_we_o => l2p_dma_we,
l2p_dma_ack_i => l2p_dma_ack,
l2p_dma_stall_i => l2p_dma_stall,
p2l_dma_cyc_i => p2l_dma_cyc
);
-----------------------------------------------------------------------------
-- P2L DMA master
-----------------------------------------------------------------------------
cmp_p2l_dma_master : p2l_dma_master
port map
(
clk_i => sys_clk,
rst_n_i => rst_n,
dma_ctrl_carrier_addr_i => dma_ctrl_carrier_addr,
dma_ctrl_host_addr_h_i => dma_ctrl_host_addr_h,
dma_ctrl_host_addr_l_i => dma_ctrl_host_addr_l,
dma_ctrl_len_i => dma_ctrl_len,
dma_ctrl_start_p2l_i => dma_ctrl_start_p2l,
dma_ctrl_start_next_i => dma_ctrl_start_next,
dma_ctrl_done_o => dma_ctrl_p2l_done,
dma_ctrl_error_o => dma_ctrl_p2l_error,
dma_ctrl_byte_swap_i => dma_ctrl_byte_swap,
dma_ctrl_abort_i => dma_ctrl_abort,
pd_pdm_hdr_start_i => p2l_hdr_start,
pd_pdm_hdr_length_i => p2l_hdr_length,
pd_pdm_hdr_cid_i => p2l_hdr_cid,
pd_pdm_master_cpld_i => p2l_master_cpld,
pd_pdm_master_cpln_i => p2l_master_cpln,
pd_pdm_data_valid_i => p2l_d_valid,
pd_pdm_data_last_i => p2l_d_last,
pd_pdm_data_i => p2l_d,
pd_pdm_be_i => p2l_be,
p2l_rdy_o => p2l_rdy_pdm,
rx_error_o => rx_error_o,
pdm_arb_valid_o => pdm_arb_valid,
pdm_arb_dframe_o => pdm_arb_dframe,
pdm_arb_data_o => pdm_arb_data,
pdm_arb_req_o => pdm_arb_req,
arb_pdm_gnt_i => arb_pdm_gnt,
p2l_dma_clk_i => dma_clk_i,
p2l_dma_adr_o => p2l_dma_adr,
p2l_dma_dat_i => p2l_dma_dat_s2m,
p2l_dma_dat_o => p2l_dma_dat_m2s,
p2l_dma_sel_o => p2l_dma_sel,
p2l_dma_cyc_o => p2l_dma_cyc,
p2l_dma_stb_o => p2l_dma_stb,
p2l_dma_we_o => p2l_dma_we,
p2l_dma_ack_i => p2l_dma_ack,
p2l_dma_stall_i => p2l_dma_stall,
l2p_dma_cyc_i => l2p_dma_cyc,
next_item_carrier_addr_o => next_item_carrier_addr,
next_item_host_addr_h_o => next_item_host_addr_h,
next_item_host_addr_l_o => next_item_host_addr_l,
next_item_len_o => next_item_len,
next_item_next_l_o => next_item_next_l,
next_item_next_h_o => next_item_next_h,
next_item_attrib_o => next_item_attrib,
next_item_valid_o => next_item_valid
);
p_dma_wb_mux : process (p2l_dma_cyc, l2p_dma_cyc, l2p_dma_we, p2l_dma_we,
l2p_dma_stb, p2l_dma_stb, l2p_dma_sel, p2l_dma_sel,
l2p_dma_dat_m2s, p2l_dma_dat_m2s, l2p_dma_adr, p2l_dma_adr)
begin
if (l2p_dma_cyc = '1') then
dma_adr_o <= l2p_dma_adr;
dma_dat_o <= l2p_dma_dat_m2s;
dma_sel_o <= l2p_dma_sel;
dma_cyc_o <= l2p_dma_cyc;
dma_stb_o <= l2p_dma_stb;
dma_we_o <= l2p_dma_we;
elsif (p2l_dma_cyc = '1') then
dma_adr_o <= p2l_dma_adr;
dma_dat_o <= p2l_dma_dat_m2s;
dma_sel_o <= p2l_dma_sel;
dma_cyc_o <= p2l_dma_cyc;
dma_stb_o <= p2l_dma_stb;
dma_we_o <= p2l_dma_we;
else
dma_adr_o <= (others => '0');
dma_dat_o <= (others => '0');
dma_sel_o <= (others => '0');
dma_cyc_o <= '0';
dma_stb_o <= '0';
dma_we_o <= '0';
end if;
end process p_dma_wb_mux;
l2p_dma_dat_s2m <= dma_dat_i;
p2l_dma_dat_s2m <= dma_dat_i;
l2p_dma_ack <= dma_ack_i;
p2l_dma_ack <= dma_ack_i;
l2p_dma_stall <= dma_stall_i;
p2l_dma_stall <= dma_stall_i;
--===========================================================================
-- L2P DataPath
--===========================================================================
-----------------------------------------------------------------------------
-- Resync GN412x L2P status signals
-----------------------------------------------------------------------------
p_l2p_status_sync : process (sys_clk, rst_n)
begin
if(rst_n = c_RST_ACTIVE) then
l_wr_rdy_t <= "00";
l_wr_rdy_t2 <= "00";
l_wr_rdy <= "00";
p_rd_d_rdy_t <= "00";
p_rd_d_rdy_t2 <= "00";
p_rd_d_rdy <= "00";
l2p_rdy_t <= '0';
l2p_rdy_t2 <= '0';
l2p_rdy <= '0';
l2p_edb_o <= '0';
l2p_edb_t <= '0';
l2p_edb_t2 <= '0';
elsif rising_edge(sys_clk) then
-- must be checked before l2p_dma_master issues a master write
l_wr_rdy_t <= l_wr_rdy_i;
l_wr_rdy_t2 <= l_wr_rdy_t;
l_wr_rdy <= l_wr_rdy_t2;
-- must be checked before wbmaster32 sends read completion with data
p_rd_d_rdy_t <= p_rd_d_rdy_i;
p_rd_d_rdy_t2 <= p_rd_d_rdy_t;
p_rd_d_rdy <= p_rd_d_rdy_t2;
-- when de-asserted, l2p_dma_master must stop sending data (de-assert l2p_valid) within 3 (or 7 ?) clock cycles
l2p_rdy_t <= l2p_rdy_i;
l2p_rdy_t2 <= l2p_rdy_t;
l2p_rdy <= l2p_rdy_t2;
--assert when packet badly ends (e.g. dma abort)
l2p_edb_t <= l2p_edb;
l2p_edb_t2 <= l2p_edb_t;
l2p_edb_o <= l2p_edb_t2;
end if;
end process p_l2p_status_sync;
-----------------------------------------------------------------------------
-- L2P arbiter, arbitrates access to GN4124
-----------------------------------------------------------------------------
cmp_l2p_arbiter : l2p_arbiter
port map
(
---------------------------------------------------------
-- Clock/Reset
clk_i => sys_clk,
rst_n_i => rst_n,
---------------------------------------------------------
-- From Wishbone master (wbm) to arbiter (arb)
wbm_arb_valid_i => wbm_arb_valid,
wbm_arb_dframe_i => wbm_arb_dframe,
wbm_arb_data_i => wbm_arb_data,
wbm_arb_req_i => wbm_arb_req,
arb_wbm_gnt_o => arb_wbm_gnt,
---------------------------------------------------------
-- From DMA controller (pdm) to arbiter (arb)
pdm_arb_valid_i => pdm_arb_valid,
pdm_arb_dframe_i => pdm_arb_dframe,
pdm_arb_data_i => pdm_arb_data,
pdm_arb_req_i => pdm_arb_req,
arb_pdm_gnt_o => arb_pdm_gnt,
---------------------------------------------------------
-- From P2L DMA master (pdm) to arbiter (arb)
ldm_arb_valid_i => ldm_arb_valid,
ldm_arb_dframe_i => ldm_arb_dframe,
ldm_arb_data_i => ldm_arb_data,
ldm_arb_req_i => ldm_arb_req,
arb_ldm_gnt_o => arb_ldm_gnt,
---------------------------------------------------------
-- From arbiter (arb) to serializer (ser)
arb_ser_valid_o => arb_ser_valid,
arb_ser_dframe_o => arb_ser_dframe,
arb_ser_data_o => arb_ser_data
);
-----------------------------------------------------------------------------
-- L2P_SER: Generate the L2P DDR Outputs
-----------------------------------------------------------------------------
cmp_l2p_ser : l2p_ser
port map
(
---------------------------------------------------------
-- Clocks and reset
rst_n_i => rst_n,
sys_clk_i => sys_clk,
io_clk_i => io_clk,
serdes_strobe_i => serdes_strobe,
---------------------------------------------------------
-- L2P SDR inputs
l2p_valid_i => arb_ser_valid,
l2p_dframe_i => arb_ser_dframe,
l2p_data_i => arb_ser_data,
---------------------------------------------------------
-- L2P DDR outputs
l2p_clk_p_o => l2p_clk_p_o,
l2p_clk_n_o => l2p_clk_n_o,
l2p_valid_o => l2p_valid_o,
l2p_dframe_o => l2p_dframe_o,
l2p_data_o => l2p_data_o
);
end rtl;
--==============================================================================
-- Architecture end (gn4124_core)
--==============================================================================
-------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
-------------------------------------------------------------------------------
--
-- unit name: GN4124 core arbiter (arbiter.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 12-08-2010
--
-- version: 0.1
--
-- description: Arbitrates PCIe accesses between Wishbone master,
-- L2P DMA master and P2L DMA master
--
-- dependencies:
--
-------------------------------------------------------------------------------
-- last changes: 23-09-2010 (mcattin) Add FF on data path and
-- change valid request logic
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity l2p_arbiter is
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From Wishbone master (wbm) to arbiter (arb)
wbm_arb_valid_i : in std_logic;
wbm_arb_dframe_i : in std_logic;
wbm_arb_data_i : in std_logic_vector(31 downto 0);
wbm_arb_req_i : in std_logic;
arb_wbm_gnt_o : out std_logic;
---------------------------------------------------------
-- From P2L DMA master (pdm) to arbiter (arb)
pdm_arb_valid_i : in std_logic;
pdm_arb_dframe_i : in std_logic;
pdm_arb_data_i : in std_logic_vector(31 downto 0);
pdm_arb_req_i : in std_logic;
arb_pdm_gnt_o : out std_logic;
---------------------------------------------------------
-- From L2P DMA master (ldm) to arbiter (arb)
ldm_arb_valid_i : in std_logic;
ldm_arb_dframe_i : in std_logic;
ldm_arb_data_i : in std_logic_vector(31 downto 0);
ldm_arb_req_i : in std_logic;
arb_ldm_gnt_o : out std_logic;
---------------------------------------------------------
-- From arbiter (arb) to serializer (ser)
arb_ser_valid_o : out std_logic;
arb_ser_dframe_o : out std_logic;
arb_ser_data_o : out std_logic_vector(31 downto 0)
);
end l2p_arbiter;
architecture rtl of l2p_arbiter is
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
signal wbm_arb_req_valid : std_logic;
signal pdm_arb_req_valid : std_logic;
signal ldm_arb_req_valid : std_logic;
signal arb_wbm_gnt : std_logic;
signal arb_pdm_gnt : std_logic;
signal arb_ldm_gnt : std_logic;
signal eop : std_logic; -- End of packet
signal arb_ser_valid_t : std_logic;
signal arb_ser_dframe_t : std_logic;
signal arb_ser_data_t : std_logic_vector(31 downto 0);
begin
-- A request is valid only if the access not already granted to another source
wbm_arb_req_valid <= wbm_arb_req_i and (not(arb_pdm_gnt) and not(arb_ldm_gnt));
pdm_arb_req_valid <= pdm_arb_req_i and (not(arb_wbm_gnt) and not(arb_ldm_gnt));
ldm_arb_req_valid <= ldm_arb_req_i and (not(arb_wbm_gnt) and not(arb_pdm_gnt));
-- Detect end of packet to delimit the arbitration phase
eop <= ((arb_wbm_gnt and not(wbm_arb_dframe_i) and wbm_arb_valid_i) or
(arb_pdm_gnt and not(pdm_arb_dframe_i) and pdm_arb_valid_i) or
(arb_ldm_gnt and not(ldm_arb_dframe_i) and ldm_arb_valid_i));
-----------------------------------------------------------------------------
-- Arbitration is started when a valid request is present and ends when the
-- EOP condition is detected
--
-- Strict priority arbitration scheme
-- Highest : WBM request
-- : LDM request
-- Lowest : PDM request
-----------------------------------------------------------------------------
process (clk_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
arb_wbm_gnt <= '0';
arb_pdm_gnt <= '0';
arb_ldm_gnt <= '0';
elsif rising_edge(clk_i) then
--if (arb_req_valid = '1') then
if (wbm_arb_req_valid = '1') then
arb_wbm_gnt <= '1';
arb_pdm_gnt <= '0';
arb_ldm_gnt <= '0';
elsif (ldm_arb_req_valid = '1') then
arb_wbm_gnt <= '0';
arb_pdm_gnt <= '0';
arb_ldm_gnt <= '1';
elsif (pdm_arb_req_valid = '1') then
arb_wbm_gnt <= '0';
arb_pdm_gnt <= '1';
arb_ldm_gnt <= '0';
elsif (eop = '1') then
arb_wbm_gnt <= '0';
arb_pdm_gnt <= '0';
arb_ldm_gnt <= '0';
end if;
end if;
end process;
process (clk_i, rst_n_i)
begin
if rst_n_i = '0' then
arb_ser_valid_t <= '0';
arb_ser_dframe_t <= '0';
arb_ser_data_t <= (others => '0');
elsif rising_edge(clk_i) then
if arb_wbm_gnt = '1' then
arb_ser_valid_t <= wbm_arb_valid_i;
arb_ser_dframe_t <= wbm_arb_dframe_i;
arb_ser_data_t <= wbm_arb_data_i;
elsif arb_pdm_gnt = '1' then
arb_ser_valid_t <= pdm_arb_valid_i;
arb_ser_dframe_t <= pdm_arb_dframe_i;
arb_ser_data_t <= pdm_arb_data_i;
elsif arb_ldm_gnt = '1' then
arb_ser_valid_t <= ldm_arb_valid_i;
arb_ser_dframe_t <= ldm_arb_dframe_i;
arb_ser_data_t <= ldm_arb_data_i;
else
arb_ser_valid_t <= '0';
arb_ser_dframe_t <= '0';
arb_ser_data_t <= (others => '0');
end if;
end if;
end process;
process (clk_i, rst_n_i)
begin
if rst_n_i = '0' then
arb_ser_valid_o <= '0';
arb_ser_dframe_o <= '0';
arb_ser_data_o <= (others => '0');
elsif rising_edge(clk_i) then
arb_ser_valid_o <= arb_ser_valid_t;
arb_ser_dframe_o <= arb_ser_dframe_t;
arb_ser_data_o <= arb_ser_data_t;
end if;
end process;
arb_wbm_gnt_o <= arb_wbm_gnt;
arb_pdm_gnt_o <= arb_pdm_gnt;
arb_ldm_gnt_o <= arb_ldm_gnt;
end rtl;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: 32-bit DMA master (l2p_dma_master.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 1.0
--
-- description: Provides a pipelined Wishbone interface to performs DMA
-- transfers from local application to PCI express host.
--
-- dependencies: Xilinx FIFOs (fifo_32x512.xco)
--
--------------------------------------------------------------------------------
-- last changes: see svn log
--------------------------------------------------------------------------------
-- TODO: - byte enable support
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity l2p_dma_master is
generic (
-- Enable byte swap module (if false, no swap)
g_BYTE_SWAP : boolean := false
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From the DMA controller
dma_ctrl_target_addr_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_i : in std_logic_vector(31 downto 0);
dma_ctrl_len_i : in std_logic_vector(31 downto 0);
dma_ctrl_start_l2p_i : in std_logic;
dma_ctrl_done_o : out std_logic;
dma_ctrl_error_o : out std_logic;
dma_ctrl_byte_swap_i : in std_logic_vector(1 downto 0);
dma_ctrl_abort_i : in std_logic;
---------------------------------------------------------
-- To the arbiter (L2P data)
ldm_arb_valid_o : out std_logic; -- Read completion signals
ldm_arb_dframe_o : out std_logic; -- Toward the arbiter
ldm_arb_data_o : out std_logic_vector(31 downto 0);
ldm_arb_req_o : out std_logic;
arb_ldm_gnt_i : in std_logic;
---------------------------------------------------------
-- L2P channel control
l2p_edb_o : out std_logic; -- Asserted when transfer is aborted
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Asserted when GN4124 is ready to receive master write
l2p_rdy_i : in std_logic; -- De-asserted to pause transfer already in progress
---------------------------------------------------------
-- DMA Interface (Pipelined Wishbone)
l2p_dma_clk_i : in std_logic; -- Bus clock
l2p_dma_adr_o : out std_logic_vector(31 downto 0); -- Adress
l2p_dma_dat_i : in std_logic_vector(31 downto 0); -- Data in
l2p_dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
l2p_dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
l2p_dma_cyc_o : out std_logic; -- Read or write cycle
l2p_dma_stb_o : out std_logic; -- Read or write strobe
l2p_dma_we_o : out std_logic; -- Write
l2p_dma_ack_i : in std_logic; -- Acknowledge
l2p_dma_stall_i : in std_logic; -- for pipelined Wishbone
p2l_dma_cyc_i : in std_logic -- P2L dma wb cycle (for bus arbitration)
);
end l2p_dma_master;
architecture behaviour of l2p_dma_master is
-----------------------------------------------------------------------------
-- Constants declaration
-----------------------------------------------------------------------------
-- c_L2P_MAX_PAYLOAD is the maximum size (in 32-bit words) of the payload of a packet.
-- Allowed c_L2P_MAX_PAYLOAD values are: 32, 64, 128, 256, 512, 1024.
-- This constant must be set according to the GN4124 and motherboard chipset capabilities.
constant c_L2P_MAX_PAYLOAD : unsigned(10 downto 0) := to_unsigned(32, 11); -- in 32-bit words
constant c_ADDR_FIFO_FULL_THRES : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(500, 9));
constant c_DATA_FIFO_FULL_THRES : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(500, 9));
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- Target address counter
signal target_addr_cnt : unsigned(29 downto 0);
signal dma_length_cnt : unsigned(29 downto 0);
-- Sync FIFOs
signal fifo_rst : std_logic;
signal addr_fifo_rd : std_logic;
signal addr_fifo_valid : std_logic;
signal addr_fifo_empty : std_logic;
signal addr_fifo_dout : std_logic_vector(31 downto 0);
signal addr_fifo_din : std_logic_vector(31 downto 0);
signal addr_fifo_wr : std_logic;
signal addr_fifo_full : std_logic;
signal data_fifo_rd : std_logic;
signal data_fifo_valid : std_logic;
signal data_fifo_empty : std_logic;
signal data_fifo_dout : std_logic_vector(31 downto 0);
signal data_fifo_din : std_logic_vector(31 downto 0);
signal data_fifo_wr : std_logic;
signal data_fifo_full : std_logic;
-- Wishbone
signal wb_read_cnt : unsigned(31 downto 0);
signal wb_ack_cnt : unsigned(31 downto 0);
signal l2p_dma_cyc_t : std_logic;
signal l2p_dma_stb_t : std_logic;
-- L2P DMA Master FSM
type l2p_dma_state_type is (L2P_IDLE, L2P_WAIT_DATA, L2P_HEADER, L2P_ADDR_H,
L2P_ADDR_L, L2P_DATA, L2P_LAST_DATA, L2P_WAIT_RDY);
signal l2p_dma_current_state : l2p_dma_state_type;
-- L2P packet generator
signal s_l2p_header : std_logic_vector(31 downto 0);
signal l2p_len_cnt : unsigned(29 downto 0);
signal l2p_address_h : unsigned(31 downto 0);
signal l2p_address_l : unsigned(31 downto 0);
signal l2p_data_cnt : unsigned(10 downto 0);
signal l2p_64b_address : std_logic;
signal l2p_len_header : unsigned(9 downto 0);
signal l2p_byte_swap : std_logic_vector(1 downto 0);
signal l2p_last_packet : std_logic;
signal l2p_lbe_header : std_logic_vector(3 downto 0);
begin
------------------------------------------------------------------------------
-- Active high reset for fifo
------------------------------------------------------------------------------
-- Creates an active high reset for fifos regardless of c_RST_ACTIVE value
gen_fifo_rst_n : if c_RST_ACTIVE = '0' generate
fifo_rst <= not(rst_n_i);
end generate;
gen_fifo_rst : if c_RST_ACTIVE = '1' generate
fifo_rst <= rst_n_i;
end generate;
------------------------------------------------------------------------------
-- Target address counter
------------------------------------------------------------------------------
p_target_cnt : process (clk_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
target_addr_cnt <= (others => '0');
dma_length_cnt <= (others => '0');
dma_ctrl_error_o <= '0';
addr_fifo_wr <= '0';
elsif rising_edge(clk_i) then
if (dma_ctrl_start_l2p_i = '1') then
if (l2p_dma_current_state = L2P_IDLE) then
-- dma_ctrl_target_addr_i is a byte address and target_addr_cnt is a
-- 32-bit word address
target_addr_cnt <= unsigned(dma_ctrl_target_addr_i(31 downto 2));
-- dma_ctrl_len_i is in byte and dma_length_cnt is in 32-bit word
dma_length_cnt <= unsigned(dma_ctrl_len_i(31 downto 2));
dma_ctrl_error_o <= '0';
else
-- trying to start a DMA transfert when another is still in progress
-- will gives an error
target_addr_cnt <= (others => '0');
dma_length_cnt <= (others => '0');
dma_ctrl_error_o <= '1';
end if;
elsif (dma_length_cnt /= 0 and addr_fifo_full = '0') then
-- increment the target address and write it to address fifo
addr_fifo_wr <= '1';
target_addr_cnt <= target_addr_cnt + 1;
dma_length_cnt <= dma_length_cnt - 1;
-- Adust data width, fifo width is 32 bits
addr_fifo_din <= "00" & std_logic_vector(target_addr_cnt);
else
addr_fifo_wr <= '0';
end if;
end if;
end process p_target_cnt;
------------------------------------------------------------------------------
-- Packet generator
------------------------------------------------------------------------------
-- Sends data to the host.
-- Split in several packets if amount of data exceeds max payload size.
p_pkt_gen : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
l2p_len_cnt <= (others => '0');
l2p_data_cnt <= (others => '0');
l2p_address_h <= (others => '0');
l2p_address_l <= (others => '0');
l2p_64b_address <= '0';
l2p_len_header <= (others => '0');
l2p_byte_swap <= (others => '0');
l2p_last_packet <= '0';
elsif rising_edge(clk_i) then
-- First packet
if (l2p_dma_current_state = L2P_IDLE) then
if (dma_ctrl_start_l2p_i = '1') then
-- store DMA info locally
l2p_len_cnt <= unsigned(dma_ctrl_len_i(31 downto 2));
l2p_address_h <= unsigned(dma_ctrl_host_addr_h_i);
l2p_address_l <= unsigned(dma_ctrl_host_addr_l_i);
l2p_byte_swap <= dma_ctrl_byte_swap_i;
end if;
elsif (l2p_dma_current_state = L2P_HEADER) then
-- if DMA length is bigger than the max PCIe payload size,
-- the data is split in several packets
if (l2p_len_cnt > c_L2P_MAX_PAYLOAD) then
l2p_data_cnt <= c_L2P_MAX_PAYLOAD;
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_L2P_MAX_PAYLOAD(9 downto 0);
l2p_last_packet <= '0';
elsif (l2p_len_cnt = c_L2P_MAX_PAYLOAD) then
l2p_data_cnt <= c_L2P_MAX_PAYLOAD;
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_L2P_MAX_PAYLOAD(9 downto 0);
l2p_last_packet <= '1';
else
l2p_data_cnt <= l2p_len_cnt(10 downto 0);
l2p_len_header <= l2p_len_cnt(9 downto 0);
l2p_last_packet <= '1';
end if;
-- if host address is 64-bit, generates a 64-bit address memory write
if (l2p_address_h = 0) then
l2p_64b_address <= '0';
else
l2p_64b_address <= '1';
end if;
-- Next packet (if any)
elsif (l2p_dma_current_state = L2P_ADDR_L) then
if (l2p_last_packet = '0') then
l2p_len_cnt <= l2p_len_cnt - c_L2P_MAX_PAYLOAD;
else
l2p_len_cnt <= (others => '0');
end if;
elsif (l2p_dma_current_state = L2P_DATA and data_fifo_valid = '1') then
l2p_data_cnt <= l2p_data_cnt - 1;
elsif (l2p_last_packet = '0' and l2p_dma_current_state = L2P_LAST_DATA) then
-- load the host address of the next packet
l2p_address_l <= l2p_address_l + (c_L2P_MAX_PAYLOAD * 4);
-- load the size of the next packet
if (l2p_len_cnt > c_L2P_MAX_PAYLOAD) then
l2p_data_cnt <= c_L2P_MAX_PAYLOAD;
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_L2P_MAX_PAYLOAD(9 downto 0);
l2p_last_packet <= '0';
elsif (l2p_len_cnt = c_L2P_MAX_PAYLOAD) then
l2p_data_cnt <= c_L2P_MAX_PAYLOAD;
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_L2P_MAX_PAYLOAD(9 downto 0);
l2p_last_packet <= '1';
else
l2p_data_cnt <= l2p_len_cnt(10 downto 0);
l2p_len_header <= l2p_len_cnt(9 downto 0);
l2p_last_packet <= '1';
end if;
end if;
end if;
end process p_pkt_gen;
-- Last Byte Enable must be "0000" when length = 1
l2p_lbe_header <= "0000" when l2p_len_header = 1 else "1111";
-- Packet header
s_l2p_header <= "000" --> Traffic Class
& '0' --> Snoop
& "001" & l2p_64b_address --> Header type,
-- memory write 32-bit or
-- memory write 64-bit
& l2p_lbe_header --> LBE (Last Byte Enable)
& "1111" --> FBE (First Byte Enable)
& "000" --> Reserved
& '0' --> VC (Virtual Channel)
& "00" --> Reserved
& std_logic_vector(l2p_len_header); --> Length (in 32-bit words)
-- 0x000 => 1024 words (4096 bytes)
-----------------------------------------------------------------------------
-- L2P packet write FSM
-----------------------------------------------------------------------------
process(clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
l2p_dma_current_state <= L2P_IDLE;
ldm_arb_req_o <= '0';
ldm_arb_data_o <= (others => '0');
ldm_arb_valid_o <= '0';
ldm_arb_dframe_o <= '0';
data_fifo_rd <= '0';
dma_ctrl_done_o <= '0';
l2p_edb_o <= '0';
elsif rising_edge(clk_i) then
case l2p_dma_current_state is
when L2P_IDLE =>
-- do nothing !
data_fifo_rd <= '0';
dma_ctrl_done_o <= '0';
ldm_arb_data_o <= (others => '0');
ldm_arb_valid_o <= '0';
ldm_arb_dframe_o <= '0';
l2p_edb_o <= '0';
if (data_fifo_empty = '0') then
-- We have data to send -> prepare a packet, first the header
l2p_dma_current_state <= L2P_HEADER;
-- request access to PCIe bus
ldm_arb_req_o <= '1';
end if;
when L2P_HEADER =>
if(arb_ldm_gnt_i = '1' and l_wr_rdy_i = "11") then
-- clear access request to the arbiter
-- access is granted until dframe is cleared
ldm_arb_req_o <= '0';
-- send header
ldm_arb_data_o <= s_l2p_header;
ldm_arb_valid_o <= '1';
ldm_arb_dframe_o <= '1';
if(l2p_64b_address = '1') then
-- if host address is 64-bit, we have to send an additionnal
-- 32-word containing highest bits of the host address
l2p_dma_current_state <= L2P_ADDR_H;
else
-- for 32-bit host address, we only have to send lowest bits
l2p_dma_current_state <= L2P_ADDR_L;
-- Starts reading data in the fifo now, because there is
-- 1 cycle delay until data are available
data_fifo_rd <= '1';
end if;
else
-- arbiter or GN4124 not ready to receive a new packet
ldm_arb_valid_o <= '0';
end if;
when L2P_ADDR_H =>
-- send host address 32 highest bits
ldm_arb_data_o <= std_logic_vector(l2p_address_h);
-- Now we still have to send lowest bits of the host address
l2p_dma_current_state <= L2P_ADDR_L;
-- Starts reading data in the fifo now, because there is
-- 1 cycle delay until data are available
data_fifo_rd <= '1';
when L2P_ADDR_L =>
-- send host address 32 lowest bits
ldm_arb_data_o <= std_logic_vector(l2p_address_l);
if(l2p_data_cnt <= 1) then
-- Only one 32-bit data word to send
l2p_dma_current_state <= L2P_LAST_DATA;
-- Stop reading from fifo
data_fifo_rd <= '0';
else
-- More than one data word to send
l2p_dma_current_state <= L2P_DATA;
end if;
when L2P_DATA =>
if (data_fifo_valid = '1') then
-- send data with byte swap if requested
ldm_arb_data_o <= f_byte_swap(g_BYTE_SWAP, data_fifo_dout, l2p_byte_swap);
ldm_arb_valid_o <= '1';
else
ldm_arb_valid_o <= '0';
end if;
if (dma_ctrl_abort_i = '1') then
l2p_edb_o <= '1';
l2p_dma_current_state <= L2P_IDLE;
elsif (l2p_rdy_i = '0') then
-- GN4124 not able to receive more data, have to wait
l2p_dma_current_state <= L2P_WAIT_RDY;
-- Stop reading from fifo
data_fifo_rd <= '0';
-- Invalidate data
ldm_arb_valid_o <= '0';
elsif(data_fifo_empty = '1') then
-- data not ready yet, wait for it
l2p_dma_current_state <= L2P_WAIT_DATA;
elsif(l2p_data_cnt <= 2) then
-- Only one 32-bit data word to send
l2p_dma_current_state <= L2P_LAST_DATA;
-- Stop reading from fifo
data_fifo_rd <= '0';
end if;
when L2P_WAIT_RDY =>
ldm_arb_valid_o <= '0';
if (l2p_rdy_i = '1') then
-- GN4124 is ready to receive more data
-- Validate last data read before de-assertion of l2p_rdy
ldm_arb_valid_o <= '1';
if (l2p_data_cnt <= 1) then
-- Last data word of the packet
l2p_dma_current_state <= L2P_LAST_DATA;
else
-- More data word to be sent
l2p_dma_current_state <= L2P_DATA;
-- Re-start fifo reading
data_fifo_rd <= '1';
end if;
end if;
when L2P_WAIT_DATA =>
ldm_arb_valid_o <= '0';
if(data_fifo_empty = '0') then
if(l2p_data_cnt <= 1) then
-- Only one 32-bit data word to send
l2p_dma_current_state <= L2P_LAST_DATA;
-- Stop reading from fifo
data_fifo_rd <= '0';
else
-- data ready to be send again
l2p_dma_current_state <= L2P_DATA;
end if;
end if;
when L2P_LAST_DATA =>
if (l2p_rdy_i = '0') then
-- GN4124 not able to receive more data, have to wait
-- Invalidate data
ldm_arb_valid_o <= '0';
else
-- send last data word with byte swap if requested
ldm_arb_data_o <= f_byte_swap(g_BYTE_SWAP, data_fifo_dout, l2p_byte_swap);
ldm_arb_valid_o <= '1';
-- clear dframe signal to indicate the end of packet
ldm_arb_dframe_o <= '0';
if(l2p_len_cnt > 0) then
-- There is still data to be send -> start a new packet
l2p_dma_current_state <= L2P_HEADER;
-- As the end of packet is used to delimit arbitration phases
-- we have to ask again for permission
ldm_arb_req_o <= '1';
else
-- Nomore data to send, go back to sleep
l2p_dma_current_state <= L2P_IDLE;
-- Indicate that the DMA transfer is finished
dma_ctrl_done_o <= '1';
end if;
end if;
when others =>
-- should no arrive here, but just in case...
l2p_dma_current_state <= L2P_IDLE;
ldm_arb_req_o <= '0';
ldm_arb_data_o <= (others => '0');
ldm_arb_valid_o <= '0';
ldm_arb_dframe_o <= '0';
data_fifo_rd <= '0';
dma_ctrl_done_o <= '0';
end case;
end if;
end process;
------------------------------------------------------------------------------
-- FIFOs for transition between GN4124 core and wishbone clock domain
------------------------------------------------------------------------------
cmp_addr_fifo : fifo_32x512
port map (
rst => fifo_rst,
wr_clk => clk_i,
rd_clk => l2p_dma_clk_i,
din => addr_fifo_din,
wr_en => addr_fifo_wr,
rd_en => addr_fifo_rd,
prog_full_thresh_assert => c_ADDR_FIFO_FULL_THRES,
prog_full_thresh_negate => c_ADDR_FIFO_FULL_THRES,
dout => addr_fifo_dout,
full => open,
empty => addr_fifo_empty,
valid => addr_fifo_valid,
prog_full => addr_fifo_full);
cmp_data_fifo : fifo_32x512
port map (
rst => fifo_rst,
wr_clk => l2p_dma_clk_i,
rd_clk => clk_i,
din => data_fifo_din,
wr_en => data_fifo_wr,
rd_en => data_fifo_rd,
prog_full_thresh_assert => c_DATA_FIFO_FULL_THRES,
prog_full_thresh_negate => c_DATA_FIFO_FULL_THRES,
dout => data_fifo_dout,
full => open,
empty => data_fifo_empty,
valid => data_fifo_valid,
prog_full => data_fifo_full);
data_fifo_din <= l2p_dma_dat_i;
-- latch data when receiving ack and the cycle has been initiated by this master
data_fifo_wr <= l2p_dma_ack_i and l2p_dma_cyc_t;
------------------------------------------------------------------------------
-- Pipelined wishbone master
------------------------------------------------------------------------------
-- Initatiates read transactions as long there is an address present
-- in the address fifo. Then fills the data fifo with the read data.
-- Wishbone master only make reads
l2p_dma_we_o <= '0';
l2p_dma_dat_o <= (others => '0');
-- Read address FIFO
addr_fifo_rd <= not(addr_fifo_empty)
and not(l2p_dma_stall_i)
and not(data_fifo_full)
and not(p2l_dma_cyc_i);
-- Wishbone master process
p_wb_master : process (l2p_dma_clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
l2p_dma_adr_o <= (others => '0');
l2p_dma_stb_t <= '0';
l2p_dma_cyc_t <= '0';
l2p_dma_sel_o <= (others => '0');
elsif rising_edge(l2p_dma_clk_i) then
-- adr signal management
if (addr_fifo_valid = '1') then
l2p_dma_adr_o <= addr_fifo_dout;
end if;
-- stb and sel signals management
if (addr_fifo_valid = '1') then --or (l2p_dma_stall_i = '1' and l2p_dma_stb_t = '1') then
l2p_dma_stb_t <= '1';
l2p_dma_sel_o <= (others => '1');
else
l2p_dma_stb_t <= '0';
l2p_dma_sel_o <= (others => '0');
end if;
-- cyc signal management
if (addr_fifo_valid = '1') then
l2p_dma_cyc_t <= '1';
elsif (wb_ack_cnt = wb_read_cnt-1 and l2p_dma_ack_i = '1') then
-- last ack received -> end of the transaction
l2p_dma_cyc_t <= '0';
end if;
end if;
end process p_wb_master;
-- for read back
l2p_dma_cyc_o <= l2p_dma_cyc_t;
l2p_dma_stb_o <= l2p_dma_stb_t;
-- Wishbone read cycle counter
p_wb_read_cnt : process (l2p_dma_clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
wb_read_cnt <= (others => '0');
elsif rising_edge(l2p_dma_clk_i) then
if (addr_fifo_valid = '1') then
wb_read_cnt <= wb_read_cnt + 1;
end if;
end if;
end process p_wb_read_cnt;
-- Wishbone ack counter
p_wb_ack_cnt : process (l2p_dma_clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
wb_ack_cnt <= (others => '0');
elsif rising_edge(l2p_dma_clk_i) then
if (l2p_dma_ack_i = '1' and l2p_dma_cyc_t = '1') then
wb_ack_cnt <= wb_ack_cnt + 1;
end if;
end if;
end process p_wb_ack_cnt;
end behaviour;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: L2P serializer (l2p_ser.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 1.0
--
-- description: Generates the DDR L2P bus from SDR that is synchronous to the
-- core clock.
--
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: 23-09-2010 (mcattin) Always active high reset for FFs.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity l2p_ser is
generic (
g_IS_SPARTAN6 : boolean := false
);
port
(
---------------------------------------------------------
-- Reset and clock
clk_p_i : in std_logic;
clk_n_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Serializer inputs
l2p_valid_i : in std_logic;
l2p_dframe_i : in std_logic;
l2p_data_i : in std_logic_vector(31 downto 0);
---------------------------------------------------------
-- L2P DDR outputs
l2p_clk_p_o : out std_logic;
l2p_clk_n_o : out std_logic;
l2p_valid_o : out std_logic;
l2p_dframe_o : out std_logic;
l2p_data_o : out std_logic_vector(15 downto 0)
);
end l2p_ser;
architecture rtl of l2p_ser is
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- DDR FF reset
signal ff_rst : std_logic;
-- SDR to DDR signals
signal dframe_d : std_logic;
signal valid_d : std_logic;
signal data_d : std_logic_vector(l2p_data_i'range);
signal l2p_clk_sdr : std_logic;
begin
------------------------------------------------------------------------------
-- Active high reset for DDR FF
------------------------------------------------------------------------------
gen_fifo_rst_n : if c_RST_ACTIVE = '0' generate
ff_rst <= not(rst_n_i);
end generate;
gen_fifo_rst : if c_RST_ACTIVE = '1' generate
ff_rst <= rst_n_i;
end generate;
-----------------------------------------------------------------------------
-- Re-allign data tightly for the positive clock edge
-----------------------------------------------------------------------------
process (clk_p_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
dframe_d <= '0';
valid_d <= '0';
data_d <= (others => '0');
elsif rising_edge(clk_p_i) then
dframe_d <= l2p_dframe_i;
valid_d <= l2p_valid_i;
data_d <= l2p_data_i;
end if;
end process;
------------------------------------------------------------------------------
-- Align control signals to the negative clock edge
------------------------------------------------------------------------------
process (clk_n_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
l2p_valid_o <= '0';
l2p_dframe_o <= '0';
elsif rising_edge(clk_n_i) then
l2p_valid_o <= valid_d;
l2p_dframe_o <= dframe_d;
end if;
end process;
------------------------------------------------------------------------------
-- DDR FF instanciation for data
------------------------------------------------------------------------------
-- Spartan3 primitives instanciation
gen_out_ddr_ff : if g_IS_SPARTAN6 = false generate
-- Data
DDROUT : for i in 0 to 15 generate
U : OFDDRRSE
port map
(
Q => l2p_data_o(i),
C0 => clk_n_i,
C1 => clk_p_i,
CE => '1',
D0 => data_d(i),
D1 => data_d(i+16),
R => ff_rst,
S => '0'
);
end generate;
end generate gen_out_ddr_ff;
-- Spartan6 primitives instanciation
gen_out_ddr_ff_s6 : if g_IS_SPARTAN6 = true generate
-- Data
DDROUT : for i in 0 to 15 generate
U : ODDR2
port map
(
Q => l2p_data_o(i),
C0 => clk_n_i,
C1 => clk_p_i,
CE => '1',
D0 => data_d(i),
D1 => data_d(i+16),
R => ff_rst,
S => '0'
);
end generate;
end generate gen_out_ddr_ff_s6;
------------------------------------------------------------------------------
-- DDR source synchronous clock generation
------------------------------------------------------------------------------
L2P_CLK_BUF : OBUFDS
port map(
O => l2p_clk_p_o,
OB => l2p_clk_n_o,
I => l2p_clk_sdr);
-- Spartan3 primitives instanciation
gen_l2p_clk_ddr_ff : if g_IS_SPARTAN6 = false generate
-- L2P clock
L2P_CLK_int : FDDRRSE
port map(
Q => l2p_clk_sdr,
C0 => clk_n_i,
C1 => clk_p_i,
CE => '1',
D0 => '1',
D1 => '0',
R => '0',
S => '0');
end generate gen_l2p_clk_ddr_ff;
-- Spartan6 primitives instanciation
gen_l2p_clk_ddr_ff_s6 : if g_IS_SPARTAN6 = true generate
-- L2P clock
L2P_CLK_int : ODDR2
port map(
Q => l2p_clk_sdr,
C0 => clk_n_i,
C1 => clk_p_i,
CE => '1',
D0 => '1',
D1 => '0',
R => '0',
S => '0');
end generate gen_l2p_clk_ddr_ff_s6;
end rtl;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: L2P serializer (l2p_ser_s6.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 1.0
--
-- description: Generates the DDR L2P bus from SDR that is synchronous to the
-- core clock. Spartan6 FPGAs version.
--
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: 23-09-2010 (mcattin) Always active high reset for FFs.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity l2p_ser is
port
(
---------------------------------------------------------
-- Reset and clock
rst_n_i : in std_logic;
sys_clk_i : in std_logic;
io_clk_i : in std_logic;
serdes_strobe_i : in std_logic;
---------------------------------------------------------
-- L2P SDR inputs
l2p_valid_i : in std_logic;
l2p_dframe_i : in std_logic;
l2p_data_i : in std_logic_vector(31 downto 0);
---------------------------------------------------------
-- L2P DDR outputs
l2p_clk_p_o : out std_logic;
l2p_clk_n_o : out std_logic;
l2p_valid_o : out std_logic;
l2p_dframe_o : out std_logic;
l2p_data_o : out std_logic_vector(15 downto 0)
);
end l2p_ser;
architecture rtl of l2p_ser is
-----------------------------------------------------------------------------
-- Components declaration
-----------------------------------------------------------------------------
component serdes_n_to_1_s2_se
generic (
S : integer := 2; -- Parameter to set the serdes factor 1..8
D : integer := 16) ; -- Set the number of inputs and outputs
port (
txioclk : in std_logic; -- IO Clock network
txserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset
gclk : in std_logic; -- Global clock
datain : in std_logic_vector((D*S)-1 downto 0); -- Data for output
dataout : out std_logic_vector(D-1 downto 0)) ; -- output
end component serdes_n_to_1_s2_se;
component serdes_n_to_1_s2_diff
generic (
S : integer := 2; -- Parameter to set the serdes factor 1..8
D : integer := 1) ; -- Set the number of inputs and outputs
port (
txioclk : in std_logic; -- IO Clock network
txserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset
gclk : in std_logic; -- Global clock
datain : in std_logic_vector((D*S)-1 downto 0); -- Data for output
dataout_p : out std_logic_vector(D-1 downto 0); -- output
dataout_n : out std_logic_vector(D-1 downto 0)) ; -- output
end component serdes_n_to_1_s2_diff;
-----------------------------------------------------------------------------
-- Comnstants declaration
-----------------------------------------------------------------------------
constant S : integer := 2; -- Set the serdes factor to 2
constant D : integer := 16; -- Set the number of outputs
constant c_TX_CLK : std_logic_vector(1 downto 0) := "01";
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- Serdes reset
signal rst : std_logic;
-- SDR signals
signal l2p_dframe_t : std_logic_vector(1 downto 0);
signal l2p_valid_t : std_logic_vector(1 downto 0);
signal l2p_dframe_v : std_logic_vector(0 downto 0);
signal l2p_valid_v : std_logic_vector(0 downto 0);
signal l2p_clk_p_v : std_logic_vector(0 downto 0);
signal l2p_clk_n_v : std_logic_vector(0 downto 0);
begin
------------------------------------------------------------------------------
-- Active high reset for DDR FF
------------------------------------------------------------------------------
gen_fifo_rst_n : if c_RST_ACTIVE = '0' generate
rst <= not(rst_n_i);
end generate;
gen_fifo_rst : if c_RST_ACTIVE = '1' generate
rst <= rst_n_i;
end generate;
------------------------------------------------------------------------------
-- Instantiate serialiser to generate forwarded clock
------------------------------------------------------------------------------
cmp_clk_out : serdes_n_to_1_s2_diff
generic map(
S => S,
D => 1)
port map (
txioclk => io_clk_i,
txserdesstrobe => serdes_strobe_i,
gclk => sys_clk_i,
reset => rst,
datain => c_TX_CLK, -- Transmit a constant to make the clock
dataout_p => l2p_clk_p_v,
dataout_n => l2p_clk_n_v);
-- Type conversion, std_logic_vector to std_logic
l2p_clk_p_o <= l2p_clk_p_v(0);
l2p_clk_n_o <= l2p_clk_n_v(0);
------------------------------------------------------------------------------
-- Instantiate serialisers for output data lines
------------------------------------------------------------------------------
cmp_data_out : serdes_n_to_1_s2_se
generic map(
S => S,
D => D)
port map (
txioclk => io_clk_i,
txserdesstrobe => serdes_strobe_i,
gclk => sys_clk_i,
reset => rst,
datain => l2p_data_i,
dataout => l2p_data_o);
------------------------------------------------------------------------------
-- Instantiate serialisers for dframe
------------------------------------------------------------------------------
cmp_dframe_out : serdes_n_to_1_s2_se
generic map(
S => S,
D => 1)
port map (
txioclk => io_clk_i,
txserdesstrobe => serdes_strobe_i,
gclk => sys_clk_i,
reset => rst,
datain => l2p_dframe_t,
dataout => l2p_dframe_v);
-- Serialize two times the same value
l2p_dframe_t <= l2p_dframe_i & l2p_dframe_i;
-- Type conversion, std_logic_vector to std_logic
l2p_dframe_o <= l2p_dframe_v(0);
------------------------------------------------------------------------------
-- Instantiate serialisers for valid
------------------------------------------------------------------------------
cmp_valid_out : serdes_n_to_1_s2_se
generic map(
S => S,
D => 1)
port map (
txioclk => io_clk_i,
txserdesstrobe => serdes_strobe_i,
gclk => sys_clk_i,
reset => rst,
datain => l2p_valid_t,
dataout => l2p_valid_v);
-- Serialize two times the same value
l2p_valid_t <= l2p_valid_i & l2p_valid_i;
-- Type conversion, std_logic_vector to std_logic
l2p_valid_o <= l2p_valid_v(0);
end rtl;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: P2L 32-bit datapath decoder (p2l_decode32.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 1.0
--
-- description: PCIe to local bus packet decoder - For 32-bit data path design.
--
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: 27-09-2010 (mcattin) Rewrite a part of the decoder logic
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity p2l_decode32 is
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- Input from the deserializer
des_p2l_valid_i : in std_logic;
des_p2l_dframe_i : in std_logic;
des_p2l_data_i : in std_logic_vector(31 downto 0);
---------------------------------------------------------
-- Decoder outputs
--
-- Header
p2l_hdr_start_o : out std_logic; -- Header strobe
p2l_hdr_length_o : out std_logic_vector(9 downto 0); -- Packet length in 32-bit words multiples
p2l_hdr_cid_o : out std_logic_vector(1 downto 0); -- Completion ID
p2l_hdr_last_o : out std_logic; -- Indicates Last packet in a completion
p2l_hdr_stat_o : out std_logic_vector(1 downto 0); -- Completion Status
-- "00" = Successful completion
-- "01" = Unsupported request
-- "10" = Completer abort
-- "11" = Completion time-out
-- Packet type (for routing)
p2l_target_mrd_o : out std_logic; -- Target memory read (to wbmaster32)
p2l_target_mwr_o : out std_logic; -- Target memory write (to wbmaster32)
p2l_master_cpld_o : out std_logic; -- Master completion with data (to p2l_dma_master)
p2l_master_cpln_o : out std_logic; -- Master completion without data (to p2l_dma_master)
-- Address
p2l_addr_start_o : out std_logic; -- Address strobe
p2l_addr_o : out std_logic_vector(31 downto 0); -- Target address (in byte) that will increment with data
-- increment = 4 bytes
-- Data
p2l_d_valid_o : out std_logic; -- Indicates Data is valid
p2l_d_last_o : out std_logic; -- Indicates end of the packet
p2l_d_o : out std_logic_vector(31 downto 0); -- Data
p2l_be_o : out std_logic_vector(3 downto 0) -- Byte Enable for data
);
end p2l_decode32;
architecture rtl of p2l_decode32 is
-----------------------------------------------------------------------------
-- to_mvl Function
-----------------------------------------------------------------------------
function f_to_mvl (b : in boolean) return std_logic is
begin
if (b = true) then
return('1');
else
return('0');
end if;
end f_to_mvl;
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
signal des_p2l_valid_d : std_logic;
signal des_p2l_dframe_d : std_logic;
signal p2l_packet_start : std_logic;
signal p2l_packet_start_d : std_logic;
signal p2l_packet_end : std_logic;
signal p2l_addr_cycle : std_logic;
signal p2l_data_cycle : std_logic;
signal p2l_hdr_strobe : std_logic; -- Indicates Header start cycle
signal p2l_hdr_length : std_logic_vector(9 downto 0); -- Latched LENGTH value from header
signal p2l_hdr_cid : std_logic_vector(1 downto 0); -- Completion ID
signal p2l_hdr_last : std_logic; -- Indicates Last packet in a completion
signal p2l_hdr_stat : std_logic_vector(1 downto 0); -- Completion Status
signal p2l_addr_start : std_logic;
signal p2l_addr : unsigned(31 downto 0); -- Registered and counting Address
signal p2l_d_valid : std_logic; -- Indicates Address/Data is valid
signal p2l_d_first : std_logic;
signal p2l_d_last : std_logic; -- Indicates end of the packet
signal p2l_d : std_logic_vector(31 downto 0); -- Address/Data
signal p2l_be : std_logic_vector(3 downto 0); -- Byte Enable for data
signal p2l_hdr_fbe : std_logic_vector(3 downto 0); -- First Byte Enable
signal p2l_hdr_lbe : std_logic_vector(3 downto 0); -- Last Byte Enable
signal target_mrd : std_logic;
signal target_mwr : std_logic;
signal master_cpld : std_logic;
signal master_cpln : std_logic;
begin
-----------------------------------------------------------------------------
-- 1 tick delay version of des_p2l_valid_i and des_p2l_dframe_i,
-- for start and end frame detection
-----------------------------------------------------------------------------
process (clk_i, rst_n_i)
begin
if rst_n_i = c_RST_ACTIVE then
des_p2l_dframe_d <= '0';
des_p2l_valid_d <= '0';
elsif rising_edge(clk_i) then
des_p2l_dframe_d <= des_p2l_dframe_i;
des_p2l_valid_d <= des_p2l_valid_i;
end if;
end process;
------------------------------------------------------------------------------
-- Start and end packet detection
------------------------------------------------------------------------------
p2l_packet_start <= des_p2l_dframe_i and not(des_p2l_dframe_d) and des_p2l_valid_i;
p2l_packet_end <= des_p2l_valid_d and not(des_p2l_dframe_d);
-----------------------------------------------------------------------------
-- Decode packet type
-----------------------------------------------------------------------------
p_type_decode : process (clk_i, rst_n_i)
begin
if rst_n_i = c_RST_ACTIVE then
target_mrd <= '0';
target_mwr <= '0';
master_cpld <= '0';
master_cpln <= '0';
elsif rising_edge(clk_i) then
-- New packet starts, check type for routing
if (p2l_packet_start = '1') then
-- Target read request
target_mrd <= f_to_mvl(des_p2l_data_i(27 downto 24) = "0000");
-- Target write
target_mwr <= f_to_mvl(des_p2l_data_i(27 downto 24) = "0010");
-- Master read completion with data
master_cpld <= f_to_mvl(des_p2l_data_i(27 downto 24) = "0101");
-- Master read completion without data
master_cpln <= f_to_mvl(des_p2l_data_i(27 downto 24) = "0100");
elsif (p2l_packet_end = '1') then
target_mrd <= '0';
target_mwr <= '0';
master_cpld <= '0';
master_cpln <= '0';
end if;
end if;
end process p_type_decode;
-----------------------------------------------------------------------------
-- Packet header decoding
-----------------------------------------------------------------------------
p_header_decode : process (clk_i, rst_n_i)
begin
if rst_n_i = c_RST_ACTIVE then
p2l_hdr_strobe <= '0';
p2l_hdr_length <= (others => '0');
p2l_hdr_cid <= (others => '0');
p2l_hdr_last <= '0';
p2l_hdr_stat <= (others => '0');
p2l_hdr_fbe <= (others => '0');
p2l_hdr_lbe <= (others => '0');
elsif rising_edge(clk_i) then
if (p2l_packet_start = '1') then
p2l_hdr_strobe <= '1';
p2l_hdr_length <= des_p2l_data_i(9 downto 0);
p2l_hdr_cid <= des_p2l_data_i(11 downto 10);
p2l_hdr_last <= des_p2l_data_i(15);
if (des_p2l_data_i(26) = '1') then
-- packet type = read completion
p2l_hdr_stat <= des_p2l_data_i(17 downto 16); -- Completion status
else
-- Target read or write
p2l_hdr_fbe <= des_p2l_data_i(19 downto 16); -- First Byte Enable
p2l_hdr_lbe <= des_p2l_data_i(23 downto 20); -- Last Byte Enable
end if;
else
p2l_hdr_strobe <= '0';
end if;
end if;
end process p_header_decode;
-----------------------------------------------------------------------------
-- Packet address decoding
-----------------------------------------------------------------------------
p_addr_decode : process (clk_i, rst_n_i)
begin
if rst_n_i = c_RST_ACTIVE then
p2l_addr_cycle <= '0';
p2l_addr <= (others => '0');
p2l_addr_start <= '0';
elsif rising_edge(clk_i) then
-- Indicate address cycle(s)
-- Address cycle comes just after the header.
-- Read completion packet doesn't have an address field, then addr_cycle is not asserted.
if (p2l_packet_start = '1' and des_p2l_data_i(26) = '0') then
p2l_addr_cycle <= '1';
elsif (p2l_addr_cycle = '1' and des_p2l_valid_i = '1') then
p2l_addr_cycle <= '0';
end if;
-- Generates address strobe
-- No address strobe for read completion packets
if ((target_mwr or target_mrd) = '1') then
p2l_addr_start <= p2l_addr_cycle and des_p2l_valid_i;
else
p2l_addr_start <= '0';
end if;
-- Put address on a dedicated bus
-- Bits 1-0 are coding the BAR for target read/write
-- "00" = BAR 0
-- "01" = BAR 2
-- "10" = Expansion ROM
-- "11" = Reserved
if (p2l_addr_cycle = '1' and des_p2l_valid_i = '1' and (target_mwr or target_mrd) = '1') then
-- Latch target address
p2l_addr <= unsigned(des_p2l_data_i);
elsif (p2l_d_valid = '1' and (target_mwr or target_mrd) = '1') then
-- Increment address with data (32-bit data word => increment = +4 bytes)
p2l_addr(31 downto 2) <= p2l_addr(31 downto 2) + 1;
end if;
end if;
end process p_addr_decode;
-----------------------------------------------------------------------------
-- Packet data decoding (data strobe)
-----------------------------------------------------------------------------
p_data_decode : process (clk_i, rst_n_i)
begin
if rst_n_i = c_RST_ACTIVE then
p2l_data_cycle <= '0';
p2l_d_valid <= '0';
p2l_d_last <= '0';
p2l_d <= (others => '0');
elsif rising_edge(clk_i) then
-- Indicates data cycle(s)
-- Data cycle comes after an address cycle, exept for read completion packet
-- in this case it comes just after the header.
if ((p2l_addr_cycle = '1' or (p2l_packet_start = '1' and des_p2l_data_i(26) = '1'))
and des_p2l_valid_i = '1' and des_p2l_dframe_i = '1') then
p2l_data_cycle <= '1';
elsif (des_p2l_dframe_i = '0') then
p2l_data_cycle <= '0';
end if;
-- Generates data strobe
-- For read completion, data are valid just after the header (no address)
--if (master_cpld = '1') then
-- p2l_d_valid <= des_p2l_valid_i;
--else
p2l_d_valid <= p2l_data_cycle and des_p2l_valid_i;
--end if;
-- Generates last data signal
p2l_d_last <= p2l_data_cycle and not(des_p2l_dframe_i);
-- Latch data on the bus
if(des_p2l_valid_i = '1') then
p2l_d <= des_p2l_data_i;
end if;
end if;
end process p_data_decode;
-----------------------------------------------------------------------------
-- Byte enable
-----------------------------------------------------------------------------
p_be_decode : process (clk_i, rst_n_i)
begin
if rst_n_i = c_RST_ACTIVE then
p2l_be <= (others => '0');
elsif rising_edge(clk_i) then
if (p2l_addr_start = '1') then
p2l_be <= p2l_hdr_fbe; -- First Byte Enable
elsif ((p2l_data_cycle and not(des_p2l_dframe_i)) = '1') then
p2l_be <= p2l_hdr_lbe; -- Last Byte Enable
elsif(p2l_data_cycle = '1') then
p2l_be <= (others => '1'); -- Intermediate Byte Enables
end if;
end if;
end process p_be_decode;
-----------------------------------------------------------------------------
-- Assigns signals to output ports
-----------------------------------------------------------------------------
p2l_hdr_start_o <= p2l_hdr_strobe;
p2l_hdr_length_o <= p2l_hdr_length;
p2l_hdr_cid_o <= p2l_hdr_cid;
p2l_hdr_last_o <= p2l_hdr_last;
p2l_hdr_stat_o <= p2l_hdr_stat;
p2l_addr_start_o <= p2l_addr_start;
p2l_addr_o <= std_logic_vector(p2l_addr);
p2l_d_valid_o <= p2l_d_valid;
p2l_d_last_o <= p2l_d_last;
p2l_d_o <= p2l_d;
p2l_be_o <= p2l_be;
p2l_target_mrd_o <= target_mrd;
p2l_target_mwr_o <= target_mwr;
p2l_master_cpld_o <= master_cpld;
p2l_master_cpln_o <= master_cpln;
end rtl;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: P2L deserializer (p2l_des.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 1.0
--
-- description: Takes the DDR P2L bus and converts to SDR that is synchronous
-- to the core clock.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: 23-09-2010 (mcattin) Always active high reset for FFs.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity p2l_des is
generic (
g_IS_SPARTAN6 : boolean := false
);
port
(
---------------------------------------------------------
-- Reset and clock
rst_n_i : in std_logic;
clk_p_i : in std_logic;
clk_n_i : in std_logic;
---------------------------------------------------------
-- P2L clock domain (DDR)
--
-- P2L inputs
p2l_valid_i : in std_logic;
p2l_dframe_i : in std_logic;
p2l_data_i : in std_logic_vector(15 downto 0);
---------------------------------------------------------
-- Core clock domain (SDR)
--
-- Deserialized output
p2l_valid_o : out std_logic;
p2l_dframe_o : out std_logic;
p2l_data_o : out std_logic_vector(31 downto 0)
);
end p2l_des;
architecture rtl of p2l_des is
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- DDR FF reset
signal ff_rst : std_logic;
signal p2l_data_d : std_logic_vector(p2l_data_i'range);
-- SDR signals
signal p2l_valid_p : std_logic;
signal p2l_valid_n : std_logic;
signal p2l_dframe_p : std_logic;
signal p2l_dframe_n : std_logic;
signal p2l_data_p : std_logic_vector(p2l_data_i'range);
signal p2l_data_n : std_logic_vector(p2l_data_i'range);
signal p2l_data_sdr_l : std_logic_vector(p2l_data_i'range);
signal p2l_data_sdr : std_logic_vector(p2l_data_i'length*2-1 downto 0);
begin
------------------------------------------------------------------------------
-- Active high reset for DDR FF
------------------------------------------------------------------------------
gen_fifo_rst_n : if c_RST_ACTIVE = '0' generate
ff_rst <= not(rst_n_i);
end generate;
gen_fifo_rst : if c_RST_ACTIVE = '1' generate
ff_rst <= rst_n_i;
end generate;
------------------------------------------------------------------------------
-- DDR FF instanciation
------------------------------------------------------------------------------
-- Spartan3 primitives instanciation
gen_in_ddr_ff : if g_IS_SPARTAN6 = false generate
-- Data
DDRFF_D : for i in p2l_data_i'range generate
U : IFDDRRSE
port map
(
Q0 => p2l_data_n(i),
Q1 => p2l_data_p(i),
C0 => clk_n_i,
C1 => clk_p_i,
CE => '1',
D => p2l_data_i(i),
R => ff_rst,
S => '0'
);
end generate;
-- dframe
DDRFF_F : IFDDRRSE
port map
(
Q0 => p2l_dframe_n,
Q1 => p2l_dframe_p,
C0 => clk_n_i,
C1 => clk_p_i,
CE => '1',
D => p2l_dframe_i,
R => ff_rst,
S => '0'
);
-- valid
DDRFF_V : IFDDRRSE
port map
(
Q0 => p2l_valid_n,
Q1 => p2l_valid_p,
C0 => clk_n_i,
C1 => clk_p_i,
CE => '1',
D => p2l_valid_i,
R => ff_rst,
S => '0'
);
end generate gen_in_ddr_ff;
-- Spartan6 primitives instanciation
gen_in_ddr_ff_s6 : if g_IS_SPARTAN6 = true generate
end generate gen_in_ddr_ff_s6;
-----------------------------------------------------------------------------
-- Align positive edge data to negative edge clock
-----------------------------------------------------------------------------
process (clk_n_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
p2l_data_sdr_l <= (others => '0');
elsif rising_edge(clk_n_i) then
p2l_data_sdr_l <= p2l_data_p;
end if;
end process;
-- Combine 16-bit DDR data into 32-bit word
p2l_data_sdr <= p2l_data_n & p2l_data_sdr_l;
-----------------------------------------------------------------------------
-- Final positive edge clock alignment
-----------------------------------------------------------------------------
process (clk_p_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
p2l_valid_o <= '0';
p2l_dframe_o <= '0';
p2l_data_o <= (others => '0');
elsif rising_edge(clk_p_i) then
p2l_valid_o <= p2l_valid_p;
p2l_dframe_o <= p2l_dframe_p;
p2l_data_o <= p2l_data_sdr;
end if;
end process;
end rtl;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: P2L deserializer (p2l_des_s6.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 1.0
--
-- description: Takes the DDR P2L bus and converts to SDR that is synchronous
-- to the core clock. Spartan6 FPGAs version.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: 23-09-2010 (mcattin) Always active high reset for FFs.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity p2l_des is
port
(
---------------------------------------------------------
-- Reset and clock
rst_n_i : in std_logic;
sys_clk_i : in std_logic;
io_clk_i : in std_logic;
serdes_strobe_i : in std_logic;
---------------------------------------------------------
-- P2L clock domain (DDR)
--
-- P2L inputs
p2l_valid_i : in std_logic;
p2l_dframe_i : in std_logic;
p2l_data_i : in std_logic_vector(15 downto 0);
---------------------------------------------------------
-- Core clock domain (SDR)
--
-- Deserialized output
p2l_valid_o : out std_logic;
p2l_dframe_o : out std_logic;
p2l_data_o : out std_logic_vector(31 downto 0)
);
end p2l_des;
architecture rtl of p2l_des is
-----------------------------------------------------------------------------
-- Components declaration
-----------------------------------------------------------------------------
component serdes_1_to_n_data_s2_se
generic (
USE_PD : boolean := false; -- Parameter to set generation of phase detector logic
S : integer := 2; -- Parameter to set the serdes factor 1..8
D : integer := 16) ; -- Set the number of inputs and outputs
port (
use_phase_detector : in std_logic; -- Set generation of phase detector logic
datain : in std_logic_vector(D-1 downto 0); -- Input from se receiver pin
rxioclk : in std_logic; -- IO Clock network
rxserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset line
gclk : in std_logic; -- Global clock
bitslip : in std_logic; -- Bitslip control line
debug_in : in std_logic_vector(1 downto 0); -- input debug data
data_out : out std_logic_vector((D*S)-1 downto 0); -- Output data
-- Debug bus, 2D+6 = 2 lines per input (from mux and ce) + 7, leave nc if debug not required
debug : out std_logic_vector((2*D)+6 downto 0)) ;
end component serdes_1_to_n_data_s2_se;
-----------------------------------------------------------------------------
-- Comnstants declaration
-----------------------------------------------------------------------------
constant S : integer := 2; -- Set the serdes factor to 2
constant D : integer := 16; -- Set the number of inputs and outputs
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- Serdes reset
signal rst : std_logic;
-- SDR signals
signal p2l_valid_v : std_logic_vector(0 downto 0);
signal p2l_dframe_v : std_logic_vector(0 downto 0);
signal p2l_valid_t : std_logic_vector(1 downto 0);
signal p2l_dframe_t : std_logic_vector(1 downto 0);
signal p2l_data_t : std_logic_vector(p2l_data_o'range);
signal p2l_valid_t2 : std_logic;
signal p2l_dframe_t2 : std_logic;
signal p2l_data_t2 : std_logic_vector(p2l_data_o'range);
signal p2l_data_bitslip : std_logic_vector(1 downto 0);
signal p2l_data_bitslip_p : std_logic;
--signal p2l_ctrl_v : std_logic_vector(1 downto 0);
--signal p2l_ctrl_t : std_logic_vector(3 downto 0);
begin
------------------------------------------------------------------------------
-- Active high reset
------------------------------------------------------------------------------
gen_rst_n : if c_RST_ACTIVE = '0' generate
rst <= not(rst_n_i);
end generate;
gen_rst : if c_RST_ACTIVE = '1' generate
rst <= rst_n_i;
end generate;
------------------------------------------------------------------------------
-- data input bit slip
------------------------------------------------------------------------------
p_din_bitslip : process (sys_clk_i, rst_n_i)
begin
if rst_n_i = c_RST_ACTIVE then
p2l_data_bitslip <= (others => '0');
elsif rising_edge(sys_clk_i) then
p2l_data_bitslip <= p2l_data_bitslip(0) & '1';
end if;
end process p_din_bitslip;
p2l_data_bitslip_p <= p2l_data_bitslip(0) and not(p2l_data_bitslip(1));
------------------------------------------------------------------------------
-- data inputs
------------------------------------------------------------------------------
cmp_data_in : serdes_1_to_n_data_s2_se
generic map(
USE_PD => false,
S => S,
D => D)
port map (
use_phase_detector => '0', -- '1' enables the phase detector logic
datain => p2l_data_i,
rxioclk => io_clk_i,
rxserdesstrobe => serdes_strobe_i,
gclk => sys_clk_i,
bitslip => '0', --p2l_data_bitslip_p,
reset => rst,
data_out => p2l_data_t,
debug_in => "00",
debug => open);
------------------------------------------------------------------------------
-- dframe input
------------------------------------------------------------------------------
cmp_dframe_in : serdes_1_to_n_data_s2_se
generic map(
USE_PD => false,
S => S,
D => 1)
port map (
use_phase_detector => '0', -- '1' enables the phase detector logic
datain => p2l_dframe_v,
rxioclk => io_clk_i,
rxserdesstrobe => serdes_strobe_i,
gclk => sys_clk_i,
bitslip => '0',
reset => rst,
data_out => p2l_dframe_t,
debug_in => "00",
debug => open);
-- Type conversion, std_logic to std_logic_vector
p2l_dframe_v(0) <= p2l_dframe_i;
------------------------------------------------------------------------------
-- valid input
------------------------------------------------------------------------------
cmp_valid_in : serdes_1_to_n_data_s2_se
generic map(
USE_PD => false,
S => S,
D => 1)
port map (
use_phase_detector => '0', -- '1' enables the phase detector logic
datain => p2l_valid_v,
rxioclk => io_clk_i,
rxserdesstrobe => serdes_strobe_i,
gclk => sys_clk_i,
bitslip => '0',
reset => rst,
data_out => p2l_valid_t,
debug_in => "00",
debug => open);
-- Type conversion, std_logic to std_logic_vector
p2l_valid_v(0) <= p2l_valid_i;
p_in_sys_sync : process (sys_clk_i, rst_n_i)
begin
if rst_n_i = c_RST_ACTIVE then
p2l_data_o <= (others => '0');
p2l_dframe_o <= '0';
p2l_valid_o <= '0';
p2l_data_t2 <= (others => '0');
p2l_dframe_t2 <= '0';
p2l_valid_t2 <= '0';
elsif rising_edge(sys_clk_i) then
p2l_data_t2 <= p2l_data_t;
p2l_dframe_t2 <= p2l_dframe_t(0);
p2l_valid_t2 <= p2l_valid_t(0);
p2l_data_o <= p2l_data_t2;
p2l_dframe_o <= p2l_dframe_t2;
p2l_valid_o <= p2l_valid_t2;
end if;
end process p_in_sys_sync;
end rtl;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: 32 bit P2L DMA master (p2l_dma_master.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 31-08-2010
--
-- version: 0.1
--
-- description: Provides a pipelined Wishbone interface to performs DMA
-- transfers from PCI express host to local application.
-- This entity is also used to catch the next item in chained DMA.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- last changes: see svn log
--------------------------------------------------------------------------------
-- TODO: - byte enable support.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity p2l_dma_master is
generic (
-- Enable byte swap module (if false, no swap)
g_BYTE_SWAP : boolean := false
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From the DMA controller
dma_ctrl_carrier_addr_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_h_i : in std_logic_vector(31 downto 0);
dma_ctrl_host_addr_l_i : in std_logic_vector(31 downto 0);
dma_ctrl_len_i : in std_logic_vector(31 downto 0);
dma_ctrl_start_p2l_i : in std_logic;
dma_ctrl_start_next_i : in std_logic;
dma_ctrl_done_o : out std_logic;
dma_ctrl_error_o : out std_logic;
dma_ctrl_byte_swap_i : in std_logic_vector(1 downto 0);
dma_ctrl_abort_i : in std_logic;
---------------------------------------------------------
-- From P2L Decoder (receive the read completion)
--
-- Header
pd_pdm_hdr_start_i : in std_logic; -- Header strobe
pd_pdm_hdr_length_i : in std_logic_vector(9 downto 0); -- Packet length in 32-bit words multiples
pd_pdm_hdr_cid_i : in std_logic_vector(1 downto 0); -- Completion ID
pd_pdm_master_cpld_i : in std_logic; -- Master read completion with data
pd_pdm_master_cpln_i : in std_logic; -- Master read completion without data
--
-- Data
pd_pdm_data_valid_i : in std_logic; -- Indicates Data is valid
pd_pdm_data_last_i : in std_logic; -- Indicates end of the packet
pd_pdm_data_i : in std_logic_vector(31 downto 0); -- Data
pd_pdm_be_i : in std_logic_vector(3 downto 0); -- Byte Enable for data
---------------------------------------------------------
-- P2L control
p2l_rdy_o : out std_logic; -- De-asserted to pause transfer already in progress
rx_error_o : out std_logic; -- Asserted when transfer is aborted
---------------------------------------------------------
-- To the P2L Interface (send the DMA Master Read request)
pdm_arb_valid_o : out std_logic; -- Read completion signals
pdm_arb_dframe_o : out std_logic; -- Toward the arbiter
pdm_arb_data_o : out std_logic_vector(31 downto 0);
pdm_arb_req_o : out std_logic;
arb_pdm_gnt_i : in std_logic;
---------------------------------------------------------
-- DMA Interface (Pipelined Wishbone)
p2l_dma_clk_i : in std_logic; -- Bus clock
p2l_dma_adr_o : out std_logic_vector(31 downto 0); -- Adress
p2l_dma_dat_i : in std_logic_vector(31 downto 0); -- Data in
p2l_dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
p2l_dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
p2l_dma_cyc_o : out std_logic; -- Read or write cycle
p2l_dma_stb_o : out std_logic; -- Read or write strobe
p2l_dma_we_o : out std_logic; -- Write
p2l_dma_ack_i : in std_logic; -- Acknowledge
p2l_dma_stall_i : in std_logic; -- for pipelined Wishbone
l2p_dma_cyc_i : in std_logic; -- L2P dma wb cycle (for bus arbitration)
---------------------------------------------------------
-- To the DMA controller
next_item_carrier_addr_o : out std_logic_vector(31 downto 0);
next_item_host_addr_h_o : out std_logic_vector(31 downto 0);
next_item_host_addr_l_o : out std_logic_vector(31 downto 0);
next_item_len_o : out std_logic_vector(31 downto 0);
next_item_next_l_o : out std_logic_vector(31 downto 0);
next_item_next_h_o : out std_logic_vector(31 downto 0);
next_item_attrib_o : out std_logic_vector(31 downto 0);
next_item_valid_o : out std_logic
);
end p2l_dma_master;
architecture behaviour of p2l_dma_master is
-----------------------------------------------------------------------------
-- Constants declaration
-----------------------------------------------------------------------------
-- c_MAX_READ_REQ_SIZE is the maximum size (in 32-bit words) of the payload of a packet.
-- Allowed c_MAX_READ_REQ_SIZE values are: 32, 64, 128, 256, 512, 1024.
-- This constant must be set according to the GN4124 and motherboard chipset capabilities.
constant c_MAX_READ_REQ_SIZE : unsigned(10 downto 0) := to_unsigned(1024, 11);
constant c_TO_WB_FIFO_FULL_THRES : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(500, 9));
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- control signals
signal is_next_item : std_logic;
signal completion_error : std_logic;
signal dma_busy_error : std_logic;
signal dma_length_error : std_logic;
signal dma_ctrl_done_t : std_logic;
signal rx_error_t : std_logic;
-- L2P packet generator
signal l2p_address_h : std_logic_vector(31 downto 0);
signal l2p_address_l : std_logic_vector(31 downto 0);
signal l2p_len_cnt : unsigned(29 downto 0);
signal l2p_len_header : unsigned(9 downto 0);
signal l2p_64b_address : std_logic;
signal s_l2p_header : std_logic_vector(31 downto 0);
signal l2p_last_packet : std_logic;
-- Target address counter
signal target_addr_cnt : unsigned(29 downto 0);
-- sync fifo
signal fifo_rst : std_logic;
signal to_wb_fifo_empty : std_logic;
signal to_wb_fifo_full : std_logic;
signal to_wb_fifo_rd : std_logic;
signal to_wb_fifo_wr : std_logic;
signal to_wb_fifo_din : std_logic_vector(63 downto 0);
signal to_wb_fifo_dout : std_logic_vector(63 downto 0);
signal to_wb_fifo_valid : std_logic;
signal to_wb_fifo_byte_swap : std_logic_vector(1 downto 0);
-- wishbone
signal wb_write_cnt : unsigned(31 downto 0);
signal wb_ack_cnt : unsigned(31 downto 0);
signal p2l_dma_cyc_t : std_logic;
signal p2l_dma_stb_t : std_logic;
-- P2L DMA read request FSM
type p2l_dma_state_type is (P2L_IDLE, P2L_HEADER, P2L_ADDR_H, P2L_ADDR_L, P2L_WAIT_READ_COMPLETION);
signal p2l_dma_current_state : p2l_dma_state_type;
signal p2l_data_cnt : unsigned(10 downto 0);
begin
------------------------------------------------------------------------------
-- Active high reset for fifo
------------------------------------------------------------------------------
-- Creates an active high reset for fifos regardless of c_RST_ACTIVE value
gen_fifo_rst_n : if c_RST_ACTIVE = '0' generate
fifo_rst <= not(rst_n_i);
end generate;
gen_fifo_rst : if c_RST_ACTIVE = '1' generate
fifo_rst <= rst_n_i;
end generate;
-- Errors to DMA controller
dma_ctrl_error_o <= dma_busy_error or completion_error;
------------------------------------------------------------------------------
-- PCIe read request
------------------------------------------------------------------------------
-- Stores infofmation for read request packet
-- Can be a P2L DMA transfer or catching the next item of a chained DMA
p_read_req : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
l2p_address_h <= (others => '0');
l2p_address_l <= (others => '0');
l2p_len_cnt <= (others => '0');
l2p_len_header <= (others => '0');
l2p_64b_address <= '0';
is_next_item <= '0';
l2p_last_packet <= '0';
elsif rising_edge(clk_i) then
if (p2l_dma_current_state = P2L_IDLE) then
if (dma_ctrl_start_p2l_i = '1' or dma_ctrl_start_next_i = '1') then
-- Stores DMA info locally
l2p_address_h <= dma_ctrl_host_addr_h_i;
l2p_address_l <= dma_ctrl_host_addr_l_i;
l2p_len_cnt <= unsigned(dma_ctrl_len_i(31 downto 2)); -- dma_ctrl_len_i is in byte
if (dma_ctrl_start_next_i = '1') then
-- Catching next DMA item
is_next_item <= '1'; -- flag for data retrieve block
else
-- P2L DMA transfer
is_next_item <= '0';
end if;
if (dma_ctrl_host_addr_h_i = X"00000000") then
l2p_64b_address <= '0';
else
l2p_64b_address <= '1';
end if;
end if;
elsif (p2l_dma_current_state = P2L_HEADER) then
-- if DMA length is bigger than the max PCIe payload size,
-- we have to generate several read request
if (l2p_len_cnt > c_MAX_READ_REQ_SIZE) then
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_MAX_READ_REQ_SIZE(9 downto 0);
l2p_last_packet <= '0';
elsif (l2p_len_cnt = c_MAX_READ_REQ_SIZE) then
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_MAX_READ_REQ_SIZE(9 downto 0);
l2p_last_packet <= '1';
else
l2p_len_header <= l2p_len_cnt(9 downto 0);
l2p_last_packet <= '1';
end if;
elsif (p2l_dma_current_state = P2L_ADDR_L) then
-- Subtract the number of word requested to generate a new read request if needed
if (l2p_last_packet = '0') then
l2p_len_cnt <= l2p_len_cnt - c_MAX_READ_REQ_SIZE;
else
l2p_len_cnt <= (others => '0');
end if;
end if;
end if;
end process p_read_req;
s_l2p_header <= "000" --> Traffic Class
& '0' --> Snoop
& "000" & l2p_64b_address --> Packet type = read request (32 or 64 bits)
& "1111" --> LBE (Last Byte Enable)
& "1111" --> FBE (First Byte Enable)
& "000" --> Reserved
& '0' --> VC (Virtual Channel)
& "01" --> CID
& std_logic_vector(l2p_len_header); --> Length (in 32-bit words)
-- 0x000 => 1024 words (4096 bytes)
-----------------------------------------------------------------------------
-- PCIe read request FSM
-----------------------------------------------------------------------------
p_read_req_fsm : process (clk_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
p2l_dma_current_state <= P2L_IDLE;
pdm_arb_req_o <= '0';
pdm_arb_data_o <= (others => '0');
pdm_arb_valid_o <= '0';
pdm_arb_dframe_o <= '0';
dma_ctrl_done_t <= '0';
next_item_valid_o <= '0';
completion_error <= '0';
rx_error_t <= '0';
elsif rising_edge(clk_i) then
case p2l_dma_current_state is
when P2L_IDLE =>
-- Clear status bits
dma_ctrl_done_t <= '0';
next_item_valid_o <= '0';
completion_error <= '0';
rx_error_t <= '0';
-- Start a read request when a P2L DMA is initated or when the DMA
-- controller asks for the next DMA info (in a chained DMA).
if (dma_ctrl_start_p2l_i = '1' or dma_ctrl_start_next_i = '1') then
-- request access to PCIe bus
pdm_arb_req_o <= '1';
-- prepare a packet, first the header
p2l_dma_current_state <= P2L_HEADER;
end if;
when P2L_HEADER =>
if(arb_pdm_gnt_i = '1') then
-- clear access request to the arbiter
-- access is granted until dframe is cleared
pdm_arb_req_o <= '0';
-- send header
pdm_arb_data_o <= s_l2p_header;
pdm_arb_valid_o <= '1';
pdm_arb_dframe_o <= '1';
if(l2p_64b_address = '1') then
-- if host address is 64-bit, we have to send an additionnal
-- 32-word containing highest bits of the host address
p2l_dma_current_state <= P2L_ADDR_H;
else
-- for 32-bit host address, we only have to send lowest bits
p2l_dma_current_state <= P2L_ADDR_L;
end if;
end if;
when P2L_ADDR_H =>
-- send host address 32 highest bits
pdm_arb_data_o <= l2p_address_h;
p2l_dma_current_state <= P2L_ADDR_L;
when P2L_ADDR_L =>
-- send host address 32 lowest bits
pdm_arb_data_o <= l2p_address_l;
-- clear dframe signal to indicate the end of packet
pdm_arb_dframe_o <= '0';
p2l_dma_current_state <= P2L_WAIT_READ_COMPLETION;
when P2L_WAIT_READ_COMPLETION =>
-- End of the read request packet
pdm_arb_valid_o <= '0';
if (dma_ctrl_abort_i = '1') then
rx_error_t <= '1';
p2l_dma_current_state <= P2L_IDLE;
elsif (pd_pdm_master_cpld_i = '1' and pd_pdm_data_last_i = '1'
and p2l_data_cnt <= 1) then
-- last word of read completion has been received
if (l2p_last_packet = '0') then
-- A new read request is needed, DMA size > max payload
p2l_dma_current_state <= P2L_HEADER;
-- As the end of packet is used to delimit arbitration phases
-- we have to ask again for permission
pdm_arb_req_o <= '1';
else
-- indicate end of DMA transfer
if (is_next_item = '1') then
next_item_valid_o <= '1';
else
dma_ctrl_done_t <= '1';
end if;
p2l_dma_current_state <= P2L_IDLE;
end if;
elsif (pd_pdm_master_cpln_i = '1') then
-- should not return a read completion without data
completion_error <= '1';
p2l_dma_current_state <= P2L_IDLE;
end if;
when others =>
p2l_dma_current_state <= P2L_IDLE;
pdm_arb_req_o <= '0';
pdm_arb_data_o <= (others => '0');
pdm_arb_valid_o <= '0';
pdm_arb_dframe_o <= '0';
dma_ctrl_done_t <= '0';
next_item_valid_o <= '0';
completion_error <= '0';
rx_error_t <= '0';
end case;
end if;
end process p_read_req_fsm;
------------------------------------------------------------------------------
-- Pipeline control signals
------------------------------------------------------------------------------
p_ctrl_pipe : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
rx_error_o <= '0';
dma_ctrl_done_o <= '0';
elsif rising_edge(clk_i) then
rx_error_o <= rx_error_t;
dma_ctrl_done_o <= dma_ctrl_done_t;
end if;
end process p_ctrl_pipe;
------------------------------------------------------------------------------
-- Received data counter
------------------------------------------------------------------------------
p_recv_data_cnt : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
p2l_data_cnt <= (others => '0');
elsif rising_edge(clk_i) then
if (p2l_dma_current_state = P2L_ADDR_L) then
-- Store number of 32-bit data words to be received for the current read request
if l2p_len_header = 0 then
p2l_data_cnt <= to_unsigned(1024, p2l_data_cnt'length);
else
p2l_data_cnt <= '0' & l2p_len_header;
end if;
elsif (p2l_dma_current_state = P2L_WAIT_READ_COMPLETION
and pd_pdm_data_valid_i = '1') then
-- decrement number of data to be received
p2l_data_cnt <= p2l_data_cnt - 1;
end if;
end if;
end process p_recv_data_cnt;
------------------------------------------------------------------------------
-- Next DMA item retrieve
------------------------------------------------------------------------------
p_next_item : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
next_item_carrier_addr_o <= (others => '0');
next_item_host_addr_h_o <= (others => '0');
next_item_host_addr_l_o <= (others => '0');
next_item_len_o <= (others => '0');
next_item_next_l_o <= (others => '0');
next_item_next_h_o <= (others => '0');
next_item_attrib_o <= (others => '0');
elsif rising_edge(clk_i) then
if (p2l_dma_current_state = P2L_WAIT_READ_COMPLETION
and is_next_item = '1' and pd_pdm_data_valid_i = '1') then
-- next item data are supposed to be received in the rigth order !!
case p2l_data_cnt(2 downto 0) is
when "111" =>
next_item_carrier_addr_o <= pd_pdm_data_i;
when "110" =>
next_item_host_addr_l_o <= pd_pdm_data_i;
when "101" =>
next_item_host_addr_h_o <= pd_pdm_data_i;
when "100" =>
next_item_len_o <= pd_pdm_data_i;
when "011" =>
next_item_next_l_o <= pd_pdm_data_i;
when "010" =>
next_item_next_h_o <= pd_pdm_data_i;
when "001" =>
next_item_attrib_o <= pd_pdm_data_i;
when others =>
null;
end case;
end if;
end if;
end process p_next_item;
------------------------------------------------------------------------------
-- Target address counter
------------------------------------------------------------------------------
p_addr_cnt : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
target_addr_cnt <= (others => '0');
dma_busy_error <= '0';
to_wb_fifo_din <= (others => '0');
to_wb_fifo_wr <= '0';
to_wb_fifo_byte_swap <= (others => '0');
elsif rising_edge(clk_i) then
if (dma_ctrl_start_p2l_i = '1') then
if (p2l_dma_current_state = P2L_IDLE) then
-- dma_ctrl_target_addr_i is a byte address and target_addr_cnt is a
-- 32-bit word address
target_addr_cnt <= unsigned(dma_ctrl_carrier_addr_i(31 downto 2));
-- stores byte swap info for the current DMA transfer
to_wb_fifo_byte_swap <= dma_ctrl_byte_swap_i;
else
dma_busy_error <= '1';
end if;
elsif (p2l_dma_current_state = P2L_WAIT_READ_COMPLETION
and is_next_item = '0' and pd_pdm_data_valid_i = '1') then
-- increment target address counter
target_addr_cnt <= target_addr_cnt + 1;
-- write target address and data to the sync fifo
to_wb_fifo_wr <= '1';
to_wb_fifo_din(31 downto 0) <= f_byte_swap(g_BYTE_SWAP, pd_pdm_data_i, to_wb_fifo_byte_swap);
to_wb_fifo_din(61 downto 32) <= std_logic_vector(target_addr_cnt);
else
dma_busy_error <= '0';
to_wb_fifo_wr <= '0';
end if;
end if;
end process p_addr_cnt;
------------------------------------------------------------------------------
-- FIFOs for transition between GN4124 core and wishbone clock domain
------------------------------------------------------------------------------
cmp_to_wb_fifo : fifo_64x512
port map (
rst => fifo_rst,
wr_clk => clk_i,
rd_clk => p2l_dma_clk_i,
din => to_wb_fifo_din,
wr_en => to_wb_fifo_wr,
rd_en => to_wb_fifo_rd,
prog_full_thresh_assert => c_TO_WB_FIFO_FULL_THRES,
prog_full_thresh_negate => c_TO_WB_FIFO_FULL_THRES,
dout => to_wb_fifo_dout,
full => open,
empty => to_wb_fifo_empty,
valid => to_wb_fifo_valid,
prog_full => to_wb_fifo_full);
-- pause transfer from GN4124 if fifo is (almost) full
p2l_rdy_o <= not(to_wb_fifo_full);
------------------------------------------------------------------------------
-- Wishbone master (write only)
------------------------------------------------------------------------------
-- fifo read
to_wb_fifo_rd <= not(to_wb_fifo_empty)
and not(p2l_dma_stall_i)
and not(l2p_dma_cyc_i);
-- write only
p2l_dma_we_o <= '1';
-- Wishbone master process
p_wb_master : process (rst_n_i, p2l_dma_clk_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
p2l_dma_cyc_t <= '0';
p2l_dma_stb_t <= '0';
p2l_dma_sel_o <= "0000";
p2l_dma_adr_o <= (others => '0');
p2l_dma_dat_o <= (others => '0');
elsif rising_edge(p2l_dma_clk_i) then
-- data and address
if (to_wb_fifo_valid = '1') then
p2l_dma_adr_o <= "00" & to_wb_fifo_dout(61 downto 32);
p2l_dma_dat_o <= to_wb_fifo_dout(31 downto 0);
end if;
-- stb and sel signals management
if (to_wb_fifo_valid = '1') then --or (p2l_dma_stall_i = '1' and p2l_dma_stb_t = '1') then
p2l_dma_stb_t <= '1';
p2l_dma_sel_o <= (others => '1');
else
p2l_dma_stb_t <= '0';
p2l_dma_sel_o <= (others => '0');
end if;
-- cyc signal management
if (to_wb_fifo_valid = '1') then
p2l_dma_cyc_t <= '1';
elsif (wb_ack_cnt = wb_write_cnt-1 and p2l_dma_ack_i = '1') then
-- last ack received -> end of the transaction
p2l_dma_cyc_t <= '0';
end if;
end if;
end process p_wb_master;
-- for read back
p2l_dma_cyc_o <= p2l_dma_cyc_t;
p2l_dma_stb_o <= p2l_dma_stb_t;
-- Wishbone write cycle counter
p_wb_write_cnt : process (p2l_dma_clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
wb_write_cnt <= (others => '0');
elsif rising_edge(p2l_dma_clk_i) then
if (to_wb_fifo_valid = '1') then
wb_write_cnt <= wb_write_cnt + 1;
end if;
end if;
end process p_wb_write_cnt;
-- Wishbone ack counter
p_wb_ack_cnt : process (p2l_dma_clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
wb_ack_cnt <= (others => '0');
elsif rising_edge(p2l_dma_clk_i) then
if (p2l_dma_ack_i = '1' and p2l_dma_cyc_t = '1') then
wb_ack_cnt <= wb_ack_cnt + 1;
end if;
end if;
end process p_wb_ack_cnt;
end behaviour;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: serdes_1_to_n_clk_ddr_s2_diff.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: 1-bit generic 1:n DDR clock receiver module for serdes factors from 2 to 8 with differential inputs
-- Instantiates necessary BUFIO2 clock buffers
--
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity serdes_1_to_n_clk_ddr_s2_diff is
generic (
S : integer := 2; -- Parameter to set the serdes factor 1..8
DIFF_TERM : boolean := false) ; -- Enable or disable internal differential termination
port (
clkin_p : in std_logic; -- Input from LVDS receiver pin
clkin_n : in std_logic; -- Input from LVDS receiver pin
rxioclkp : out std_logic; -- IO Clock network
rxioclkn : out std_logic; -- IO Clock network
rx_serdesstrobe : out std_logic; -- Parallel data capture strobe
rx_bufg_x1 : out std_logic) ; -- Global clock
end serdes_1_to_n_clk_ddr_s2_diff;
architecture arch_serdes_1_to_n_clk_ddr_s2_diff of serdes_1_to_n_clk_ddr_s2_diff is
signal ddly_m : std_logic; -- Master output from IODELAY1
signal ddly_s : std_logic; -- Slave output from IODELAY1
signal rx_clk_in : std_logic; --
signal iob_data_in_p : std_logic; --
signal iob_data_in_n : std_logic; --
signal rx_clk_in_p : std_logic; --
signal rx_clk_in_n : std_logic; --
signal rx_bufio2_x1 : std_logic; --
constant RX_SWAP_CLK : std_logic := '0'; -- pinswap mask for input clock (0 = no swap (default), 1 = swap). Allows input to be connected the wrong way round to ease PCB routing.
begin
iob_clk_in : IBUFDS_DIFF_OUT generic map(
DIFF_TERM => DIFF_TERM)
port map (
I => clkin_p,
IB => clkin_n,
O => rx_clk_in_p,
OB => rx_clk_in_n) ;
iob_data_in_p <= rx_clk_in_p xor RX_SWAP_CLK; -- Invert clock as required
iob_data_in_n <= rx_clk_in_n xor RX_SWAP_CLK; -- Invert clock as required
iodelay_m : IODELAY2 generic map(
DATA_RATE => "SDR", -- <SDR>, DDR
SIM_TAPDELAY_VALUE => 49, -- nominal tap delay (sim parameter only)
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL", -- "NORMAL", "PCI"
SERDES_MODE => "MASTER", -- <NONE>, MASTER, SLAVE
IDELAY_TYPE => "FIXED", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "STAY_AT_LIMIT", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN") -- "IO", "IDATAIN", "ODATAIN"
port map (
IDATAIN => iob_data_in_p, -- data from master IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_m, -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => '0', -- High speed clock for calibration
IOCLK1 => '0', -- High speed clock for calibration
CLK => '0', -- Fabric clock (GCLK) for control signals
CAL => '0', -- Calibrate enable signal
INC => '0', -- Increment counter
CE => '0', -- Clock Enable
RST => '0', -- Reset delay line to 1/2 max in this case
BUSY => open) ; -- output signal indicating sync circuit has finished / calibration has finished
iodelay_s : IODELAY2 generic map(
DATA_RATE => "SDR", -- <SDR>, DDR
SIM_TAPDELAY_VALUE => 49, -- nominal tap delay (sim parameter only)
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL", -- "NORMAL", "PCI"
SERDES_MODE => "SLAVE", -- <NONE>, MASTER, SLAVE
IDELAY_TYPE => "FIXED", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "STAY_AT_LIMIT", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN") -- "IO", "IDATAIN", "ODATAIN"
port map (
IDATAIN => iob_data_in_n, -- data from slave IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_s, -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => '0', -- High speed clock for calibration
IOCLK1 => '0', -- High speed clock for calibration
CLK => '0', -- Fabric clock (GCLK) for control signals
CAL => '0', -- Calibrate control signal, never needed as the slave supplies the clock input to the PLL
INC => '0', -- Increment counter
CE => '0', -- Clock Enable
RST => '0', -- Reset delay line
BUSY => open) ; -- output signal indicating sync circuit has finished / calibration has finished
bufg_pll_x1 : BUFG port map (I => rx_bufio2_x1, O => rx_bufg_x1);
bufio2_2clk_inst : BUFIO2_2CLK generic map(
DIVIDE => S) -- The DIVCLK divider divide-by value; default 1
port map (
I => ddly_m, -- Input source clock 0 degrees
IB => ddly_s, -- Input source clock 0 degrees
IOCLK => rxioclkp, -- Output Clock for IO
DIVCLK => rx_bufio2_x1, -- Output Divided Clock
SERDESSTROBE => rx_serdesstrobe) ; -- Output SERDES strobe (Clock Enable)
bufio2_inst : BUFIO2 generic map(
I_INVERT => false, --
DIVIDE_BYPASS => false, --
USE_DOUBLER => false) --
port map (
I => ddly_s, -- N_clk input from IDELAY
IOCLK => rxioclkn, -- Output Clock
DIVCLK => open, -- Output Divided Clock
SERDESSTROBE => open) ; -- Output SERDES strobe (Clock Enable)
end arch_serdes_1_to_n_clk_ddr_s2_diff;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: serdes_1_to_n_clk_pll_s2_diff.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: 1-bit generic 1:n clock receiver modulefor serdes factors
-- from 2 to 8
-- Instantiates necessary clock buffers and PLL
-- Contains state machine to calibrate clock input delay line,
-- and perform bitslip if required.
-- Takes in 1 bit of differential data and deserialises this to
-- n bits for where this data is required
-- data is received LSB first
-- 0, 1, 2 ......
--
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity serdes_1_to_n_clk_pll_s2_diff is
generic (
PLLD : integer := 1; -- Parameter to set division for PLL
PLLX : integer := 2; -- Parameter to set multiplier for PLL (7 for video links, 2 for DDR etc)
CLKIN_PERIOD : real := 5.000; -- clock period (ns) of input clock on clkin_p
S : integer := 2; -- Parameter to set the serdes factor 1..8
BS : boolean := false; -- Parameter to enable bitslip TRUE or FALSE
DIFF_TERM : boolean := false) ; -- Enable or disable internal differential termination
port (
clkin_p : in std_logic; -- Input from LVDS receiver pin
clkin_n : in std_logic; -- Input from LVDS receiver pin
reset : in std_logic; -- Reset line
pattern1 : in std_logic_vector(S-1 downto 0); -- Data to define pattern that bitslip should search for
pattern2 : in std_logic_vector(S-1 downto 0); -- Data to define alternate pattern that bitslip should search for
rxioclk : out std_logic; -- IO Clock network
rx_serdesstrobe : out std_logic; -- Parallel data capture strobe
rx_bufg_pll_x1 : out std_logic; -- Global clock
rx_pll_lckd : out std_logic; -- PLL locked - only used if a 2nd BUFPLL is required
rx_pllout_xs : out std_logic; -- Multiplied PLL clock - only used if a 2nd BUFPLL is required
bitslip : out std_logic; -- Bitslip control line
datain : out std_logic_vector(S-1 downto 0); -- Output data
rx_bufpll_lckd : out std_logic); -- BUFPLL locked
end serdes_1_to_n_clk_pll_s2_diff;
architecture arch_serdes_1_to_n_clk_pll_s2_diff of serdes_1_to_n_clk_pll_s2_diff is
signal P_clk : std_logic; -- P clock out to BUFIO2
signal buf_pll_fb_clk : std_logic; -- PLL feedback clock into BUFIOFB
signal ddly_m : std_logic; -- Master output from IODELAY1
signal ddly_s : std_logic; -- Slave output from IODELAY1
signal mdataout : std_logic_vector(7 downto 0); --
signal cascade : std_logic; --
signal pd_edge : std_logic; --
signal busys : std_logic; --
signal busym : std_logic; --
signal rx_clk_in : std_logic; --
signal feedback : std_logic; --
signal buf_P_clk : std_logic; --
signal iob_data_in : std_logic; --
signal rx_bufg_pll_x1_int : std_logic;
signal rxioclk_int : std_logic;
signal rx_serdesstrobe_int : std_logic;
signal rx_pllout_xs_int : std_logic;
signal rx_pllout_x1 : std_logic;
signal rx_pll_lckd_int : std_logic;
signal state : integer range 0 to 9;
signal bslip : std_logic;
signal count : std_logic_vector(2 downto 0);
signal busyd : std_logic;
signal counter : std_logic_vector(11 downto 0);
signal clk_iserdes_data : std_logic_vector(S-1 downto 0);
signal cal_clk : std_logic;
signal rst_clk : std_logic;
signal rx_bufplllckd : std_logic;
signal not_rx_bufpll_lckd : std_logic;
signal busy_clk : std_logic;
signal enable : std_logic;
constant RX_SWAP_CLK : std_logic := '0'; -- pinswap mask for input clock (0 = no swap (default), 1 = swap). Allows input to be connected the wrong way round to ease PCB routing.
begin
rx_bufg_pll_x1 <= rx_bufg_pll_x1_int;
rxioclk <= rxioclk_int;
rx_serdesstrobe <= rx_serdesstrobe_int;
rx_pllout_xs <= rx_pllout_xs_int;
rx_pll_lckd <= rx_pll_lckd_int;
bitslip <= bslip;
iob_clk_in : IBUFDS generic map(
DIFF_TERM => DIFF_TERM)
port map (
I => clkin_p,
IB => clkin_n,
O => rx_clk_in);
iob_data_in <= rx_clk_in xor RX_SWAP_CLK; -- Invert clock as required
busy_clk <= busym;
datain <= clk_iserdes_data;
-- Bitslip and CAL state machine
process (rx_bufg_pll_x1_int, not_rx_bufpll_lckd)
begin
if not_rx_bufpll_lckd = '1' then
state <= 0;
enable <= '0';
cal_clk <= '0';
rst_clk <= '0';
bslip <= '0';
busyd <= '1';
counter <= "000000000000";
elsif rx_bufg_pll_x1_int'event and rx_bufg_pll_x1_int = '1' then
busyd <= busy_clk;
if counter(5) = '1' then
enable <= '1';
end if;
if counter(11) = '1' then
state <= 0;
cal_clk <= '0';
rst_clk <= '0';
bslip <= '0';
busyd <= '1';
counter <= "000000000000";
else
counter <= counter + 1;
if state = 0 and enable = '1' and busyd = '0' then
state <= 1;
elsif state = 1 then -- cal high
cal_clk <= '1'; state <= 2;
elsif state = 2 and busyd = '1' then -- wait for busy high
cal_clk <= '0'; state <= 3; -- cal low
elsif state = 3 and busyd = '0' then -- wait for busy low
rst_clk <= '1'; state <= 4; -- rst high
elsif state = 4 then -- rst low
rst_clk <= '0'; state <= 5;
elsif state = 5 and busyd = '0' then -- wait for busy low
state <= 6;
count <= "000";
elsif state = 6 then -- hang around
count <= count + 1;
if count = "111" then
state <= 7;
end if;
elsif state = 7 then
if BS = true and clk_iserdes_data /= pattern1 and clk_iserdes_data /= pattern2 then
bslip <= '1'; -- bitslip needed
state <= 8;
count <= "000";
else
state <= 9;
end if;
elsif state = 8 then
bslip <= '0'; -- bitslip low
count <= count + 1;
if count = "111" then
state <= 7;
end if;
elsif state = 9 then -- repeat after a delay
state <= 9;
end if;
end if;
end if;
end process;
loop0 : for i in 0 to (S - 1) generate -- Limit the output data bus to the most significant 'S' number of bits
clk_iserdes_data(i) <= mdataout(8+i-S);
end generate;
iodelay_m : IODELAY2 generic map(
DATA_RATE => "SDR", -- <SDR>, DDR
SIM_TAPDELAY_VALUE => 50, -- nominal tap delay (sim parameter only)
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL", -- "NORMAL", "PCI"
SERDES_MODE => "MASTER", -- <NONE>, MASTER, SLAVE
IDELAY_TYPE => "VARIABLE_FROM_HALF_MAX", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "STAY_AT_LIMIT", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN") -- "IO", "IDATAIN", "ODATAIN"
port map (
IDATAIN => iob_data_in, -- data from master IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_m, -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => rxioclk_int, -- High speed clock for calibration
IOCLK1 => '0', -- High speed clock for calibration
CLK => rx_bufg_pll_x1_int, -- Fabric clock (GCLK) for control signals
CAL => cal_clk, -- Calibrate enable signal
INC => '0', -- Increment counter
CE => '0', -- Clock Enable
RST => rst_clk, -- Reset delay line to 1/2 max in this case
BUSY => busym) ; -- output signal indicating sync circuit has finished / calibration has finished
iodelay_s : IODELAY2 generic map(
DATA_RATE => "SDR", -- <SDR>, DDR
SIM_TAPDELAY_VALUE => 50, -- nominal tap delay (sim parameter only)
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL", -- "NORMAL", "PCI"
SERDES_MODE => "SLAVE", -- <NONE>, MASTER, SLAVE
IDELAY_TYPE => "FIXED", -- <DEFAULT>, FIXED, VARIABLE
COUNTER_WRAPAROUND => "STAY_AT_LIMIT", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN") -- "IO", "IDATAIN", "ODATAIN"
port map (
IDATAIN => iob_data_in, -- data from slave IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_s, -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => '0', -- High speed clock for calibration
IOCLK1 => '0', -- High speed clock for calibration
CLK => '0', -- Fabric clock (GCLK) for control signals
CAL => '0', -- Calibrate control signal, never needed as the slave supplies the clock input to the PLL
INC => '0', -- Increment counter
CE => '0', -- Clock Enable
RST => '0', -- Reset delay line
BUSY => open) ; -- output signal indicating sync circuit has finished / calibration has finished
P_clk_bufio2_inst : BUFIO2 generic map(
DIVIDE => 1, -- The DIVCLK divider divide-by value; default 1
DIVIDE_BYPASS => true) -- DIVCLK output sourced from Divider (FALSE) or from I input, by-passing Divider (TRUE); default TRUE
port map (
I => P_clk, -- P_clk input from IDELAY
IOCLK => open, -- Output Clock
DIVCLK => buf_P_clk, -- Output Divided Clock
SERDESSTROBE => open) ; -- Output SERDES strobe (Clock Enable)
P_clk_bufio2fb_inst : BUFIO2FB generic map(
DIVIDE_BYPASS => true) -- DIVCLK output sourced from Divider (FALSE) or from I input, by-passing Divider (TRUE); default TRUE
port map (
I => feedback, -- PLL generated Clock
O => buf_pll_fb_clk) ; -- PLL Output Feedback Clock
iserdes_m : ISERDES2 generic map(
DATA_WIDTH => S, -- SERDES word width. This should match the setting in BUFPLL
DATA_RATE => "SDR", -- <SDR>, DDR
BITSLIP_ENABLE => true, -- <FALSE>, TRUE
SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
INTERFACE_TYPE => "RETIMED") -- NETWORKING, NETWORKING_PIPELINED, <RETIMED>
port map (
D => ddly_m,
CE0 => '1',
CLK0 => rxioclk_int,
CLK1 => '0',
IOCE => rx_serdesstrobe_int,
RST => reset,
CLKDIV => rx_bufg_pll_x1_int,
SHIFTIN => pd_edge,
BITSLIP => bslip,
FABRICOUT => open,
DFB => open,
CFB0 => open,
CFB1 => open,
Q4 => mdataout(7),
Q3 => mdataout(6),
Q2 => mdataout(5),
Q1 => mdataout(4),
VALID => open,
INCDEC => open,
SHIFTOUT => cascade);
iserdes_s : ISERDES2 generic map(
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE => "SDR", -- <SDR>, DDR
BITSLIP_ENABLE => true, -- <FALSE>, TRUE
SERDES_MODE => "SLAVE", -- <DEFAULT>, MASTER, SLAVE
INTERFACE_TYPE => "RETIMED") -- NETWORKING, NETWORKING_PIPELINED, <RETIMED>
port map (
D => ddly_s,
CE0 => '1',
CLK0 => rxioclk_int,
CLK1 => '0',
IOCE => rx_serdesstrobe_int,
RST => reset,
CLKDIV => rx_bufg_pll_x1_int,
SHIFTIN => cascade,
BITSLIP => bslip,
FABRICOUT => open,
DFB => P_clk,
CFB0 => feedback,
CFB1 => open,
Q4 => mdataout(3),
Q3 => mdataout(2),
Q2 => mdataout(1),
Q1 => mdataout(0),
VALID => open,
INCDEC => open,
SHIFTOUT => pd_edge);
rx_pll_adv_inst : PLL_ADV generic map(
BANDWIDTH => "OPTIMIZED", -- "high", "low" or "optimized"
CLKFBOUT_MULT => PLLX, -- multiplication factor for all output clocks
CLKFBOUT_PHASE => 0.0, -- phase shift (degrees) of all output clocks
CLKIN1_PERIOD => CLKIN_PERIOD, -- clock period (ns) of input clock on clkin1
CLKIN2_PERIOD => CLKIN_PERIOD, -- clock period (ns) of input clock on clkin2
CLKOUT0_DIVIDE => 1, -- division factor for clkout0 (1 to 128)
CLKOUT0_DUTY_CYCLE => 0.5, -- duty cycle for clkout0 (0.01 to 0.99)
CLKOUT0_PHASE => 0.0, -- phase shift (degrees) for clkout0 (0.0 to 360.0)
CLKOUT1_DIVIDE => 1, -- division factor for clkout1 (1 to 128)
CLKOUT1_DUTY_CYCLE => 0.5, -- duty cycle for clkout1 (0.01 to 0.99)
CLKOUT1_PHASE => 0.0, -- phase shift (degrees) for clkout1 (0.0 to 360.0)
CLKOUT2_DIVIDE => S, -- division factor for clkout2 (1 to 128)
CLKOUT2_DUTY_CYCLE => 0.5, -- duty cycle for clkout2 (0.01 to 0.99)
CLKOUT2_PHASE => 90.0, -- phase shift (degrees) for clkout2 (0.0 to 360.0)
CLKOUT3_DIVIDE => 7, -- division factor for clkout3 (1 to 128)
CLKOUT3_DUTY_CYCLE => 0.5, -- duty cycle for clkout3 (0.01 to 0.99)
CLKOUT3_PHASE => 0.0, -- phase shift (degrees) for clkout3 (0.0 to 360.0)
CLKOUT4_DIVIDE => 7, -- division factor for clkout4 (1 to 128)
CLKOUT4_DUTY_CYCLE => 0.5, -- duty cycle for clkout4 (0.01 to 0.99)
CLKOUT4_PHASE => 0.0, -- phase shift (degrees) for clkout4 (0.0 to 360.0)
CLKOUT5_DIVIDE => 7, -- division factor for clkout5 (1 to 128)
CLKOUT5_DUTY_CYCLE => 0.5, -- duty cycle for clkout5 (0.01 to 0.99)
CLKOUT5_PHASE => 0.0, -- phase shift (degrees) for clkout5 (0.0 to 360.0)
-- COMPENSATION => "SOURCE_SYNCHRONOUS", -- "SYSTEM_SYNCHRONOUS", "SOURCE_SYNCHRONOUS", "INTERNAL", "EXTERNAL", "DCM2PLL", "PLL2DCM"
DIVCLK_DIVIDE => PLLD, -- division factor for all clocks (1 to 52)
CLK_FEEDBACK => "CLKOUT0",
REF_JITTER => 0.100) -- input reference jitter (0.000 to 0.999 ui%)
port map (
CLKFBDCM => open, -- output feedback signal used when pll feeds a dcm
CLKFBOUT => open, -- general output feedback signal
CLKOUT0 => rx_pllout_xs_int, -- x7 clock for transmitter
CLKOUT1 => open,
CLKOUT2 => rx_pllout_x1, -- x1 clock for BUFG
CLKOUT3 => open, -- one of six general clock output signals
CLKOUT4 => open, -- one of six general clock output signals
CLKOUT5 => open, -- one of six general clock output signals
CLKOUTDCM0 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM1 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM2 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM3 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM4 => open, -- one of six clock outputs to connect to the dcm
CLKOUTDCM5 => open, -- one of six clock outputs to connect to the dcm
DO => open, -- dynamic reconfig data output (16-bits)
DRDY => open, -- dynamic reconfig ready output
LOCKED => rx_pll_lckd_int, -- active high pll lock signal
CLKFBIN => buf_pll_fb_clk, -- clock feedback input
CLKIN1 => buf_P_clk, -- primary clock input
CLKIN2 => '0', -- secondary clock input
CLKINSEL => '1', -- selects '1' = clkin1, '0' = clkin2
DADDR => "00000", -- dynamic reconfig address input (5-bits)
DCLK => '0', -- dynamic reconfig clock input
DEN => '0', -- dynamic reconfig enable input
DI => "0000000000000000", -- dynamic reconfig data input (16-bits)
DWE => '0', -- dynamic reconfig write enable input
RST => reset, -- asynchronous pll reset
REL => '0') ; -- used to force the state of the PFD outputs (test only)
bufg_135 : BUFG port map (I => rx_pllout_x1, O => rx_bufg_pll_x1_int);
rx_bufpll_inst : BUFPLL generic map(
DIVIDE => S) -- PLLIN0 divide-by value to produce rx_serdesstrobe (1 to 8); default 1
port map (
PLLIN => rx_pllout_xs_int, -- PLL Clock input
GCLK => rx_bufg_pll_x1_int, -- Global Clock input
LOCKED => rx_pll_lckd_int, -- Clock0 locked input
IOCLK => rxioclk_int, -- Output PLL Clock
LOCK => rx_bufplllckd, -- BUFPLL Clock and strobe locked
serdesstrobe => rx_serdesstrobe_int) ; -- Output SERDES strobe
rx_bufpll_lckd <= rx_pll_lckd_int and rx_bufplllckd;
not_rx_bufpll_lckd <= not (rx_pll_lckd_int and rx_bufplllckd);
end arch_serdes_1_to_n_clk_pll_s2_diff;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: serdes_1_to_n_data_ddr_s2_se.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: D-bit generic 1:n data receiver module with differential inputs for DDR systems
-- Takes in 1 bit of differential data and deserialises this to n bits
-- data is received LSB first
-- Serial input words
-- Line0 : 0, ...... DS-(S+1)
-- Line1 : 1, ...... DS-(S+2)
-- Line(D-1) : . .
-- Line(D) : D-1, ...... DS
-- Parallel output word
-- DS, DS-1 ..... 1, 0
--
-- Includes state machine to control CAL and the phase detector if required
-- Note for serdes factors of 4 and less, only one input delay and serdes is needed, this
-- makes use of the phase detector impossible unless USE_PD is set TRUE.
-- Data inversion can be accomplished via the RX_SWAP_MASK parameter if required
--
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity serdes_1_to_n_data_ddr_s2_se is
generic (
USE_PD : boolean := false; -- Parameter to set generation of phase detector logic
S : integer := 8; -- Parameter to set the serdes factor 1..8
D : integer := 16) ; -- Set the number of inputs and outputs
port (
use_phase_detector : in std_logic; -- '1' enables the phase detector logic if USE_PD = TRUE
datain : in std_logic_vector(D-1 downto 0); -- Input from se receiver pin
rxioclkp : in std_logic; -- IO Clock network
rxioclkn : in std_logic; -- IO Clock network
rxserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset line
gclk : in std_logic; -- Global clock
bitslip : in std_logic; -- Bitslip control line
data_out : out std_logic_vector((D*S)-1 downto 0); -- Output data
debug_in : in std_logic_vector(1 downto 0); -- Debug Inputs, set to '0' if not required
debug : out std_logic_vector((2*D)+6 downto 0)) ; -- Debug output bus, 2D+6 = 2 lines per input (from mux and ce) + 7, leave nc if debug not required
end serdes_1_to_n_data_ddr_s2_se;
architecture arch_serdes_1_to_n_data_ddr_s2_se of serdes_1_to_n_data_ddr_s2_se is
signal ddly_m : std_logic_vector(D-1 downto 0); -- Master output from IODELAY1
signal ddly_s : std_logic_vector(D-1 downto 0); -- Slave output from IODELAY1
signal mdataout : std_logic_vector((8*D)-1 downto 0);
signal cascade : std_logic_vector(D-1 downto 0);
signal pd_edge : std_logic_vector(D-1 downto 0);
signal busys : std_logic_vector(D-1 downto 0);
signal busym : std_logic_vector(D-1 downto 0);
signal rx_data_in : std_logic_vector(D-1 downto 0);
signal rx_data_in_fix : std_logic_vector(D-1 downto 0);
signal state : integer range 0 to 8;
signal busy_data_d : std_logic;
signal busy_data : std_logic_vector(D-1 downto 0);
signal inc_data : std_logic;
signal ce_data : std_logic_vector(D-1 downto 0);
signal incdec_data_d : std_logic;
signal valid_data_d : std_logic;
signal counter : std_logic_vector(8 downto 0);
signal enable : std_logic;
signal cal_data_master : std_logic;
signal rst_data : std_logic;
signal pdcounter : std_logic_vector(4 downto 0);
signal ce_data_int : std_logic_vector(D-1 downto 0);
signal inc_data_int : std_logic;
signal incdec_data : std_logic_vector(D-1 downto 0);
signal cal_data_slave : std_logic;
signal valid_data : std_logic_vector(D-1 downto 0);
signal mux : std_logic_vector(D-1 downto 0);
signal ce_data_inta : std_logic;
signal flag : std_logic;
signal cal_data_sint : std_logic;
signal incdec_data_or : std_logic_vector(D downto 0);
signal incdec_data_im : std_logic_vector(D-1 downto 0);
signal valid_data_or : std_logic_vector(D downto 0);
signal valid_data_im : std_logic_vector(D-1 downto 0);
signal busy_data_or : std_logic_vector(D downto 0);
signal all_ce : std_logic_vector(D-1 downto 0);
constant RX_SWAP_MASK : std_logic_vector(D-1 downto 0) := (others => '0'); -- pinswap mask for input bits (0 = no swap (default), 1 = swap). Allows inputs to be connected the wrong way round to ease PCB routing.
begin
cal_data_slave <= cal_data_sint;
debug <= mux & cal_data_master & rst_data & cal_data_slave & busy_data_d & inc_data & ce_data & valid_data_d & incdec_data_d;
process (gclk, reset)
begin
if reset = '1' then
state <= 0;
cal_data_master <= '0';
cal_data_sint <= '0';
counter <= (others => '0');
enable <= '0';
counter <= (others => '0');
mux <= (0 => '1', others => '0');
elsif gclk'event and gclk = '1' then
counter <= counter + 1;
if counter(8) = '1' then
counter <= "000000000";
end if;
if counter(5) = '1' then
enable <= '1';
end if;
if state = 0 and enable = '1' then -- Wait for all IODELAYs to be available
cal_data_master <= '0';
cal_data_sint <= '0';
rst_data <= '0';
if busy_data_d = '0' then
state <= 1;
end if;
elsif state = 1 then -- Issue calibrate command to both master and slave
cal_data_master <= '1';
cal_data_sint <= '1';
if busy_data_d = '1' then -- and wait for command to be accepted
state <= 2;
end if;
elsif state = 2 then -- Now RST all master and slave IODELAYs
cal_data_master <= '0';
cal_data_sint <= '0';
if busy_data_d = '0' then
rst_data <= '1';
state <= 3;
end if;
elsif state = 3 then -- Wait for all IODELAYs to be available
rst_data <= '0';
if busy_data_d = '0' then
state <= 4;
end if;
elsif state = 4 then -- Hang around
if counter(8) = '1' then
state <= 5;
end if;
elsif state = 5 then -- Calibrate slave only
if busy_data_d = '0' then
cal_data_sint <= '1';
state <= 6;
if D /= 1 then
mux <= mux(D-2 downto 0) & mux(D-1);
end if;
end if;
elsif state = 6 then -- Wait for command to be accepted
if busy_data_d = '1' then
cal_data_sint <= '0';
state <= 7;
end if;
elsif state = 7 then -- Wait for all IODELAYs to be available, ie CAL command finished
cal_data_sint <= '0';
if busy_data_d = '0' then
state <= 4;
end if;
end if;
end if;
end process;
process (gclk, reset)
begin
if reset = '1' then
pdcounter <= "10000";
ce_data_inta <= '0';
flag <= '0';
elsif gclk'event and gclk = '1' then
busy_data_d <= busy_data_or(D);
if use_phase_detector = '1' and USE_PD = true then -- decide whther pd is used
incdec_data_d <= incdec_data_or(D);
valid_data_d <= valid_data_or(D);
if ce_data_inta = '1' then
ce_data <= mux;
else
ce_data <= (others => '0');
end if;
if state = 7 then
flag <= '0';
elsif state /= 4 or busy_data_d = '1' then -- Reset filter if state machine issues a cal command or unit is busy
pdcounter <= "10000";
ce_data_inta <= '0';
elsif pdcounter = "11111" and flag = '0' then -- Filter has reached positive max - increment the tap count
ce_data_inta <= '1';
inc_data_int <= '1';
pdcounter <= "10000";
flag <= '0';
elsif pdcounter = "00000" and flag = '0' then -- Filter has reached negative max - decrement the tap count
ce_data_inta <= '1';
inc_data_int <= '0';
pdcounter <= "10000";
flag <= '0';
elsif valid_data_d = '1' then -- increment filter
ce_data_inta <= '0';
if incdec_data_d = '1' and pdcounter /= "11111" then
pdcounter <= pdcounter + 1;
elsif incdec_data_d = '0' and pdcounter /= "00000" then -- decrement filter
pdcounter <= pdcounter - 1;
end if;
else
ce_data_inta <= '0';
end if;
else
ce_data <= all_ce;
inc_data_int <= debug_in(1);
end if;
end if;
end process;
inc_data <= inc_data_int;
incdec_data_or(0) <= '0'; -- Input Mux - Initialise generate loop OR gates
valid_data_or(0) <= '0';
busy_data_or(0) <= '0';
loop0 : for i in 0 to (D - 1) generate
incdec_data_im(i) <= incdec_data(i) and mux(i); -- Input muxes
incdec_data_or(i+1) <= incdec_data_im(i) or incdec_data_or(i); -- AND gates to allow just one signal through at a tome
valid_data_im(i) <= valid_data(i) and mux(i); -- followed by an OR
valid_data_or(i+1) <= valid_data_im(i) or valid_data_or(i); -- for the three inputs from each PD
busy_data_or(i+1) <= busy_data(i) or busy_data_or(i); -- The busy signals just need an OR gate
all_ce(i) <= debug_in(0);
rx_data_in_fix(i) <= rx_data_in(i) xor RX_SWAP_MASK(i); -- Invert signals as required
iob_clk_in : IBUF port map (
I => datain(i),
O => rx_data_in(i));
loop2 : if (USE_PD = true or S > 4) generate --Two oserdes are needed
busy_data(i) <= busys(i);
iodelay_m : IODELAY2 generic map(
DATA_RATE => "DDR", -- <SDR>, DDR
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL" , -- NORMAL, PCI
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_TYPE => "DIFF_PHASE_DETECTOR", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "WRAPAROUND", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN", -- "IO", "IDATAIN", "ODATAIN"
SERDES_MODE => "MASTER", -- <NONE>, MASTER, SLAVE
SIM_TAPDELAY_VALUE => 49) --
port map (
IDATAIN => rx_data_in_fix(i), -- data from primary IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_m(i), -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => rxioclkp, -- High speed clock for calibration
IOCLK1 => rxioclkn, -- High speed clock for calibration
CLK => gclk, -- Fabric clock (GCLK) for control signals
CAL => cal_data_master, -- Calibrate control signal
INC => inc_data, -- Increment counter
CE => ce_data(i), -- Clock Enable
RST => rst_data, -- Reset delay line
BUSY => open) ; -- output signal indicating sync circuit has finished / calibration has finished
iodelay_s : IODELAY2 generic map(
DATA_RATE => "DDR", -- <SDR>, DDR
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL" , -- NORMAL, PCI
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_TYPE => "DIFF_PHASE_DETECTOR", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "WRAPAROUND", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN", -- "IO", "IDATAIN", "ODATAIN"
SERDES_MODE => "SLAVE", -- <NONE>, MASTER, SLAVE
SIM_TAPDELAY_VALUE => 49) --
port map (
IDATAIN => rx_data_in_fix(i), -- data from primary IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_s(i), -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => rxioclkp, -- High speed clock for calibration
IOCLK1 => rxioclkn, -- High speed clock for calibration
CLK => gclk, -- Fabric clock (GCLK) for control signals
CAL => cal_data_slave, -- Calibrate control signal
INC => inc_data, -- Increment counter
CE => ce_data(i), -- Clock Enable
RST => rst_data, -- Reset delay line
BUSY => busys(i)) ; -- output signal indicating sync circuit has finished / calibration has finished
iserdes_m : ISERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE => "DDR", -- <SDR>, DDR
BITSLIP_ENABLE => true, -- <FALSE>, TRUE
SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
INTERFACE_TYPE => "RETIMED") -- NETWORKING, NETWORKING_PIPELINED, <RETIMED>
port map (
D => ddly_m(i),
CE0 => '1',
CLK0 => rxioclkp,
CLK1 => rxioclkn,
IOCE => rxserdesstrobe,
RST => reset,
CLKDIV => gclk,
SHIFTIN => pd_edge(i),
BITSLIP => bitslip,
FABRICOUT => open,
Q4 => mdataout((8*i)+7),
Q3 => mdataout((8*i)+6),
Q2 => mdataout((8*i)+5),
Q1 => mdataout((8*i)+4),
DFB => open, -- are these the same as above? These were in Johns design
CFB0 => open,
CFB1 => open,
VALID => open,
INCDEC => open,
SHIFTOUT => cascade(i));
iserdes_s : ISERDES2 generic map(
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE => "DDR", -- <SDR>, DDR
BITSLIP_ENABLE => true, -- <FALSE>, TRUE
SERDES_MODE => "SLAVE", -- <DEFAULT>, MASTER, SLAVE
INTERFACE_TYPE => "RETIMED") -- NETWORKING, NETWORKING_PIPELINED, <RETIMED>
port map (
D => ddly_s(i),
CE0 => '1',
CLK0 => rxioclkp,
CLK1 => rxioclkn,
IOCE => rxserdesstrobe,
RST => reset,
CLKDIV => gclk,
SHIFTIN => cascade(i),
BITSLIP => bitslip,
FABRICOUT => open,
Q4 => mdataout((8*i)+3),
Q3 => mdataout((8*i)+2),
Q2 => mdataout((8*i)+1),
Q1 => mdataout((8*i)+0),
DFB => open, -- are these the same as above? These were in Johns design
CFB0 => open,
CFB1 => open,
VALID => open,
INCDEC => open,
SHIFTOUT => pd_edge(i));
end generate;
loop3 : if (USE_PD /= true and S < 5) generate -- Only one oserdes is needed
busy_data(i) <= busym(i);
iodelay_m : IODELAY2 generic map(
DATA_RATE => "DDR", -- <SDR>, DDR
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL" , -- NORMAL, PCI
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_TYPE => "VARIABLE_FROM_HALF_MAX", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "WRAPAROUND", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN", -- "IO", "IDATAIN", "ODATAIN"
-- SERDES_MODE => "MASTER", -- <NONE>, MASTER, SLAVE
SIM_TAPDELAY_VALUE => 49) --
port map (
IDATAIN => rx_data_in_fix(i), -- data from primary IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_m(i), -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => rxioclkp, -- High speed clock for calibration
IOCLK1 => rxioclkn, -- High speed clock for calibration
CLK => gclk, -- Fabric clock (GCLK) for control signals
CAL => cal_data_master, -- Calibrate control signal
INC => inc_data, -- Increment counter
CE => ce_data(i), -- Clock Enable
RST => rst_data, -- Reset delay line
BUSY => busym(i)) ; -- output signal indicating sync circuit has finished / calibration has finished
iserdes_m : ISERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE => "DDR", -- <SDR>, DDR
BITSLIP_ENABLE => true, -- <FALSE>, TRUE
-- SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
INTERFACE_TYPE => "RETIMED") -- NETWORKING, NETWORKING_PIPELINED, <RETIMED>
port map (
D => ddly_m(i),
CE0 => '1',
CLK0 => rxioclkp,
CLK1 => rxioclkn,
IOCE => rxserdesstrobe,
RST => reset,
CLKDIV => gclk,
SHIFTIN => '0',
BITSLIP => bitslip,
FABRICOUT => open,
Q4 => mdataout((8*i)+7),
Q3 => mdataout((8*i)+6),
Q2 => mdataout((8*i)+5),
Q1 => mdataout((8*i)+4),
DFB => open,
CFB0 => open,
CFB1 => open,
VALID => open,
INCDEC => open,
SHIFTOUT => open);
end generate;
loop1 : for j in 7 downto (8-S) generate
data_out(((D*(j+S-8))+i)) <= mdataout((8*i)+j);
end generate;
end generate;
end arch_serdes_1_to_n_data_ddr_s2_se;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: serdes_1_to_n_data_s2_se.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: D-bit generic 1:n data receiver module with se inputs
-- Takes in 1 bit of se data and deserialises this to n bits
-- data is received LSB first
-- Serial input words
-- Line0 : 0, ...... DS-(S+1)
-- Line1 : 1, ...... DS-(S+2)
-- Line(D-1) : . .
-- Line0(D) : D-1, ...... DS
-- Parallel output word
-- DS, DS-1 ..... 1, 0
--
-- Includes state machine to control CAL and the phase detector
-- Data inversion can be accomplished via the RX_RX_SWAP_MASK
-- parameter if required
--
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity serdes_1_to_n_data_s2_se is
generic (
USE_PD : boolean := false; -- Parameter to set generation of phase detector logic
S : integer := 2; -- Parameter to set the serdes factor 1..8
D : integer := 16) ; -- Set the number of inputs and outputs
port (
use_phase_detector : in std_logic; -- Set generation of phase detector logic
datain : in std_logic_vector(D-1 downto 0); -- Input from se receiver pin
rxioclk : in std_logic; -- IO Clock network
rxserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset line
gclk : in std_logic; -- Global clock
bitslip : in std_logic; -- Bitslip control line
debug_in : in std_logic_vector(1 downto 0); -- input debug data
data_out : out std_logic_vector((D*S)-1 downto 0); -- Output data
debug : out std_logic_vector((2*D)+6 downto 0)) ; -- Debug bus, 2D+6 = 2 lines per input (from mux and ce) + 7, leave nc if debug not required
end serdes_1_to_n_data_s2_se;
architecture arch_serdes_1_to_n_data_s2_se of serdes_1_to_n_data_s2_se is
signal ddly_m : std_logic_vector(D-1 downto 0); -- Master output from IODELAY1
signal ddly_s : std_logic_vector(D-1 downto 0); -- Slave output from IODELAY1
signal cascade : std_logic_vector(D-1 downto 0);
signal busys : std_logic_vector(D-1 downto 0);
signal rx_data_in : std_logic_vector(D-1 downto 0);
signal rx_data_in_fix : std_logic_vector(D-1 downto 0);
signal state : integer range 0 to 8;
signal busyd : std_logic_vector(D-1 downto 0);
signal cal_data_sint : std_logic;
signal ce_data_inta : std_logic;
signal busy_data : std_logic_vector(D-1 downto 0);
signal busy_data_d : std_logic;
signal counter : std_logic_vector(8 downto 0);
signal enable : std_logic;
signal pd_edge : std_logic_vector(D-1 downto 0);
signal cal_data_slave : std_logic;
signal cal_data_master : std_logic;
signal valid_data : std_logic_vector(D-1 downto 0);
signal valid_data_d : std_logic;
signal rst_data : std_logic;
signal mdataout : std_logic_vector((8*D)-1 downto 0);
signal pdcounter : std_logic_vector(4 downto 0);
signal inc_data : std_logic;
signal ce_data : std_logic_vector(D-1 downto 0);
signal inc_data_int : std_logic;
signal incdec_data : std_logic_vector(D-1 downto 0);
signal incdec_data_d : std_logic;
signal flag : std_logic;
signal mux : std_logic_vector(D-1 downto 0);
signal incdec_data_or : std_logic_vector(D downto 0);
signal valid_data_or : std_logic_vector(D downto 0);
signal busy_data_or : std_logic_vector(D downto 0);
signal incdec_data_im : std_logic_vector(D-1 downto 0);
signal valid_data_im : std_logic_vector(D-1 downto 0);
signal all_ce : std_logic_vector(D-1 downto 0);
constant RX_SWAP_MASK : std_logic_vector(D-1 downto 0) := (others => '0'); -- pinswap mask for input bits (0 = no swap (default), 1 = swap). Allows inputs to be connected the wrong way round to ease PCB routing.
begin
busy_data <= busys;
debug <= mux & cal_data_master & rst_data & cal_data_slave & busy_data_d & inc_data & ce_data & valid_data_d & incdec_data_d;
cal_data_slave <= cal_data_sint;
process (gclk, reset)
begin
if reset = '1' then
state <= 0;
cal_data_master <= '0';
cal_data_sint <= '0';
counter <= (others => '0');
enable <= '0';
counter <= (others => '0');
mux <= (0 => '1', others => '0');
elsif gclk'event and gclk = '1' then
counter <= counter + 1;
if counter(8) = '1' then
counter <= "000000000";
end if;
if counter(5) = '1' then
enable <= '1';
end if;
if state = 0 and enable = '1' then -- Wait for all IODELAYs to be available
cal_data_master <= '0';
cal_data_sint <= '0';
rst_data <= '0';
if busy_data_d = '0' then
state <= 1;
end if;
elsif state = 1 then -- Issue calibrate command to both master and slave
cal_data_master <= '1';
cal_data_sint <= '1';
if busy_data_d = '1' then -- and wait for command to be accepted
state <= 2;
end if;
elsif state = 2 then -- Now RST all master and slave IODELAYs
cal_data_master <= '0';
cal_data_sint <= '0';
if busy_data_d = '0' then
rst_data <= '1';
state <= 3;
end if;
elsif state = 3 then -- Wait for all IODELAYs to be available
rst_data <= '0';
if busy_data_d = '0' then
state <= 4;
end if;
elsif state = 4 then -- Hang around
if counter(8) = '1' then
state <= 5;
end if;
elsif state = 5 then -- Calibrate slave only
if busy_data_d = '0' then
cal_data_sint <= '1';
state <= 6;
if D /= 1 then
mux <= mux(D-2 downto 0) & mux(D-1);
end if;
end if;
elsif state = 6 then -- Wait for command to be accepted
if busy_data_d = '1' then
cal_data_sint <= '0';
state <= 7;
end if;
elsif state = 7 then -- Wait for all IODELAYs to be available, ie CAL command finished
cal_data_sint <= '0';
if busy_data_d = '0' then
state <= 4;
end if;
end if;
end if;
end process;
process (gclk, reset)
begin
if reset = '1' then
pdcounter <= "10000";
ce_data_inta <= '0';
flag <= '0';
elsif gclk'event and gclk = '1' then
busy_data_d <= busy_data_or(D);
if use_phase_detector = '1' then -- decide whther pd is used
incdec_data_d <= incdec_data_or(D);
valid_data_d <= valid_data_or(D);
if ce_data_inta = '1' then
ce_data <= mux;
else
ce_data <= (others => '0');
end if;
if state = 7 then
flag <= '0';
elsif state /= 4 or busy_data_d = '1' then -- Reset filter if state machine issues a cal command or unit is busy
pdcounter <= "10000";
ce_data_inta <= '0';
elsif pdcounter = "11111" and flag = '0' then -- Filter has reached positive max - increment the tap count
ce_data_inta <= '1';
inc_data_int <= '1';
pdcounter <= "10000";
flag <= '0';
elsif pdcounter = "00000" and flag = '0' then -- Filter has reached negative max - decrement the tap count
ce_data_inta <= '1';
inc_data_int <= '0';
pdcounter <= "10000";
flag <= '0';
elsif valid_data_d = '1' then -- increment filter
ce_data_inta <= '0';
if incdec_data_d = '1' and pdcounter /= "11111" then
pdcounter <= pdcounter + 1;
elsif incdec_data_d = '0' and pdcounter /= "00000" then -- decrement filter
pdcounter <= pdcounter - 1;
end if;
else
ce_data_inta <= '0';
end if;
else
ce_data <= all_ce;
inc_data_int <= debug_in(1);
end if;
end if;
end process;
inc_data <= inc_data_int;
incdec_data_or(0) <= '0'; -- Input Mux - Initialise generate loop OR gates
valid_data_or(0) <= '0';
busy_data_or(0) <= '0';
loop0 : for i in 0 to (D - 1) generate
incdec_data_im(i) <= incdec_data(i) and mux(i); -- Input muxes
incdec_data_or(i+1) <= incdec_data_im(i) or incdec_data_or(i); -- AND gates to allow just one signal through at a tome
valid_data_im(i) <= valid_data(i) and mux(i); -- followed by an OR
valid_data_or(i+1) <= valid_data_im(i) or valid_data_or(i); -- for the three inputs from each PD
busy_data_or(i+1) <= busy_data(i) or busy_data_or(i); -- The busy signals just need an OR gate
all_ce(i) <= debug_in(0);
rx_data_in_fix(i) <= rx_data_in(i) xor RX_SWAP_MASK(i); -- Invert signals as required
iob_clk_in : IBUF port map (
I => datain(i),
O => rx_data_in(i));
loop2 : if (USE_PD = true) generate --Two oserdes are needed
iodelay_m : IODELAY2 generic map(
DATA_RATE => "SDR", -- <SDR>, DDR
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL" , -- NORMAL, PCI
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_TYPE => "DIFF_PHASE_DETECTOR", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "WRAPAROUND", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN", -- "IO", "IDATAIN", "ODATAIN"
SERDES_MODE => "MASTER", -- <NONE>, MASTER, SLAVE
SIM_TAPDELAY_VALUE => 49) --
port map (
IDATAIN => rx_data_in_fix(i), -- data from primary IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_m(i), -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => rxioclk, -- High speed clock for calibration
IOCLK1 => '0', -- High speed clock for calibration
CLK => gclk, -- Fabric clock (GCLK) for control signals
CAL => cal_data_master, -- Calibrate control signal
INC => inc_data, -- Increment counter
CE => ce_data(i), -- Clock Enable
RST => rst_data, -- Reset delay line
BUSY => open) ; -- output signal indicating sync circuit has finished / calibration has finished
iodelay_s : IODELAY2 generic map(
DATA_RATE => "SDR", -- <SDR>, DDR
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL", -- NORMAL, PCI
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_TYPE => "DIFF_PHASE_DETECTOR", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "WRAPAROUND" , -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN" , -- "IO", "IDATAIN", "ODATAIN"
SERDES_MODE => "SLAVE", -- <NONE>, MASTER, SLAVE
SIM_TAPDELAY_VALUE => 49) --
port map (
IDATAIN => rx_data_in_fix(i), -- data from primary IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_s(i), -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => rxioclk, -- High speed clock for calibration
IOCLK1 => '0', -- High speed clock for calibration
CLK => gclk, -- Fabric clock (GCLK) for control signals
CAL => cal_data_slave, -- Calibrate control signal
INC => inc_data, -- Increment counter
CE => ce_data(i) , -- Clock Enable
RST => rst_data, -- Reset delay line
BUSY => busys(i)) ; -- output signal indicating sync circuit has finished / calibration has finished
iserdes_m : ISERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE => "SDR", -- <SDR>, DDR
BITSLIP_ENABLE => true, -- <FALSE>, TRUE
SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
INTERFACE_TYPE => "RETIMED") -- NETWORKING, NETWORKING_PIPELINED, <RETIMED>
port map (
D => ddly_m(i),
CE0 => '1',
CLK0 => rxioclk,
CLK1 => '0',
IOCE => rxserdesstrobe,
RST => reset,
CLKDIV => gclk,
SHIFTIN => pd_edge(i),
BITSLIP => bitslip,
FABRICOUT => open,
Q4 => mdataout((8*i)+7),
Q3 => mdataout((8*i)+6),
Q2 => mdataout((8*i)+5),
Q1 => mdataout((8*i)+4),
DFB => open,
CFB0 => open,
CFB1 => open,
VALID => valid_data(i),
INCDEC => incdec_data(i),
SHIFTOUT => cascade(i));
iserdes_s : ISERDES2 generic map(
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE => "SDR", -- <SDR>, DDR
BITSLIP_ENABLE => true, -- <FALSE>, TRUE
SERDES_MODE => "SLAVE", -- <DEFAULT>, MASTER, SLAVE
INTERFACE_TYPE => "RETIMED") -- NETWORKING, NETWORKING_PIPELINED, <RETIMED>
port map (
D => ddly_s(i),
CE0 => '1',
CLK0 => rxioclk,
CLK1 => '0',
IOCE => rxserdesstrobe,
RST => reset,
CLKDIV => gclk,
SHIFTIN => cascade(i),
BITSLIP => bitslip,
FABRICOUT => open,
Q4 => mdataout((8*i)+3),
Q3 => mdataout((8*i)+2),
Q2 => mdataout((8*i)+1),
Q1 => mdataout((8*i)+0),
DFB => open,
CFB0 => open,
CFB1 => open,
VALID => open,
INCDEC => open,
SHIFTOUT => pd_edge(i));
end generate;
loop3 : if (USE_PD /= true) generate -- Only one oserdes is needed
iodelay_m : IODELAY2 generic map(
DATA_RATE => "SDR", -- <SDR>, DDR
IDELAY_VALUE => 0, -- {0 ... 255}
IDELAY2_VALUE => 0, -- {0 ... 255}
IDELAY_MODE => "NORMAL" , -- NORMAL, PCI
ODELAY_VALUE => 0, -- {0 ... 255}
IDELAY_TYPE => "VARIABLE_FROM_HALF_MAX", -- "DEFAULT", "DIFF_PHASE_DETECTOR", "FIXED", "VARIABLE_FROM_HALF_MAX", "VARIABLE_FROM_ZERO"
COUNTER_WRAPAROUND => "WRAPAROUND", -- <STAY_AT_LIMIT>, WRAPAROUND
DELAY_SRC => "IDATAIN", -- "IO", "IDATAIN", "ODATAIN"
-- SERDES_MODE => "MASTER", -- <NONE>, MASTER, SLAVE
SIM_TAPDELAY_VALUE => 49) --
port map (
IDATAIN => rx_data_in_fix(i), -- data from primary IOB
TOUT => open, -- tri-state signal to IOB
DOUT => open, -- output data to IOB
T => '1', -- tri-state control from OLOGIC/OSERDES2
ODATAIN => '0', -- data from OLOGIC/OSERDES2
DATAOUT => ddly_m(i), -- Output data 1 to ILOGIC/ISERDES2
DATAOUT2 => open, -- Output data 2 to ILOGIC/ISERDES2
IOCLK0 => rxioclk, -- High speed clock for calibration
IOCLK1 => '0', -- High speed clock for calibration
CLK => gclk, -- Fabric clock (GCLK) for control signals
CAL => cal_data_master, -- Calibrate control signal
INC => inc_data, -- Increment counter
CE => ce_data(i), -- Clock Enable
RST => rst_data, -- Reset delay line
BUSY => open) ; -- output signal indicating sync circuit has finished / calibration has finished
iserdes_m : ISERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE => "SDR", -- <SDR>, DDR
BITSLIP_ENABLE => true, -- <FALSE>, TRUE
-- SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
INTERFACE_TYPE => "RETIMED") -- NETWORKING, NETWORKING_PIPELINED, <RETIMED>
port map (
D => rx_data_in_fix(i),--ddly_m(i),
CE0 => '1',
CLK0 => rxioclk,
CLK1 => '0',
IOCE => rxserdesstrobe,
RST => reset,
CLKDIV => gclk,
SHIFTIN => '0',
BITSLIP => bitslip,
FABRICOUT => open,
Q4 => mdataout((8*i)+7),
Q3 => mdataout((8*i)+6),
Q2 => mdataout((8*i)+5),
Q1 => mdataout((8*i)+4),
DFB => open,
CFB0 => open,
CFB1 => open,
VALID => open,
INCDEC => open,
SHIFTOUT => open);
end generate;
loop1 : for j in 7 downto (8-S) generate
data_out(((D*(j+S-8))+i)) <= mdataout((8*i)+j);
end generate;
end generate;
end arch_serdes_1_to_n_data_s2_se;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: serdes_n_to_1_ddr_s2_diff.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: D-bit generic DDR n:1 transmitter module
-- Takes in n bits of data and serialises this to 1 bit
-- data is transmitted LSB first
-- Parallel input word
-- DS, DS-1 ..... 1, 0
-- Serial output words
-- Line0 : 0, ...... DS-(S+1)
-- Line1 : 1, ...... DS-(S+2)
-- Line(D-1) : . .
-- Line0(D) : D-1, ...... DS
-- Data inversion can be accomplished via the TX_SWAP_MASK parameter if required
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity serdes_n_to_1_ddr_s2_diff is
generic (
S : integer := 8; -- Parameter to set the serdes factor 1..8
D : integer := 16) ; -- Set the number of inputs and outputs
port (
txioclkp : in std_logic; -- IO Clock network
txioclkn : in std_logic; -- IO Clock network
txserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset
gclk : in std_logic; -- Global clock
datain : in std_logic_vector((D*S)-1 downto 0); -- Data for output
dataout_p : out std_logic_vector(D-1 downto 0); -- output
dataout_n : out std_logic_vector(D-1 downto 0)) ; -- output
end serdes_n_to_1_ddr_s2_diff;
architecture arch_serdes_n_to_1_ddr_s2_diff of serdes_n_to_1_ddr_s2_diff is
signal cascade_di : std_logic_vector(D-1 downto 0);
signal cascade_do : std_logic_vector(D-1 downto 0);
signal cascade_ti : std_logic_vector(D-1 downto 0);
signal cascade_to : std_logic_vector(D-1 downto 0);
signal mdataina : std_logic_vector(D*8 downto 0);
signal mdatainb : std_logic_vector(D*4 downto 0);
signal tx_data_out : std_logic_vector(D downto 0);
constant TX_SWAP_MASK : std_logic_vector(D-1 downto 0) := (others => '0'); -- pinswap mask for input bits (0 = no swap (default), 1 = swap). Allows inputs to be connected the wrong way round to ease PCB routing.
begin
loop0 : for i in 0 to (D - 1) generate
io_clk_out : obufds port map (
O => dataout_p(i),
OB => dataout_n(i),
I => tx_data_out(i));
loop1 : if (S > 4) generate -- Two oserdes are needed
loop2 : for j in 0 to (S - 1) generate
-- re-arrange data bits for transmission and invert lines as given by the mask
-- NOTE If pin inversion is required (non-zero SWAP MASK) then inverters will occur in fabric, as there are no inverters in the ISERDES2
-- This can be avoided by doing the inversion (if necessary) in the user logic
mdataina((8*i)+j) <= datain((i)+(D*j)) xor TX_SWAP_MASK(i);
end generate;
oserdes_m : OSERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "DDR", -- <SDR>, DDR
DATA_RATE_OT => "DDR", -- <SDR>, DDR
SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => tx_data_out(i),
OCE => '1',
CLK0 => txioclkp,
CLK1 => txioclkn,
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdataina((8*i)+7),
D3 => mdataina((8*i)+6),
D2 => mdataina((8*i)+5),
D1 => mdataina((8*i)+4),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => '1', -- Dummy input in Master
SHIFTIN2 => '1', -- Dummy input in Master
SHIFTIN3 => cascade_do(i), -- Cascade output D data from slave
SHIFTIN4 => cascade_to(i), -- Cascade output T data from slave
SHIFTOUT1 => cascade_di(i), -- Cascade input D data to slave
SHIFTOUT2 => cascade_ti(i), -- Cascade input T data to slave
SHIFTOUT3 => open, -- Dummy output in Master
SHIFTOUT4 => open) ; -- Dummy output in Master
oserdes_s : OSERDES2 generic map(
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "DDR", -- <SDR>, DDR
DATA_RATE_OT => "DDR", -- <SDR>, DDR
SERDES_MODE => "SLAVE", -- <DEFAULT>, MASTER, SLAVE
OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => open,
OCE => '1',
CLK0 => txioclkp,
CLK1 => txioclkn,
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdataina((8*i)+3),
D3 => mdataina((8*i)+2),
D2 => mdataina((8*i)+1),
D1 => mdataina((8*i)+0),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => cascade_di(i), -- Cascade input D from Master
SHIFTIN2 => cascade_ti(i), -- Cascade input T from Master
SHIFTIN3 => '1', -- Dummy input in Slave
SHIFTIN4 => '1', -- Dummy input in Slave
SHIFTOUT1 => open, -- Dummy output in Slave
SHIFTOUT2 => open, -- Dummy output in Slave
SHIFTOUT3 => cascade_do(i), -- Cascade output D data to Master
SHIFTOUT4 => cascade_to(i)) ; -- Cascade output T data to Master
end generate;
loop3 : if (S < 5) generate -- Only one oserdes needed
loop4 : for j in 0 to (S - 1) generate
-- re-arrange data bits for transmission and invert lines as given by the mask
-- NOTE If pin inversion is required (non-zero SWAP MASK) then inverters will occur in fabric, as there are no inverters in the ISERDES2
-- This can be avoided by doing the inversion (if necessary) in the user logic
mdatainb((4*i)+j) <= datain((i)+(D*j)) xor TX_SWAP_MASK(i);
end generate;
oserdes_m : OSERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "DDR", -- <SDR>, DDR
DATA_RATE_OT => "DDR") -- <SDR>, DDR
-- SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
-- OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => tx_data_out(i),
OCE => '1',
CLK0 => txioclkp,
CLK1 => txioclkn,
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdatainb((4*i)+3),
D3 => mdatainb((4*i)+2),
D2 => mdatainb((4*i)+1),
D1 => mdatainb((4*i)+0),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => '1', -- No cascades needed
SHIFTIN2 => '1', -- No cascades needed
SHIFTIN3 => '1', -- No cascades needed
SHIFTIN4 => '1', -- No cascades needed
SHIFTOUT1 => open, -- No cascades needed
SHIFTOUT2 => open, -- No cascades needed
SHIFTOUT3 => open, -- No cascades needed
SHIFTOUT4 => open) ; -- No cascades needed
end generate;
end generate;
end arch_serdes_n_to_1_ddr_s2_diff;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: serdes_n_to_1_ddr_s2_se.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: D-bit generic DDR n:1 transmitter module
-- Takes in n bits of data and serialises this to 1 bit
-- data is transmitted LSB first. Single ended version
-- Parallel input word
-- DS, DS-1 ..... 1, 0
-- Serial output words
-- Line0 : 0, ...... DS-(S+1)
-- Line1 : 1, ...... DS-(S+2)
-- Line(D-1) : . .
-- Line0(D) : D-1, ...... DS
-- Data inversion can be accomplished via the TX_SWAP_MASK parameter if required
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity serdes_n_to_1_ddr_s2_se is
generic (
S : integer := 8; -- Parameter to set the serdes factor 1..8
D : integer := 16) ; -- Set the number of inputs and outputs
port (
txioclkp : in std_logic; -- IO Clock network
txioclkn : in std_logic; -- IO Clock network
txserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset
gclk : in std_logic; -- Global clock
datain : in std_logic_vector((D*S)-1 downto 0); -- Data for output
dataout : out std_logic_vector(D-1 downto 0)) ; -- output
end serdes_n_to_1_ddr_s2_se;
architecture arch_serdes_n_to_1_ddr_s2_se of serdes_n_to_1_ddr_s2_se is
signal cascade_di : std_logic_vector(D-1 downto 0);
signal cascade_do : std_logic_vector(D-1 downto 0);
signal cascade_ti : std_logic_vector(D-1 downto 0);
signal cascade_to : std_logic_vector(D-1 downto 0);
signal mdataina : std_logic_vector(D*8 downto 0);
signal mdatainb : std_logic_vector(D*4 downto 0);
signal tx_data_out : std_logic_vector(D downto 0);
constant TX_SWAP_MASK : std_logic_vector(D-1 downto 0) := (others => '0'); -- pinswap mask for input bits (0 = no swap (default), 1 = swap). Allows inputs to be connected the wrong way round to ease PCB routing.
begin
loop0 : for i in 0 to (D - 1) generate
io_clk_out : obuf port map (
O => dataout(i),
I => tx_data_out(i));
loop1 : if (S > 4) generate -- Two oserdes are needed
loop2 : for j in 0 to (S - 1) generate
-- re-arrange data bits for transmission and invert lines as given by the mask
-- NOTE If pin inversion is required (non-zero SWAP MASK) then inverters will occur in fabric, as there are no inverters in the ISERDES2
-- This can be avoided by doing the inversion (if necessary) in the user logic
mdataina((8*i)+j) <= datain((i)+(D*j)) xor TX_SWAP_MASK(i);
end generate;
oserdes_m : OSERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "DDR", -- <SDR>, DDR
DATA_RATE_OT => "DDR", -- <SDR>, DDR
SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => tx_data_out(i),
OCE => '1',
CLK0 => txioclkp,
CLK1 => txioclkn,
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdataina((8*i)+7),
D3 => mdataina((8*i)+6),
D2 => mdataina((8*i)+5),
D1 => mdataina((8*i)+4),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => '1', -- Dummy input in Master
SHIFTIN2 => '1', -- Dummy input in Master
SHIFTIN3 => cascade_do(i), -- Cascade output D data from slave
SHIFTIN4 => cascade_to(i), -- Cascade output T data from slave
SHIFTOUT1 => cascade_di(i), -- Cascade input D data to slave
SHIFTOUT2 => cascade_ti(i), -- Cascade input T data to slave
SHIFTOUT3 => open, -- Dummy output in Master
SHIFTOUT4 => open) ; -- Dummy output in Master
oserdes_s : OSERDES2 generic map(
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "DDR", -- <SDR>, DDR
DATA_RATE_OT => "DDR", -- <SDR>, DDR
SERDES_MODE => "SLAVE", -- <DEFAULT>, MASTER, SLAVE
OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => open,
OCE => '1',
CLK0 => txioclkp,
CLK1 => txioclkn,
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdataina((8*i)+3),
D3 => mdataina((8*i)+2),
D2 => mdataina((8*i)+1),
D1 => mdataina((8*i)+0),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => cascade_di(i), -- Cascade input D from Master
SHIFTIN2 => cascade_ti(i), -- Cascade input T from Master
SHIFTIN3 => '1', -- Dummy input in Slave
SHIFTIN4 => '1', -- Dummy input in Slave
SHIFTOUT1 => open, -- Dummy output in Slave
SHIFTOUT2 => open, -- Dummy output in Slave
SHIFTOUT3 => cascade_do(i), -- Cascade output D data to Master
SHIFTOUT4 => cascade_to(i)) ; -- Cascade output T data to Master
end generate;
loop3 : if (S < 5) generate -- Only one oserdes needed
loop4 : for j in 0 to (S - 1) generate
-- re-arrange data bits for transmission and invert lines as given by the mask
-- NOTE If pin inversion is required (non-zero SWAP MASK) then inverters will occur in fabric, as there are no inverters in the ISERDES2
-- This can be avoided by doing the inversion (if necessary) in the user logic
mdatainb((4*i)+j) <= datain((i)+(D*j)) xor TX_SWAP_MASK(i);
end generate;
oserdes_m : OSERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "DDR", -- <SDR>, DDR
DATA_RATE_OT => "DDR") -- <SDR>, DDR
-- SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
-- OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => tx_data_out(i),
OCE => '1',
CLK0 => txioclkp,
CLK1 => txioclkn,
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdatainb((4*i)+3),
D3 => mdatainb((4*i)+2),
D2 => mdatainb((4*i)+1),
D1 => mdatainb((4*i)+0),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => '1', -- No cascades needed
SHIFTIN2 => '1', -- No cascades needed
SHIFTIN3 => '1', -- No cascades needed
SHIFTIN4 => '1', -- No cascades needed
SHIFTOUT1 => open, -- No cascades needed
SHIFTOUT2 => open, -- No cascades needed
SHIFTOUT3 => open, -- No cascades needed
SHIFTOUT4 => open) ; -- No cascades needed
end generate;
end generate;
end arch_serdes_n_to_1_ddr_s2_se;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: serdes_n_to_1_s2_diff.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: D-bit generic n:1 transmitter module
-- Takes in n bits of data and serialises this to 1 bit
-- data is transmitted LSB first
-- Parallel input word
-- DS, DS-1 ..... 1, 0
-- Serial output words
-- Line0 : 0, ...... DS-(S+1)
-- Line1 : 1, ...... DS-(S+2)
-- Line(D-1) : . .
-- Line0(D) : D-1, ...... DS
-- Data inversion can be accomplished via the TX_SWAP_MASK
-- parameter if required
--
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity serdes_n_to_1_s2_diff is
generic (
S : integer := 2; -- Parameter to set the serdes factor 1..8
D : integer := 16) ; -- Set the number of inputs and outputs
port (
txioclk : in std_logic; -- IO Clock network
txserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset
gclk : in std_logic; -- Global clock
datain : in std_logic_vector((D*S)-1 downto 0); -- Data for output
dataout_p : out std_logic_vector(D-1 downto 0); -- output
dataout_n : out std_logic_vector(D-1 downto 0)) ; -- output
end serdes_n_to_1_s2_diff;
architecture arch_serdes_n_to_1_s2_diff of serdes_n_to_1_s2_diff is
signal cascade_di : std_logic_vector(D-1 downto 0);
signal cascade_do : std_logic_vector(D-1 downto 0);
signal cascade_ti : std_logic_vector(D-1 downto 0);
signal cascade_to : std_logic_vector(D-1 downto 0);
signal mdataina : std_logic_vector(D*8 downto 0);
signal mdatainb : std_logic_vector(D*4 downto 0);
signal tx_data_out : std_logic_vector(D-1 downto 0);
constant TX_SWAP_MASK : std_logic_vector(D-1 downto 0) := (others => '0'); -- pinswap mask for input bits (0 = no swap (default), 1 = swap). Allows inputs to be connected the wrong way round to ease PCB routing.
begin
loop0 : for i in 0 to (D - 1) generate
io_clk_out : obufds port map (
O => dataout_p(i),
OB => dataout_n(i),
I => tx_data_out(i));
loop1 : if (S > 4) generate -- Two oserdes are needed
loop2 : for j in 0 to (S - 1) generate
-- re-arrange data bits for transmission and invert lines as given by the mask
-- NOTE If pin inversion is required (non-zero SWAP MASK) then inverters will occur in fabric, as there are no inverters in the ISERDES2
-- This can be avoided by doing the inversion (if necessary) in the user logic
mdataina((8*i)+j) <= datain((i)+(D*j)) xor TX_SWAP_MASK(i);
end generate;
oserdes_m : OSERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "SDR", -- <SDR>, DDR
DATA_RATE_OT => "SDR", -- <SDR>, DDR
SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => tx_data_out(i),
OCE => '1',
CLK0 => txioclk,
CLK1 => '0',
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdataina((8*i)+7),
D3 => mdataina((8*i)+6),
D2 => mdataina((8*i)+5),
D1 => mdataina((8*i)+4),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => '1', -- Dummy input in Master
SHIFTIN2 => '1', -- Dummy input in Master
SHIFTIN3 => cascade_do(i), -- Cascade output D data from slave
SHIFTIN4 => cascade_to(i), -- Cascade output T data from slave
SHIFTOUT1 => cascade_di(i), -- Cascade input D data to slave
SHIFTOUT2 => cascade_ti(i), -- Cascade input T data to slave
SHIFTOUT3 => open, -- Dummy output in Master
SHIFTOUT4 => open) ; -- Dummy output in Master
oserdes_s : OSERDES2 generic map(
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "SDR", -- <SDR>, DDR
DATA_RATE_OT => "SDR", -- <SDR>, DDR
SERDES_MODE => "SLAVE", -- <DEFAULT>, MASTER, SLAVE
OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => open,
OCE => '1',
CLK0 => txioclk,
CLK1 => '0',
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdataina((8*i)+3),
D3 => mdataina((8*i)+2),
D2 => mdataina((8*i)+1),
D1 => mdataina((8*i)+0),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => cascade_di(i), -- Cascade input D from Master
SHIFTIN2 => cascade_ti(i), -- Cascade input T from Master
SHIFTIN3 => '1', -- Dummy input in Slave
SHIFTIN4 => '1', -- Dummy input in Slave
SHIFTOUT1 => open, -- Dummy output in Slave
SHIFTOUT2 => open, -- Dummy output in Slave
SHIFTOUT3 => cascade_do(i), -- Cascade output D data to Master
SHIFTOUT4 => cascade_to(i)) ; -- Cascade output T data to Master
end generate;
loop3 : if (S < 5) generate -- Only one oserdes needed
loop4 : for j in 0 to (S - 1) generate
-- re-arrange data bits for transmission and invert lines as given by the mask
-- NOTE If pin inversion is required (non-zero SWAP MASK) then inverters will occur in fabric, as there are no inverters in the ISERDES2
-- This can be avoided by doing the inversion (if necessary) in the user logic
mdatainb((4*i)+j) <= datain((i)+(D*j)) xor TX_SWAP_MASK(i);
end generate;
oserdes_m : OSERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "SDR", -- <SDR>, DDR
DATA_RATE_OT => "SDR") -- <SDR>, DDR
-- SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
-- OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => tx_data_out(i),
OCE => '1',
CLK0 => txioclk,
CLK1 => '0',
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdatainb((4*i)+3),
D3 => mdatainb((4*i)+2),
D2 => mdatainb((4*i)+1),
D1 => mdatainb((4*i)+0),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => '1', -- No cascades needed
SHIFTIN2 => '1', -- No cascades needed
SHIFTIN3 => '1', -- No cascades needed
SHIFTIN4 => '1', -- No cascades needed
SHIFTOUT1 => open, -- No cascades needed
SHIFTOUT2 => open, -- No cascades needed
SHIFTOUT3 => open, -- No cascades needed
SHIFTOUT4 => open) ; -- No cascades needed
end generate;
end generate;
end arch_serdes_n_to_1_s2_diff;
------------------------------------------------------------------------------
-- Copyright (c) 2009 Xilinx, Inc.
-- This design is confidential and proprietary of Xilinx, All Rights Reserved.
------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Version: 1.0
-- \ \ Filename: serdes_n_to_1_s2_se.vhd
-- / / Date Last Modified: November 5 2009
-- /___/ /\ Date Created: August 1 2008
-- \ \ / \
-- \___\/\___\
--
--Device: Spartan 6
--Purpose: D-bit generic n:1 transmitter module
-- Takes in n bits of data and serialises this to 1 bit
-- data is transmitted LSB first
-- Parallel input word
-- DS, DS-1 ..... 1, 0
-- Serial output words
-- Line0 : 0, ...... DS-(S+1)
-- Line1 : 1, ...... DS-(S+2)
-- Line(D-1) : . .
-- Line0(D) : D-1, ...... DS
-- Data inversion can be accomplished via the TX_SWAP_MASK
-- parameter if required
--
--Reference:
--
--Revision History:
-- Rev 1.0 - First created (nicks)
------------------------------------------------------------------------------
--
-- Disclaimer:
--
-- This disclaimer is not a license and does not grant any rights to the materials
-- distributed herewith. Except as otherwise provided in a valid license issued to you
-- by Xilinx, and to the maximum extent permitted by applicable law:
-- (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL FAULTS,
-- AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY,
-- INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, OR
-- FITNESS FOR ANY PARTICULAR PURPOSE; and (2) Xilinx shall not be liable (whether in contract
-- or tort, including negligence, or under any other theory of liability) for any loss or damage
-- of any kind or nature related to, arising under or in connection with these materials,
-- including for any direct, or any indirect, special, incidental, or consequential loss
-- or damage (including loss of data, profits, goodwill, or any type of loss or damage suffered
-- as a result of any action brought by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the possibility of the same.
--
-- Critical Applications:
--
-- Xilinx products are not designed or intended to be fail-safe, or for use in any application
-- requiring fail-safe performance, such as life-support or safety devices or systems,
-- Class III medical devices, nuclear facilities, applications related to the deployment of airbags,
-- or any other applications that could lead to death, personal injury, or severe property or
-- environmental damage (individually and collectively, "Critical Applications"). Customer assumes
-- the sole risk and liability of any use of Xilinx products in Critical Applications, subject only
-- to applicable laws and regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
library unisim;
use unisim.vcomponents.all;
entity serdes_n_to_1_s2_se is
generic (
S : integer := 2; -- Parameter to set the serdes factor 1..8
D : integer := 16) ; -- Set the number of inputs and outputs
port (
txioclk : in std_logic; -- IO Clock network
txserdesstrobe : in std_logic; -- Parallel data capture strobe
reset : in std_logic; -- Reset
gclk : in std_logic; -- Global clock
datain : in std_logic_vector((D*S)-1 downto 0); -- Data for output
dataout : out std_logic_vector(D-1 downto 0)) ; -- output
end serdes_n_to_1_s2_se;
architecture arch_serdes_n_to_1_s2_se of serdes_n_to_1_s2_se is
signal cascade_di : std_logic_vector(D-1 downto 0);
signal cascade_do : std_logic_vector(D-1 downto 0);
signal cascade_ti : std_logic_vector(D-1 downto 0);
signal cascade_to : std_logic_vector(D-1 downto 0);
signal mdataina : std_logic_vector(D*8 downto 0);
signal mdatainb : std_logic_vector(D*4 downto 0);
signal tx_data_out : std_logic_vector(D-1 downto 0);
constant TX_SWAP_MASK : std_logic_vector(D-1 downto 0) := (others => '0'); -- pinswap mask for input bits (0 = no swap (default), 1 = swap). Allows inputs to be connected the wrong way round to ease PCB routing.
begin
loop0 : for i in 0 to (D - 1) generate
io_clk_out : obuf port map (
O => dataout(i),
I => tx_data_out(i));
loop1 : if (S > 4) generate -- Two oserdes are needed
loop2 : for j in 0 to (S - 1) generate
-- re-arrange data bits for transmission and invert lines as given by the mask
-- NOTE If pin inversion is required (non-zero SWAP MASK) then inverters will occur in fabric, as there are no inverters in the ISERDES2
-- This can be avoided by doing the inversion (if necessary) in the user logic
mdataina((8*i)+j) <= datain((i)+(D*j)) xor TX_SWAP_MASK(i);
end generate;
oserdes_m : OSERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "SDR", -- <SDR>, DDR
DATA_RATE_OT => "SDR", -- <SDR>, DDR
SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => tx_data_out(i),
OCE => '1',
CLK0 => txioclk,
CLK1 => '0',
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdataina((8*i)+7),
D3 => mdataina((8*i)+6),
D2 => mdataina((8*i)+5),
D1 => mdataina((8*i)+4),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => '1', -- Dummy input in Master
SHIFTIN2 => '1', -- Dummy input in Master
SHIFTIN3 => cascade_do(i), -- Cascade output D data from slave
SHIFTIN4 => cascade_to(i), -- Cascade output T data from slave
SHIFTOUT1 => cascade_di(i), -- Cascade input D data to slave
SHIFTOUT2 => cascade_ti(i), -- Cascade input T data to slave
SHIFTOUT3 => open, -- Dummy output in Master
SHIFTOUT4 => open) ; -- Dummy output in Master
oserdes_s : OSERDES2 generic map(
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "SDR", -- <SDR>, DDR
DATA_RATE_OT => "SDR", -- <SDR>, DDR
SERDES_MODE => "SLAVE", -- <DEFAULT>, MASTER, SLAVE
OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => open,
OCE => '1',
CLK0 => txioclk,
CLK1 => '0',
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdataina((8*i)+3),
D3 => mdataina((8*i)+2),
D2 => mdataina((8*i)+1),
D1 => mdataina((8*i)+0),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => cascade_di(i), -- Cascade input D from Master
SHIFTIN2 => cascade_ti(i), -- Cascade input T from Master
SHIFTIN3 => '1', -- Dummy input in Slave
SHIFTIN4 => '1', -- Dummy input in Slave
SHIFTOUT1 => open, -- Dummy output in Slave
SHIFTOUT2 => open, -- Dummy output in Slave
SHIFTOUT3 => cascade_do(i), -- Cascade output D data to Master
SHIFTOUT4 => cascade_to(i)) ; -- Cascade output T data to Master
end generate;
loop3 : if (S < 5) generate -- Only one oserdes needed
loop4 : for j in 0 to (S - 1) generate
-- re-arrange data bits for transmission and invert lines as given by the mask
-- NOTE If pin inversion is required (non-zero SWAP MASK) then inverters will occur in fabric, as there are no inverters in the ISERDES2
-- This can be avoided by doing the inversion (if necessary) in the user logic
mdatainb((4*i)+j) <= datain((i)+(D*j)) xor TX_SWAP_MASK(i);
end generate;
oserdes_m : OSERDES2 generic map (
DATA_WIDTH => S, -- SERDES word width. This should match the setting is BUFPLL
DATA_RATE_OQ => "SDR", -- <SDR>, DDR
DATA_RATE_OT => "SDR") -- <SDR>, DDR
-- SERDES_MODE => "MASTER", -- <DEFAULT>, MASTER, SLAVE
-- OUTPUT_MODE => "DIFFERENTIAL")
port map (
OQ => tx_data_out(i),
OCE => '1',
CLK0 => txioclk,
CLK1 => '0',
IOCE => txserdesstrobe,
RST => reset,
CLKDIV => gclk,
D4 => mdatainb((4*i)+3),
D3 => mdatainb((4*i)+2),
D2 => mdatainb((4*i)+1),
D1 => mdatainb((4*i)+0),
TQ => open,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TRAIN => '0',
TCE => '1',
SHIFTIN1 => '1', -- No cascades needed
SHIFTIN2 => '1', -- No cascades needed
SHIFTIN3 => '1', -- No cascades needed
SHIFTIN4 => '1', -- No cascades needed
SHIFTOUT1 => open, -- No cascades needed
SHIFTOUT2 => open, -- No cascades needed
SHIFTOUT3 => open, -- No cascades needed
SHIFTOUT4 => open) ; -- No cascades needed
end generate;
end generate;
end arch_serdes_n_to_1_s2_se;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: 32-bit Wishbone master (wbmaster32.vhd)
--
-- authors: Simon Deprez (simon.deprez@cern.ch)
-- Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 12-08-2010
--
-- version: 0.2
--
-- description: Provides a Wishbone interface for single read and write
-- control and status registers
--
-- dependencies: Xilinx FIFOs (fifo_32x512.xco, fifo_64x512.xco)
--
--------------------------------------------------------------------------------
-- last changes: 27-09-2010 (mcattin) Split wishbone and gn4124 clock domains
-- All signals crossing the clock domains are now going through fifos.
-- Dead times optimisation in packet generator.
--------------------------------------------------------------------------------
-- TODO: - byte enable support.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity wbmaster32 is
generic
(
g_BAR0_APERTURE : integer := 20; -- BAR0 aperture, defined in GN4124 PCI_BAR_CONFIG register (0x80C)
-- => number of bits to address periph on the board
g_WB_SLAVES_NB : integer := 2
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- From P2L packet decoder
--
-- Header
pd_wbm_hdr_start_i : in std_logic; -- Header strobe
pd_wbm_hdr_length_i : in std_logic_vector(9 downto 0); -- Packet length in 32-bit words multiples
pd_wbm_hdr_cid_i : in std_logic_vector(1 downto 0); -- Completion ID
pd_wbm_target_mrd_i : in std_logic; -- Target memory read
pd_wbm_target_mwr_i : in std_logic; -- Target memory write
--
-- Address
pd_wbm_addr_start_i : in std_logic; -- Address strobe
pd_wbm_addr_i : in std_logic_vector(31 downto 0); -- Target address (in byte) that will increment with data
-- increment = 4 bytes
--
-- Data
pd_wbm_data_valid_i : in std_logic; -- Indicates Data is valid
pd_wbm_data_last_i : in std_logic; -- Indicates end of the packet
pd_wbm_data_i : in std_logic_vector(31 downto 0); -- Data
pd_wbm_be_i : in std_logic_vector(3 downto 0); -- Byte Enable for data
---------------------------------------------------------
-- P2L channel control
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- Ready to accept target write
p2l_rdy_o : out std_logic; -- De-asserted to pause transfer already in progress
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- Asserted when GN4124 ready to accept read completion with data
---------------------------------------------------------
-- To the arbiter (L2P data)
wbm_arb_valid_o : out std_logic; -- Read completion signals
wbm_arb_dframe_o : out std_logic; -- Toward the arbiter
wbm_arb_data_o : out std_logic_vector(31 downto 0);
wbm_arb_req_o : out std_logic;
arb_wbm_gnt_i : in std_logic;
---------------------------------------------------------
-- CSR wishbone interface
wb_clk_i : in std_logic; -- Wishbone bus clock
wb_adr_o : out std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0); -- Address
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic; -- Strobe
wb_we_o : out std_logic; -- Write
wb_cyc_o : out std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Cycle
wb_dat_i : in std_logic_vector((32*g_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0) -- Acknowledge
);
end wbmaster32;
architecture behaviour of wbmaster32 is
-----------------------------------------------------------------------------
-- Constants declaration
-----------------------------------------------------------------------------
constant c_TO_WB_FIFO_FULL_THRES : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(500, 9));
constant c_FROM_WB_FIFO_FULL_THRES : std_logic_vector(8 downto 0) := std_logic_vector(to_unsigned(500, 9));
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- Sync fifos
signal fifo_rst : std_logic;
signal to_wb_fifo_empty : std_logic;
signal to_wb_fifo_full : std_logic;
signal to_wb_fifo_rd : std_logic;
signal to_wb_fifo_wr : std_logic;
signal to_wb_fifo_din : std_logic_vector(63 downto 0);
signal to_wb_fifo_dout : std_logic_vector(63 downto 0);
signal to_wb_fifo_rw : std_logic;
signal to_wb_fifo_data : std_logic_vector(31 downto 0);
signal to_wb_fifo_addr : std_logic_vector(30 downto 0);
signal from_wb_fifo_empty : std_logic;
signal from_wb_fifo_full : std_logic;
signal from_wb_fifo_rd : std_logic;
signal from_wb_fifo_wr : std_logic;
signal from_wb_fifo_din : std_logic_vector(31 downto 0);
signal from_wb_fifo_dout : std_logic_vector(31 downto 0);
-- Wishbone
type wishbone_state_type is (WB_IDLE, WB_READ_FIFO, WB_CYCLE, WB_WAIT_ACK);
signal wishbone_current_state : wishbone_state_type;
--signal s_wb_we : std_logic;
signal s_wb_periph_addr : std_logic_vector(log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
signal wb_periph_addr : std_logic_vector(log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
signal s_wb_periph_select : std_logic_vector((2**s_wb_periph_addr'length)-1 downto 0);
signal s_wb_ack_muxed : std_logic;
signal wb_ack_t : std_logic;
signal s_wb_dat_i_muxed : std_logic_vector(31 downto 0);
signal wb_dat_i_t : std_logic_vector(31 downto 0);
signal wb_cyc_t : std_logic;
signal s_wb_cyc_demuxed : std_logic_vector(g_WB_SLAVES_NB-1 downto 0);
signal wb_dat_o_t : std_logic_vector(31 downto 0);
signal wb_stb_t : std_logic;
signal wb_adr_t : std_logic_vector(30 downto 0);
signal wb_we_t : std_logic;
signal wb_sel_t : std_logic_vector(3 downto 0);
-- L2P packet generator
type l2p_read_cpl_state_type is (L2P_IDLE, L2P_HEADER, L2P_DATA);
signal l2p_read_cpl_current_state : l2p_read_cpl_state_type;
signal p2l_cid : std_logic_vector(1 downto 0);
signal s_l2p_header : std_logic_vector(31 downto 0);
begin
------------------------------------------------------------------------------
-- Active high reset for fifo
------------------------------------------------------------------------------
-- Creates an active high reset for fifos regardless of c_RST_ACTIVE value
gen_fifo_rst_n : if c_RST_ACTIVE = '0' generate
fifo_rst <= not(rst_n_i);
end generate;
gen_fifo_rst : if c_RST_ACTIVE = '1' generate
fifo_rst <= rst_n_i;
end generate;
------------------------------------------------------------------------------
-- Write frame from P2L decoder to fifo
------------------------------------------------------------------------------
-- ready to receive new target write if fifo not full
p_wr_rdy_o <= "00" when to_wb_fifo_full = '1' else "11";
-- pause transfer from GN4124 when fifo is full
p2l_rdy_o <= not(to_wb_fifo_full);
p_from_decoder : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
to_wb_fifo_din <= (others => '0');
to_wb_fifo_wr <= '0';
elsif rising_edge(clk_i) then
if (pd_wbm_target_mwr_i = '1' and pd_wbm_data_valid_i = '1') then
-- Target write
-- wishbone address is in 32-bit words and address from PCIe in byte
-- pd_wbm_addr_i(0) represent the BAR (0 = BAR0, 1 = BAR 2)
to_wb_fifo_din(62 downto 32) <= pd_wbm_addr_i(0) & pd_wbm_addr_i(31 downto 2);
to_wb_fifo_din(31 downto 0) <= pd_wbm_data_i;
to_wb_fifo_din(63) <= '1';
to_wb_fifo_wr <= '1';
elsif (pd_wbm_target_mrd_i = '1' and pd_wbm_addr_start_i = '1') then
-- Target read request
-- wishbone address is in 32-bit words and address from PCIe in byte
-- pd_wbm_addr_i(0) represent the BAR (0 = BAR0, 1 = BAR 2)
to_wb_fifo_din(62 downto 32) <= pd_wbm_addr_i(0) & pd_wbm_addr_i(31 downto 2);
to_wb_fifo_din(63) <= '0';
to_wb_fifo_wr <= '1';
else
to_wb_fifo_wr <= '0';
end if;
end if;
end process p_from_decoder;
------------------------------------------------------------------------------
-- Packet generator
------------------------------------------------------------------------------
-- Generates read completion with requested data
-- Single 32-bit word read only
-- Store CID for read completion packet
p_pkt_gen : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
p2l_cid <= (others => '0');
elsif rising_edge(clk_i) then
if (pd_wbm_hdr_start_i = '1') then
p2l_cid <= pd_wbm_hdr_cid_i;
end if;
end if;
end process p_pkt_gen;
--read completion header
s_l2p_header <= "000" --> Traffic Class
& '0' --> Reserved
& "0101" --> Read completion (Master read competition with data)
& "000000" --> Reserved
& "00" --> Completion Status
& '1' --> Last completion packet
& "00" --> Reserved
& '0' --> VC (Vitrual Channel)
& p2l_cid --> CID (Completion Identifer)
& "0000000001"; --> Length (Single 32-bit word read only)
------------------------------------------------------------------------------
-- L2P packet write FSM
------------------------------------------------------------------------------
process (clk_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
l2p_read_cpl_current_state <= L2P_IDLE;
wbm_arb_req_o <= '0';
wbm_arb_data_o <= (others => '0');
wbm_arb_valid_o <= '0';
wbm_arb_dframe_o <= '0';
from_wb_fifo_rd <= '0';
elsif rising_edge(clk_i) then
case l2p_read_cpl_current_state is
when L2P_IDLE =>
wbm_arb_req_o <= '0';
wbm_arb_data_o <= (others => '0');
wbm_arb_valid_o <= '0';
wbm_arb_dframe_o <= '0';
if(from_wb_fifo_empty = '0' and p_rd_d_rdy_i = "11") then
-- generate a packet when read data in fifo and GN4124 ready to receive the packet
wbm_arb_req_o <= '1';
from_wb_fifo_rd <= '1';
l2p_read_cpl_current_state <= L2P_HEADER;
end if;
when L2P_HEADER =>
from_wb_fifo_rd <= '0';
if(arb_wbm_gnt_i = '1') then
wbm_arb_req_o <= '0';
wbm_arb_data_o <= s_l2p_header;
wbm_arb_valid_o <= '1';
wbm_arb_dframe_o <= '1';
l2p_read_cpl_current_state <= L2P_DATA;
end if;
when L2P_DATA =>
l2p_read_cpl_current_state <= L2P_IDLE;
wbm_arb_data_o <= from_wb_fifo_dout;
wbm_arb_dframe_o <= '0';
when others =>
l2p_read_cpl_current_state <= L2P_IDLE;
wbm_arb_req_o <= '0';
wbm_arb_data_o <= (others => '0');
wbm_arb_valid_o <= '0';
wbm_arb_dframe_o <= '0';
from_wb_fifo_rd <= '0';
end case;
end if;
end process;
-----------------------------------------------------------------------------
-- FIFOs for transition between GN4124 core and wishbone clock domain
-----------------------------------------------------------------------------
-- fifo for PCIe to WB transfer
cmp_fifo_to_wb : fifo_64x512
port map (
rst => fifo_rst,
wr_clk => clk_i,
rd_clk => wb_clk_i,
din => to_wb_fifo_din,
wr_en => to_wb_fifo_wr,
rd_en => to_wb_fifo_rd,
prog_full_thresh_assert => c_TO_WB_FIFO_FULL_THRES,
prog_full_thresh_negate => c_TO_WB_FIFO_FULL_THRES,
dout => to_wb_fifo_dout,
full => open,
empty => to_wb_fifo_empty,
valid => open,
prog_full => to_wb_fifo_full);
to_wb_fifo_rw <= to_wb_fifo_dout(63);
to_wb_fifo_addr <= to_wb_fifo_dout(62 downto 32); -- 31-bit
to_wb_fifo_data <= to_wb_fifo_dout(31 downto 0); -- 32-bit
-- fifo for WB to PCIe transfer
cmp_from_wb_fifo : fifo_32x512
port map (
rst => fifo_rst,
wr_clk => wb_clk_i,
rd_clk => clk_i,
din => from_wb_fifo_din,
wr_en => from_wb_fifo_wr,
rd_en => from_wb_fifo_rd,
prog_full_thresh_assert => c_FROM_WB_FIFO_FULL_THRES,
prog_full_thresh_negate => c_FROM_WB_FIFO_FULL_THRES,
dout => from_wb_fifo_dout,
full => open,
empty => from_wb_fifo_empty,
valid => open,
prog_full => from_wb_fifo_full);
-----------------------------------------------------------------------------
-- Wishbone master FSM
-----------------------------------------------------------------------------
p_wb_fsm : process (wb_clk_i, rst_n_i)
begin
if(rst_n_i = c_RST_ACTIVE) then
wishbone_current_state <= WB_IDLE;
to_wb_fifo_rd <= '0';
wb_cyc_t <= '0';
wb_stb_t <= '0';
wb_we_t <= '0';
wb_sel_t <= "0000";
wb_dat_o_t <= (others => '0');
wb_adr_t <= (others => '0');
from_wb_fifo_din <= (others => '0');
from_wb_fifo_wr <= '0';
elsif rising_edge(wb_clk_i) then
case wishbone_current_state is
when WB_IDLE =>
-- stop writing to fifo
from_wb_fifo_wr <= '0';
-- clear bus
wb_cyc_t <= '0';
wb_stb_t <= '0';
wb_sel_t <= "0000";
-- Wait for a Wishbone cycle
if (to_wb_fifo_empty = '0') then
-- read requset in fifo (address, data and transfer type)
to_wb_fifo_rd <= '1';
wishbone_current_state <= WB_READ_FIFO;
end if;
when WB_READ_FIFO =>
-- read only one request in fifo (no block transfer)
to_wb_fifo_rd <= '0';
wishbone_current_state <= WB_CYCLE;
when WB_CYCLE =>
-- initate a bus cycle
wb_cyc_t <= '1';
wb_stb_t <= '1';
wb_we_t <= to_wb_fifo_rw;
wb_sel_t <= "1111";
wb_adr_t <= to_wb_fifo_addr;
--if (to_wb_fifo_rw = '1') then
wb_dat_o_t <= to_wb_fifo_data;
--end if;
-- wait for slave to ack
wishbone_current_state <= WB_WAIT_ACK;
when WB_WAIT_ACK =>
wb_stb_t <= '0';
if (wb_ack_t = '1') then
-- for read cycles write read data to fifo
if (wb_we_t = '0') then
from_wb_fifo_din <= wb_dat_i_t;
from_wb_fifo_wr <= '1';
end if;
-- end of the bus cycle
wb_cyc_t <= '0';
wishbone_current_state <= WB_IDLE;
end if;
when others =>
-- should not get here!
wishbone_current_state <= WB_IDLE;
wb_cyc_t <= '0';
wb_stb_t <= '0';
wb_we_t <= '0';
wb_sel_t <= "0000";
wb_dat_o_t <= (others => '0');
wb_adr_t <= (others => '0');
to_wb_fifo_rd <= '0';
from_wb_fifo_din <= (others => '0');
from_wb_fifo_wr <= '0';
end case;
end if;
end process p_wb_fsm;
------------------------------------------------------------------------------
-- Wishbone master address decoding
------------------------------------------------------------------------------
-- Take the first N bits of the address to select the active wb peripheral
-- g_BAR0_APERTURE represents byte address window, has to be shifted right by 2 to match wishbone 32-bit word addresses
s_wb_periph_addr <= wb_adr_t(g_BAR0_APERTURE-3 downto g_BAR0_APERTURE-log2_ceil(g_WB_SLAVES_NB)-2);
-----------------------------------------------------------------------------
-- One-hot decode function, s_wb_periph_select <= onehot_decode(s_wb_periph_addr);
-----------------------------------------------------------------------------
onehot_decode : process(s_wb_periph_addr)
variable v_onehot : std_logic_vector((2**s_wb_periph_addr'length)-1 downto 0);
variable v_index : integer range 0 to (2**s_wb_periph_addr'length)-1;
begin
v_onehot := (others => '0');
v_index := 0;
for i in s_wb_periph_addr'range loop
if (s_wb_periph_addr(i) = '1') then
v_index := 2*v_index+1;
else
v_index := 2*v_index;
end if;
end loop;
v_onehot(v_index) := '1';
s_wb_periph_select <= v_onehot;
end process onehot_decode;
-- Register multiplexed ack and data + periph address
p_wb_in_regs : process (wb_clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
wb_periph_addr <= (others => '0');
wb_dat_i_t <= (others => '0');
wb_ack_t <= '0';
elsif rising_edge(wb_clk_i) then
wb_periph_addr <= s_wb_periph_addr;
wb_dat_i_t <= s_wb_dat_i_muxed;
wb_ack_t <= s_wb_ack_muxed;
end if;
end process p_wb_in_regs;
-- Select ack line of the active peripheral
p_ack_mux : process (wb_ack_i, wb_periph_addr)
begin
if (to_integer(unsigned(wb_periph_addr)) < g_WB_SLAVES_NB) then
s_wb_ack_muxed <= wb_ack_i(to_integer(unsigned(wb_periph_addr)));
else
s_wb_ack_muxed <= '0';
end if;
end process p_ack_mux;
-- Select input data of the active peripheral
p_din_mux : process (wb_dat_i, wb_periph_addr)
begin
if (to_integer(unsigned(wb_periph_addr)) < g_WB_SLAVES_NB) then
s_wb_dat_i_muxed <=
wb_dat_i(31+(32*to_integer(unsigned(wb_periph_addr))) downto 32*to_integer(unsigned(wb_periph_addr)));
else
s_wb_dat_i_muxed <= (others => 'X');
end if;
end process p_din_mux;
-- Assert the cyc line of the selected peripheral
gen_cyc_demux : for i in 0 to g_WB_SLAVES_NB-1 generate
s_wb_cyc_demuxed(i) <= wb_cyc_t and s_wb_periph_select(i) and not(wb_ack_t);
end generate gen_cyc_demux;
-- Wishbone bus outputs
wb_dat_o <= wb_dat_o_t;
wb_stb_o <= wb_stb_t;
wb_we_o <= wb_we_t;
wb_adr_o <= wb_adr_t(g_BAR0_APERTURE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
wb_sel_o <= wb_sel_t;
wb_cyc_o <= s_wb_cyc_demuxed;
end behaviour;
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : acam chip data interface (acam_databus_interface)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : interface with the acam chip pins for data acquisition and register configuration.
-- acts as a wishbone slave.
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for acam_databus_interface
----------------------------------------------------------------------------------------------------
entity acam_databus_interface is
generic(
g_width : integer :=32
);
port(
-- signals external to the chip: interface with acam
ef1_i : in std_logic;
ef2_i : in std_logic;
lf1_i : in std_logic;
lf2_i : in std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
-- wishbone slave signals internal to the chip: interface with other modules
clk_i : in std_logic;
reset_i : in std_logic;
adr_i : in std_logic_vector(19 downto 0);
cyc_i : in std_logic;
dat_i : in std_logic_vector(g_width-1 downto 0);
stb_i : in std_logic;
we_i : in std_logic;
ack_o : out std_logic;
dat_o : out std_logic_vector(g_width-1 downto 0)
);
end acam_databus_interface;
----------------------------------------------------------------------------------------------------
-- architecture declaration for acam_databus_interface
----------------------------------------------------------------------------------------------------
architecture rtl of acam_databus_interface is
type t_acam_interface is (idle, rd_start, read, rd_ack, wr_start, write, wr_ack);
signal acam_data_st, nxt_acam_data_st : t_acam_interface;
signal ef1 : std_logic;
signal ef2 : std_logic;
signal lf1 : std_logic;
signal lf2 : std_logic;
signal clk : std_logic;
signal reset : std_logic;
signal adr : std_logic_vector(19 downto 0);
signal cyc : std_logic;
signal stb : std_logic;
signal we : std_logic;
signal cs : std_logic;
signal rd : std_logic;
signal wr : std_logic;
signal ack : std_logic;
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
databus_access_seq_fsm: process
begin
if reset ='1' then
acam_data_st <= idle;
else
acam_data_st <= nxt_acam_data_st;
end if;
wait until clk ='1';
end process;
databus_access_comb_fsm: process(acam_data_st, stb, cyc, we)
begin
case acam_data_st is
when idle =>
ack <= '0';
cs <= '0';
rd <= '0';
wr <= '0';
if stb ='1' and cyc ='1' then
if we = '1' then
nxt_acam_data_st <= wr_start;
else
nxt_acam_data_st <= rd_start;
end if;
else
nxt_acam_data_st <= idle;
end if;
when rd_start =>
ack <= '0';
cs <= '1';
rd <= '1';
wr <= '0';
nxt_acam_data_st <= read;
when read =>
ack <= '0';
cs <= '1';
rd <= '1';
wr <= '0';
nxt_acam_data_st <= rd_ack;
when rd_ack =>
ack <= '1';
cs <= '1';
rd <= '1';
wr <= '0';
nxt_acam_data_st <= idle;
when wr_start =>
ack <= '0';
cs <= '1';
rd <= '0';
wr <= '1';
nxt_acam_data_st <= write;
when write =>
ack <= '0';
cs <= '1';
rd <= '0';
wr <= '1';
nxt_acam_data_st <= wr_ack;
when wr_ack =>
ack <= '1';
cs <= '0';
rd <= '0';
wr <= '0';
nxt_acam_data_st <= idle;
when others =>
ack <= '0';
cs <= '0';
rd <= '0';
wr <= '0';
nxt_acam_data_st <= idle;
end case;
end process;
ef1 <= ef1_i;
ef2 <= ef2_i;
lf1 <= lf1_i;
lf2 <= lf2_i;
clk <= clk_i;
reset <= reset_i;
adr <= adr_i;
cyc <= cyc_i;
data_bus_io <= dat_i(27 downto 0);
stb <= stb_i;
we <= we_i;
address_o <= adr(3 downto 0);
cs_n_o <= not(cs);
oe_n_o <= '1';
rd_n_o <= not(rd);
wr_n_o <= not(wr);
ack_o <= ack;
dat_o <= ef1 & ef2 & lf1 & lf2 & data_bus_io;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : acam chip timing control interface (acam_timecontrol_interface)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : interface with the acam chip pins for control and timing
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for acam_timing_interface
----------------------------------------------------------------------------------------------------
entity acam_timecontrol_interface is
generic(
g_width : integer :=32
);
port(
-- signals external to the chip: interface with acam
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
stop_dis_o : out std_logic;
-- signals internal to the chip: interface with other modules
clk_i : in std_logic;
one_hz_p_i : in std_logic;
reset_i : in std_logic;
acam_errflag_p_o : out std_logic;
acam_intflag_p_o : out std_logic
);
end acam_timecontrol_interface;
----------------------------------------------------------------------------------------------------
-- architecture declaration for acam_timecontrol_interface
----------------------------------------------------------------------------------------------------
architecture rtl of acam_timecontrol_interface is
component incr_counter
generic(
width : integer :=32
);
port(
clk : in std_logic;
end_value : in std_logic_vector(width-1 downto 0);
incr : in std_logic;
reset : in std_logic;
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
signal clk : std_logic;
signal counter_reset : std_logic;
signal one_hz_p : std_logic;
signal reset : std_logic;
signal s_int_flag : unsigned(2 downto 0);
signal s_err_flag : unsigned(2 downto 0);
signal start_dis : std_logic;
signal start_window : std_logic;
signal window_inverted : std_logic;
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
sync_err_flag: process -- synchronisation registers for ERR external signal
begin
if reset ='1' then
s_err_flag <= (others=>'0');
else
s_err_flag <= shift_right(s_err_flag,1);
s_err_flag(2) <= err_flag_i;
end if;
wait until clk ='1';
end process;
sync_int_flag: process -- synchronisation registers for INT external signal
begin
if reset ='1' then
s_int_flag <= (others=>'0');
else
s_int_flag <= shift_right(s_int_flag,1);
s_int_flag(2) <= int_flag_i;
end if;
wait until clk ='1';
end process;
acam_errflag_p_o <= not(s_err_flag(1)) and s_err_flag(0);
acam_intflag_p_o <= not(s_int_flag(1)) and s_int_flag(0);
-- generation of the window allowing the start:
-- every second an external start retrigger is generated by the
-- rising edge of the ref_clk
start_disable_control: process
begin
if reset ='1' then
start_dis <='1';
else
start_dis <= not(start_window);
end if;
wait until clk ='1';
end process;
window_counter: incr_counter
generic map(
width => g_width
)
port map(
clk => clk,
end_value => x"00000004",
incr => '1',
reset => counter_reset,
count_done => window_inverted,
current_value => open
);
start_window <= not(window_inverted);
counter_reset <= reset or one_hz_p;
clk <= clk_i;
one_hz_p <= one_hz_p_i;
reset <= reset_i;
start_dis_o <= start_dis;
stop_dis_o <= '0';
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : Clock and reset management unit (clk_rst_managr.vhd)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : independent block that uses the spec clk to parameterize
-- the TDC mezzanine PLL that will be used by all the other
-- blocks. Includes input clk buffers for Xilinx Spartan6.
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library UNISIM;
use UNISIM.vcomponents.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for clk_rst_managr
----------------------------------------------------------------------------------------------------
entity clk_rst_managr is
generic(
nb_of_reg : integer:=67
);
port(
acam_refclk_i : in std_logic;
pll_ld_i : in std_logic;
pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
gnum_reset_i : in std_logic;
spec_clk_i : in std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
acam_refclk_o : out std_logic;
general_reset_o : out std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
spec_clk_o : out std_logic;
tdc_clk_o : out std_logic
);
end clk_rst_managr;
----------------------------------------------------------------------------------------------------
-- architecture declaration for clk_rst_managr
----------------------------------------------------------------------------------------------------
architecture rtl of clk_rst_managr is
component incr_counter
generic(
width : integer :=32
);
port(
clk : in std_logic;
end_value : in std_logic_vector(width-1 downto 0);
incr : in std_logic;
reset : in std_logic;
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
subtype t_byte is std_logic_vector(7 downto 0);
type t_instr is array (1 downto 0) of t_byte;
type t_stream is array (nb_of_reg downto 0) of t_byte;
type t_pll_init_st is (start, sending_instruction, sending_data, done);
-- the PLL circuit AD9516-4 needs to be configured through 68 registers
-- the values and addresses are obtained from a dedicated Analog Devices
-- software and from the datasheet.
constant reg_000 : t_byte:=x"18";
constant reg_001 : t_byte:=x"00";
constant reg_002 : t_byte:=x"10";
constant reg_003 : t_byte:=x"C3";
constant reg_004 : t_byte:=x"00";
constant reg_010 : t_byte:=x"7C";
constant reg_011 : t_byte:=x"01";
constant reg_012 : t_byte:=x"00";
constant reg_013 : t_byte:=x"03";
constant reg_014 : t_byte:=x"09";
constant reg_015 : t_byte:=x"00";
constant reg_016 : t_byte:=x"04";
constant reg_017 : t_byte:=x"00";
constant reg_018 : t_byte:=x"07";
constant reg_019 : t_byte:=x"00";
constant reg_01A : t_byte:=x"00";
constant reg_01B : t_byte:=x"00";
constant reg_01C : t_byte:=x"02";
constant reg_01D : t_byte:=x"00";
constant reg_01E : t_byte:=x"00";
constant reg_01F : t_byte:=x"1E";
constant reg_0A0 : t_byte:=x"01";
constant reg_0A1 : t_byte:=x"00";
constant reg_0A2 : t_byte:=x"00";
constant reg_0A3 : t_byte:=x"01";
constant reg_0A4 : t_byte:=x"00";
constant reg_0A5 : t_byte:=x"00";
constant reg_0A6 : t_byte:=x"01";
constant reg_0A7 : t_byte:=x"00";
constant reg_0A8 : t_byte:=x"00";
constant reg_0A9 : t_byte:=x"01";
constant reg_0AA : t_byte:=x"00";
constant reg_0AB : t_byte:=x"00";
constant reg_0F0 : t_byte:=x"0A";
constant reg_0F1 : t_byte:=x"0A";
constant reg_0F2 : t_byte:=x"0A";
constant reg_0F3 : t_byte:=x"0A";
constant reg_0F4 : t_byte:=x"0A";
constant reg_0F5 : t_byte:=x"0A";
constant reg_140 : t_byte:=x"4A";
constant reg_141 : t_byte:=x"5A";
constant reg_142 : t_byte:=x"43";
constant reg_143 : t_byte:=x"42";
constant reg_190 : t_byte:=x"00";
constant reg_191 : t_byte:=x"80";
constant reg_192 : t_byte:=x"00";
constant reg_193 : t_byte:=x"00";
constant reg_194 : t_byte:=x"80";
constant reg_195 : t_byte:=x"00";
constant reg_196 : t_byte:=x"00";
constant reg_197 : t_byte:=x"80";
constant reg_198 : t_byte:=x"00";
constant reg_199 : t_byte:=x"22";
constant reg_19A : t_byte:=x"00";
constant reg_19B : t_byte:=x"11";
constant reg_19C : t_byte:=x"00";
constant reg_19D : t_byte:=x"00";
constant reg_19E : t_byte:=x"22";
constant reg_19F : t_byte:=x"00";
constant reg_1A0 : t_byte:=x"11";
constant reg_1A1 : t_byte:=x"20";
constant reg_1A2 : t_byte:=x"00";
constant reg_1A3 : t_byte:=x"00";
constant reg_1E0 : t_byte:=x"00";
constant reg_1E1 : t_byte:=x"02";
constant reg_230 : t_byte:=x"00";
constant reg_231 : t_byte:=x"00";
constant reg_232 : t_byte:=x"01";
-- the 16-bit instruction word indicates a write cycle
-- in streaming mode starting in address 231
constant instr_wd_msb : t_byte:=x"62";
constant instr_wd_lsb : t_byte:=x"31";
signal pll_init_st : t_pll_init_st;
signal nxt_pll_init_st : t_pll_init_st;
signal stream : t_stream;
signal instruction : t_instr;
signal acam_refclk_buf : std_logic;
signal tdc_clk_buf : std_logic;
signal bit_being_sent : std_logic;
signal byte_being_sent : t_byte;
signal bit_index : integer range 7 downto 0:=7;
signal byte_index : integer range nb_of_reg downto 0:=1;
signal spec_clk_buf : std_logic;
signal gnum_reset : std_logic;
signal gral_incr : std_logic;
signal inv_reset : std_logic;
signal cs : std_logic;
signal acam_refclk : std_logic;
signal half_clk : std_logic:='0';
signal spec_clk : std_logic;
signal tdc_clk : std_logic;
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
--Clock input buffer instantiations
-----------------------------------
tdc_clk125_ibuf : IBUFDS
generic map (
DIFF_TERM => false, -- Differential Termination
IBUF_LOW_PWR => true, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "DEFAULT"
)
port map (
O => tdc_clk_buf, -- Buffer output
I => tdc_clk_p_i, -- Diff_p buffer input (connect directly to top-level port)
IB => tdc_clk_n_i -- Diff_n buffer input (connect directly to top-level port)
);
tdc_clk125_gbuf : BUFG
port map (
O => tdc_clk,
I => tdc_clk_buf
);
spec_clk_ibuf : IBUFG
port map (
I => spec_clk_i,
O => spec_clk_buf
);
spec_clk_gbuf : BUFG
port map (
O => spec_clk,
I => spec_clk_buf
);
acam_refclk_ibuf : IBUFG
port map (
I => acam_refclk_i,
O => acam_refclk_buf
);
acam_refclk_gbuf : BUFG
port map (
O => acam_refclk,
I => acam_refclk_buf
);
general_power_on_reset: incr_counter
port map(
clk => spec_clk,
end_value => x"0000007D", -- 125 clk ticks
incr => gral_incr,
reset => gnum_reset,
count_done => inv_reset,
current_value => open
);
gral_reset_incr: process
begin
if spec_clk ='0' then
gral_incr <= '1';
else
gral_incr <= '0';
end if;
wait until tdc_clk ='1';
end process;
general_reset_o <= not(inv_reset);
-- Processes for initialization of the PLL
------------------------------------------
pll_initialization_seq: process
begin
if gnum_reset ='1' then
pll_init_st <= start;
else
pll_init_st <= nxt_pll_init_st;
end if;
wait until spec_clk ='1';
end process;
pll_initialization_comb: process(pll_init_st, byte_index, bit_index, half_clk)
begin
case pll_init_st is
when start =>
cs <= '1';
nxt_pll_init_st <= sending_instruction;
when sending_instruction =>
cs <= '0';
if byte_index = 0
and bit_index = 0
and half_clk = '1' then
nxt_pll_init_st <= sending_data;
else
nxt_pll_init_st <= sending_instruction;
end if;
when sending_data =>
cs <= '0';
if byte_index = 0
and bit_index = 0
and half_clk = '1' then
nxt_pll_init_st <= done;
else
nxt_pll_init_st <= sending_data;
end if;
when done =>
cs <= '1';
nxt_pll_init_st <= done;
when others =>
cs <= '1';
nxt_pll_init_st <= start;
end case;
end process;
index_control: process
begin
if cs ='1' then
bit_index <= 7;
elsif bit_index = 0 then
bit_index <= 7;
else
bit_index <= bit_index -1;
end if;
if cs ='1' then
byte_index <= 1;
elsif bit_index = 0 then
if byte_index = 0 then
byte_index <= nb_of_reg;
else
byte_index <= byte_index -1;
end if;
end if;
wait until half_clk ='0';
end process;
clock_halfer: process
begin
half_clk <= not(half_clk);
wait until spec_clk ='0';
end process;
bit_being_sent <= byte_being_sent(bit_index);
byte_being_sent <= instruction(byte_index) when pll_init_st = sending_instruction
else stream(byte_index);
-- Assignement of the values to be sent for the configurations of the PLL
-------------------------------------------------------------------------
instruction(1) <= instr_wd_msb;
instruction(0) <= instr_wd_lsb;
-- according to the datasheet the register 232 should be written last
-- to validate the transfer from the buffer to the valid registers
stream(0) <= reg_232;
stream(1) <= reg_000;
stream(2) <= reg_001;
stream(3) <= reg_002;
stream(4) <= reg_003;
stream(5) <= reg_004;
stream(6) <= reg_010;
stream(7) <= reg_011;
stream(8) <= reg_012;
stream(9) <= reg_013;
stream(10) <= reg_014;
stream(11) <= reg_015;
stream(12) <= reg_016;
stream(13) <= reg_017;
stream(14) <= reg_018;
stream(15) <= reg_019;
stream(16) <= reg_01A;
stream(17) <= reg_01B;
stream(18) <= reg_01C;
stream(19) <= reg_01D;
stream(20) <= reg_01E;
stream(21) <= reg_01F;
stream(22) <= reg_0A0;
stream(23) <= reg_0A1;
stream(24) <= reg_0A2;
stream(25) <= reg_0A3;
stream(26) <= reg_0A4;
stream(27) <= reg_0A5;
stream(28) <= reg_0A6;
stream(29) <= reg_0A7;
stream(30) <= reg_0A8;
stream(31) <= reg_0A9;
stream(32) <= reg_0AA;
stream(33) <= reg_0AB;
stream(34) <= reg_0F0;
stream(35) <= reg_0F1;
stream(36) <= reg_0F2;
stream(37) <= reg_0F3;
stream(38) <= reg_0F4;
stream(39) <= reg_0F5;
stream(40) <= reg_140;
stream(41) <= reg_141;
stream(42) <= reg_142;
stream(43) <= reg_143;
stream(44) <= reg_190;
stream(45) <= reg_191;
stream(46) <= reg_192;
stream(47) <= reg_193;
stream(48) <= reg_194;
stream(49) <= reg_195;
stream(50) <= reg_196;
stream(51) <= reg_197;
stream(52) <= reg_198;
stream(53) <= reg_199;
stream(54) <= reg_19A;
stream(55) <= reg_19B;
stream(56) <= reg_19C;
stream(57) <= reg_19D;
stream(58) <= reg_19E;
stream(59) <= reg_19F;
stream(60) <= reg_1A0;
stream(61) <= reg_1A1;
stream(62) <= reg_1A2;
stream(63) <= reg_1A3;
stream(64) <= reg_1E0;
stream(65) <= reg_1E1;
stream(66) <= reg_230;
stream(67) <= reg_231;
-- Input and Output signals
---------------------------
gnum_reset <= gnum_reset_i;
acam_refclk_o <= acam_refclk;
pll_cs_o <= cs;
pll_sdi_o <= bit_being_sent;
pll_sclk_o <= half_clk;
spec_clk_o <= spec_clk;
tdc_clk_o <= tdc_clk;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
-- Created by : G. Penacoba
-- Creation Date: May 2011
-- Description: Stop counter. Configurable start_value and width.
-- Current count value and done signal available.
-- Done signal asserted simultaneous to value=0.
-- Countdown is launched each time start is asserted
-- for one clock tick.
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity countdown_counter is
generic(
width : integer :=32
);
port(
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
start_value : in std_logic_vector(width-1 downto 0);
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end countdown_counter;
architecture rtl of countdown_counter is
constant zeroes : unsigned(width-1 downto 0):=(others=>'0');
signal one : unsigned(width-1 downto 0);
signal value : unsigned(width-1 downto 0):=(others=>'0'); -- initialized to avoid simulation warnings
begin
decount: process
begin
if reset = '1' then
count_done <= '0';
value <= zeroes;
elsif start='1' then
count_done <= '0';
value <= unsigned(start_value) - "1";
elsif value = zeroes then
count_done <= '0';
value <= zeroes;
elsif value = one then
count_done <= '1';
value <= value - "1";
else
count_done <= '0';
value <= value - "1";
end if;
wait until clk ='1';
end process;
current_value <= std_logic_vector(value);
one <= zeroes + "1";
end rtl;
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : timestamp data formatting (data_formatting)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : formats the timestamp coming from the acam plus the coarse timing
-- plus the UTC time
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for data_formatting
----------------------------------------------------------------------------------------------------
entity data_formatting is
generic(
g_width : integer :=32
);
port(
acam_start01_i : in std_logic_vector(16 downto 0);
acam_timestamp_i : in std_logic_vector(28 downto 0);
acam_timestamp_valid_i : in std_logic;
clk_i : in std_logic;
reset_i : in std_logic;
start_nb_offset_i : in std_logic_vector(g_width-1 downto 0);
utc_current_time_i : in std_logic_vector(g_width-1 downto 0);
full_timestamp_o : out std_logic_vector(3*g_width-1 downto 0);
full_timestamp_valid_o : out std_logic
);
end data_formatting;
----------------------------------------------------------------------------------------------------
-- architecture declaration for data_formatting
----------------------------------------------------------------------------------------------------
architecture rtl of data_formatting is
signal acam_channel : std_logic_vector(2 downto 0);
signal acam_fine_timestamp : std_logic_vector(16 downto 0);
signal acam_start01 : std_logic_vector(16 downto 0);
signal acam_timestamp : std_logic_vector(28 downto 0);
signal acam_timestamp_valid : std_logic;
signal clk : std_logic;
signal reset : std_logic;
signal start_nb_offset : std_logic_vector(g_width-1 downto 0);
signal utc_current_time : std_logic_vector(g_width-1 downto 0);
signal full_timestamp : std_logic_vector(3*g_width-1 downto 0);
signal full_timestamp_valid : std_logic;
signal reserved : std_logic_vector(2 downto 0):=(others=>'0');
signal u_start_nb_offset : unsigned(g_width-1 downto 0);
signal u_acam_start_nb : unsigned(7 downto 0);
signal start_nb : std_logic_vector(g_width-1 downto 0);
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
full_timestamp_register: process
begin
if reset ='1' then
full_timestamp <= (others=>'0');
elsif acam_timestamp_valid ='1' then
full_timestamp(95 downto 64) <= utc_current_time;
full_timestamp(63 downto 40) <= start_nb(23 downto 0);
full_timestamp(39 downto 23) <= acam_fine_timestamp;
full_timestamp(22 downto 6) <= acam_start01;
full_timestamp(5 downto 3) <= acam_channel;
full_timestamp(2 downto 0) <= reserved;
end if;
wait until clk ='1';
end process;
valid_onetick_signal: process
begin
full_timestamp_valid <= acam_timestamp_valid;
wait until clk ='1';
end process;
acam_start01 <= acam_start01_i;
acam_timestamp <= acam_timestamp_i;
acam_timestamp_valid <= acam_timestamp_valid_i;
clk <= clk_i;
reset <= reset_i;
start_nb_offset <= start_nb_offset_i;
utc_current_time <= utc_current_time_i;
full_timestamp_o <= full_timestamp;
full_timestamp_valid_o <= full_timestamp_valid;
u_start_nb_offset <= unsigned(start_nb_offset);
u_acam_start_nb <= unsigned(acam_timestamp(25 downto 18));
start_nb <= std_logic_vector(u_start_nb_offset + u_acam_start_nb);
acam_fine_timestamp <= acam_timestamp(16 downto 0);
acam_channel <= acam_timestamp(28 downto 26);
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : data polling engine (data_polling)
-- author : G. Penacoba
-- date : June 2011
-- version : Revision 1
-- description : engine polling data continuouly from the acam interface provided the FIFO is not
-- empty. acts as a wishbone master.
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do: empty FIFO signals from Acam are missing (maybe putting them in the data?)
-- other Acam configuration registers maybe...
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for data_polling
----------------------------------------------------------------------------------------------------
entity data_polling is
generic(
g_width : integer :=32
);
port(
-- wishbone master signals internal to the chip: interface with other modules
ack_i : in std_logic;
dat_i : in std_logic_vector(31 downto 0);
cyc_o : out std_logic;
dat_o : out std_logic_vector(31 downto 0);
stb_o : out std_logic;
we_o : out std_logic;
-- signals internal to the chip: interface with other modules
clk_i : in std_logic;
one_hz_p_i : in std_logic;
reset_i : in std_logic;
start_timer_reg_i : in std_logic_vector(7 downto 0);
acam_start01_o : out std_logic_vector(16 downto 0);
acam_timestamp_o : out std_logic_vector(28 downto 0);
acam_timestamp_valid_o : out std_logic
);
end acam_databus_interface;
----------------------------------------------------------------------------------------------------
-- architecture declaration for data_polling
----------------------------------------------------------------------------------------------------
architecture rtl of data_polling is
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
-- Created by : G. Penacoba
-- Creation Date: May 2011
-- Description: Free running counter. Configurable start_value and width.
-- Current count value and done signal available.
-- Done signal asserted simultaneous to value=0.
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity free_counter is
generic(
width : integer :=32
);
port(
clk : in std_logic;
enable : in std_logic;
reset : in std_logic;
start_value : in std_logic_vector(width-1 downto 0);
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end free_counter;
architecture rtl of free_counter is
constant zeroes : unsigned(width-1 downto 0):=(others=>'0');
signal one : unsigned(width-1 downto 0);
signal value : unsigned(width-1 downto 0):=(others=>'0'); -- initialized to avoid simulation warnings
begin
decount: process
begin
if reset = '1' then
count_done <= '0';
value <= unsigned(start_value) - "1";
elsif value = zeroes then
count_done <= '0';
value <= unsigned(start_value) - "1";
elsif enable ='1' then
if value = one then
count_done <= '1';
value <= value - "1";
else
count_done <= '0';
value <= value - "1";
end if;
end if;
wait until clk ='1';
end process;
current_value <= std_logic_vector(value);
one <= zeroes + "1";
end rtl;
-- Created by : G. Penacoba
-- Creation Date: May 2011
-- Description: Stop counter. Configurable end_value and width.
-- Current count value and done signal available.
-- Done signal asserted simultaneous to value=end_value.
-- Needs a reset to restart.
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity incr_counter is
generic(
width : integer :=32
);
port(
clk : in std_logic;
end_value : in std_logic_vector(width-1 downto 0);
incr : in std_logic;
reset : in std_logic;
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end incr_counter;
architecture rtl of incr_counter is
constant zeroes : unsigned(width-1 downto 0):=(others=>'0');
signal end_minus_one : unsigned(width-1 downto 0);
signal value : unsigned(width-1 downto 0):=(others=>'0'); -- initialized to avoid simulation warnings
begin
count: process
begin
if reset = '1' then
count_done <= '0';
value <= zeroes;
elsif value = unsigned(end_value) then
count_done <= '1';
value <= unsigned(end_value);
elsif incr ='1' then
if value = end_minus_one then
count_done <= '1';
value <= value + "1";
else
count_done <= '0';
value <= value + "1";
end if;
end if;
wait until clk ='1';
end process;
current_value <= std_logic_vector(value);
end_minus_one <= unsigned(end_value) - "1";
end rtl;
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : one hertz pulse generator (one_hz_gen)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : generates one pulse every second synchronously with the acam reference clock
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for one_hz_gen
----------------------------------------------------------------------------------------------------
entity one_hz_gen is
generic(
g_width : integer :=32
);
port(
acam_refclk_i : in std_logic;
clk_i : in std_logic;
clock_period_i : in std_logic_vector(g_width-1 downto 0);
pulse_delay_i : in std_logic_vector(g_width-1 downto 0);
reset_i : in std_logic;
one_hz_p_o : out std_logic
);
end one_hz_gen;
----------------------------------------------------------------------------------------------------
-- architecture declaration for one_hz_gen
----------------------------------------------------------------------------------------------------
architecture rtl of one_hz_gen is
component free_counter
generic(
width : integer :=32
);
port(
clk : in std_logic;
enable : in std_logic;
reset : in std_logic;
start_value : in std_logic_vector(width-1 downto 0);
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
component countdown_counter
generic(
width : integer :=32
);
port(
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
start_value : in std_logic_vector(width-1 downto 0);
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
constant constant_delay : unsigned(3 downto 0):=x"4";
signal clk : std_logic;
signal one_hz_p_pre : std_logic;
signal one_hz_p_post : std_logic;
signal onesec_counter_en : std_logic;
signal refclk_edge : std_logic;
signal reset : std_logic;
signal s_acam_refclk : unsigned(3 downto 0);
signal total_delay : std_logic_vector(g_width-1 downto 0);
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
sync_acam_refclk: process
begin
if reset ='1' then
s_acam_refclk <= (others=>'0');
else
s_acam_refclk <= shift_right(s_acam_refclk,1);
s_acam_refclk(3) <= acam_refclk_i;
end if;
wait until clk ='1';
end process;
onesec_trigger: process
begin
if reset ='1' then
onesec_counter_en <= '0';
elsif refclk_edge ='1' then
onesec_counter_en <= '1';
end if;
wait until clk ='1';
end process;
clock_periods_counter: free_counter
generic map(
width => g_width
)
port map(
clk => clk_i,
enable => onesec_counter_en,
reset => reset_i,
start_value => clock_period_i,
count_done => one_hz_p_pre,
current_value => open
);
pulse_delayer_counter: countdown_counter
generic map(
width => g_width
)
port map(
clk => clk_i,
reset => reset_i,
start => one_hz_p_pre,
start_value => total_delay,
count_done => one_hz_p_post,
current_value => open
);
clk <= clk_i;
reset <= reset_i;
refclk_edge <= not(s_acam_refclk(3)) and
s_acam_refclk(2) and
s_acam_refclk(1) and
not(s_acam_refclk(0));
total_delay <= std_logic_vector(unsigned(pulse_delay_i)+constant_delay);
one_hz_p_o <= one_hz_p_post;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
"AD9516 Setup File"
"Rev.","1.1.0"
""
"Addr(Hex)","Value(Bin)","Value(Hex)"
"0000","00011000","18"
"0001","00000000","00"
"0002","00010000","10"
"0003","11000011","C3"
"0004","00000000","00"
"0010","01111100","7C"
"0011","00000001","01"
"0012","00000000","00"
"0013","00000011","03"
"0014","00001001","09"
"0015","00000000","00"
"0016","00000100","04"
"0017","00000000","00"
"0018","00000111","07"
"0019","00000000","00"
"001A","00000000","00"
"001B","00000000","00"
"001C","00000010","02"
"001D","00000000","00"
"001E","00000000","00"
"001F","00001110","0E"
"00A0","00000001","01"
"00A1","00000000","00"
"00A2","00000000","00"
"00A3","00000001","01"
"00A4","00000000","00"
"00A5","00000000","00"
"00A6","00000001","01"
"00A7","00000000","00"
"00A8","00000000","00"
"00A9","00000001","01"
"00AA","00000000","00"
"00AB","00000000","00"
"00F0","00001010","0A"
"00F1","00001010","0A"
"00F2","00001010","0A"
"00F3","00001010","0A"
"00F4","00001010","0A"
"00F5","00001010","0A"
"0140","01001010","4A"
"0141","01011010","5A"
"0142","01000011","43"
"0143","01000010","42"
"0190","00000000","00"
"0191","10000000","80"
"0192","00000000","00"
"0193","10111011","BB"
"0194","00000000","00"
"0195","00000000","00"
"0196","00000000","00"
"0197","00000000","00"
"0198","00000000","00"
"0199","00100010","22"
"019A","00000000","00"
"019B","00010001","11"
"019C","00000000","00"
"019D","00000000","00"
"019E","00100010","22"
"019F","00000000","00"
"01A0","00010001","11"
"01A1","00100000","20"
"01A2","00000000","00"
"01A3","00000000","00"
"01E0","00000000","00"
"01E1","00000010","02"
"0230","00000000","00"
"0231","00000000","00"
"0232","00000000","00"
"","",""
"Other Settings..."
"REF 1:",20
"REF 2:",30.72
"VCO:",1500
"CLK:",1200
"CPRSet:",5100
"Auto Update:",1
"Load All Regs:",1
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : internal start number offset generator (start_nb_offset_gen)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : generates the offset to be added to the start number provided by tha Acam
-- by counting the number of times the 1-Byte counter of the Acam is overloaded.
-- The result is then multiplied by 256 (shifted by 8).
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for start_nb_offset_gen
----------------------------------------------------------------------------------------------------
entity start_nb_offset_gen is
generic(
g_width : integer :=32
);
port(
acam_intflag_p_i : in std_logic;
clk_i : in std_logic;
one_hz_p_i : in std_logic;
reset_i : in std_logic;
start_nb_offset_o : out std_logic_vector(g_width-1 downto 0)
);
end start_nb_offset_gen;
----------------------------------------------------------------------------------------------------
-- architecture declaration for start_nb_offset_gen
----------------------------------------------------------------------------------------------------
architecture rtl of start_nb_offset_gen is
component incr_counter
generic(
width : integer :=32
);
port(
clk : in std_logic;
end_value : in std_logic_vector(width-1 downto 0);
incr : in std_logic;
reset : in std_logic;
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
signal acam_intflag_p : std_logic;
signal clk : std_logic;
signal counter_reset : std_logic;
signal offset_value : std_logic_vector(g_width-1 downto 0);
signal offset_to_shift : unsigned(g_width-1 downto 0);
signal one_hz_p : std_logic;
signal reset : std_logic;
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
acam_irflag_counter: incr_counter
generic map(
width => g_width
)
port map(
clk => clk,
end_value => x"FFFFFFFF",
incr => acam_intflag_p,
reset => counter_reset,
count_done => open,
current_value => offset_value
);
counter_reset <= reset or one_hz_p;
offset_to_shift <= unsigned(offset_value);
start_nb_offset_o <= std_logic_vector(shift_left(offset_to_shift,8));
acam_intflag_p <= acam_intflag_p_i;
clk <= clk_i;
one_hz_p <= one_hz_p_i;
reset <= reset_i;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : Package for TDC core (tdc_core_pkg.vhd)
-- author : G. Penacoba
-- date : Jul 2011
-- version : Revision 1
-- description : Package containing core wide constants and components
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
----------------------------------------------------------------------------------------------------
-- Package declaration
----------------------------------------------------------------------------------------------------
package tdc_core_pkg is
component countdown_counter
generic(
width : integer :=32
);
port(
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
start_value : in std_logic_vector(width-1 downto 0);
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
component free_counter is
generic(
width : integer :=32
);
port(
clk : in std_logic;
enable : in std_logic;
reset : in std_logic;
start_value : in std_logic_vector(width-1 downto 0);
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
component incr_counter
generic(
width : integer :=32
);
port(
clk : in std_logic;
end_value : in std_logic_vector(width-1 downto 0);
incr : in std_logic;
reset : in std_logic;
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
constant data_width : integer:=32;
constant tdc_led_period_sim : std_logic_vector(data_width-1 downto 0):=x"0000F424";
constant tdc_led_period_syn : std_logic_vector(data_width-1 downto 0):=x"03B9ACA0";
constant spec_led_period_sim : std_logic_vector(data_width-1 downto 0):=x"00004E20";
constant spec_led_period_syn : std_logic_vector(data_width-1 downto 0):=x"01312D00";
constant visible_blink_length : std_logic_vector(data_width-1 downto 0):=x"00BEBC20";
end tdc_core_pkg;
----------------------------------------------------------------------------------------------------
-- Package body
----------------------------------------------------------------------------------------------------
package body tdc_core_pkg is
end tdc_core_pkg;
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : TDC top level (top_tdc.vhd)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : top level for preliminary testing of the acam chip on the TDC card
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tdc_core_pkg.all;
use work.gn4124_core_pkg.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for top_tdc
----------------------------------------------------------------------------------------------------
entity top_tdc is
generic(
g_width : integer :=32;
values_for_simulation : boolean :=FALSE
);
port(
-- interface with GNUM
rst_n_a_i : in std_logic;
-- P2L Direction
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i: in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
-- L2P Direction
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o: out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i: in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
-- interface signals with PLL circuit on TDC mezzanine
acam_refclk_i : in std_logic;
pll_ld_i : in std_logic;
pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
-- interface signals with acam (timing) on TDC mezzanine
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
-- interface signals with acam (data) on TDC mezzanine
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_i : in std_logic;
ef2_i : in std_logic;
lf1_i : in std_logic;
lf2_i : in std_logic;
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
-- other signals on the TDC mezzanine
mute_inputs_o : out std_logic;
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
term_en_1_o : out std_logic;
term_en_2_o : out std_logic;
term_en_3_o : out std_logic;
term_en_4_o : out std_logic;
term_en_5_o : out std_logic;
-- other signals on the SPEC carrier
spec_aux0_i : in std_logic;
spec_aux1_i : in std_logic;
spec_aux2_o : out std_logic;
spec_aux3_o : out std_logic;
spec_aux4_o : out std_logic;
spec_aux5_o : out std_logic;
spec_led_green_o : out std_logic;
spec_led_red_o : out std_logic;
spec_clk_i : in std_logic
);
end top_tdc;
----------------------------------------------------------------------------------------------------
-- architecture declaration for top_tdc
----------------------------------------------------------------------------------------------------
architecture rtl of top_tdc is
component one_hz_gen
generic(
g_width : integer :=32
);
port(
acam_refclk_i : in std_logic;
clk_i : in std_logic;
clock_period_i : in std_logic_vector(g_width-1 downto 0);
pulse_delay_i : in std_logic_vector(g_width-1 downto 0);
reset_i : in std_logic;
one_hz_p_o : out std_logic
);
end component;
-- component start_nb_offset_gen is
-- generic(
-- g_width : integer :=32
-- );
-- port(
-- acam_intflag_p_i : in std_logic;
-- clk_i : in std_logic;
-- one_hz_p_i : in std_logic;
-- reset_i : in std_logic;
--
-- start_nb_offset_o : out std_logic_vector(g_width-1 downto 0)
-- );
-- end component;
--
-- component data_formatting
-- generic(
-- g_width : integer :=32
-- );
-- port(
-- acam_start01_i : in std_logic_vector(16 downto 0);
-- acam_timestamp_i : in std_logic_vector(28 downto 0);
-- acam_timestamp_valid_i : in std_logic;
-- clk_i : in std_logic;
-- reset_i : in std_logic;
-- start_nb_offset_i : in std_logic_vector(g_width-1 downto 0);
-- utc_current_time_i : in std_logic_vector(g_width-1 downto 0);
--
-- full_timestamp_o : out std_logic_vector(3*g_width-1 downto 0);
-- full_timestamp_valid_o : out std_logic
-- );
-- end component;
component acam_timecontrol_interface
generic(
g_width : integer :=32
);
port(
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
stop_dis_o : out std_logic;
clk_i : in std_logic;
one_hz_p_i : in std_logic;
reset_i : in std_logic;
acam_errflag_p_o : out std_logic;
acam_intflag_p_o : out std_logic
);
end component;
component acam_databus_interface
generic(
g_width : integer :=32
);
port(
ef1_i : in std_logic;
ef2_i : in std_logic;
lf1_i : in std_logic;
lf2_i : in std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
clk_i : in std_logic;
reset_i : in std_logic;
adr_i : in std_logic_vector(19 downto 0);
cyc_i : in std_logic;
dat_i : in std_logic_vector(31 downto 0);
stb_i : in std_logic;
we_i : in std_logic;
ack_o : out std_logic;
dat_o : out std_logic_vector(31 downto 0)
);
end component;
component clk_rst_managr
port(
acam_refclk_i : in std_logic;
pll_ld_i : in std_logic;
pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
gnum_reset_i : in std_logic;
spec_clk_i : in std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
acam_refclk_o : out std_logic;
general_reset_o : out std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
spec_clk_o : out std_logic;
tdc_clk_o : out std_logic
);
end component;
component gn4124_core
generic(
g_BAR0_APERTURE : integer := 20; -- BAR0 aperture, defined in GN4124 PCI_BAR_CONFIG register (0x80C)
-- => number of bits to address periph on the board
g_CSR_WB_SLAVES_NB : integer := 1; -- Number of CSR wishbone slaves
g_DMA_WB_SLAVES_NB : integer := 1; -- Number of DMA wishbone slaves
g_DMA_WB_ADDR_WIDTH : integer := 26 -- DMA wishbone address bus width
);
port
(
---------------------------------------------------------
-- Control and status
--
-- Asynchronous reset from GN4124
rst_n_a_i : in std_logic;
-- P2L clock PLL locked
p2l_pll_locked : out std_logic;
-- Debug ouputs
debug_o : out std_logic_vector(7 downto 0);
---------------------------------------------------------
-- P2L Direction
--
-- Source Sync DDR related signals
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i : in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
-- P2L Control
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
---------------------------------------------------------
-- L2P Direction
--
-- Source Sync DDR related signals
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o : out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
-- L2P Control
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
---------------------------------------------------------
-- Interrupt interface
dma_irq_o : out std_logic_vector(1 downto 0); -- Interrupts sources to IRQ manager
irq_p_i : in std_logic; -- Interrupt request pulse from IRQ manager
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
---------------------------------------------------------
-- Target interface (CSR wishbone master)
wb_clk_i : in std_logic;
wb_adr_o : out std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_CSR_WB_SLAVES_NB+1)-1 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic;
wb_we_o : out std_logic;
wb_cyc_o : out std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
wb_dat_i : in std_logic_vector((32*g_CSR_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
---------------------------------------------------------
-- DMA interface (Pipelined wishbone master)
dma_clk_i : in std_logic;
dma_adr_o : out std_logic_vector(31 downto 0);
dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
dma_stb_o : out std_logic;
dma_we_o : out std_logic;
dma_cyc_o : out std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_dat_i : in std_logic_vector((32*g_DMA_WB_SLAVES_NB)-1 downto 0); -- Data in
dma_ack_i : in std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_stall_i : in std_logic--_vector(g_DMA_WB_SLAVES_NB-1 downto 0) -- for pipelined Wishbone
);
end component;
--used to generate the one_hz_p pulse
constant sim_clock_period : std_logic_vector(g_width-1 downto 0):=x"0001E848"; -- 1 ms at 125 MHz (tdc board clock)
constant syn_clock_period : std_logic_vector(g_width-1 downto 0):=x"07735940"; -- 1 s at 125 MHz (tdc board clock)
-- used for regular blinking of the red led
constant spec_led_period_sim : std_logic_vector(g_width-1 downto 0):=x"00004E20"; -- 1 ms at 20 MHz (spec board clock)
constant spec_led_period_syn : std_logic_vector(g_width-1 downto 0):=x"01312D00"; -- 1 s at 20 MHz (spec board clock)
signal spec_led_period : std_logic_vector(g_width-1 downto 0);
signal tdc_led_count_done : std_logic;
signal spec_led_count_done : std_logic;
-- will be registers of the core
signal pulse_delay : std_logic_vector(g_width-1 downto 0);
signal clock_period : std_logic_vector(g_width-1 downto 0);
signal gnum_reset : std_logic;
signal pll_cs : std_logic;
signal spec_clk : std_logic;
signal tdc_led_status : std_logic:='0';
signal tdc_led_trig1 : std_logic:='0';
signal tdc_led_trig2 : std_logic:='0';
signal tdc_led_trig3 : std_logic:='0';
signal tdc_led_trig4 : std_logic:='0';
signal tdc_led_trig5 : std_logic:='0';
signal spec_led_green : std_logic:='0';
signal spec_led_red : std_logic:='0';
signal acam_errflag_p : std_logic;
signal acam_intflag_p : std_logic;
signal acam_refclk : std_logic;
signal acam_start01 : std_logic_vector(16 downto 0);
signal acam_timestamp : std_logic_vector(28 downto 0);
signal acam_timestamp_valid : std_logic;
signal clk : std_logic;
signal full_timestamp : std_logic_vector(3*g_width-1 downto 0);
signal full_timestamp_valid : std_logic;
signal general_reset : std_logic;
signal one_hz_p : std_logic;
signal start_nb_offset : std_logic_vector(g_width-1 downto 0);
signal start_timer_reg : std_logic_vector(7 downto 0);
signal utc_current_time : std_logic_vector(g_width-1 downto 0);
signal acm_adr : std_logic_vector(19 downto 0);
signal acm_cyc : std_logic;
signal acm_stb : std_logic;
signal acm_we : std_logic;
signal acm_ack : std_logic;
signal acm_dat_r : std_logic_vector(g_width-1 downto 0);
signal acm_dat_w : std_logic_vector(g_width-1 downto 0);
signal dma_irq : std_logic_vector(1 downto 0);
signal irq_p : std_logic;
signal csr_adr : std_logic_vector(18 downto 0);
signal csr_dat_r : std_logic_vector(31 downto 0);
signal csr_sel : std_logic_vector(3 downto 0);
signal csr_stb : std_logic;
signal csr_we : std_logic;
signal csr_cyc : std_logic_vector(0 downto 0);
signal csr_dat_w : std_logic_vector(31 downto 0);
signal csr_ack : std_logic_vector(0 downto 0);
signal dma_adr : std_logic_vector(31 downto 0);
signal dma_dat_i : std_logic_vector(31 downto 0);
signal dma_sel : std_logic_vector(3 downto 0);
signal dma_stb : std_logic;
signal dma_we : std_logic;
signal dma_cyc : std_logic;
signal dma_dat_o : std_logic_vector(31 downto 0);
signal dma_ack : std_logic;
signal dma_stall : std_logic;
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
one_second_block: one_hz_gen
generic map(
g_width => g_width
)
port map(
acam_refclk_i => acam_refclk,
clk_i => clk,
clock_period_i => clock_period,
pulse_delay_i => pulse_delay,
reset_i => general_reset,
one_hz_p_o => one_hz_p
);
-- start_nb_block: start_nb_offset_gen
-- generic map(
-- g_width => g_width
-- )
-- port map(
-- acam_intflag_p_i => acam_intflag_p,
-- clk_i => clk,
-- one_hz_p_i => one_hz_p,
-- reset_i => general_reset,
--
-- start_nb_offset_o => start_nb_offset
-- );
-- data_formatting_block: data_formatting
-- generic map(
-- g_width => g_width
-- )
-- port map(
-- acam_start01_i => acam_start01,
-- acam_timestamp_i => acam_timestamp,
-- acam_timestamp_valid_i => acam_timestamp_valid,
-- clk_i => clk_i,
-- reset_i => general_reset,
-- start_nb_offset_i => start_nb_offset,
-- utc_current_time_i => utc_current_time,
--
-- full_timestamp_o => full_timestamp,
-- full_timestamp_valid_o => full_timestamp_valid
-- );
acam_timing_block: acam_timecontrol_interface
generic map(
g_width => g_width
)
port map(
-- signals external to the chip: interface with acam
err_flag_i => err_flag_i,
int_flag_i => int_flag_i,
-- this is the config for acam test, in normal application connect the outputs
start_dis_o => open,
stop_dis_o => open,
-- start_dis_o => start_dis_o,
-- stop_dis_o => stop_dis_o,
-- signals internal to the chip: interface with other modules
clk_i => clk,
one_hz_p_i => one_hz_p,
reset_i => general_reset,
acam_errflag_p_o => acam_errflag_p,
acam_intflag_p_o => acam_intflag_p
);
acam_data_block: acam_databus_interface
generic map(
g_width => g_width
)
port map(
-- signals external to the chip: interface with acam
ef1_i => ef1_i,
ef2_i => ef2_i,
lf1_i => lf1_i,
lf2_i => lf2_i,
data_bus_io => data_bus_io,
address_o => address_o,
cs_n_o => cs_n_o,
oe_n_o => oe_n_o,
rd_n_o => rd_n_o,
wr_n_o => wr_n_o,
-- signals internal to the chip: interface with other modules
clk_i => clk,
reset_i => general_reset,
adr_i => acm_adr,
cyc_i => acm_cyc,
dat_i => acm_dat_w,
stb_i => acm_stb,
we_i => acm_we,
ack_o => acm_ack,
dat_o => acm_dat_r
);
gnum_interface_block: gn4124_core
generic map(
g_CSR_WB_SLAVES_NB => 1
)
port map(
rst_n_a_i => rst_n_a_i,
p2l_pll_locked => open,
debug_o => open,
p2l_clk_p_i => p2l_clk_p_i,
p2l_clk_n_i => p2l_clk_n_i,
p2l_data_i => p2l_data_i,
p2l_dframe_i => p2l_dframe_i,
p2l_valid_i => p2l_valid_i,
p2l_rdy_o => p2l_rdy_o,
p_wr_req_i => p_wr_req_i,
p_wr_rdy_o => p_wr_rdy_o,
rx_error_o => rx_error_o,
vc_rdy_i => vc_rdy_i,
l2p_clk_p_o => l2p_clk_p_o,
l2p_clk_n_o => l2p_clk_n_o,
l2p_data_o => l2p_data_o ,
l2p_dframe_o => l2p_dframe_o,
l2p_valid_o => l2p_valid_o,
l2p_edb_o => l2p_edb_o,
l2p_rdy_i => l2p_rdy_i,
l_wr_rdy_i => l_wr_rdy_i,
p_rd_d_rdy_i => p_rd_d_rdy_i,
tx_error_i => tx_error_i,
irq_p_o => irq_p_o,
dma_irq_o => dma_irq,
irq_p_i => irq_p,
wb_clk_i => clk,
wb_adr_o => csr_adr,
wb_dat_o => csr_dat_w,
wb_sel_o => csr_sel,
wb_stb_o => csr_stb,
wb_we_o => csr_we,
wb_cyc_o => csr_cyc,
wb_dat_i => csr_dat_r,
wb_ack_i => csr_ack,
dma_clk_i => clk,
dma_adr_o => dma_adr,
dma_dat_o => dma_dat_i,
dma_sel_o => dma_sel,
dma_stb_o => dma_stb,
dma_we_o => dma_we,
dma_cyc_o => dma_cyc,
dma_dat_i => dma_dat_O,
dma_ack_i => dma_ack,
dma_stall_i => dma_stall
);
clocks_and_resets_management_block: clk_rst_managr
port map(
acam_refclk_i => acam_refclk_i,
pll_ld_i => pll_ld_i,
pll_refmon_i => pll_refmon_i,
pll_sdo_i => pll_sdo_i,
pll_status_i => pll_status_i,
gnum_reset_i => gnum_reset,
spec_clk_i => spec_clk_i,
tdc_clk_p_i => tdc_clk_p_i,
tdc_clk_n_i => tdc_clk_n_i,
acam_refclk_o => acam_refclk,
general_reset_o => general_reset,
pll_cs_o => pll_cs,
pll_dac_sync_o => pll_dac_sync_o,
pll_sdi_o => pll_sdi_o,
pll_sclk_o => pll_sclk_o,
spec_clk_o => spec_clk,
tdc_clk_o => clk
);
spec_led_counter: free_counter
port map(
clk => spec_clk,
enable => '1',
reset => gnum_reset,
start_value => spec_led_period,
count_done => spec_led_count_done,
current_value => open
);
spec_led_period <= spec_led_period_sim when values_for_simulation
else spec_led_period_syn;
spec_led: process
begin
if spec_led_count_done ='1' then
spec_led_red <= not(spec_led_red);
end if;
wait until spec_clk ='1';
end process;
spec_led_green <= pll_ld_i;
tdc_led_counter: countdown_counter
port map(
clk => clk,
reset => general_reset,
start => one_hz_p,
start_value => visible_blink_length,
count_done => tdc_led_count_done,
current_value => open
);
tdc_led_status <= not(tdc_led_count_done);
-- inputs
gnum_reset <= not(rst_n_a_i);
-- internal signals
acm_adr(19) <= '0';
acm_adr(18 downto 0) <= csr_adr;
acm_cyc <= csr_cyc(0);
acm_stb <= csr_stb;
acm_we <= csr_we;
acm_dat_w <= csr_dat_w;
csr_ack(0) <= acm_ack;
csr_dat_r <= acm_dat_r;
-- outputs
pll_cs_o <= pll_cs;
tdc_led_status_o <= tdc_led_status;
tdc_led_trig1_o <= tdc_led_trig1;
tdc_led_trig2_o <= tdc_led_trig2;
tdc_led_trig3_o <= tdc_led_trig3;
tdc_led_trig4_o <= tdc_led_trig4;
tdc_led_trig5_o <= tdc_led_trig5;
spec_led_green_o <= spec_led_green;
spec_led_red_o <= spec_led_red;
-- this is the config for acam test...
clock_period <= sim_clock_period when values_for_simulation
else syn_clock_period;
pulse_delay <= x"00000000";
start_dis_o <= '0';
stop_dis_o <= '0';
start_from_fpga_o <= one_hz_p when spec_aux1_i ='0' else not(spec_aux0_i);
spec_aux2_o <= spec_aux0_i;
spec_aux3_o <= spec_aux1_i;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : PLL test top level (top_tdc.vhd)
-- author : G. Penacoba
-- date : June 2011
-- version : Revision 1
-- description : top level for preliminary testing of the PLL on the TDC card
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
--use work.tdc_core_pkg.all;
--use work.gn4124_core_pkg.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for top_tdc
----------------------------------------------------------------------------------------------------
entity top_tdc is
generic(
g_width : integer :=32;
values_for_simulation : boolean :=FALSE
);
port(
-- interface with GNUM on SPEC carrier
rst_n_a_i : in std_logic;
-- P2L Direction
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i: in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
-- L2P Direction
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o: out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i: in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
-- interface signals with PLL circuit on TDC mezzanine
acam_refclk_i : in std_logic;
pll_ld_i : in std_logic;
pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
-- interface signals with acam (timing) on TDC mezzanine
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
-- interface signals with acam (data) on TDC mezzanine
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_i : in std_logic;
ef2_i : in std_logic;
lf1_i : in std_logic;
lf2_i : in std_logic;
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
-- other signals on the TDC mezzanine
mute_inputs_o : out std_logic;
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
term_en_1_o : out std_logic;
term_en_2_o : out std_logic;
term_en_3_o : out std_logic;
term_en_4_o : out std_logic;
term_en_5_o : out std_logic;
-- other signals on the SPEC carrier
spec_aux0_i : in std_logic;
spec_aux1_i : in std_logic;
spec_aux2_o : out std_logic;
spec_aux3_o : out std_logic;
spec_aux4_o : out std_logic;
spec_aux5_o : out std_logic;
spec_led_green_o : out std_logic;
spec_led_red_o : out std_logic;
spec_clk_i : in std_logic
);
end top_tdc;
----------------------------------------------------------------------------------------------------
-- architecture declaration for top_tdc
----------------------------------------------------------------------------------------------------
architecture rtl of top_tdc is
component clk_rst_managr
port(
acam_refclk_i : in std_logic;
pll_ld_i : in std_logic;
pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
gnum_reset_i : in std_logic;
spec_clk_i : in std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
acam_refclk_o : out std_logic;
general_reset_o : out std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
spec_clk_o : out std_logic;
tdc_clk_o : out std_logic
);
end component;
component free_counter is
generic(
width : integer :=32
);
port(
clk : in std_logic;
enable : in std_logic;
reset : in std_logic;
start_value : in std_logic_vector(width-1 downto 0);
count_done : out std_logic;
current_value : out std_logic_vector(width-1 downto 0)
);
end component;
constant tdc_led_period_sim : std_logic_vector(g_width-1 downto 0):=x"0000F424"; -- 0.5 ms at 125 MHz (tdc board clock)
constant tdc_led_period_syn : std_logic_vector(g_width-1 downto 0):=x"03B9ACA0"; -- 0.5 ms at 125 MHz (tdc board clock)
constant spec_led_period_sim : std_logic_vector(g_width-1 downto 0):=x"00004E20"; -- 1 ms at 20 MHz (spec board clock)
constant spec_led_period_syn : std_logic_vector(g_width-1 downto 0):=x"01312D00"; -- 1 s at 20 MHz (spec board clock)
signal tdc_led_period : std_logic_vector(g_width-1 downto 0);
signal spec_led_period : std_logic_vector(g_width-1 downto 0);
signal tdc_led_count_done : std_logic;
signal spec_led_count_done : std_logic;
-- will be registers of the core
signal pulse_delay : std_logic_vector(g_width-1 downto 0):=x"00000000";
signal clock_period : std_logic_vector(g_width-1 downto 0):=x"000030D4";
signal gnum_reset : std_logic;
signal pll_cs : std_logic;
signal tdc_led_status : std_logic:='0';
signal tdc_led_trig1 : std_logic:='0';
signal tdc_led_trig2 : std_logic:='0';
signal tdc_led_trig3 : std_logic:='0';
signal tdc_led_trig4 : std_logic:='0';
signal tdc_led_trig5 : std_logic:='0';
signal spec_led_green : std_logic:='0';
signal spec_led_red : std_logic:='0';
signal acam_errflag_p : std_logic;
signal acam_intflag_p : std_logic;
signal acam_start01 : std_logic_vector(16 downto 0);
signal acam_timestamp : std_logic_vector(28 downto 0);
signal acam_timestamp_valid : std_logic;
signal full_timestamp : std_logic_vector(3*g_width-1 downto 0);
signal full_timestamp_valid : std_logic;
signal one_hz_p : std_logic;
signal general_reset : std_logic;
signal start_nb_offset : std_logic_vector(g_width-1 downto 0);
signal start_timer_reg : std_logic_vector(7 downto 0);
signal utc_current_time : std_logic_vector(g_width-1 downto 0);
signal acm_adr : std_logic_vector(19 downto 0);
signal acm_cyc : std_logic;
signal acm_stb : std_logic;
signal acm_we : std_logic;
signal acm_ack : std_logic;
signal acm_dat_r : std_logic_vector(g_width-1 downto 0);
signal acm_dat_w : std_logic_vector(g_width-1 downto 0);
signal dma_irq : std_logic_vector(1 downto 0);
signal irq_p : std_logic;
signal csr_clk : std_logic;
signal csr_adr : std_logic_vector(18 downto 0);
signal csr_dat_r : std_logic_vector(31 downto 0);
signal csr_sel : std_logic_vector(3 downto 0);
signal csr_stb : std_logic;
signal csr_we : std_logic;
signal csr_cyc : std_logic_vector(0 downto 0);
signal csr_dat_w : std_logic_vector(31 downto 0);
signal csr_ack : std_logic_vector(0 downto 0);
signal dma_clk : std_logic;
signal dma_adr : std_logic_vector(31 downto 0);
signal dma_dat_i : std_logic_vector(31 downto 0);
signal dma_sel : std_logic_vector(3 downto 0);
signal dma_stb : std_logic;
signal dma_we : std_logic;
signal dma_cyc : std_logic;
signal dma_dat_o : std_logic_vector(31 downto 0);
signal dma_ack : std_logic;
signal dma_stall : std_logic;
signal acam_refclk : std_logic;
signal clk : std_logic;
signal spec_clk : std_logic;
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
clocks_and_resets_management_block: clk_rst_managr
port map(
acam_refclk_i => acam_refclk_i,
pll_ld_i => pll_ld_i,
pll_refmon_i => pll_refmon_i,
pll_sdo_i => pll_sdo_i,
pll_status_i => pll_status_i,
gnum_reset_i => gnum_reset,
spec_clk_i => spec_clk_i,
tdc_clk_p_i => tdc_clk_p_i,
tdc_clk_n_i => tdc_clk_n_i,
acam_refclk_o => acam_refclk,
general_reset_o => general_reset,
pll_cs_o => pll_cs,
pll_dac_sync_o => pll_dac_sync_o,
pll_sdi_o => pll_sdi_o,
pll_sclk_o => pll_sclk_o,
spec_clk_o => spec_clk,
tdc_clk_o => clk
);
tdc_led_counter: free_counter
port map(
clk => clk,
enable => '1',
reset => general_reset,
start_value => tdc_led_period,
count_done => tdc_led_count_done,
current_value => open
);
tdc_led_period <= tdc_led_period_sim when values_for_simulation
else tdc_led_period_syn;
spec_led_red_counter: free_counter
port map(
clk => spec_clk,
enable => '1',
reset => gnum_reset,
start_value => spec_led_period,
count_done => spec_led_count_done,
current_value => open
);
spec_led_period <= spec_led_period_sim when values_for_simulation
else spec_led_period_syn;
tdc_led: process
begin
if tdc_led_count_done ='1' then
tdc_led_status <= not(tdc_led_status);
end if;
wait until clk='1';
end process;
spec_led: process
begin
if spec_led_count_done ='1' then
spec_led_red <= not(spec_led_red);
end if;
wait until spec_clk ='1';
end process;
spec_led_green <= pll_ld_i;
-- inputs
gnum_reset <= not(rst_n_a_i);
-- outputs
pll_cs_o <= pll_cs;
tdc_led_status_o <= tdc_led_status;
spec_led_green_o <= spec_led_green;
spec_led_red_o <= spec_led_red;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : TDC top level (top_tdc.vhd)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : top level of tdc project
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tdc_core_pkg.all;
use work.gn4124_core_pkg.all;
----------------------------------------------------------------------------------------------------
-- entity declaration for top_tdc
----------------------------------------------------------------------------------------------------
entity top_tdc is
generic(
g_width : integer :=32;
values_for_simulation : boolean :=FALSE
);
port(
-- interface with GNUM
rst_n_a_i : in std_logic;
-- P2L Direction
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i: in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
-- L2P Direction
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o: out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i: in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
-- interface signals with PLL circuit on TDC mezzanine
acam_refclk_i : in std_logic;
pll_ld_i : in std_logic;
pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
-- interface signals with acam (timing) on TDC mezzanine
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
-- interface signals with acam (data) on TDC mezzanine
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_i : in std_logic;
ef2_i : in std_logic;
lf1_i : in std_logic;
lf2_i : in std_logic;
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
-- other signals on the TDC mezzanine
mute_inputs_o : out std_logic;
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
term_en_1_o : out std_logic;
term_en_2_o : out std_logic;
term_en_3_o : out std_logic;
term_en_4_o : out std_logic;
term_en_5_o : out std_logic;
-- other signals on the SPEC carrier
spec_aux0_i : in std_logic;
spec_aux1_i : in std_logic;
spec_aux2_o : out std_logic;
spec_aux3_o : out std_logic;
spec_aux4_o : out std_logic;
spec_aux5_o : out std_logic;
spec_led_green_o : out std_logic;
spec_led_red_o : out std_logic;
spec_clk_i : in std_logic
);
end top_tdc;
----------------------------------------------------------------------------------------------------
-- architecture declaration for top_tdc
----------------------------------------------------------------------------------------------------
architecture rtl of top_tdc is
component one_hz_gen
generic(
g_width : integer :=32
);
port(
acam_refclk_i : in std_logic;
clk_i : in std_logic;
clock_period_i : in std_logic_vector(g_width-1 downto 0);
pulse_delay_i : in std_logic_vector(g_width-1 downto 0);
reset_i : in std_logic;
one_hz_p_o : out std_logic
);
end component;
-- component start_nb_offset_gen is
-- generic(
-- g_width : integer :=32
-- );
-- port(
-- acam_intflag_p_i : in std_logic;
-- clk_i : in std_logic;
-- one_hz_p_i : in std_logic;
-- reset_i : in std_logic;
--
-- start_nb_offset_o : out std_logic_vector(g_width-1 downto 0)
-- );
-- end component;
--
-- component data_formatting
-- generic(
-- g_width : integer :=32
-- );
-- port(
-- acam_start01_i : in std_logic_vector(16 downto 0);
-- acam_timestamp_i : in std_logic_vector(28 downto 0);
-- acam_timestamp_valid_i : in std_logic;
-- clk_i : in std_logic;
-- reset_i : in std_logic;
-- start_nb_offset_i : in std_logic_vector(g_width-1 downto 0);
-- utc_current_time_i : in std_logic_vector(g_width-1 downto 0);
--
-- full_timestamp_o : out std_logic_vector(3*g_width-1 downto 0);
-- full_timestamp_valid_o : out std_logic
-- );
-- end component;
component acam_timecontrol_interface
generic(
g_width : integer :=32
);
port(
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
stop_dis_o : out std_logic;
clk_i : in std_logic;
one_hz_p_i : in std_logic;
reset_i : in std_logic;
acam_errflag_p_o : out std_logic;
acam_intflag_p_o : out std_logic
);
end component;
component acam_databus_interface
generic(
g_width : integer :=32
);
port(
ef1_i : in std_logic;
ef2_i : in std_logic;
lf1_i : in std_logic;
lf2_i : in std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
clk_i : in std_logic;
reset_i : in std_logic;
adr_i : in std_logic_vector(19 downto 0);
cyc_i : in std_logic;
dat_i : in std_logic_vector(31 downto 0);
stb_i : in std_logic;
we_i : in std_logic;
ack_o : out std_logic;
dat_o : out std_logic_vector(31 downto 0)
);
end component;
component clk_rst_managr
port(
acam_refclk_i : in std_logic;
pll_ld_i : in std_logic;
pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
gnum_reset_i : in std_logic;
spec_clk_i : in std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
acam_refclk_o : out std_logic;
general_reset_o : out std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
spec_clk_o : out std_logic;
tdc_clk_o : out std_logic
);
end component;
component gn4124_core
generic(
g_BAR0_APERTURE : integer := 20; -- BAR0 aperture, defined in GN4124 PCI_BAR_CONFIG register (0x80C)
-- => number of bits to address periph on the board
g_CSR_WB_SLAVES_NB : integer := 1; -- Number of CSR wishbone slaves
g_DMA_WB_SLAVES_NB : integer := 1; -- Number of DMA wishbone slaves
g_DMA_WB_ADDR_WIDTH : integer := 26 -- DMA wishbone address bus width
);
port
(
---------------------------------------------------------
-- Control and status
--
-- Asynchronous reset from GN4124
rst_n_a_i : in std_logic;
-- P2L clock PLL locked
p2l_pll_locked : out std_logic;
-- Debug ouputs
debug_o : out std_logic_vector(7 downto 0);
---------------------------------------------------------
-- P2L Direction
--
-- Source Sync DDR related signals
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i : in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
-- P2L Control
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
---------------------------------------------------------
-- L2P Direction
--
-- Source Sync DDR related signals
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o : out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
-- L2P Control
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i : in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
---------------------------------------------------------
-- Interrupt interface
dma_irq_o : out std_logic_vector(1 downto 0); -- Interrupts sources to IRQ manager
irq_p_i : in std_logic; -- Interrupt request pulse from IRQ manager
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
---------------------------------------------------------
-- Target interface (CSR wishbone master)
wb_clk_i : in std_logic;
wb_adr_o : out std_logic_vector(g_BAR0_APERTURE-log2_ceil(g_CSR_WB_SLAVES_NB+1)-1 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic;
wb_we_o : out std_logic;
wb_cyc_o : out std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
wb_dat_i : in std_logic_vector((32*g_CSR_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_CSR_WB_SLAVES_NB-1 downto 0);
---------------------------------------------------------
-- DMA interface (Pipelined wishbone master)
dma_clk_i : in std_logic;
dma_adr_o : out std_logic_vector(31 downto 0);
dma_dat_o : out std_logic_vector(31 downto 0); -- Data out
dma_sel_o : out std_logic_vector(3 downto 0); -- Byte select
dma_stb_o : out std_logic;
dma_we_o : out std_logic;
dma_cyc_o : out std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_dat_i : in std_logic_vector((32*g_DMA_WB_SLAVES_NB)-1 downto 0); -- Data in
dma_ack_i : in std_logic; --_vector(g_DMA_WB_SLAVES_NB-1 downto 0);
dma_stall_i : in std_logic--_vector(g_DMA_WB_SLAVES_NB-1 downto 0) -- for pipelined Wishbone
);
end component;
constant sim_clock_period : std_logic_vector(g_width-1 downto 0):=x"0001E848"; -- 1 ms
constant syn_clock_period : std_logic_vector(g_width-1 downto 0):=x"07735940"; -- 1 s
signal tdc_led_period : std_logic_vector(g_width-1 downto 0);
signal spec_led_period : std_logic_vector(g_width-1 downto 0);
signal tdc_led_count_done : std_logic;
signal spec_led_count_done : std_logic;
-- will be registers of the core
signal pulse_delay : std_logic_vector(g_width-1 downto 0);
signal clock_period : std_logic_vector(g_width-1 downto 0);
signal gnum_reset : std_logic;
signal pll_cs : std_logic;
signal spec_clk : std_logic;
signal tdc_led_status : std_logic:='0';
signal tdc_led_trig1 : std_logic:='0';
signal tdc_led_trig2 : std_logic:='0';
signal tdc_led_trig3 : std_logic:='0';
signal tdc_led_trig4 : std_logic:='0';
signal tdc_led_trig5 : std_logic:='0';
signal spec_led_green : std_logic:='0';
signal spec_led_red : std_logic:='0';
signal acam_errflag_p : std_logic;
signal acam_intflag_p : std_logic;
signal acam_refclk : std_logic;
signal acam_start01 : std_logic_vector(16 downto 0);
signal acam_timestamp : std_logic_vector(28 downto 0);
signal acam_timestamp_valid : std_logic;
signal clk : std_logic;
signal full_timestamp : std_logic_vector(3*g_width-1 downto 0);
signal full_timestamp_valid : std_logic;
signal general_reset : std_logic;
signal one_hz_p : std_logic;
signal start_nb_offset : std_logic_vector(g_width-1 downto 0);
signal start_timer_reg : std_logic_vector(7 downto 0);
signal utc_current_time : std_logic_vector(g_width-1 downto 0);
signal acm_adr : std_logic_vector(19 downto 0);
signal acm_cyc : std_logic;
signal acm_stb : std_logic;
signal acm_we : std_logic;
signal acm_ack : std_logic;
signal acm_dat_r : std_logic_vector(g_width-1 downto 0);
signal acm_dat_w : std_logic_vector(g_width-1 downto 0);
signal dma_irq : std_logic_vector(1 downto 0);
signal irq_p : std_logic;
signal csr_adr : std_logic_vector(18 downto 0);
signal csr_dat_r : std_logic_vector(31 downto 0);
signal csr_sel : std_logic_vector(3 downto 0);
signal csr_stb : std_logic;
signal csr_we : std_logic;
signal csr_cyc : std_logic_vector(0 downto 0);
signal csr_dat_w : std_logic_vector(31 downto 0);
signal csr_ack : std_logic_vector(0 downto 0);
signal dma_adr : std_logic_vector(31 downto 0);
signal dma_dat_i : std_logic_vector(31 downto 0);
signal dma_sel : std_logic_vector(3 downto 0);
signal dma_stb : std_logic;
signal dma_we : std_logic;
signal dma_cyc : std_logic;
signal dma_dat_o : std_logic_vector(31 downto 0);
signal dma_ack : std_logic;
signal dma_stall : std_logic;
----------------------------------------------------------------------------------------------------
-- architecture begins
----------------------------------------------------------------------------------------------------
begin
one_second_block: one_hz_gen
generic map(
g_width => g_width
)
port map(
acam_refclk_i => acam_refclk,
clk_i => clk,
clock_period_i => clock_period,
pulse_delay_i => pulse_delay,
reset_i => general_reset,
one_hz_p_o => one_hz_p
);
-- start_nb_block: start_nb_offset_gen
-- generic map(
-- g_width => g_width
-- )
-- port map(
-- acam_intflag_p_i => acam_intflag_p,
-- clk_i => clk,
-- one_hz_p_i => one_hz_p,
-- reset_i => general_reset,
--
-- start_nb_offset_o => start_nb_offset
-- );
-- data_formatting_block: data_formatting
-- generic map(
-- g_width => g_width
-- )
-- port map(
-- acam_start01_i => acam_start01,
-- acam_timestamp_i => acam_timestamp,
-- acam_timestamp_valid_i => acam_timestamp_valid,
-- clk_i => clk_i,
-- reset_i => general_reset,
-- start_nb_offset_i => start_nb_offset,
-- utc_current_time_i => utc_current_time,
--
-- full_timestamp_o => full_timestamp,
-- full_timestamp_valid_o => full_timestamp_valid
-- );
acam_timing_block: acam_timecontrol_interface
generic map(
g_width => g_width
)
port map(
-- signals external to the chip: interface with acam
err_flag_i => err_flag_i,
int_flag_i => int_flag_i,
-- this is the config for acam test, in normal application connect the outputs
start_dis_o => open,
stop_dis_o => open,
-- start_dis_o => start_dis_o,
-- stop_dis_o => stop_dis_o,
-- signals internal to the chip: interface with other modules
clk_i => clk,
one_hz_p_i => one_hz_p,
reset_i => general_reset,
acam_errflag_p_o => acam_errflag_p,
acam_intflag_p_o => acam_intflag_p
);
acam_data_block: acam_databus_interface
generic map(
g_width => g_width
)
port map(
-- signals external to the chip: interface with acam
ef1_i => ef1_i,
ef2_i => ef2_i,
lf1_i => lf1_i,
lf2_i => lf2_i,
data_bus_io => data_bus_io,
address_o => address_o,
cs_n_o => cs_n_o,
oe_n_o => oe_n_o,
rd_n_o => rd_n_o,
wr_n_o => wr_n_o,
-- signals internal to the chip: interface with other modules
clk_i => clk,
reset_i => general_reset,
adr_i => acm_adr,
cyc_i => acm_cyc,
dat_i => acm_dat_w,
stb_i => acm_stb,
we_i => acm_we,
ack_o => acm_ack,
dat_o => acm_dat_r
);
gnum_interface_block: gn4124_core
generic map(
g_CSR_WB_SLAVES_NB => 1
)
port map(
rst_n_a_i => rst_n_a_i,
p2l_pll_locked => open,
debug_o => open,
p2l_clk_p_i => p2l_clk_p_i,
p2l_clk_n_i => p2l_clk_n_i,
p2l_data_i => p2l_data_i,
p2l_dframe_i => p2l_dframe_i,
p2l_valid_i => p2l_valid_i,
p2l_rdy_o => p2l_rdy_o,
p_wr_req_i => p_wr_req_i,
p_wr_rdy_o => p_wr_rdy_o,
rx_error_o => rx_error_o,
vc_rdy_i => vc_rdy_i,
l2p_clk_p_o => l2p_clk_p_o,
l2p_clk_n_o => l2p_clk_n_o,
l2p_data_o => l2p_data_o ,
l2p_dframe_o => l2p_dframe_o,
l2p_valid_o => l2p_valid_o,
l2p_edb_o => l2p_edb_o,
l2p_rdy_i => l2p_rdy_i,
l_wr_rdy_i => l_wr_rdy_i,
p_rd_d_rdy_i => p_rd_d_rdy_i,
tx_error_i => tx_error_i,
irq_p_o => irq_p_o,
dma_irq_o => dma_irq,
irq_p_i => irq_p,
wb_clk_i => clk,
wb_adr_o => csr_adr,
wb_dat_o => csr_dat_w,
wb_sel_o => csr_sel,
wb_stb_o => csr_stb,
wb_we_o => csr_we,
wb_cyc_o => csr_cyc,
wb_dat_i => csr_dat_r,
wb_ack_i => csr_ack,
dma_clk_i => clk,
dma_adr_o => dma_adr,
dma_dat_o => dma_dat_i,
dma_sel_o => dma_sel,
dma_stb_o => dma_stb,
dma_we_o => dma_we,
dma_cyc_o => dma_cyc,
dma_dat_i => dma_dat_O,
dma_ack_i => dma_ack,
dma_stall_i => dma_stall
);
clocks_and_resets_management_block: clk_rst_managr
port map(
acam_refclk_i => acam_refclk_i,
pll_ld_i => pll_ld_i,
pll_refmon_i => pll_refmon_i,
pll_sdo_i => pll_sdo_i,
pll_status_i => pll_status_i,
gnum_reset_i => gnum_reset,
spec_clk_i => spec_clk_i,
tdc_clk_p_i => tdc_clk_p_i,
tdc_clk_n_i => tdc_clk_n_i,
acam_refclk_o => acam_refclk,
general_reset_o => general_reset,
pll_cs_o => pll_cs,
pll_dac_sync_o => pll_dac_sync_o,
pll_sdi_o => pll_sdi_o,
pll_sclk_o => pll_sclk_o,
spec_clk_o => spec_clk,
tdc_clk_o => clk
);
spec_led_counter: free_counter
port map(
clk => spec_clk,
enable => '1',
reset => gnum_reset,
start_value => spec_led_period,
count_done => spec_led_count_done,
current_value => open
);
spec_led_period <= spec_led_period_sim when values_for_simulation
else spec_led_period_syn;
spec_led: process
begin
if spec_led_count_done ='1' then
spec_led_red <= not(spec_led_red);
end if;
wait until spec_clk ='1';
end process;
spec_led_green <= pll_ld_i;
tdc_led_counter: countdown_counter
port map(
clk => clk,
reset => general_reset,
start => one_hz_p,
start_value => visible_blink_length,
count_done => tdc_led_count_done,
current_value => open
);
tdc_led_status <= not(tdc_led_count_done);
-- inputs
gnum_reset <= not(rst_n_a_i);
-- internal signals
acm_adr(19) <= '0';
acm_adr(18 downto 0) <= csr_adr;
acm_cyc <= csr_cyc(0);
acm_stb <= csr_stb;
acm_we <= csr_we;
acm_dat_w <= csr_dat_w;
csr_ack(0) <= acm_ack;
csr_dat_r <= acm_dat_r;
clock_period <= sim_clock_period when values_for_simulation
else syn_clock_period;
pulse_delay <= x"00000000";
-- outputs
pll_cs_o <= pll_cs;
tdc_led_status_o <= tdc_led_status;
tdc_led_trig1_o <= tdc_led_trig1;
tdc_led_trig2_o <= tdc_led_trig2;
tdc_led_trig3_o <= tdc_led_trig3;
tdc_led_trig4_o <= tdc_led_trig4;
tdc_led_trig5_o <= tdc_led_trig5;
spec_led_green_o <= spec_led_green;
spec_led_red_o <= spec_led_red;
-- this is the config for acam test...
start_dis_o <= '0';
stop_dis_o <= '0';
start_from_fpga_o <= one_hz_p when spec_aux1_i ='0' else not(spec_aux0_i);
spec_aux2_o <= spec_aux0_i;
spec_aux3_o <= spec_aux1_i;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
-- Created by : G. Penacoba
-- Creation Date: June 2011
-- Description: reproduced roughly the functionality of the acam:
-- handles the FIFO and the data communication handshake
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity acam_data_model is
port(
start01_i : in std_logic_vector(16 downto 0);
timestamp_for_fifo1 : in std_logic_vector(27 downto 0);
timestamp_for_fifo2 : in std_logic_vector(27 downto 0);
address_i : in std_logic_vector(3 downto 0);
cs_n_i : in std_logic;
oe_n_i : in std_logic;
rd_n_i : in std_logic;
wr_n_i : in std_logic;
data_bus_o : out std_logic_vector(27 downto 0);
ef1_o : out std_logic;
ef2_o : out std_logic;
lf1_o : out std_logic;
lf2_o : out std_logic
);
end acam_data_model;
architecture behavioral of acam_data_model is
component acam_fifo_model
generic(
size : integer;
full_threshold : integer;
empty_threshold : integer
);
port(
data_input : in std_logic_vector(27 downto 0);
rd_fifo : in std_logic;
data_output : out std_logic_vector(27 downto 0);
empty : out std_logic;
full : out std_logic
);
end component;
constant ts_ad : time:= 2000 ps; -- minimum address setup time
constant th_ad : time:= 0 ps; -- minimum address hold time
constant tpw_rl : time:= 6000 ps; -- minimum read low time
constant tpw_rh : time:= 6000 ps; -- minimum read high time
constant tpw_wl : time:= 6000 ps; -- minimum write low time
constant tpw_wh : time:= 6000 ps; -- minimum write high time
constant tv_dr : time:= 11800 ps; -- maximum read data valid time
constant th_dr : time:= 4000 ps; -- minimum read data hold time
constant ts_dw : time:= 5000 ps; -- minimum write data setup time
constant th_dw : time:= 4000 ps; -- minimum write data hold time
constant ts_csn : time:= 0 ps; -- minimum chip select setup time
constant th_csn : time:= 0 ps; -- minimum chip select hold time
constant ts_ef : time:= 11800 ps; -- maximum empty flag set time
signal address : std_logic_vector(3 downto 0);
signal cs_n : std_logic;
signal oe_n : std_logic;
signal rd_n : std_logic;
signal wr_n : std_logic;
signal data_bus : std_logic_vector(27 downto 0):= (others =>'Z');
signal ef1 : std_logic;
signal ef2 : std_logic;
signal lf1 : std_logic;
signal lf2 : std_logic;
signal address_change_time : time:= 0 ps;
signal data_change_time : time:= 0 ps;
signal cs_falling_time : time:= 0 ps;
signal cs_rising_time : time:= 0 ps;
signal rd_falling_time : time:= 0 ps;
signal rd_rising_time : time:= 0 ps;
signal wr_falling_time : time:= 0 ps;
signal wr_rising_time : time:= 0 ps;
signal start01 : std_logic_vector(16 downto 0);
signal data_for_bus : std_logic_vector(27 downto 0);
signal data_from_fifo1 : std_logic_vector(27 downto 0);
signal data_from_fifo2 : std_logic_vector(27 downto 0);
signal rd_fifo1 : std_logic;
signal rd_fifo2 : std_logic;
begin
read: process
begin
wait until rd_n ='0';
if cs_n ='0' then
wait for tv_dr;
data_bus <= data_for_bus;
end if;
wait until rd_n ='1';
if cs_n ='0' then
wait for th_dr;
data_bus <= (others =>'Z');
end if;
end process;
data_mux: process(address, data_from_fifo1, data_from_fifo2, start01, rd_n, cs_n)
begin
case address is
when x"8" =>
data_for_bus <= data_from_fifo1;
if rd_n ='0' and cs_n ='0' then
rd_fifo1 <= '1';
rd_fifo2 <= '0';
else
rd_fifo1 <= '0';
rd_fifo2 <= '0';
end if;
when x"9" =>
data_for_bus <= data_from_fifo2;
if rd_n ='0' and cs_n ='0' then
rd_fifo1 <= '0';
rd_fifo2 <= '1';
else
rd_fifo1 <= '0';
rd_fifo2 <= '0';
end if;
when x"A" =>
data_for_bus <= "00000000000" & start01;
rd_fifo1 <= '0';
rd_fifo2 <= '0';
when others =>
data_for_bus <= (others => 'Z');
rd_fifo1 <= '0';
rd_fifo2 <= '0';
end case;
end process;
interface_fifo1: acam_fifo_model
generic map(
size => 256,
full_threshold => 20,
empty_threshold => 10
)
port map(
data_input => timestamp_for_fifo1,
rd_fifo => rd_fifo1,
data_output => data_from_fifo1,
empty => ef1,
full => lf1
);
interface_fifo2: acam_fifo_model
generic map(
size => 256,
full_threshold => 20,
empty_threshold => 10
)
port map(
data_input => timestamp_for_fifo2,
rd_fifo => rd_fifo2,
data_output => data_from_fifo2,
empty => ef2,
full => lf2
);
start01 <= start01_i;
address <= address_i;
cs_n <= cs_n_i;
oe_n <= oe_n_i;
rd_n <= rd_n_i;
wr_n <= wr_n_i;
data_bus_o <= data_bus;
ef1_o <= ef1;
ef2_o <= ef2;
lf1_o <= lf1;
lf2_o <= lf2;
address_timing: process(address)
begin
address_change_time <= now;
end process;
data_timing: process(address)
begin
data_change_time <= now;
end process;
read_timing: process(rd_n)
begin
if falling_edge(rd_n) then
rd_falling_time <= now;
end if;
if rising_edge(rd_n) then
rd_rising_time <= now;
end if;
end process;
write_timing: process(wr_n)
begin
if falling_edge(wr_n) then
wr_falling_time <= now;
end if;
if rising_edge(wr_n) then
wr_rising_time <= now;
end if;
end process;
chip_select_timing: process(cs_n)
begin
if falling_edge(cs_n) then
cs_falling_time <= now;
end if;
if rising_edge(cs_n) then
cs_rising_time <= now;
end if;
end process;
reporting_read_times: process(rd_falling_time, rd_rising_time)
begin
if rd_rising_time - rd_falling_time < tpw_rl
and rd_rising_time - rd_falling_time > 0 ps
and now /= 0 ps then
report LF & " #### Timing error in read signal when reading: minimum low time not respected" & LF
severity warning;
end if;
if rd_falling_time - rd_rising_time < tpw_rh
and rd_falling_time - rd_rising_time > 0 ps
and now /= 0 ps then
report LF & " #### Timing error in read signal when reading: minimum high time not respected" & LF
severity warning;
end if;
end process;
reporting_write_times: process(wr_falling_time, wr_rising_time)
begin
if wr_rising_time - wr_falling_time < tpw_wl
and wr_rising_time - wr_falling_time > 0 ps
and now /= 0 ps then
report LF & " #### Timing error in read signal when writing: minimum low time not respected" & LF
severity warning;
end if;
if wr_falling_time - wr_rising_time < tpw_wh
and wr_falling_time - wr_rising_time > 0 ps
and now /= 0 ps then
report " #### Timing error in read signal when writing: minimum high time not respected" & LF
severity warning;
end if;
end process;
reporting_setup_rd: process(rd_falling_time)
begin
if rd_falling_time - address_change_time < ts_ad and now /= 0 ps then
report LF & " #### Timing error in address bus when reading: minimum setup time not respected" & LF
severity warning;
end if;
if rd_falling_time - cs_falling_time < ts_csn and now /= 0 ps then
report LF & " #### Timing error in chip select signal when reading: minimum setup time not respected" & LF
severity warning;
end if;
end process;
reporting_setup_wr: process(wr_falling_time)
begin
if wr_falling_time - address_change_time < ts_ad and now /= 0 ps then
report LF & " #### Timing error in address bus when writing: minimum setup time not respected" & LF
severity warning;
end if;
if wr_falling_time - cs_falling_time < ts_csn then
report LF & " #### Timing error in chip select signal when writing: minimum setup time not respected" & LF
severity warning;
end if;
end process;
reporting_hold_ad: process(address_change_time)
begin
if address_change_time - rd_rising_time < th_ad and now /= 0 ps then
report LF & " #### Timing error in address bus when reading: minimum hold time not respected" & LF
severity warning;
end if;
if address_change_time - wr_rising_time < th_ad and now /= 0 ps then
report LF & " #### Timing error in address bus when writing: minimum hold time not respected" & LF
severity warning;
end if;
end process;
reporting_hold_cs: process(cs_rising_time)
begin
if cs_rising_time - rd_rising_time < th_csn and now /= 0 ps then
report LF & " #### Timing error in chip select signal when reading: minimum hold time not respected" & LF
severity warning;
end if;
if cs_rising_time - wr_rising_time < th_csn and now /= 0 ps then
report LF & " #### Timing error in chip select signal when writing: minimum hold time not respected" & LF
severity warning;
end if;
end process;
reporting_data_setup_wr: process(wr_rising_time)
begin
if wr_rising_time - data_change_time < ts_dw and now /= 0 ps then
report LF & " #### Timing error in data bus when writing: minimum setup time not respected" & LF
severity warning;
end if;
end process;
reporting_data_hold_wr: process(data_change_time)
begin
if data_change_time - wr_rising_time < th_dw and now /= 0 ps then
report LF & " #### Timing error in data bus when writing: minimum hold time not respected" & LF
severity warning;
end if;
end process;
end behavioral;
-- Created by : G. Penacoba
-- Creation Date: June 2011
-- Description: reproduces roughly the functionality of the acam:
-- handles the FIFO and the data communication handshake
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity acam_fifo_model is
generic(
size : integer;
full_threshold : integer;
empty_threshold : integer
);
port(
data_input : in std_logic_vector(27 downto 0);
rd_fifo : in std_logic;
data_output : out std_logic_vector(27 downto 0);
empty : out std_logic;
full : out std_logic
);
end acam_fifo_model;
architecture behavioral of acam_fifo_model is
subtype index is natural range size-1 downto 0;
subtype memory_cell is std_logic_vector(27 downto 0);
type memory_block is array (natural range size-1 downto 0) of memory_cell;
signal fifo : memory_block;
signal wr_pointer : index:= 0;
signal rd_pointer : index:= 0;
signal level : index:= 0;
begin
writing: process(data_input)
begin
if now /= 0 ps then
fifo(wr_pointer) <= data_input;
if wr_pointer = size-1 then
wr_pointer <= 0;
else
wr_pointer <= wr_pointer + 1;
end if;
end if;
end process;
reading: process(rd_fifo)
begin
if rising_edge(rd_fifo) then
data_output <= fifo(rd_pointer);
end if;
if falling_edge(rd_fifo) then
if rd_pointer = size-1 then
rd_pointer <= 0;
else
rd_pointer <= rd_pointer + 1;
end if;
end if;
end process;
flags: process(level)
begin
if level > full_threshold then
full <= '1';
else
full <= '0';
end if;
if level < empty_threshold then
empty <= '1';
else
empty <= '0';
end if;
end process;
filling_level: process(rd_pointer, wr_pointer)
begin
if wr_pointer >= rd_pointer then
level <= wr_pointer - rd_pointer;
else
level <= wr_pointer + 256 - rd_pointer;
end if;
end process;
-- process(level)
-- begin
-- report " filling level " & integer'image(level) & LF &
-- " rd_pointer " & integer'image(rd_pointer) & LF &
-- " wr_pointer " & integer'image(wr_pointer) & LF;
-- end process;
corruption_reporting_reading: process(rd_pointer)
begin
if now /= 0 ps then
if rd_pointer = wr_pointer then
report LF & " #### Interface FIFO is empty: no further reading should be performed" & LF
severity warning;
end if;
end if;
end process;
corruption_reporting_writing: process(wr_pointer)
begin
if now /= 0 ps then
if rd_pointer = wr_pointer then
report LF & " #### Interface FIFO is full: no further writing should be performed" & LF
severity warning;
end if;
end if;
end process;
end behavioral;
-- Creation Date: May 2011
-- Description: reproduced roughly the functionality of the acam:
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity acam_model is
generic(
start_retrig_period : time:= 3200 ns;
refclk_period : time:= 32 ns
);
port(
tstart_i : in std_logic;
tstop1_i : in std_logic;
tstop2_i : in std_logic;
tstop3_i : in std_logic;
tstop4_i : in std_logic;
tstop5_i : in std_logic;
startdis_i : in std_logic;
stopdis_i : in std_logic;
int_flag_o : out std_logic;
err_flag_o : out std_logic;
address_i : in std_logic_vector(3 downto 0);
cs_n_i : in std_logic;
oe_n_i : in std_logic;
rd_n_i : in std_logic;
wr_n_i : in std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_o : out std_logic;
ef2_o : out std_logic;
lf1_o : out std_logic;
lf2_o : out std_logic
);
end acam_model;
architecture behavioral of acam_model is
component acam_timing_model
generic(
refclk_period : time:= 32 ns;
start_retrig_period : time:= 3200 ns
);
port(
tstart_i : in std_logic;
tstop1_i : in std_logic;
tstop2_i : in std_logic;
tstop3_i : in std_logic;
tstop4_i : in std_logic;
tstop5_i : in std_logic;
startdis_i : in std_logic;
stopdis_i : in std_logic;
err_flag_o : out std_logic;
int_flag_o : out std_logic;
start01_o : out std_logic_vector(16 downto 0);
timestamp_for_fifo1 : out std_logic_vector(27 downto 0);
timestamp_for_fifo2 : out std_logic_vector(27 downto 0)
);
end component;
component acam_data_model
port(
start01_i : in std_logic_vector(16 downto 0);
timestamp_for_fifo1 : in std_logic_vector(27 downto 0);
timestamp_for_fifo2 : in std_logic_vector(27 downto 0);
address_i : in std_logic_vector(3 downto 0);
cs_n_i : in std_logic;
oe_n_i : in std_logic;
rd_n_i : in std_logic;
wr_n_i : in std_logic;
data_bus_o : out std_logic_vector(27 downto 0);
ef1_o : out std_logic;
ef2_o : out std_logic;
lf1_o : out std_logic;
lf2_o : out std_logic
);
end component;
signal timestamp_for_fifo1 : std_logic_vector(27 downto 0);
signal timestamp_for_fifo2 : std_logic_vector(27 downto 0);
signal start01 : std_logic_vector(16 downto 0);
begin
timing_block: acam_timing_model
generic map(
refclk_period => refclk_period,
start_retrig_period => start_retrig_period
)
port map(
tstart_i => tstart_i,
tstop1_i => tstop1_i,
tstop2_i => tstop2_i,
tstop3_i => tstop3_i,
tstop4_i => tstop4_i,
tstop5_i => tstop5_i,
startdis_i => startdis_i,
stopdis_i => stopdis_i,
err_flag_o => err_flag_o,
int_flag_o => int_flag_o,
start01_o => start01,
timestamp_for_fifo1 => timestamp_for_fifo1,
timestamp_for_fifo2 => timestamp_for_fifo2
);
data_block: acam_data_model
port map(
start01_i => start01,
timestamp_for_fifo1 => timestamp_for_fifo1,
timestamp_for_fifo2 => timestamp_for_fifo2,
address_i => address_i,
cs_n_i => cs_n_i,
oe_n_i => oe_n_i,
rd_n_i => rd_n_i,
wr_n_i => wr_n_i,
data_bus_o => data_bus_io,
ef1_o => ef1_o,
ef2_o => ef2_o,
lf1_o => lf1_o,
lf2_o => lf2_o
);
end behavioral;
-- Created by : G. Penacoba
-- Creation Date: May 2011
-- Description: reproduced roughly the functionality of the acam:
-- measures the time between input pulses.
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity acam_timing_model is
generic(
refclk_period : time:= 32 ns;
start_retrig_period : time:= 3200 ns
);
port(
tstart_i : in std_logic;
tstop1_i : in std_logic;
tstop2_i : in std_logic;
tstop3_i : in std_logic;
tstop4_i : in std_logic;
tstop5_i : in std_logic;
startdis_i : in std_logic;
stopdis_i : in std_logic;
err_flag_o : out std_logic;
int_flag_o : out std_logic;
start01_o : out std_logic_vector(16 downto 0);
timestamp_for_fifo1 : out std_logic_vector(27 downto 0);
timestamp_for_fifo2 : out std_logic_vector(27 downto 0)
);
end acam_timing_model;
architecture behavioral of acam_timing_model is
constant resolution : time:= 81 ps;
signal tstart : std_logic;
signal tstop1 : std_logic;
signal tstop2 : std_logic;
signal tstop3 : std_logic;
signal tstop4 : std_logic;
signal tstop5 : std_logic;
signal startdis : std_logic;
signal stopdis : std_logic;
signal intflag : std_logic;
signal start01_reg : std_logic_vector(16 downto 0);
signal start01 : time:= 0 ps;
signal start_trig : time:= 0 ps;
signal stop1_trig : time:= 0 ps;
signal stop2_trig : time:= 0 ps;
signal stop3_trig : time:= 0 ps;
signal stop4_trig : time:= 0 ps;
signal stop5_trig : time:= 0 ps;
signal stop1 : time:= 0 ps;
signal stop2 : time:= 0 ps;
signal stop3 : time:= 0 ps;
signal stop4 : time:= 0 ps;
signal stop5 : time:= 0 ps;
signal start_nb1 : integer:=0;
signal start_nb2 : integer:=0;
signal start_nb3 : integer:=0;
signal start_nb4 : integer:=0;
signal start_nb5 : integer:=0;
signal start_retrig_nb : integer:=0;
signal start_retrig_p : std_logic;
begin
listening: process (tstart, tstop1, tstop2, tstop3, tstop4, tstop5)
begin
if rising_edge(tstart) then
if startdis ='0' then
start_trig <= now;
end if;
end if;
if rising_edge(tstop1) then
if stopdis ='0' then
stop1_trig <= now;
end if;
end if;
if rising_edge(tstop2) then
if stopdis ='0' then
stop2_trig <= now;
end if;
end if;
if rising_edge(tstop3) then
if stopdis ='0' then
stop3_trig <= now;
end if;
end if;
if rising_edge(tstop4) then
if stopdis ='0' then
stop4_trig <= now;
end if;
end if;
if rising_edge(tstop5) then
if stopdis ='0' then
stop5_trig <= now;
end if;
end if;
end process;
measuring1: process(stop1_trig)
begin
if start_retrig_nb > 1 then
stop1 <= (stop1_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop1 <= (stop1_trig-start_trig-start01);
else
stop1 <= (stop1_trig-start_trig);
end if;
start_nb1 <= start_retrig_nb mod 256;
end process;
measuring2: process(stop2_trig)
begin
if start_retrig_nb > 1 then
stop2 <= (stop2_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop2 <= (stop2_trig-start_trig-start01);
else
stop2 <= (stop2_trig-start_trig);
end if;
start_nb2 <= start_retrig_nb mod 256;
end process;
measuring3: process(stop3_trig)
begin
if start_retrig_nb > 1 then
stop3 <= (stop3_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop3 <= (stop3_trig-start_trig-start01);
else
stop3 <= (stop3_trig-start_trig);
end if;
start_nb3 <= start_retrig_nb mod 256;
end process;
measuring4: process(stop4_trig)
begin
if start_retrig_nb > 1 then
stop4 <= (stop4_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop4 <= (stop4_trig-start_trig-start01);
else
stop4 <= (stop4_trig-start_trig);
end if;
start_nb4 <= start_retrig_nb mod 256;
end process;
measuring5: process(stop5_trig)
begin
if start_retrig_nb > 1 then
stop5 <= (stop5_trig-start_trig-start01)-((start_retrig_nb-1)*start_retrig_period);
elsif start_retrig_nb = 1 then
stop5 <= (stop5_trig-start_trig-start01);
else
stop5 <= (stop5_trig-start_trig);
end if;
start_nb5 <= start_retrig_nb mod 256;
end process;
measuring_start01: process(start_retrig_p)
begin
if rising_edge(start_retrig_p) then
if start_retrig_nb = 0 then
start01 <= now - start_trig;
end if;
end if;
end process;
writing_fifo1: process (tstop1, tstop2, tstop3, tstop4)
begin
if falling_edge(tstop1) then
timestamp_for_fifo1(27 downto 26) <= "00";
timestamp_for_fifo1(25 downto 18) <= std_logic_vector(to_unsigned(start_nb1,8));
timestamp_for_fifo1(17) <= '1';
timestamp_for_fifo1(16 downto 0) <= std_logic_vector(to_unsigned(stop1/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 1:" & LF &
"===============================" & LF &
"Channel 1" & LF &
"Start number: " & integer'image(start_nb1) & LF &
"Time Interval: " & integer'image(stop1/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
if falling_edge(tstop2) then
timestamp_for_fifo1(27 downto 26) <= "01";
timestamp_for_fifo1(25 downto 18) <= std_logic_vector(to_unsigned(start_nb2,8));
timestamp_for_fifo1(17) <= '1';
timestamp_for_fifo1(16 downto 0) <= std_logic_vector(to_unsigned(stop2/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 1:" & LF &
"===============================" & LF &
"Channel 2" & LF &
"Start number: " & integer'image(start_nb2) & LF &
"Time Interval: " & integer'image(stop2/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
if falling_edge(tstop3) then
timestamp_for_fifo1(27 downto 26) <= "10";
timestamp_for_fifo1(25 downto 18) <= std_logic_vector(to_unsigned(start_nb3,8));
timestamp_for_fifo1(17) <= '1';
timestamp_for_fifo1(16 downto 0) <= std_logic_vector(to_unsigned(stop3/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 1:" & LF &
"===============================" & LF &
"Channel 3" & LF &
"Start number: " & integer'image(start_nb3) & LF &
"Time Interval: " & integer'image(stop3/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
if falling_edge(tstop4) then
timestamp_for_fifo1(27 downto 26) <= "11";
timestamp_for_fifo1(25 downto 18) <= std_logic_vector(to_unsigned(start_nb4,8));
timestamp_for_fifo1(17) <= '1';
timestamp_for_fifo1(16 downto 0) <= std_logic_vector(to_unsigned(stop4/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 1:" & LF &
"===============================" & LF &
"Channel 4" & LF &
"Start number: " & integer'image(start_nb4) & LF &
"Time Interval: " & integer'image(stop4/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
end process;
writing_fifo2: process (tstop5)
begin
if falling_edge(tstop5) then
timestamp_for_fifo2(27 downto 26) <= "00";
timestamp_for_fifo2(25 downto 18) <= std_logic_vector(to_unsigned(start_nb5,8));
timestamp_for_fifo2(17) <= '1';
timestamp_for_fifo2(16 downto 0) <= std_logic_vector(to_unsigned(stop5/resolution,17));
start01_reg <= std_logic_vector(to_unsigned(start01/resolution,17));
report " Timestamp for interface FIFO 2:" & LF &
"===============================" & LF &
"Channel 5" & LF &
"Start number: " & integer'image(start_nb5) & LF &
"Time Interval: " & integer'image(stop5/resolution) & LF &
"Start01: " & integer'image(start01/resolution) & LF;
end if;
end process;
start_retrigger_pulses: process
begin
start_retrig_p <= '0' after 333 ps;
wait for start_retrig_period/4;
start_retrig_p <= '1' after 333 ps;
wait for start_retrig_period/4;
start_retrig_p <= '0' after 333 ps;
wait for start_retrig_period/2;
end process;
start_nb_counter: process(tstart, start_retrig_p)
begin
if rising_edge(tstart) then
start_retrig_nb <= 0;
elsif rising_edge(start_retrig_p) then
start_retrig_nb <= start_retrig_nb + 1;
end if;
end process;
interrupt_flag: process(start_retrig_nb)
begin
if (start_retrig_nb mod 256) > 127 then
intflag <= '1';
else
intflag <= '0';
end if;
end process;
tstart <= tstart_i;
tstop1 <= tstop1_i;
tstop2 <= tstop2_i;
tstop3 <= tstop3_i;
tstop4 <= tstop4_i;
tstop5 <= tstop5_i;
startdis <= startdis_i;
stopdis <= stopdis_i;
int_flag_o <= intflag;
start01_o <= start01_reg;
end behavioral;
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--==========================================================================--
--
-- *MODULE << cmd_router >>
--
-- *Description : This module routes commands to all command driven modules
-- in the simulation. It instanciates N_FILES instances of
-- cmd_router1 and agregates the outputs to control N_BFM BFMs.
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
--
--==========================================================================--
--==========================================================================--
-- Operation
--
-- This module opens a text file and passes commands to individual vhdl models.
--
--==========================================================================--
entity cmd_router is
generic( N_BFM : integer := 8;
N_FILES : integer := 3;
FIFO_DEPTH : integer := 16;
STRING_MAX : integer := 256
);
port( CMD : out string(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean
);
end cmd_router;
architecture MODEL of cmd_router is
component cmd_router1
generic( N_BFM : integer := 8;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256;
FILENAME : string :="cmdfile.vec"
);
port( CMD : out STRING(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean;
CMD_DONE_IN : in boolean;
CMD_DONE_OUT : out boolean
);
end component; -- cmd_router1
type FILE_ARRAY is array (natural range <>) of string(1 to 31);
type CMD_ARRAY is array (natural range <>) of string(CMD'range);
type CMD_REQ_ARRAY is array (natural range <>) of bit_vector(N_BFM-1 downto 0);
type integer_vector is array (natural range <>) of integer;
type boolean_vector is array (natural range <>) of boolean;
constant MAX_FILES : integer := 10;
constant FILENAMES : FILE_ARRAY(0 to MAX_FILES-1) := (others=>"data_vectors/acam_test_cmd0.vec");
-- , "data_vectors/acam_test_cmd1.vec");
-- "data_vectors/acam_test_cmd2.vec", "data_vectors/acam_test_cmd3.vec",
-- "data_vectors/acam_test_cmd4.vec", "data_vectors/acam_test_cmd5.vec",
-- "data_vectors/acam_test_cmd6.vec", "data_vectors/acam_test_cmd7.vec",
-- "data_vectors/acam_test_cmd8.vec", "data_vectors/acam_test_cmd9.vec" );
signal CMDo : CMD_ARRAY(N_FILES-1 downto 0);
signal REQ : bit_vector(CMD_REQ'range);
signal CMD_REQo : CMD_REQ_ARRAY(N_FILES-1 downto 0);
signal CMD_ACKi : CMD_REQ_ARRAY(N_FILES-1 downto 0);
signal CMD_ACK_MASK : CMD_REQ_ARRAY(N_FILES-1 downto 0); -- 1 bit_vector per file to mask CMD_ACK
signal CMD_CLOCK_ENo : boolean_vector(N_FILES-1 downto 0);
signal CMD_ALL_DONE : boolean;
signal CMD_DONE_OUT : boolean_vector(N_FILES-1 downto 0);
function or_reduce(ARG: bit_vector) return bit is
variable result: bit;
begin
result := '0';
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function or_reduce(ARG: boolean_vector) return boolean is
variable result: boolean;
begin
result := FALSE;
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function and_reduce(ARG: boolean_vector) return boolean is
variable result: boolean;
begin
result := TRUE;
for i in ARG'range loop
result := result and ARG(i);
end loop;
return result;
end;
begin
-----------------------------------------------------------------------------
-- Instanciate 1 cmd_router1 per file to be processed
-----------------------------------------------------------------------------
G1 : for i in 0 to N_FILES-1 generate
U1 : cmd_router1
generic map
( N_BFM => N_BFM,
FIFO_DEPTH => FIFO_DEPTH,
STRING_MAX => STRING_MAX,
FILENAME => FILENAMES(i)
)
port map
( CMD => CMDo(i),
CMD_REQ => CMD_REQo(i),
CMD_ACK => CMD_ACKi(i),
CMD_ERR => CMD_ERR,
CMD_CLOCK_EN => CMD_CLOCK_ENo(i),
CMD_DONE_IN => CMD_ALL_DONE,
CMD_DONE_OUT => CMD_DONE_OUT(i)
);
end generate;
-----------------------------------------------------------------------------
-- Multiplex the commands from the cmd_router1 modules
-----------------------------------------------------------------------------
process
variable vDONE : boolean;
begin
CMD <= (others => '0');
wait on CMD_REQo;
vDONE := FALSE;
while(not vDONE) loop
vDONE := TRUE;
for i in 0 to N_FILES-1 loop -- Loop on each file
if(or_reduce(CMD_REQo(i)) = '1') then -- this file wants to do a command
vDONE := FALSE;
--
-- if the ACK is already on from another cmd_router1
--
while(or_reduce(CMD_REQo(i) and CMD_ACK) = '1') loop
wait on CMD_ACK;
end loop;
--
-- Do the request
--
CMD <= CMDo(i);
REQ <= CMD_REQo(i);
--
-- Wait for the ACK
--
wait until(CMD_ACK'event and (or_reduce(CMD_ACK and REQ) = '1'));
--
-- send the ack to the proper file
--
for j in 0 to N_FILES-1 loop
if(i = j) then -- enable this one
CMD_ACK_MASK(j) <= CMD_ACK_MASK(j) or REQ;
else
CMD_ACK_MASK(j) <= CMD_ACK_MASK(j) and not REQ;
end if;
end loop;
--
-- Wait for the request to de-assert
--
while(or_reduce(CMD_REQo(i) and REQ) = '1') loop
wait on CMD_REQo;
end loop;
REQ <= (others => '0');
end if;
end loop;
end loop;
end process;
process(CMD_ACK, CMD_ACK_MASK)
begin
for i in 0 to N_FILES-1 loop -- Loop on each file
CMD_ACKi(i) <= CMD_ACK and CMD_ACK_MASK(i);
end loop;
end process;
CMD_REQ <= REQ;
CMD_ALL_DONE <= and_reduce(CMD_DONE_OUT);
CMD_CLOCK_EN <= CMD_CLOCK_ENo(0);
end MODEL;
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
--library std_developerskit;
--use std_developerskit.std_iopak.all;
use work.util.all;
use work.textutil.all;
--==========================================================================--
--
-- *MODULE << model1 >>
--
-- *Description : This module routes commands to all command driven modules
-- in the simulation.
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
--
--==========================================================================--
--==========================================================================--
-- Operation
--
-- This module opens a text file and passes commands to individual vhdl models.
--
--==========================================================================--
entity cmd_router1 is
generic( N_BFM : integer := 8;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256;
FILENAME : string :="cmdfile.vec"
);
port( CMD : out STRING(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean;
CMD_DONE_IN : in boolean;
CMD_DONE_OUT : out boolean
);
end cmd_router1;
architecture MODEL of cmd_router1 is
type STRING_ARRAY is array (FIFO_DEPTH-1 downto 0) of STRING(1 to STRING_MAX);
type FD_ARRAY is array (N_BFM-1 downto 0) of STRING_ARRAY;
type integer_vector is array (natural range <>) of integer;
signal FD : FD_ARRAY;
signal ERR_CNT : integer;
signal PUSH_PTR : integer_vector(N_BFM-1 downto 0);
signal POP_PTR : integer_vector(N_BFM-1 downto 0);
signal SET_CHAN : std_ulogic;
signal POP_INIT : std_ulogic;
signal CMD_REQo : bit_vector(CMD_REQ'range);
signal LINE_NUM : integer;
begin
PUSH_PROCESS : process
file FOUT : text open write_mode is "usc.lst";
file stim_file : text open read_mode is FILENAME;
file out_file : text open write_mode is "STD_OUTPUT";
-------- For VHDL-87
-- file stim_file : text is in FILENAME;
-- file out_file : text is out "STD_OUTPUT";
variable input_line : line;
variable output_line : line;
variable tmp_lout : line;
variable command : string(1 to 8);
variable tmp_str : string(1 to STRING_MAX);
variable input_str : string(1 to STRING_MAX);
variable i : integer;
variable CHANNEL : integer;
variable S_PTR : integer;
variable vLINE_NUM : integer;
variable vPUSH_PTR : integer_vector(N_BFM-1 downto 0);
variable DONE : boolean;
variable EOS : integer;
variable ERR : integer;
begin
-----------------------------------------------------------------------------
-- Main Loop
-----------------------------------------------------------------------------
vLINE_NUM := 0;
PUSH_PTR <= (others => 0);
vPUSH_PTR := (others => 0);
CHANNEL := 0;
CMD_CLOCK_EN <= TRUE;
SET_CHAN <= '0';
CMD_DONE_OUT <= FALSE;
if(POP_INIT /= '1') then
wait until(POP_INIT'event and (POP_INIT = '1'));
end if;
ST_LOOP: while not endfile(stim_file) loop
readline(stim_file, input_line);
S_PTR := 1;
vLINE_NUM := vLINE_NUM + 1;
LINE_NUM <= vLINE_NUM;
-- Copy the line
input_str := (others => ' ');
input_str(1 to 6) := To_Strn(vLINE_NUM, 6);
input_str(7 to 8) := string'(": ");
input_str(9 to input_line'length+8) := string'(input_line.all);
while(input_str(S_PTR) /= ':') loop
S_PTR := S_PTR + 1;
end loop;
S_PTR := S_PTR + 1;
sget_token(input_str, S_PTR, command);
SET_CHAN <= '1';
for j in STRING_MAX downto 1 loop
if(input_str(j) /= ' ') then
EOS := j;
exit;
end if;
end loop;
---------------------------
-- "model" command ?
---------------------------
if(command(1 to 5) = "model") then
sget_int(input_str, S_PTR, i);
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
if((i >= N_BFM) or (i < 0)) then
CHANNEL := N_BFM-1;
write(tmp_lout, string'("ERROR: Invalid Channel "));
write(tmp_lout, i);
writeline(out_file, tmp_lout);
else
CHANNEL := i;
end if;
---------------------------
-- "sync" command ?
---------------------------
elsif(command(1 to 4) = "sync") then
loop
DONE := TRUE;
for i in PUSH_PTR'reverse_range loop
if((vPUSH_PTR(i) /= POP_PTR(i)) or (CMD_ACK(i) /= '0')) then
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on POP_PTR, CMD_ACK;
end loop;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
---------------------------
-- "gsync" and "ckoff" command ?
---------------------------
elsif((command(1 to 5) = "gsync") or (command(1 to 5) = "ckoff")) then
write(tmp_lout, FILENAME);
write(tmp_lout, string'(": entering the gsync command"));
writeline(out_file, tmp_lout);
loop
DONE := TRUE;
for i in PUSH_PTR'reverse_range loop
if((vPUSH_PTR(i) /= POP_PTR(i)) or (CMD_ACK(i) /= '0')) then
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on POP_PTR, CMD_ACK;
end loop;
CMD_DONE_OUT <= TRUE;
-- wait for the external CMD_DONE_IN to be done
while (not CMD_DONE_IN) loop
wait on CMD_DONE_IN;
end loop;
CMD_DONE_OUT <= FALSE;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
if (command(1 to 5) = "ckoff") then
CMD_CLOCK_EN <= FALSE;
end if;
write(tmp_lout, FILENAME);
write(tmp_lout, string'(": gsync command is DONE"));
writeline(out_file, tmp_lout);
--------------------
-- ckon
--------------------
elsif (command(1 to 4) = "ckon") then
CMD_CLOCK_EN <= TRUE;
write(tmp_lout, FILENAME);
write(tmp_lout, input_str(1 to EOS));
writeline(out_file, tmp_lout);
---------------------------
-- put the line in the FIFO
---------------------------
else
FD(CHANNEL)(vPUSH_PTR(CHANNEL)) <= input_str;
vPUSH_PTR(CHANNEL) := vPUSH_PTR(CHANNEL) + 1;
if(vPUSH_PTR(CHANNEL) >= FIFO_DEPTH) then
vPUSH_PTR(CHANNEL) := 0;
end if;
if(vPUSH_PTR(CHANNEL) = POP_PTR(CHANNEL)) then -- The FIFO is full
wait until(POP_PTR'event and (vPUSH_PTR(CHANNEL) /= POP_PTR(CHANNEL)));
end if;
PUSH_PTR(CHANNEL) <= vPUSH_PTR(CHANNEL);
end if;
end loop;
loop
DONE := TRUE;
for i in POP_PTR'reverse_range loop
if((POP_PTR(i) /= vPUSH_PTR(i)) or (CMD_ACK(i) = '1')) then -- FIFO channel not empty
DONE := FALSE;
end if;
end loop;
if(DONE) then
exit;
end if;
wait on CMD_ACK, POP_PTR;
end loop;
CMD_DONE_OUT <= TRUE;
write(output_line, string'("******************************* Test Finished *******************************"));
writeline(out_file, output_line);
write(output_line, string'("* Total Errors for "));
write(output_line, FILENAME);
write(output_line, string'(": "));
write(output_line, err_cnt);
writeline(out_file, output_line);
write(output_line, string'("*****************************************************************************"));
writeline(out_file, output_line);
file_close(stim_file); -- Close File
loop
wait for 100000 us;
end loop;
end process;
-----------------------------------------------------------------------------
-- POP Process
-----------------------------------------------------------------------------
POP_PROCESS : process
variable vPOP_PTR : integer_vector(POP_PTR'range);
variable DONE : boolean;
file out_file : text open write_mode is "STD_OUTPUT";
-------- For VHDL-87
-- file out_file : text is out "STD_OUTPUT";
variable tmp_lout : line;
variable CHAR_PTR : integer;
variable EOS : integer;
begin
CHAR_PTR := 1;
ERR_CNT <= 0;
POP_PTR <= (others => 0);
vPOP_PTR := (others => 0);
CMD_REQo <= (others => '0');
POP_INIT <= '1';
if(SET_CHAN /= '1') then
wait until(SET_CHAN'event and (SET_CHAN = '1'));
end if;
loop
DONE := FALSE;
loop
DONE := TRUE;
for i in POP_PTR'reverse_range loop
if((vPOP_PTR(i) /= PUSH_PTR(i)) and (CMD_ACK(i) = '0')) then -- FIFO channel not empty
CMD <= FD(i)(vPOP_PTR(i));
CMD_REQo(i) <= '1';
for j in STRING_MAX downto 1 loop
if(FD(i)(vPOP_PTR(i))(j) /= ' ') then
EOS := j;
exit;
end if;
end loop;
write(tmp_lout, FILENAME);
write(tmp_lout, FD(i)(vPOP_PTR(i))(1 to EOS));
writeline(out_file, tmp_lout);
if(CMD_ACK(i) /= '1') then
wait until(CMD_ACK'event and (CMD_ACK(i) = '1'));
end if;
CMD_REQo(i) <= '0';
DONE := FALSE;
vPOP_PTR(i) := vPOP_PTR(i) + 1;
if(vPOP_PTR(i) >= FIFO_DEPTH) then
vPOP_PTR(i) := 0;
end if;
POP_PTR(i) <= vPOP_PTR(i);
end if;
end loop;
if(DONE) then
exit;
end if;
end loop;
wait on PUSH_PTR, CMD_ACK;
end loop;
end process;
CMD_REQ <= CMD_REQo;
end MODEL;
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
library IEEE;
use IEEE.std_logic_1164.all;
use std.textio.all;
use work.util.all;
-----------------------------------------------------------------------------
-- *Module : textutil
--
-- *Description : Improved Free-format string and line manipulation
--
-- *History: M. Alford (originaly created 1993 with subsequent updates)
-----------------------------------------------------------------------------
package textutil is
procedure read_token(L : inout line; X : out STRING);
procedure sget_token(S : in string; P : inout integer; X : out STRING);
procedure sget_vector(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR);
procedure sget_vector_64(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR);
procedure sget_int(S : in string; P : inout integer; X : out integer);
function hex_char_to_vector(C : in character) return STD_ULOGIC_VECTOR;
function vector_to_hex_char(V : in STD_ULOGIC_VECTOR) return character;
function is_hex(C : in character) return BOOLEAN;
function hex_char_to_int(C : in character) return integer;
procedure read_vector(L : inout line; VEC : out STD_ULOGIC_VECTOR);
procedure read_int(L : inout line; I : out integer);
procedure write_hex_vector(L : inout line; V : in STD_ULOGIC_VECTOR);
function to_str(constant V: in STD_ULOGIC_VECTOR) return STRING;
function to_str(constant V: in STD_ULOGIC) return STRING;
function to_str(constant val : in INTEGER) return STRING;
function to_strn(constant val : in INTEGER; constant n : in INTEGER) return STRING;
end textutil;
package body textutil is
-----------------------------------------------------------------------------
-- *Module : read_token
--
-- *Description : Skip over spaces then load a token string from a line
-- until either the string is full or the token is finished
-- (i.e. another space). The output string is padded out
-- with blanks at the end if the token length is less then
-- the full string length.
-----------------------------------------------------------------------------
procedure read_token(L : inout line; X : out STRING) is
variable char : character;
begin
if(L'length > 0) then
char := ' ';
while((char = ' ') and (L'length > 0)) loop -- Skip spaces
read(L, char);
end loop;
for i in X'low to X'high loop
X(i) := char;
if(char /= ' ') then
if(L'length > 0) then
read(L, char);
else
char := ' ';
end if;
end if;
end loop;
else
assert false report "Couldn't read a token from file"
severity error;
end if;
end read_token;
-----------------------------------------------------------------------------
-- *Module : sget_token
--
-- *Description : Same as read_token except for strings.
-----------------------------------------------------------------------------
procedure sget_token(S : in string; P : inout integer; X : out STRING) is
variable char : character;
begin
if(S'length > P) then
char := ' ';
while((char = ' ') and (S'length >= P)) loop -- Skip spaces
char := S(P);
P := P + 1;
end loop;
for i in X'low to X'high loop
X(i) := char;
if(char /= ' ') then
if(S'length > P) then
char := S(P);
P := P + 1;
else
char := ' ';
end if;
end if;
end loop;
else
assert false report "Couldn't read a token from a string"
severity error;
end if;
end sget_token;
-----------------------------------------------------------------------------
-- *Module : hex_char_to_vector
--
-- *Description : Convert a hex character to a vector
-----------------------------------------------------------------------------
function hex_char_to_vector(C : in character) return STD_ULOGIC_VECTOR is
variable X : STD_ULOGIC_VECTOR( 3 downto 0);
begin
case C is
when '0' => X := "0000";
when '1' => X := "0001";
when '2' => X := "0010";
when '3' => X := "0011";
when '4' => X := "0100";
when '5' => X := "0101";
when '6' => X := "0110";
when '7' => X := "0111";
when '8' => X := "1000";
when '9' => X := "1001";
when 'A' => X := "1010";
when 'B' => X := "1011";
when 'C' => X := "1100";
when 'D' => X := "1101";
when 'E' => X := "1110";
when 'F' => X := "1111";
when 'a' => X := "1010";
when 'b' => X := "1011";
when 'c' => X := "1100";
when 'd' => X := "1101";
when 'e' => X := "1110";
when 'f' => X := "1111";
when others =>
X := "0000";
assert false report "Invalid Hex Character"
severity error;
end case;
return(X);
end hex_char_to_vector;
-----------------------------------------------------------------------------
-- *Module : vector_to_hex_char
--
-- *Description : Convert a vector to a hex character. Only uses low 4 bits.
-----------------------------------------------------------------------------
function vector_to_hex_char(V : in STD_ULOGIC_VECTOR) return character is
variable C : character;
variable VV : STD_ULOGIC_VECTOR(3 downto 0);
begin
if(V'length < 4) then
VV := To_X01(V(V'low + 3 downto V'low));
else
VV := To_X01(V(V'low + V'length - 1 downto V'low));
end if;
case VV is
when "0000" => C := '0';
when "0001" => C := '1';
when "0010" => C := '2';
when "0011" => C := '3';
when "0100" => C := '4';
when "0101" => C := '5';
when "0110" => C := '6';
when "0111" => C := '7';
when "1000" => C := '8';
when "1001" => C := '9';
when "1010" => C := 'A';
when "1011" => C := 'B';
when "1100" => C := 'C';
when "1101" => C := 'D';
when "1110" => C := 'E';
when "1111" => C := 'F';
when others => C := 'X';
end case;
return(C);
end vector_to_hex_char;
-----------------------------------------------------------------------------
-- *Module : is_hex
--
-- *Description : report if a char is ASCII hex
-----------------------------------------------------------------------------
function is_hex(C : in character) return BOOLEAN is
variable X : boolean;
begin
case C is
when '0' => X := TRUE;
when '1' => X := TRUE;
when '2' => X := TRUE;
when '3' => X := TRUE;
when '4' => X := TRUE;
when '5' => X := TRUE;
when '6' => X := TRUE;
when '7' => X := TRUE;
when '8' => X := TRUE;
when '9' => X := TRUE;
when 'A' => X := TRUE;
when 'B' => X := TRUE;
when 'C' => X := TRUE;
when 'D' => X := TRUE;
when 'E' => X := TRUE;
when 'F' => X := TRUE;
when 'a' => X := TRUE;
when 'b' => X := TRUE;
when 'c' => X := TRUE;
when 'd' => X := TRUE;
when 'e' => X := TRUE;
when 'f' => X := TRUE;
when others =>
X := FALSE;
end case;
return(X);
end is_hex;
-----------------------------------------------------------------------------
-- *Module : hex_char_to_int
--
-- *Description : Convert a hex character to an integer
-----------------------------------------------------------------------------
function hex_char_to_int(C : in character) return integer is
variable X : integer;
begin
case C is
when '0' => X := 0;
when '1' => X := 1;
when '2' => X := 2;
when '3' => X := 3;
when '4' => X := 4;
when '5' => X := 5;
when '6' => X := 6;
when '7' => X := 7;
when '8' => X := 8;
when '9' => X := 9;
when 'A' => X := 10;
when 'B' => X := 11;
when 'C' => X := 12;
when 'D' => X := 13;
when 'E' => X := 14;
when 'F' => X := 15;
when 'a' => X := 10;
when 'b' => X := 11;
when 'c' => X := 12;
when 'd' => X := 13;
when 'e' => X := 14;
when 'f' => X := 15;
when others =>
X := 0;
assert false report "Invalid Hex Character"
severity error;
end case;
return(X);
end hex_char_to_int;
-----------------------------------------------------------------------------
-- *Module : read_vector
--
-- *Description : load a vector from the input line in a free floating format
-----------------------------------------------------------------------------
procedure read_vector(L : inout line; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(31 downto 0);
begin
if(L'length > 0) then
char := ' ';
while(char = ' ') loop -- Skip spaces
read(L, char);
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
read(L, char);
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
read(L, char);
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (L'length = 0)) loop
read(L, char);
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
if(q < 0) then
q := q-2147483648;
V(30 downto 0) := to_vector(q, 31);
V(31) := '1';
else
V(30 downto 0) := to_vector(q, 31);
V(31) := '0';
end if;
VEC := V((VEC'high - VEC'low) downto 0);
else
assert false report "Couldn't read a vector"
severity error;
end if;
end read_vector;
-----------------------------------------------------------------------------
-- *Module : sget_vector
--
-- *Description : Same as sget_vector except for strings
-----------------------------------------------------------------------------
procedure sget_vector(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(31 downto 0);
begin
while(S(P) = ' ') loop -- Skip spaces
if(P >= S'length) then
P := S'length;
exit;
end if;
P := P + 1;
end loop;
if(S'length > P) then
char := S(P);
if(char = '"') then -- read in as a literal
q := v'high;
v := (others => 'U');
VEC := v(VEC'range);
char := ' ';
P := P + 1;
while((char /= '"') and not (S'length = P)) loop
char := S(P);
P := P + 1;
case char is
when '0' =>
v(q) := '0';
when '1' =>
v(q) := '1';
when 'L' | 'l' =>
v(q) := 'L';
when 'H' | 'h' =>
v(q) := 'H';
when 'Z' | 'z' =>
v(q) := 'Z';
when 'X' | 'x' =>
v(q) := 'X';
when 'U' | 'u' =>
v(q) := 'U';
when others =>
-- char := '"';
exit;
end case;
q := q - 1;
end loop;
if(v'high-q < 2) then -- only a single bit was read
VEC(VEC'low) := v(v'high);
elsif((v'high - q) > VEC'length) then -- too many bits
VEC := v(q+VEC'length downto q+1);
else -- the number of bits read is same or less than required
VEC(v'high-q-1+VEC'low downto VEC'low) := v(v'high downto q+1);
end if;
else
base := 16; -- Hex is the default
if(char = '%') then -- determine base
P := P + 1;
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
elsif((char = '0') and ((S(P+1) = 'x') or (S(P+1) = 'X'))) then
P := P + 2;
end if;
q := 0;
char := S(P);
if(is_hex(char)) then
while(is_hex(char) and not (S'length = P)) loop
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
P := P + 1;
char := S(P);
end loop;
end if;
if(q < 0) then
q := q-2147483648;
V(30 downto 0) := to_vector(q, 31);
V(31) := '1';
else
V(30 downto 0) := to_vector(q, 31);
V(31) := '0';
end if;
VEC := V((VEC'high - VEC'low) downto 0);
end if;
else
assert false report "Couldn't read a vector"
severity error;
V := (others => '0');
VEC := V((VEC'high - VEC'low) downto 0);
end if;
end sget_vector;
-----------------------------------------------------------------------------
-- *Module : sget_vector_64
--
-- *Description : Same as sget_vector except can handle 64 bit quantities and hex or binary base (no base 10)
-----------------------------------------------------------------------------
procedure sget_vector_64(S : in string; P : inout integer; VEC : out STD_ULOGIC_VECTOR) is
variable char : character;
variable base : integer;
variable q : integer;
variable v : STD_ULOGIC_VECTOR(63 downto 0);
begin
while(S(P) = ' ') loop -- Skip spaces
if(P >= S'length) then
P := S'length;
exit;
end if;
P := P + 1;
end loop;
if(S'length > P) then
char := S(P);
if(char = '"') then -- read in as a literal
q := v'high;
v := (others => 'U');
VEC := v(VEC'range);
char := ' ';
P := P + 1;
while((char /= '"') and not (S'length = P)) loop
char := S(P);
P := P + 1;
case char is
when '0' =>
v(q) := '0';
when '1' =>
v(q) := '1';
when 'L' | 'l' =>
v(q) := 'L';
when 'H' | 'h' =>
v(q) := 'H';
when 'Z' | 'z' =>
v(q) := 'Z';
when 'X' | 'x' =>
v(q) := 'X';
when 'U' | 'u' =>
v(q) := 'U';
when others =>
-- char := '"';
exit;
end case;
q := q - 1;
end loop;
if(v'high-q < 2) then -- only a single bit was read
VEC(VEC'low) := v(v'high);
elsif((v'high - q) > VEC'length) then -- too many bits
VEC := v(q+VEC'length downto q+1);
else -- the number of bits read is same or less than required
VEC(v'high-q-1+VEC'low downto VEC'low) := v(v'high downto q+1);
end if;
else
base := 16; -- Hex is the default
if(char = '%') then -- determine base
P := P + 1;
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
else
assert false report "Unsupported Base detected when reading a Vector"
severity error;
end if;
char := S(P);
-- P := P + 1;
elsif((char = '0') and ((S(P+1) = 'x') or (S(P+1) = 'X'))) then
P := P + 2;
end if;
v := (others => '0');
char := S(P);
if(base = 2) then
while(((char = '0') or (char = '1')) and not (P > S'length)) loop
if(char = '0') then
v := v(v'high-1 downto 0) & '0';
else
v := v(v'high-1 downto 0) & '1';
end if;
P := P + 1;
char := S(P);
end loop;
else
while(is_hex(char) and not (P > S'length)) loop
if(is_hex(char)) then
v := v(v'high-4 downto 0) & hex_char_to_vector(char);
end if;
P := P + 1;
char := S(P);
end loop;
end if;
VEC := V((VEC'high - VEC'low) downto 0);
end if;
else
assert false report "Couldn't read a vector"
severity error;
V := (others => '0');
VEC := V((VEC'high - VEC'low) downto 0);
end if;
end sget_vector_64;
-----------------------------------------------------------------------------
-- *Module : read_int
--
-- *Description : load an integer from the input line in a free floating format
-----------------------------------------------------------------------------
procedure read_int(L : inout line; I : out integer) is
variable char : character;
variable base : integer;
variable q : integer;
begin
if(L'length > 0) then
char := ' ';
while(char = ' ') loop -- Skip spaces
read(L, char);
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
read(L, char);
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading an integer"
severity error;
end if;
read(L, char);
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (L'length = 0)) loop
read(L, char);
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
I := q;
else
assert false report "Couldn't read an integer"
severity error;
end if;
end read_int;
-----------------------------------------------------------------------------
-- *Module : sget_int
--
-- *Description : Same as read_int except for strings
-----------------------------------------------------------------------------
procedure sget_int(S : in string; P : inout integer; X : out integer) is
variable char : character;
variable base : integer;
variable q : integer;
begin
if(S'length > P) then
char := ' ';
while(char = ' ') loop -- Skip spaces
char := S(P);
P := P + 1;
end loop;
base := 16; -- Hex is the default
if(char = '%') then -- determine base
char := S(P);
P := P + 1;
if(char = 'b' or char = 'B') then
base := 2;
elsif(char = 'x' or char = 'X') then
base := 16;
elsif(char = 'd' or char = 'D') then
base := 10;
else
assert false report "Unsupported Base detected when reading an integer"
severity error;
end if;
char := S(P);
P := P + 1;
end if;
q := 0;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
while(is_hex(char) and not (S'length = P)) loop
char := S(P);
P := P + 1;
if(is_hex(char)) then
q := q * base + hex_char_to_int(char);
end if;
end loop;
end if;
X := q;
else
assert false report "Couldn't read an integer"
severity error;
end if;
end sget_int;
-----------------------------------------------------------------------------
-- *Module : write_hex_vector
--
-- *Description : writes out a vector as hex
-----------------------------------------------------------------------------
procedure write_hex_vector(L : inout line; V : in STD_ULOGIC_VECTOR) is
variable C : character;
variable VV : STD_ULOGIC_VECTOR(((V'length + 3)/4) * 4 - 1 downto 0);
begin
VV := (others => '0');
VV(V'length -1 downto 0) := V;
for i in VV'length/4 - 1 downto 0 loop
C := vector_to_hex_char(VV(i*4+3 downto i*4));
write(L, C);
end loop;
end write_hex_vector;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a STD_ULOGIC_VECTOR to a string of the same length
-----------------------------------------------------------------------------
function to_str(constant V: in STD_ULOGIC_VECTOR) return STRING is
variable S : STRING(1 to V'length);
variable sp : integer;
begin
sp := 1;
for i in V'range loop
case V(i) is
when '1' | 'H' =>
S(sp) := '1';
when '0' | 'L' =>
S(sp) := '0';
when others =>
S(sp) := 'X';
end case;
sp := sp + 1;
end loop;
return(S);
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a STD_ULOGIC to a string
-----------------------------------------------------------------------------
function to_str(constant V: in STD_ULOGIC) return STRING is
-- variable S : STRING(1);
begin
case V is
when '1' | 'H' =>
return("1");
when '0' | 'L' =>
return("0");
when others =>
return("X");
end case;
return("X");
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_str
--
-- *Description : Converts a integer to a string
-----------------------------------------------------------------------------
function to_str(constant val : in INTEGER) return STRING is
variable result : STRING(11 downto 1) := "-2147483648"; -- smallest integer and longest string
variable tmp : INTEGER;
variable pos : NATURAL := 1;
variable digit : NATURAL;
begin
-- for the smallest integer MOD does not seem to work...
--if val = -2147483648 then : compilation error with Xilinx tools...
if val < -2147483647 then
pos := 12;
else
tmp := abs(val);
loop
digit := abs(tmp MOD 10);
tmp := tmp / 10;
result(pos) := character'val(character'pos('0') + digit);
pos := pos + 1;
exit when tmp = 0;
end loop;
if val < 0 then
result(pos) := '-';
pos := pos + 1;
end if;
end if;
return result((pos-1) downto 1);
end to_str;
-----------------------------------------------------------------------------
-- *Module : to_strn
--
-- *Description : Converts an integer to a string of length N
-----------------------------------------------------------------------------
function to_strn(constant val : in INTEGER; constant n : in INTEGER) return STRING is
variable result : STRING(11 downto 1) := "-2147483648"; -- smallest integer and longest string
variable tmp : INTEGER;
variable pos : NATURAL := 1;
variable digit : NATURAL;
begin
-- for the smallest integer MOD does not seem to work...
--if val = -2147483648 then : compilation error with Xilinx tools...
if val < -2147483647 then
pos := 12;
else
result := (others => ' ');
tmp := abs(val);
loop
digit := abs(tmp MOD 10);
tmp := tmp / 10;
result(pos) := character'val(character'pos('0') + digit);
pos := pos + 1;
exit when tmp = 0;
end loop;
if val < 0 then
result(pos) := '-';
pos := pos + 1;
end if;
end if;
return result(n downto 1);
end to_strn;
end textutil;
library ieee;
use ieee.std_logic_1164.all;
--library synopsys;
--use synopsys.arithmetic.all;
package UTIL is
function to_mvl ( b: in boolean ) return STD_ULOGIC;
function to_mvl ( i: in integer ) return STD_ULOGIC;
function to_vector(input,num_bits:integer) return STD_ULOGIC_VECTOR;
-- function to_signed( b: in std_ulogic_vector ) return signed;
-- function to_std_ulogic_vector( b: in signed ) return std_ulogic_vector;
-- function std_logic_to_std_ulogic( b: in std_logic ) return std_ulogic;
-- function std_ulogic_to_std_logic( b: in std_ulogic ) return std_logic;
function "and"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
function "and"(l: STD_ULOGIC; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function "and"(l: STD_ULOGIC_VECTOR; r: BOOLEAN) return STD_ULOGIC_VECTOR;
function "and"(l: BOOLEAN; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function "and"(l: BOOLEAN; r: STD_ULOGIC) return STD_ULOGIC;
function "and"(l: STD_ULOGIC; r: BOOLEAN) return STD_ULOGIC;
function exp(input: STD_ULOGIC; num_bits: integer) return STD_ULOGIC_VECTOR;
function exp(input: STD_ULOGIC_VECTOR; num_bits: integer) return STD_ULOGIC_VECTOR;
function conv_integer ( ARG: in STD_ULOGIC_VECTOR ) return integer;
function "+"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
-- function "+"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
-- function "-"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR;
-- function "-"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR;
function to_int(l: std_ulogic_vector) return natural;
function to_int(l: std_ulogic) return natural;
function and_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function nand_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function or_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function nor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function xor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function xnor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC;
function ge ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function gt ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function lt ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function eq ( l, r : STD_ULOGIC_VECTOR ) return BOOLEAN;
function maximum ( arg1, arg2 : INTEGER) return INTEGER;
function minimum ( arg1, arg2 : INTEGER) return INTEGER;
procedure keep(signal X: inout STD_LOGIC);
function log2(A: in integer) return integer;
-------------------------------------------------------------------
-- Declaration of Synthesis directive attributes
-------------------------------------------------------------------
ATTRIBUTE synthesis_return : string ;
end UTIL;
package body UTIL is
--------------------------------------------------------------------
-- function to_signed ( b: in std_ulogic_vector ) return signed is
-- variable result : signed(b'range);
-- begin
-- for i in b'range loop
-- result(i) := b(i);
-- end loop;
-- return result;
-- end to_signed;
--------------------------------------------------------------------
-- function to_std_ulogic_vector ( b: in signed ) return std_ulogic_vector is
-- variable result : std_ulogic_vector(b'range);
-- begin
-- for i in b'range loop
-- result(i) := b(i);
-- end loop;
-- return result;
-- end to_std_ulogic_vector;
--------------------------------------------------------------------
function to_mvl ( b: in boolean ) return STD_ULOGIC is
begin
if ( b = TRUE ) then
return( '1' );
else
return( '0' );
end if;
end to_mvl;
--------------------------------------------------------------------
function to_mvl ( i: in integer ) return STD_ULOGIC is
begin
if ( i = 1 ) then
return( '1' );
else
return( '0' );
end if;
end to_mvl;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
variable rr: STD_ULOGIC_vector(r'range);
begin
if (l = '1') then
rr := r;
else
rr := (others => '0');
end if;
return(rr);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC_VECTOR; r: STD_ULOGIC) return STD_ULOGIC_VECTOR is
variable ll: STD_ULOGIC_vector(l'range);
begin
if (r = '1') then
ll := l;
else
ll := (others => '0');
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: BOOLEAN; r: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
variable rr: STD_ULOGIC_vector(r'range);
begin
if (l) then
rr := r;
else
rr := (others => '0');
end if;
return(rr);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC_VECTOR; r: BOOLEAN) return STD_ULOGIC_VECTOR is
variable ll: STD_ULOGIC_vector(l'range);
begin
if (r) then
ll := l;
else
ll := (others => '0');
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: BOOLEAN; r: STD_ULOGIC) return STD_ULOGIC is
variable ll: STD_ULOGIC;
begin
if (l) then
ll := r;
else
ll := '0';
end if;
return(ll);
end;
--------------------------------------------------------------------
function "and"(l: STD_ULOGIC; r: BOOLEAN) return STD_ULOGIC is
variable ll: STD_ULOGIC;
begin
if (r) then
ll := l;
else
ll := '0';
end if;
return(ll);
end;
--------------------------------------------------------------------
-- function std_ulogic_to_std_logic(b : std_ulogic) return std_logic is
-- variable result: std_logic;
-- begin
-- result := b;
-- return result;
-- end;
--------------------------------------------------------------------
-- function std_logic_to_std_ulogic(b : std_logic) return std_ulogic is
-- variable result: std_ulogic;
-- begin
-- result := b;
-- return result;
-- end;
--------------------------------------------------------------------
function to_vector(input,num_bits: integer) return std_ulogic_vector is
variable vec: std_ulogic_vector(num_bits-1 downto 0);
variable a: integer;
begin
a := input;
for i in 0 to num_bits-1 loop
if ((a mod 2) = 1) then
vec(i) := '1';
else
vec(i) := '0';
end if;
a := a / 2;
end loop;
return vec;
end to_vector;
-- FUNCTION to_vector(input,num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
-- VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
-- VARIABLE weight:integer;
-- VARIABLE temp:integer;
-- BEGIN
-- weight := 2**(num_bits-1);
-- temp := input;
-- FOR i in result'HIGH DOWNTO result'LOW LOOP
-- IF temp >= weight THEN
-- result(i) := '1';
-- temp := temp - weight;
-- ELSE
-- result(i) := '0';
-- END IF;
-- weight := weight/2;
-- END LOOP;
-- RETURN result;
-- END to_vector;
--------------------------------------------------------------------
-- exp: Expand one bit into many
--------------------------------------------------------------------
FUNCTION exp(input:STD_ULOGIC; num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
BEGIN
FOR i in result'HIGH DOWNTO result'LOW LOOP
result(i) := input;
END LOOP;
RETURN result;
END exp;
--------------------------------------------------------------------
-- exp: Expand n bits into m bits
--------------------------------------------------------------------
FUNCTION exp(input:STD_ULOGIC_VECTOR; num_bits:integer) RETURN STD_ULOGIC_VECTOR IS
VARIABLE result:STD_ULOGIC_VECTOR(num_bits-1 DOWNTO 0);
BEGIN
result(input'high-input'low downto 0) := input;
result(num_bits-1 downto input'high-input'low+1) := (others => '0');
RETURN result;
END exp;
--------------------------------------------------------------------
-- conv_integer
--------------------------------------------------------------------
function conv_integer ( ARG: in STD_ULOGIC_VECTOR ) return integer is
variable result: INTEGER;
begin
assert ARG'length <= 31
report "ARG is too large in CONV_INTEGER"
severity FAILURE;
result := 0;
for i in ARG'range loop
result := result * 2;
if(ARG(i) = 'H' or ARG(i) = '1') then
result := result + 1;
end if;
end loop;
return result;
end;
--------------------------------------------------------------------
-- "+" Increment function
--------------------------------------------------------------------
function "+"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC) return STD_ULOGIC_VECTOR is
variable Q: STD_ULOGIC_VECTOR(L'range);
variable A: STD_ULOGIC;
begin
A := R;
for i in L'low to L'high loop
Q(i) := L(i) xor A;
A := A and L(i);
end loop;
return Q;
end;
--------------------------------------------------------------------
-- "+" adder function
--------------------------------------------------------------------
-- function "+"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
-- variable Q : SIGNED(L'range);
-- variable result: STD_ULOGIC_VECTOR(L'range);
-- begin
-- Q := to_signed(L) + to_signed(R);
-- result := to_std_ulogic_vector(Q);
-- return result;
-- end;
--------------------------------------------------------------------
-- "-" Decrement function
--------------------------------------------------------------------
-- function "-"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC) return STD_ULOGIC_VECTOR is
-- variable Q: STD_ULOGIC_VECTOR(L'range);
-- variable A: STD_ULOGIC;
-- begin
-- A := R;
-- for i in L'low to L'high loop
-- Q(i) := L(i) xor A;
-- A := A and not L(i);
-- end loop;
-- return Q;
-- end;
--------------------------------------------------------------------
-- "-" subtractor function
--------------------------------------------------------------------
-- function "-"(L: STD_ULOGIC_VECTOR; R: STD_ULOGIC_VECTOR) return STD_ULOGIC_VECTOR is
-- variable Q : SIGNED(L'range);
-- variable result: STD_ULOGIC_VECTOR(L'range);
-- begin
-- Q := to_signed(L) - to_signed(R);
-- result := to_std_ulogic_vector(Q);
-- return result;
-- end;
--------------------------------------------------------------------
-- to_int : Convert std_ulogic_vector to an integer
--------------------------------------------------------------------
function to_int(l: std_ulogic_vector) return natural is
variable result: natural := 0;
begin
for t1 in l'range loop
result := result * 2;
if (l(t1) = '1') or (l(t1) = 'H') then
result := result + 1;
end if;
end loop;
return result;
end to_int;
--------------------------------------------------------------------
-- to_int : Convert std_ulogic_vector to an integer
--------------------------------------------------------------------
function to_int(l: std_ulogic) return natural is
variable result: natural := 0;
begin
if (l = '1') or (l = 'H') then
result := 1;
else
result := 0;
end if;
return result;
end to_int;
--------------------------------------------------------------------
-- Reduce Functions
--------------------------------------------------------------------
function and_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '1';
for i in ARG'range loop
result := result and ARG(i);
end loop;
return result;
end;
function nand_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not and_reduce(ARG);
end;
function or_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '0';
for i in ARG'range loop
result := result or ARG(i);
end loop;
return result;
end;
function nor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not or_reduce(ARG);
end;
function xor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
variable result: STD_ULOGIC;
begin
result := '0';
for i in ARG'range loop
result := result xor ARG(i);
end loop;
return result;
end;
function xnor_reduce(ARG: STD_ULOGIC_VECTOR) return STD_ULOGIC is
begin
return not xor_reduce(ARG);
end;
--------------------------------------------------------------------
-- Some useful generic functions
--------------------------------------------------------------------
--//// Zero Extend ////
--
-- Function zxt
--
FUNCTION zxt( q : STD_ULOGIC_VECTOR; i : INTEGER ) RETURN STD_ULOGIC_VECTOR IS
VARIABLE qs : STD_ULOGIC_VECTOR (1 TO i);
VARIABLE qt : STD_ULOGIC_VECTOR (1 TO q'length);
-- Hidden function. Synthesis directives are present in its callers
BEGIN
qt := q;
IF i < q'length THEN
qs := qt( (q'length-i+1) TO qt'right);
ELSIF i > q'length THEN
qs := (OTHERS=>'0');
qs := qs(1 TO (i-q'length)) & qt;
ELSE
qs := qt;
END IF;
RETURN qs;
END;
FUNCTION maximum (arg1,arg2:INTEGER) RETURN INTEGER IS
BEGIN
IF(arg1 > arg2) THEN
RETURN(arg1) ;
ELSE
RETURN(arg2) ;
END IF;
END ;
FUNCTION minimum (arg1,arg2:INTEGER) RETURN INTEGER IS
BEGIN
IF(arg1 < arg2) THEN
RETURN(arg1) ;
ELSE
RETURN(arg2) ;
END IF;
END ;
--------------------------------------------------------------------
-- Comparision functions
--------------------------------------------------------------------
--
-- Equal functions.
--
TYPE stdlogic_boolean_table IS ARRAY(std_ulogic, std_ulogic) OF BOOLEAN;
CONSTANT eq_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 0 |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | L |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION eq ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
-- Equal for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "EQ" ;
BEGIN
result := eq_table( l, r );
RETURN result ;
END;
FUNCTION eq ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Arithmetic Equal for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "EQ" ;
BEGIN
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'range LOOP
IF NOT eq( lt(i), rt(i) ) THEN
result := FALSE;
RETURN result ;
END IF;
END LOOP;
RETURN TRUE;
END;
TYPE std_ulogic_fuzzy_state IS ('U', 'X', 'T', 'F', 'N');
TYPE std_ulogic_fuzzy_state_table IS ARRAY ( std_ulogic, std_ulogic ) OF std_ulogic_fuzzy_state;
CONSTANT ge_fuzzy_table : std_ulogic_fuzzy_state_table := (
-- ----------------------------------------------------
-- | U X 0 1 Z W L H D | |
-- ----------------------------------------------------
( 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U', 'U' ), -- | U |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | X |
( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | 0 |
( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | 1 |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | Z |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | W |
( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | L |
( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | H |
( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ) -- | D |
);
FUNCTION ge ( L,R : std_ulogic_vector ) RETURN boolean IS
CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
VARIABLE lt : std_ulogic_vector ( 1 to ml );
VARIABLE rt : std_ulogic_vector ( 1 to ml );
VARIABLE res : std_ulogic_fuzzy_state;
-- Greater-than-or-equal for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GTE" ;
begin
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'RANGE LOOP
res := ge_fuzzy_table( lt(i), rt(i) );
CASE res IS
WHEN 'U' => RETURN FALSE;
WHEN 'X' => RETURN FALSE;
WHEN 'T' => RETURN TRUE;
WHEN 'F' => RETURN FALSE;
WHEN OTHERS => null;
END CASE;
END LOOP;
result := TRUE ;
RETURN result;
end ;
--
-- Greater Than functions.
--
CONSTANT gtb_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 0 |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | L |
( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION gt ( l, r : std_logic ) RETURN BOOLEAN IS
-- Greater-than for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GT" ;
BEGIN
result := gtb_table( l, r );
RETURN result ;
END ;
FUNCTION gt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Greater-than for two logic unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "GT" ;
BEGIN
lt := zxt( l, ml );
rt := zxt( r, ml );
FOR i IN lt'range LOOP
IF NOT eq( lt(i), rt(i) ) THEN
result := gt( lt(i), rt(i) );
RETURN result ;
END IF;
END LOOP;
RETURN FALSE;
END;
--
-- Less Than functions.
--
CONSTANT ltb_table : stdlogic_boolean_table := (
--
----------------------------------------------------------------------------
-- | U X 0 1 Z W L H D | |
--
----------------------------------------------------------------------------
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 0 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 1 |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | L |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | H |
( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
);
FUNCTION lt ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
-- Less-than for two logic types
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "LT" ;
BEGIN
result := ltb_table( l, r );
RETURN result ;
END;
FUNCTION lt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
CONSTANT ml : INTEGER := maximum( l'length, r'length );
VARIABLE ltt : STD_ULOGIC_VECTOR ( 1 TO ml );
VARIABLE rtt : STD_ULOGIC_VECTOR ( 1 TO ml );
-- Less-than for two Unsigned vectors
VARIABLE result : BOOLEAN ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "LT" ;
BEGIN
ltt := zxt( l, ml );
rtt := zxt( r, ml );
FOR i IN ltt'range LOOP
IF NOT eq( ltt(i), rtt(i) ) THEN
result := lt( ltt(i), rtt(i) );
RETURN result ;
END IF;
END LOOP;
RETURN FALSE;
END;
--------------------------------------------------------------------
-- "keep" Retain Last value when floated
--------------------------------------------------------------------
procedure keep(signal X: inout STD_LOGIC) is
begin
if(X = 'Z') then
if(X'last_value = '0') then
X <= 'L';
elsif(X'last_value = '1') then
X <= 'H';
else
X <= 'Z';
end if;
else
X <= 'Z';
end if;
end keep;
---------------------------------------------------------------------
-- log base 2 function
---------------------------------------------------------------------
function log2 ( A: in integer ) return integer is
variable B : integer;
begin
B := 1;
for i in 0 to 31 loop
if not ( A > B ) then
return ( i );
exit;
end if;
B := B * 2;
end loop;
end log2;
end UTIL;
-- Created by : G. Penacoba
-- Creation Date: May 2011
-- Description: generates start and stop pulses for test-bench
-- Modified by:
-- Modification Date:
-- Modification consisted on:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_textio.all;
use std.textio.all;
entity start_stop_gen is
port(
tstart_o : out std_logic;
tstop1_o : out std_logic;
tstop2_o : out std_logic;
tstop3_o : out std_logic;
tstop4_o : out std_logic;
tstop5_o : out std_logic
);
end start_stop_gen;
architecture behavioral of start_stop_gen is
signal tstart : std_logic:='0';
signal tstop1 : std_logic:='0';
signal tstop2 : std_logic:='0';
signal tstop3 : std_logic:='0';
signal tstop4 : std_logic:='0';
signal tstop5 : std_logic:='0';
signal pulse_channel : integer;
signal pulse_length : time;
begin
-- process reading the schedule of frame exchange from a text file
------------------------------------------------------------------
sequence: process
file sequence_file : text open read_mode is "data_vectors/pulses.txt";
variable sequence_line : line;
variable interval_time : time;
variable coma : string(1 to 1);
variable pulse_ch : integer;
variable pulse_lgth : time;
begin
readline (sequence_file, sequence_line);
read (sequence_line, interval_time);
read (sequence_line, coma);
read (sequence_line, pulse_ch);
read (sequence_line, coma);
read (sequence_line, pulse_lgth);
wait for interval_time;
pulse_channel <= pulse_ch;
pulse_length <= pulse_lgth;
if endfile(sequence_file) then
file_close(sequence_file);
wait;
end if;
end process;
start_extender: process
begin
wait until pulse_channel = 0;
tstart <= '1';
wait for pulse_length;
tstart <= '0';
end process;
stop1_extender: process
begin
wait until pulse_channel = 1;
tstop1 <= '1';
wait for pulse_length;
tstop1 <= '0';
end process;
stop2_extender: process
begin
wait until pulse_channel = 2;
tstop2 <= '1';
wait for pulse_length;
tstop2 <= '0';
end process;
stop3_extender: process
begin
wait until pulse_channel = 3;
tstop3 <= '1';
wait for pulse_length;
tstop3 <= '0';
end process;
stop4_extender: process
begin
wait until pulse_channel = 4;
tstop4 <= '1';
wait for pulse_length;
tstop4 <= '0';
end process;
stop5_extender: process
begin
wait until pulse_channel = 5;
tstop5 <= '1';
wait for pulse_length;
tstop5 <= '0';
end process;
tstart_o <= tstart;
tstop1_o <= tstop1;
tstop2_o <= tstop2;
tstop3_o <= tstop3;
tstop4_o <= tstop4;
tstop5_o <= tstop5;
end behavioral;
----------------------------------------------------------------------------------------------------
-- CERN-BE-CO-HT
----------------------------------------------------------------------------------------------------
--
-- unit name : TDC test-bench (tb_tdc)
-- author : G. Penacoba
-- date : May 2011
-- version : Revision 1
-- description : top module for test-bench
-- dependencies:
-- references :
-- modified by :
--
----------------------------------------------------------------------------------------------------
-- last changes:
----------------------------------------------------------------------------------------------------
-- to do:
----------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity tb_tdc is
end tb_tdc;
architecture behavioral of tb_tdc is
component top_tdc
generic(
g_width : integer :=32;
values_for_simulation : boolean :=FALSE
);
port(
-- interface with GNUM circuit
rst_n_a_i : in std_logic;
-- P2L Direction
p2l_clk_p_i : in std_logic; -- Receiver Source Synchronous Clock+
p2l_clk_n_i : in std_logic; -- Receiver Source Synchronous Clock-
p2l_data_i : in std_logic_vector(15 downto 0); -- Parallel receive data
p2l_dframe_i: in std_logic; -- Receive Frame
p2l_valid_i : in std_logic; -- Receive Data Valid
p2l_rdy_o : out std_logic; -- Rx Buffer Full Flag
p_wr_req_i : in std_logic_vector(1 downto 0); -- PCIe Write Request
p_wr_rdy_o : out std_logic_vector(1 downto 0); -- PCIe Write Ready
rx_error_o : out std_logic; -- Receive Error
vc_rdy_i : in std_logic_vector(1 downto 0); -- Virtual channel ready
-- L2P Direction
l2p_clk_p_o : out std_logic; -- Transmitter Source Synchronous Clock+
l2p_clk_n_o : out std_logic; -- Transmitter Source Synchronous Clock-
l2p_data_o : out std_logic_vector(15 downto 0); -- Parallel transmit data
l2p_dframe_o: out std_logic; -- Transmit Data Frame
l2p_valid_o : out std_logic; -- Transmit Data Valid
l2p_edb_o : out std_logic; -- Packet termination and discard
l2p_rdy_i : in std_logic; -- Tx Buffer Full Flag
l_wr_rdy_i : in std_logic_vector(1 downto 0); -- Local-to-PCIe Write
p_rd_d_rdy_i: in std_logic_vector(1 downto 0); -- PCIe-to-Local Read Response Data Ready
tx_error_i : in std_logic; -- Transmit Error
irq_p_o : out std_logic; -- Interrupt request pulse to GN4124 GPIO
-- interface signals with PLL circuit
acam_refclk_i : in std_logic;
pll_ld_i : in std_logic;
pll_refmon_i : in std_logic;
pll_sdo_i : in std_logic;
pll_status_i : in std_logic;
pll_cs_o : out std_logic;
pll_dac_sync_o : out std_logic;
pll_sdi_o : out std_logic;
pll_sclk_o : out std_logic;
tdc_clk_p_i : in std_logic;
tdc_clk_n_i : in std_logic;
-- interface signals with acam (timing)
err_flag_i : in std_logic;
int_flag_i : in std_logic;
start_dis_o : out std_logic;
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
-- interface signals with acam (data)
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_i : in std_logic;
ef2_i : in std_logic;
lf1_i : in std_logic;
lf2_i : in std_logic;
address_o : out std_logic_vector(3 downto 0);
cs_n_o : out std_logic;
oe_n_o : out std_logic;
rd_n_o : out std_logic;
wr_n_o : out std_logic;
-- other signals on the tdc card
mute_inputs_o : out std_logic;
tdc_led_status_o : out std_logic;
tdc_led_trig1_o : out std_logic;
tdc_led_trig2_o : out std_logic;
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
-- other signals on the spec card
spec_aux0_i : in std_logic;
spec_aux1_i : in std_logic;
spec_aux2_o : out std_logic;
spec_aux3_o : out std_logic;
spec_aux4_o : out std_logic;
spec_aux5_o : out std_logic;
spec_led_green_o : out std_logic;
spec_led_red_o : out std_logic;
spec_clk_i : in std_logic
);
end component;
component acam_model
generic(
start_retrig_period : time:= 3200 ns;
refclk_period : time:= 32 ns
);
port(
tstart_i : in std_logic;
tstop1_i : in std_logic;
tstop2_i : in std_logic;
tstop3_i : in std_logic;
tstop4_i : in std_logic;
tstop5_i : in std_logic;
startdis_i : in std_logic;
stopdis_i : in std_logic;
int_flag_o : out std_logic;
err_flag_o : out std_logic;
address_i : in std_logic_vector(3 downto 0);
cs_n_i : in std_logic;
oe_n_i : in std_logic;
rd_n_i : in std_logic;
wr_n_i : in std_logic;
data_bus_io : inout std_logic_vector(27 downto 0);
ef1_o : out std_logic;
ef2_o : out std_logic;
lf1_o : out std_logic;
lf2_o : out std_logic
);
end component;
component start_stop_gen
port(
tstart_o : out std_logic;
tstop1_o : out std_logic;
tstop2_o : out std_logic;
tstop3_o : out std_logic;
tstop4_o : out std_logic;
tstop5_o : out std_logic
);
end component;
-----------------------------------------------------------------------------
-- GN4124 Local Bus Model
-----------------------------------------------------------------------------
component GN412X_BFM
generic
(
STRING_MAX : integer := 256; -- Command string maximum length
T_LCLK : time := 10 ns; -- Local Bus Clock Period
T_P2L_CLK_DLY : time := 2 ns; -- Delay from LCLK to P2L_CLK
INSTANCE_LABEL : string := "GN412X_BFM"; -- Label string to be used as a prefix for messages from the model
MODE_PRIMARY : boolean := true -- TRUE for BFM acting as GN412x, FALSE for BFM acting as the DUT
);
port
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD : in string(1 to STRING_MAX);
CMD_REQ : in bit;
CMD_ACK : out bit;
CMD_CLOCK_EN : in boolean;
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn : in std_logic;
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n : out std_logic;
RSTOUT33n : out std_logic;
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
------------------------------------------------------------- __ Direction for primary mode
-- / \
LCLK, LCLKn : inout std_logic; -- Out
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp, L2P_CLKn : inout std_logic; -- In
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA : inout std_logic_vector(15 downto 0); -- In -- Parallel Transmit Data.
L2P_DFRAME : inout std_logic; -- In -- Transmit Data Frame.
L2P_VALID : inout std_logic; -- In -- Transmit Data Valid.
L2P_EDB : inout std_logic; -- In -- End-of-Packet Bad Flag.
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY : inout std_logic_vector(1 downto 0); -- Out -- Local-to-PCIe Write.
P_RD_D_RDY : inout std_logic_vector(1 downto 0); -- Out -- PCIe-to-Local Read Response Data Ready.
L2P_RDY : inout std_logic; -- Out -- Tx Buffer Full Flag.
TX_ERROR : inout std_logic; -- Out -- Transmit Error.
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp, P2L_CLKn : inout std_logic; -- Out -- P2L Source Synchronous Clock.
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA : inout std_logic_vector(15 downto 0); -- Out -- Parallel Receive Data.
P2L_DFRAME : inout std_logic; -- Out -- Receive Frame.
P2L_VALID : inout std_logic; -- Out -- Receive Data Valid.
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY : inout std_logic; -- In -- Rx Buffer Full Flag.
P_WR_REQ : inout std_logic_vector(1 downto 0); -- Out -- PCIe Write Request.
P_WR_RDY : inout std_logic_vector(1 downto 0); -- In -- PCIe Write Ready.
RX_ERROR : inout std_logic; -- In -- Receive Error.
VC_RDY : inout std_logic_vector(1 downto 0); -- Out -- Virtual Channel Ready Status.
-------------------------------------------------------------
-- GPIO signals
--
GPIO : inout std_logic_vector(15 downto 0)
);
end component; --GN412X_BFM;
-----------------------------------------------------------------------------
-- CMD_ROUTER component
-----------------------------------------------------------------------------
component cmd_router
generic(N_BFM : integer := 8;
N_FILES : integer := 3;
FIFO_DEPTH : integer := 8;
STRING_MAX : integer := 256
);
port(CMD : out string(1 to STRING_MAX);
CMD_REQ : out bit_vector(N_BFM-1 downto 0);
CMD_ACK : in bit_vector(N_BFM-1 downto 0);
CMD_ERR : in bit_vector(N_BFM-1 downto 0);
CMD_CLOCK_EN : out boolean
);
end component; --cmd_router;
constant pll_clk_period : time:= 8 ns;
constant g_width : integer:= 32;
constant start_retrig_period : time:= 3200 ns;
constant spec_clk_period : time:= 50 ns;
-- Number of Models receiving commands
constant N_BFM : integer := 1; -- 0 : GN412X_BFM in Model Mode
-- -- 1 : GN412X_BFM in DUT mode
-- Number of files to feed BFMs
constant N_FILES : integer := 1;
--
-- Depth of the command FIFO for each model
constant FIFO_DEPTH : integer := 16;
--
-- Maximum width of a command string
constant STRING_MAX : integer := 256;
signal acam_refclk_i : std_logic:='0';
signal tdc_clk_p_i : std_logic:='0';
signal tdc_clk_n_i : std_logic:='1';
signal spec_clk_i : std_logic:='0';
signal pll_ld_i : std_logic;
signal pll_refmon_i : std_logic;
signal pll_sdo_i : std_logic;
signal pll_status_i : std_logic;
signal pll_cs_o : std_logic;
signal pll_dac_sync_o : std_logic;
signal pll_sdi_o : std_logic;
signal pll_sclk_o : std_logic;
signal mute_inputs : std_logic;
signal address_o : std_logic_vector(3 downto 0);
signal cs_n_o : std_logic;
signal data_bus_io : std_logic_vector(27 downto 0);
signal ef1_i : std_logic;
signal ef2_i : std_logic;
signal err_flag_i : std_logic;
signal int_flag_i : std_logic;
signal lf1_i : std_logic;
signal lf2_i : std_logic;
signal oe_n_o : std_logic;
signal rd_n_o : std_logic;
signal start_dis_o : std_logic;
signal start_from_fpga_o : std_logic;
signal stop_dis_o : std_logic;
signal wr_n_o : std_logic;
--signal tstart : std_logic;
signal tstop1 : std_logic;
signal tstop2 : std_logic;
signal tstop3 : std_logic;
signal tstop4 : std_logic;
signal tstop5 : std_logic;
signal tdc_led_status : std_logic;
signal tdc_led_trig1 : std_logic;
signal tdc_led_trig2 : std_logic;
signal tdc_led_trig3 : std_logic;
signal tdc_led_trig4 : std_logic;
signal tdc_led_trig5 : std_logic;
signal spec_aux0_i : std_logic;
signal spec_aux1_i : std_logic;
signal spec_aux2_o : std_logic;
signal spec_aux3_o : std_logic;
signal spec_aux4_o : std_logic;
signal spec_aux5_o : std_logic;
signal spec_led_green : std_logic;
signal spec_led_red : std_logic;
-- GN4124 interface
signal rst_n : std_logic;
signal irq_p : std_logic;
signal RSTINn : std_logic;
signal RSTOUT18n : std_logic;
signal RSTOUT33n : std_logic;
signal LCLK, LCLKn : std_logic;
signal P2L_CLKp, P2L_CLKn : std_logic;
signal P2L_DATA : std_logic_vector(15 downto 0);
signal P2L_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal P2L_DFRAME : std_logic;
signal P2L_VALID : std_logic;
signal P2L_RDY : std_logic;
signal P_WR_REQ : std_logic_vector(1 downto 0);
signal P_WR_RDY : std_logic_vector(1 downto 0);
signal RX_ERROR : std_logic;
signal VC_RDY : std_logic_vector(1 downto 0);
signal L2P_CLKp, L2P_CLKn : std_logic;
signal L2P_DATA : std_logic_vector(15 downto 0);
signal L2P_DATA_32 : std_logic_vector(31 downto 0); -- For monitoring use
signal L2P_DFRAME : std_logic;
signal L2P_VALID : std_logic;
signal L2P_EDB : std_logic;
signal L2P_RDY : std_logic;
signal L_WR_RDY : std_logic_vector(1 downto 0);
signal P_RD_D_RDY : std_logic_vector(1 downto 0);
signal TX_ERROR : std_logic;
signal GPIO : std_logic_vector(15 downto 0);
-----------------------------------------------------------------------------
-- Command Router Signals
-----------------------------------------------------------------------------
signal CMD : string(1 to STRING_MAX);
signal CMD_REQ : bit_vector(N_BFM-1 downto 0);
signal CMD_ACK : bit_vector(N_BFM-1 downto 0);
signal CMD_ERR : bit_vector(N_BFM-1 downto 0);
signal CMD_CLOCK_EN : boolean;
begin
dut: top_tdc
generic map(
g_width => 32,
values_for_simulation => TRUE
)
port map(
-- interface with GNUM circuit
rst_n_a_i => rst_n,
p2l_clk_p_i => p2l_clkp,
p2l_clk_n_i => p2l_clkn,
p2l_data_i => p2l_data,
p2l_dframe_i => p2l_dframe,
p2l_valid_i => p2l_valid,
p2l_rdy_o => p2l_rdy,
p_wr_req_i => p_wr_req,
p_wr_rdy_o => p_wr_rdy,
rx_error_o => rx_error,
vc_rdy_i => vc_rdy,
l2p_clk_p_o => l2p_clkp,
l2p_clk_n_o => l2p_clkn,
l2p_data_o => l2p_data,
l2p_dframe_o => l2p_dframe,
l2p_valid_o => l2p_valid,
l2p_edb_o => l2p_edb,
l2p_rdy_i => l2p_rdy,
l_wr_rdy_i => l_wr_rdy,
p_rd_d_rdy_i => p_rd_d_rdy,
tx_error_i => tx_error,
irq_p_o => irq_p,
-- interface with PLL circuit
acam_refclk_i => acam_refclk_i,
pll_ld_i => pll_ld_i,
pll_refmon_i => pll_refmon_i,
pll_sdo_i => pll_sdo_i,
pll_status_i => pll_status_i,
pll_cs_o => pll_cs_o,
pll_dac_sync_o => pll_dac_sync_o,
pll_sdi_o => pll_sdi_o,
pll_sclk_o => pll_sclk_o,
tdc_clk_p_i => tdc_clk_p_i,
tdc_clk_n_i => tdc_clk_n_i,
-- interface signals with acam (timing)
int_flag_i => int_flag_i,
err_flag_i => err_flag_i,
start_dis_o => start_dis_o,
start_from_fpga_o => start_from_fpga_o,
stop_dis_o => stop_dis_o,
-- interface signals with acam (data)
data_bus_io => data_bus_io,
ef1_i => ef1_i,
ef2_i => ef2_i,
lf1_i => lf1_i,
lf2_i => lf2_i,
address_o => address_o,
cs_n_o => cs_n_o,
oe_n_o => oe_n_o,
rd_n_o => rd_n_o,
wr_n_o => wr_n_o,
-- other signals on the tdc card
mute_inputs_o => mute_inputs,
tdc_led_status_o => tdc_led_status,
tdc_led_trig1_o => tdc_led_trig1,
tdc_led_trig2_o => tdc_led_trig2,
tdc_led_trig3_o => tdc_led_trig3,
tdc_led_trig4_o => tdc_led_trig4,
tdc_led_trig5_o => tdc_led_trig5,
-- other signals on the spec card
spec_aux0_i => spec_aux0_i,
spec_aux1_i => spec_aux1_i,
spec_aux2_o => spec_aux2_o,
spec_aux3_o => spec_aux3_o,
spec_aux4_o => spec_aux4_o,
spec_aux5_o => spec_aux5_o,
spec_led_green_o => spec_led_green,
spec_led_red_o => spec_led_red,
spec_clk_i => spec_clk_i
);
acam: acam_model
generic map(
start_retrig_period => start_retrig_period,
refclk_period => pll_clk_period/4
)
port map(
tstart_i => start_from_fpga_o,
tstop1_i => tstop1,
tstop2_i => tstop2,
tstop3_i => tstop3,
tstop4_i => tstop4,
tstop5_i => tstop5,
startdis_i => start_dis_o,
stopdis_i => stop_dis_o,
int_flag_o => int_flag_i,
address_i => address_o,
cs_n_i => cs_n_o,
oe_n_i => oe_n_o,
rd_n_i => rd_n_o,
wr_n_i => wr_n_o,
data_bus_io => data_bus_io,
ef1_o => ef1_i,
ef2_o => ef2_i,
err_flag_o => err_flag_i,
lf1_o => lf1_i,
lf2_o => lf2_i
);
pulses_generator: start_stop_gen
port map(
tstart_o => open,
tstop1_o => tstop1,
tstop2_o => tstop2,
tstop3_o => tstop3,
tstop4_o => tstop4,
tstop5_o => tstop5
);
CMD_ERR <= (others => '0');
UC : cmd_router
generic map
(N_BFM => N_BFM,
N_FILES => N_FILES,
FIFO_DEPTH => FIFO_DEPTH,
STRING_MAX => STRING_MAX
)
port map
(CMD => CMD,
CMD_REQ => CMD_REQ,
CMD_ACK => CMD_ACK,
CMD_ERR => CMD_ERR,
CMD_CLOCK_EN => CMD_CLOCK_EN
);
-----------------------------------------------------------------------------
-- GN412x BFM - PRIMARY
-----------------------------------------------------------------------------
U0 : gn412x_bfm
generic map
(
STRING_MAX => STRING_MAX,
T_LCLK => 6.25 ns,
T_P2L_CLK_DLY => 2 ns,
INSTANCE_LABEL => "U0(Primary GN412x): ",
MODE_PRIMARY => true
)
port map
(
--=========================================================--
-------------------------------------------------------------
-- CMD_ROUTER Interface
--
CMD => CMD,
CMD_REQ => CMD_REQ(0),
CMD_ACK => CMD_ACK(0),
CMD_CLOCK_EN => CMD_CLOCK_EN,
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
-------------------------------------------------------------
-- This is the reset input to the BFM
--
RSTINn => RSTINn,
-------------------------------------------------------------
-- Reset outputs to DUT
--
RSTOUT18n => RSTOUT18n,
RSTOUT33n => RSTOUT33n,
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
-------------------------------------------------------------
--
LCLK => LCLK,
LCLKn => LCLKn,
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
L2P_CLKp => L2P_CLKp,
L2P_CLKn => L2P_CLKn,
-------------------------------------------------------------
-- L2P DDR Link
--
L2P_DATA => L2P_DATA,
L2P_DFRAME => L2P_DFRAME,
L2P_VALID => L2P_VALID,
L2P_EDB => L2P_EDB,
-------------------------------------------------------------
-- L2P SDR Controls
--
L_WR_RDY => L_WR_RDY,
P_RD_D_RDY => P_RD_D_RDY,
L2P_RDY => L2P_RDY,
TX_ERROR => TX_ERROR,
-------------------------------------------------------------
----------------- PCIe-to-Local Dataflow ---------------------
-------------------------------------------------------------
-- Transmitter Source Synchronous Clock.
--
P2L_CLKp => P2L_CLKp,
P2L_CLKn => P2L_CLKn,
-------------------------------------------------------------
-- P2L DDR Link
--
P2L_DATA => P2L_DATA,
P2L_DFRAME => P2L_DFRAME,
P2L_VALID => P2L_VALID,
-------------------------------------------------------------
-- P2L SDR Controls
--
P2L_RDY => P2L_RDY,
P_WR_REQ => P_WR_REQ,
P_WR_RDY => P_WR_RDY,
RX_ERROR => RX_ERROR,
VC_RDY => VC_RDY,
GPIO => gpio
); -- GN412X_BFM;
tdc_pll_clock: process
begin
if pll_cs_o ='1' and rst_n ='1' then
tdc_clk_p_i <= not (tdc_clk_p_i) after 1 ns;
tdc_clk_n_i <= not (tdc_clk_n_i) after 1 ns;
end if;
wait for pll_clk_period/2;
end process;
tdc_ref_clock: process
begin
if pll_cs_o ='1' and rst_n ='1' then
acam_refclk_i <= not (acam_refclk_i) after 3 ns;
end if;
wait for pll_clk_period*2;
end process;
spec_clock: process
begin
spec_clk_i <= not (spec_clk_i) after 1 ns;
wait for spec_clk_period/2;
end process;
rst_n <= RSTOUT18n;
GPIO(0) <= irq_p;
spec_aux0_i <= '1';
spec_aux1_i <= '0';
end behavioral;
rm -r backup
rm -r coreip
rm identify.log
rm rpt_tdc_top.areasrr rpt_tdc_top_areasrr.htm
rm run_ise.tcl
rm run_options.txt scratchproject.prs
rm synplicity.ucf
rm syn_tdc.edf
rm syn_tdc.fse
rm syn_tdc.htm
rm syn_tdc.map
rm syn_tdc.ncf
rm syn_tdc_prepass.srd
rm syn_tdc.sap
rm syn_tdc.srd
rm syn_tdc.srl
rm syn_tdc.srm
rm syn_tdc.srr
rm syn_tdc.srs
rm syn_tdc.szr
rm syn_tdc.tlg
rm -r syntmp
rm -r xplace
rm syn_tdc.bld
rm syn_tdc.mrp
rm syn_tdc.ncd
rm syn_tdc.ngd
rm syn_tdc_ngdbuild.xrpt
rm syn_tdc.ngm
rm syn_tdc.ngo
rm syn_tdc.pcf
rm syn_tdc_summary.xml
rm syn_tdc_usage.xml
rm tdc_top_map.xrpt
rm tdc_top_par.xrpt
rm -r xlnx_auto_0_xdb
rm -r _xmsgs
rm netlist.lst
rm par_tdc.ncd
rm par_tdc.pad
rm par_tdc_pad.csv
rm par_tdc_pad.txt
rm par_tdc.par
rm par_tdc.ptwx
rm par_tdc.unroutes
rm par_tdc.xpi
rm par_usage_statistics.html
rm par_tdc.twr
rm par_tdc.twx
rm tdc.bgn
rm tdc.bit
rm tdc_bitgen.xwbt
rm tdc.drc
rm webtalk.log
ngdbuild -uc synplicity.ucf syn_tdc.edf
map -detail -w -timing -ol high syn_tdc.ngd
par -ol high syn_tdc.ncd par_tdc
trce -u par_tdc.ncd syn_tdc.pcf
bitgen par_tdc.ncd tdc
# Synopsys, Inc. constraint file
# /afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/syn/tdc.sdc
# Written on Thu Jun 30 14:04:15 2011
# by Synplify Pro, D-2010.03 Scope Editor
# Clocks
#
define_clock {n:spec_clk} -name {spec_clk20} -freq 20 -clockgroup default_clkgroup_0
define_clock {n:clocks_management_block.half_clk} -name {half_clk} -freq 10 -clockgroup default_clkgroup_0
define_clock {n:acam_refclk} -name {acam_refclk} -freq 1.25 -clockgroup default_clkgroup_1
define_clock {n:clk} -name {tdc_clk125} -freq 125 -clockgroup default_clkgroup_1
#define_clock {spec_clk_i} -name {spec_clki} -freq 20 -clockgroup default_clkgroup_0
#define_clock {clocks_management_block.half_clk} -name {half_clk} -freq 10 -clockgroup default_clkgroup_0
#define_clock {clocks_management_block.tdc_clk125_ibuf} -name {tdc_clk125} -freq 125 -clockgroup default_clkgroup_1
# Inputs/Outputs
#
define_input_delay -default 2.00 -ref tdc_clk125:r
define_output_delay -default 2.00 -ref tdc_clk125:r
define_output_delay {p:pll_sdi_o} 2.00 -ref half_clk:r
define_output_delay {p:pll_cs_o} 2.00 -ref half_clk:r
define_output_delay {p:pll_sclk_o} 2.00 -ref half_clk:r
define_input_delay {p:pll_ld_i} 2.00 -ref half_clk:r
define_input_delay {p:pll_refmon_i} 2.00 -ref half_clk:r
define_input_delay {p:pll_sdo_i} 2.00 -ref half_clk:r
define_input_delay {p:pll_status_i} 2.00 -ref half_clk:r
# Attributes
# Global attribute definitions for improving implementation targetting Xilinx
define_global_attribute {syn_useioff} {1}
define_global_attribute {syn_noarrayports} {1}
define_global_attribute {syn_netlist_hierarchy} {0}
#pinout
define_attribute {p:rst_n_a_i} {syn_loc} {N20}
define_attribute {p:p2l_clk_p_i} {syn_loc} {M20}
define_attribute {p:p2l_clk_n_i} {syn_loc} {M19}
define_attribute {p:p2l_data_i[15]} {syn_loc} {H19}
define_attribute {p:p2l_data_i[14]} {syn_loc} {F21}
define_attribute {p:p2l_data_i[13]} {syn_loc} {F22}
define_attribute {p:p2l_data_i[12]} {syn_loc} {E20}
define_attribute {p:p2l_data_i[11]} {syn_loc} {E22}
define_attribute {p:p2l_data_i[10]} {syn_loc} {J19}
define_attribute {p:p2l_data_i[9]} {syn_loc} {H20}
define_attribute {p:p2l_data_i[8]} {syn_loc} {K19}
define_attribute {p:p2l_data_i[7]} {syn_loc} {K18}
define_attribute {p:p2l_data_i[6]} {syn_loc} {G20}
define_attribute {p:p2l_data_i[5]} {syn_loc} {G22}
define_attribute {p:p2l_data_i[4]} {syn_loc} {K17}
define_attribute {p:p2l_data_i[3]} {syn_loc} {L17}
define_attribute {p:p2l_data_i[2]} {syn_loc} {H21}
define_attribute {p:p2l_data_i[1]} {syn_loc} {H22}
define_attribute {p:p2l_data_i[0]} {syn_loc} {K20}
define_attribute {p:p2l_dframe_i} {syn_loc} {J22}
define_attribute {p:p2l_valid_i} {syn_loc} {L19}
define_attribute {p:p2l_rdy_o} {syn_loc} {J16}
define_attribute {p:p_wr_req_i[1]} {syn_loc} {M21}
define_attribute {p:p_wr_req_i[0]} {syn_loc} {M22}
define_attribute {p:p_wr_rdy_o[1]} {syn_loc} {K16}
define_attribute {p:p_wr_rdy_o[0]} {syn_loc} {L15}
define_attribute {p:rx_error_o} {syn_loc} {J17}
define_attribute {p:vc_rdy_i[1]} {syn_loc} {B22}
define_attribute {p:vc_rdy_i[0]} {syn_loc} {B21}
define_attribute {p:l2p_clk_p_o} {syn_loc} {K21}
define_attribute {p:l2p_clk_n_o} {syn_loc} {K22}
define_attribute {p:l2p_data_o[15]} {syn_loc} {Y21}
define_attribute {p:l2p_data_o[14]} {syn_loc} {W20}
define_attribute {p:l2p_data_o[13]} {syn_loc} {V20}
define_attribute {p:l2p_data_o[12]} {syn_loc} {V22}
define_attribute {p:l2p_data_o[11]} {syn_loc} {T19}
define_attribute {p:l2p_data_o[10]} {syn_loc} {T21}
define_attribute {p:l2p_data_o[9]} {syn_loc} {R22}
define_attribute {p:l2p_data_o[8]} {syn_loc} {P22}
define_attribute {p:l2p_data_o[7]} {syn_loc} {Y22}
define_attribute {p:l2p_data_o[6]} {syn_loc} {W22}
define_attribute {p:l2p_data_o[5]} {syn_loc} {V19}
define_attribute {p:l2p_data_o[4]} {syn_loc} {V21}
define_attribute {p:l2p_data_o[3]} {syn_loc} {T20}
define_attribute {p:l2p_data_o[2]} {syn_loc} {P18}
define_attribute {p:l2p_data_o[1]} {syn_loc} {P21}
define_attribute {p:l2p_data_o[0]} {syn_loc} {P16}
define_attribute {p:l2p_dframe_o} {syn_loc} {U22}
define_attribute {p:l2p_valid_o} {syn_loc} {T18}
define_attribute {p:l2p_edb_o} {syn_loc} {U20}
define_attribute {p:l2p_rdy_i} {syn_loc} {U19}
define_attribute {p:l_wr_rdy_i[1]} {syn_loc} {T22}
define_attribute {p:l_wr_rdy_i[0]} {syn_loc} {R20}
define_attribute {p:p_rd_d_rdy_i[1]} {syn_loc} {P19}
define_attribute {p:p_rd_d_rdy_i[0]} {syn_loc} {N16}
define_attribute {p:tx_error_i} {syn_loc} {M17}
define_attribute {p:irq_p_o} {syn_loc} {U16}
#define_attribute {p:spare_o} {syn_loc} {AB19}
define_attribute {p:acam_refclk_i} {syn_loc} {E16}
define_attribute {p:pll_ld_i} {syn_loc} {C18}
define_attribute {p:pll_refmon_i} {syn_loc} {D17}
define_attribute {p:pll_sdo_i} {syn_loc} {AB18}
define_attribute {p:pll_status_i} {syn_loc} {Y18}
define_attribute {p:tdc_clk_p_i} {syn_loc} {L20}
define_attribute {p:tdc_clk_n_i} {syn_loc} {L22}
define_attribute {p:pll_cs_o} {syn_loc} {AB17}
define_attribute {p:pll_dac_sync_o} {syn_loc} {AB16}
define_attribute {p:pll_sdi_o} {syn_loc} {AA18}
define_attribute {p:pll_sclk_o} {syn_loc} {Y17}
define_attribute {p:err_flag_i} {syn_loc} {V11}
define_attribute {p:int_flag_i} {syn_loc} {W11}
define_attribute {p:start_dis_o} {syn_loc} {T15}
define_attribute {p:stop_dis_o} {syn_loc} {U15}
define_attribute {p:data_bus_io[27]} {syn_loc} {AB4}
define_attribute {p:data_bus_io[26]} {syn_loc} {AA4}
define_attribute {p:data_bus_io[25]} {syn_loc} {AB9}
define_attribute {p:data_bus_io[24]} {syn_loc} {Y9}
define_attribute {p:data_bus_io[23]} {syn_loc} {Y10}
define_attribute {p:data_bus_io[22]} {syn_loc} {W10}
define_attribute {p:data_bus_io[21]} {syn_loc} {U10}
define_attribute {p:data_bus_io[20]} {syn_loc} {T10}
define_attribute {p:data_bus_io[19]} {syn_loc} {AB8}
define_attribute {p:data_bus_io[18]} {syn_loc} {AA8}
define_attribute {p:data_bus_io[17]} {syn_loc} {AB7}
define_attribute {p:data_bus_io[16]} {syn_loc} {Y7}
define_attribute {p:data_bus_io[15]} {syn_loc} {V9}
define_attribute {p:data_bus_io[14]} {syn_loc} {U9}
define_attribute {p:data_bus_io[13]} {syn_loc} {AB6}
define_attribute {p:data_bus_io[12]} {syn_loc} {AA6}
define_attribute {p:data_bus_io[11]} {syn_loc} {R8}
define_attribute {p:data_bus_io[10]} {syn_loc} {R9}
define_attribute {p:data_bus_io[9]} {syn_loc} {AB5}
define_attribute {p:data_bus_io[8]} {syn_loc} {Y5}
define_attribute {p:data_bus_io[7]} {syn_loc} {AB12}
define_attribute {p:data_bus_io[6]} {syn_loc} {U8}
define_attribute {p:data_bus_io[5]} {syn_loc} {AA12}
define_attribute {p:data_bus_io[4]} {syn_loc} {T8}
define_attribute {p:data_bus_io[3]} {syn_loc} {W8}
define_attribute {p:data_bus_io[2]} {syn_loc} {V7}
define_attribute {p:data_bus_io[1]} {syn_loc} {Y6}
define_attribute {p:data_bus_io[0]} {syn_loc} {W6}
define_attribute {p:ef1_i} {syn_loc} {W12}
define_attribute {p:ef2_i} {syn_loc} {R11}
define_attribute {p:lf1_i} {syn_loc} {Y12}
define_attribute {p:lf2_i} {syn_loc} {T11}
define_attribute {p:address_o[3]} {syn_loc} {AB15}
define_attribute {p:address_o[2]} {syn_loc} {Y15}
define_attribute {p:address_o[1]} {syn_loc} {U12}
define_attribute {p:address_o[0]} {syn_loc} {T12}
define_attribute {p:cs_n_o} {syn_loc} {T14}
define_attribute {p:oe_n_o} {syn_loc} {V13}
define_attribute {p:rd_n_o} {syn_loc} {AB13}
define_attribute {p:wr_n_o} {syn_loc} {Y13}
define_attribute {p:mute_inputs_o} {syn_loc} {C19}
define_attribute {p:tdc_led_status_o} {syn_loc} {W13}
define_attribute {p:tdc_led_trig1_o} {syn_loc} {W14}
define_attribute {p:tdc_led_trig2_o} {syn_loc} {Y14}
define_attribute {p:tdc_led_trig3_o} {syn_loc} {Y16}
define_attribute {p:tdc_led_trig4_o} {syn_loc} {W15}
define_attribute {p:tdc_led_trig5_o} {syn_loc} {V17}
define_attribute {p:term_en_1_o} {syn_loc} {W18}
define_attribute {p:term_en_2_o} {syn_loc} {B20}
define_attribute {p:term_en_3_o} {syn_loc} {A20}
define_attribute {p:term_en_4_o} {syn_loc} {H10}
define_attribute {p:term_en_5_o} {syn_loc} {E6}
define_attribute {p:spec_led_green_o} {syn_loc} {E5}
define_attribute {p:spec_led_red_o} {syn_loc} {D5}
define_attribute {p:spec_clk_i} {syn_loc} {H12}
# I/O Standards
#
define_io_standard {rst_n_a_i} syn_pad_type {LVCMOS18}
define_io_standard {p2l_clk_p_i} syn_pad_type {DIFF_SSTL_18_Class_II}
define_io_standard {p2l_clk_n_i} syn_pad_type {DIFF_SSTL_18_Class_II}
define_io_standard {p2l_data_i[15:0]} syn_pad_type {SSTL_18_Class_I}
define_io_standard {p2l_dframe_i} syn_pad_type {SSTL_18_Class_I}
define_io_standard {p2l_valid_i} syn_pad_type {SSTL_18_Class_I}
define_io_standard {p2l_rdy_o} syn_pad_type {SSTL_18_Class_I}
define_io_standard {p_wr_req_i[1:0]} syn_pad_type {SSTL_18_Class_I}
define_io_standard {p_wr_rdy_o[1:0]} syn_pad_type {SSTL_18_Class_I}
define_io_standard {rx_error_o} syn_pad_type {SSTL_18_Class_I}
define_io_standard {vc_rdy_i[1:0]} syn_pad_type {SSTL_18_Class_I}
#define_io_standard {l2p_clk_p_o} syn_pad_type {DIFF_SSTL_18_Class_II}
#define_io_standard {l2p_clk_n_o} syn_pad_type {DIFF_SSTL_18_Class_II}
define_io_standard {l2p_clk_p_o} syn_pad_type {SSTL_18_Class_I}
define_io_standard {l2p_clk_n_o} syn_pad_type {SSTL_18_Class_I}
define_io_standard {l2p_data_o[15:0]} syn_pad_type {SSTL_18_Class_I}
define_io_standard {l2p_dframe_o} syn_pad_type {SSTL_18_Class_I}
define_io_standard {l2p_valid_o} syn_pad_type {SSTL_18_Class_I}
define_io_standard {l2p_edb_o} syn_pad_type {SSTL_18_Class_I}
define_io_standard {l2p_rdy_i} syn_pad_type {SSTL_18_Class_I}
define_io_standard {l_wr_rdy_i[1:0]} syn_pad_type {SSTL_18_Class_I}
define_io_standard {p_rd_d_rdy_i[1:0]} syn_pad_type {SSTL_18_Class_I}
define_io_standard {tx_error_i} syn_pad_type {SSTL_18_Class_I}
define_io_standard {irq_p_o} syn_pad_type {LVCMOS_25}
define_io_standard {acam_refclk_i} syn_pad_type {LVCMOS_25}
define_io_standard {pll_ld_i} syn_pad_type {LVCMOS_25}
define_io_standard {pll_refmon_i} syn_pad_type {LVCMOS_25}
define_io_standard {pll_sdo_i} syn_pad_type {LVCMOS_25}
define_io_standard {pll_status_i} syn_pad_type {LVCMOS_25}
define_io_standard {tdc_clk_p_i} syn_pad_type {LVDS_25}
define_io_standard {tdc_clk_n_i} syn_pad_type {LVDS_25}
define_io_standard {pll_cs_o} syn_pad_type {LVCMOS_25}
define_io_standard {pll_dac_sync_o} syn_pad_type {LVCMOS_25}
define_io_standard {pll_sdi_o} syn_pad_type {LVCMOS_25}
define_io_standard {pll_sclk_o} syn_pad_type {LVCMOS_25}
define_io_standard {err_flag_i} syn_pad_type {LVCMOS_25}
define_io_standard {int_flag_i} syn_pad_type {LVCMOS_25}
define_io_standard {start_dis_o} syn_pad_type {LVCMOS_25}
define_io_standard {stop_dis_o} syn_pad_type {LVCMOS_25}
define_io_standard {data_bus_io[27:0]} syn_pad_type {LVCMOS_25}
define_io_standard {ef1_i} syn_pad_type {LVCMOS_25}
define_io_standard {ef2_i} syn_pad_type {LVCMOS_25}
define_io_standard {lf1_i} syn_pad_type {LVCMOS_25}
define_io_standard {lf2_i} syn_pad_type {LVCMOS_25}
define_io_standard {address_o[3:0]} syn_pad_type {LVCMOS_25}
define_io_standard {cs_n_o} syn_pad_type {LVCMOS_25}
define_io_standard {oe_n_o} syn_pad_type {LVCMOS_25}
define_io_standard {rd_n_o} syn_pad_type {LVCMOS_25}
define_io_standard {wr_n_o} syn_pad_type {LVCMOS_25}
define_io_standard {mute_inputs_o} syn_pad_type {LVCMOS_25}
define_io_standard {tdc_led_status_o} syn_pad_type {LVCMOS_25}
define_io_standard {tdc_led_trig1_o} syn_pad_type {LVCMOS_25}
define_io_standard {tdc_led_trig2_o} syn_pad_type {LVCMOS_25}
define_io_standard {tdc_led_trig3_o} syn_pad_type {LVCMOS_25}
define_io_standard {tdc_led_trig4_o} syn_pad_type {LVCMOS_25}
define_io_standard {tdc_led_trig5_o} syn_pad_type {LVCMOS_25}
define_io_standard {term_en_1_o} syn_pad_type {LVCMOS_25}
define_io_standard {term_en_2_o} syn_pad_type {LVCMOS_25}
define_io_standard {term_en_3_o} syn_pad_type {LVCMOS_25}
define_io_standard {term_en_4_o} syn_pad_type {LVCMOS_25}
define_io_standard {term_en_5_o} syn_pad_type {LVCMOS_25}
define_io_standard {spec_led_green_o} syn_pad_type {LVCMOS_25}
define_io_standard {spec_led_red_o} syn_pad_type {LVCMOS_25}
define_io_standard {spec_clk_i} syn_pad_type {LVCMOS_25}
#-- Synopsys, Inc.
#-- Version D-2010.03
#-- Project file /afs/cern.ch/eng/eda/cds_users/gfernand/projects/tdc/syn/tdc_syn_script.prj
#-- Written on Fri Jul 4 10:00:00 2011
#project files
#add_file -vhdl -lib work "../src/gnum_core/gn4124_core_pkg_s6.vhd"
#add_file -vhdl -lib work "../src/design/incr_counter.vhd"
#add_file -vhdl -lib work "../src/design/countdown_counter.vhd"
#add_file -vhdl -lib work "../src/design/one_hz_gen.vhd"
#add_file -vhdl -lib work "../src/design/start_nb_offset_gen.vhd"
#add_file -vhdl -lib work "../src/design/data_formatting.vhd"
#add_file -vhdl -lib work "../src/design/acam_timecontrol_interface.vhd"
#add_file -vhdl -lib work "../src/design/acam_databus_interface.vhd"
add_file -vhdl -lib work "../src/design/free_counter.vhd"
add_file -vhdl -lib work "../src/design/clk_managr.vhd"
#add_file -vhdl -lib work "../src/design/tdc_top.vhd"
add_file -vhdl -lib work "../src/design/tdc_pll_test/pll_test_top.vhd"
add_file -constraint -lib work "./tdc_syn_constraints.sdc"
#implementation attributes (Verilog)
set_option -vlog_std v2001
set_option -project_relative_includes 1
#implementation: "syn"
impl -add syn -type fpga
impl -active "syn"
#device options
set_option -technology Spartan6
set_option -part XC6SLX45T
set_option -package FGG484
set_option -speed_grade -2
set_option -part_companion ""
# Compiler Options
set_option -compiler_compatible 0
set_option -resource_sharing 0
set_option -synthesis_onoff_pragma 0
# sequential_optimization_options
set_option -symbolic_fsm_compiler 1
set_option -no_sequential_opt 0
#compilation/mapping options
set_option -use_fsm_explorer 0
set_option -top_module "tdc_top"
# mapper_options
set_option -frequency 20
set_option -default_enum_encoding onehot
set_option -write_verilog 0
set_option -write_vhdl 0
set_option -num_critical_paths 3
# Xilinx options
set_option -run_prop_extract 1
set_option -maxfan 10000
set_option -disable_io_insertion 0
set_option -pipe 0
set_option -retiming 0
set_option -update_models_cp 0
set_option -fixgatedclocks 3
set_option -fixgeneratedclocks 3
set_option -enable_prepacking 1
set_option -enhance_optimization 1
# NFilter (Netlist restructure)
set_option -enable_nfilter 1
set_option -popfeed 1
set_option -constprop 1
set_option -createhierarchy 0
#VIF options
set_option -write_vif 0
#automatic place and route (vendor) options
set_option -write_apr_constraint 1
#set result format/file last
project -result_file "./syn_tdc.edf"
#project -run -fg synthesis
#project -run -fg timing
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