From 698f0398f83d920d1942711b0f3c551c25d7cfc2 Mon Sep 17 00:00:00 2001 From: Hadaq in Frankfurt Date: Wed, 10 Apr 2013 12:49:12 +0200 Subject: [PATCH] first files --- soda_source/compile_periph_frankfurt.pl | 159 +++++ soda_source/project/SODA_source.ldf | 302 ++++++++++ soda_source/trb3_periph_sodasource.p2t | 21 + soda_source/trb3_periph_sodasource.prj | 180 ++++++ soda_source/trb3_periph_sodasource.vhd | 567 ++++++++++++++++++ .../trb3_periph_sodasource_constraints.lpf | 53 ++ source/soda_d8crc8.vhd | 97 +++ source/soda_packet_builder.vhd | 278 +++++++++ source/soda_packet_handler.vhd | 273 +++++++++ source/soda_superburst_gen.vhd | 54 ++ source/super_burst_generator.vhd | 73 +++ source/tb/TB_soda_source.vhd | 162 +++++ 12 files changed, 2219 insertions(+) create mode 100755 soda_source/compile_periph_frankfurt.pl create mode 100644 soda_source/project/SODA_source.ldf create mode 100644 soda_source/trb3_periph_sodasource.p2t create mode 100644 soda_source/trb3_periph_sodasource.prj create mode 100644 soda_source/trb3_periph_sodasource.vhd create mode 100644 soda_source/trb3_periph_sodasource_constraints.lpf create mode 100644 source/soda_d8crc8.vhd create mode 100644 source/soda_packet_builder.vhd create mode 100644 source/soda_packet_handler.vhd create mode 100644 source/soda_superburst_gen.vhd create mode 100644 source/super_burst_generator.vhd create mode 100644 source/tb/TB_soda_source.vhd diff --git a/soda_source/compile_periph_frankfurt.pl b/soda_source/compile_periph_frankfurt.pl new file mode 100755 index 0000000..7b30f33 --- /dev/null +++ b/soda_source/compile_periph_frankfurt.pl @@ -0,0 +1,159 @@ +#!/usr/bin/perl +use Data::Dumper; +use warnings; +use strict; + + + + +################################################################################### +#Settings for this project +my $TOPNAME = "trb3_periph_sodasource"; #Name of top-level entity +my $lattice_path = '/d/jspc29/lattice/diamond/2.01'; +my $synplify_path = '/d/jspc29/lattice/synplify/F-2012.03-SP1/'; +my $lm_license_file_for_synplify = "27000\@lxcad01.gsi.de"; +#my $lm_license_file_for_par = "1702\@hadeb05.gsi.de"; +my $lm_license_file_for_par = "1710\@cronos.e12.physik.tu-muenchen.de"; +################################################################################### + +$ENV{'PAR_DESIGN_NAME'}=$TOPNAME; + + + + + + +use FileHandle; + +$ENV{'SYNPLIFY'}=$synplify_path; +$ENV{'SYN_DISABLE_RAINBOW_DONGLE'}=1; +$ENV{'LM_LICENSE_FILE'}=$lm_license_file_for_synplify; + + + + +my $FAMILYNAME="LatticeECP3"; +my $DEVICENAME="LFE3-150EA"; +my $PACKAGE="FPBGA672"; +my $SPEEDGRADE="8"; + + +#create full lpf file +system("cp ../base/trb3_periph_hub.lpf workdir/$TOPNAME.lpf"); +#system("cat ../tdc_releases/tdc_v1.1.1/tdc_constraints.lpf >> workdir/$TOPNAME.lpf"); +system("cat ".$TOPNAME."_constraints.lpf >> workdir/$TOPNAME.lpf"); + + +#set -e +#set -o errexit + +#generate timestamp +my $t=time; +my $fh = new FileHandle(">version.vhd"); +die "could not open file" if (! defined $fh); +print $fh <close; + +system("env| grep LM_"); +my $r = ""; + +my $c="$synplify_path/bin/synplify_premier_dp -batch $TOPNAME.prj"; +$r=execute($c, "do_not_exit" ); + + +chdir "workdir"; +$fh = new FileHandle("<$TOPNAME".".srr"); +my @a = <$fh>; +$fh -> close; + + + +foreach (@a) +{ + if(/\@E:/) + { + print "\n"; + $c="cat $TOPNAME.srr | grep \"\@E\""; + system($c); + print "\n\n"; + exit 129; + } +} + + +$ENV{'LM_LICENSE_FILE'}=$lm_license_file_for_par; + + +$c=qq| $lattice_path/ispfpga/bin/lin/edif2ngd -path "../" -path "." -l $FAMILYNAME -d $DEVICENAME "$TOPNAME.edf" "$TOPNAME.ngo" |; +execute($c); + +$c=qq|$lattice_path/ispfpga/bin/lin/edfupdate -t "$TOPNAME.tcy" -w "$TOPNAME.ngo" -m "$TOPNAME.ngo" "$TOPNAME.ngx"|; +execute($c); + +$c=qq|$lattice_path/ispfpga/bin/lin/ngdbuild -a $FAMILYNAME -d $DEVICENAME -p "$lattice_path/ispfpga/ep5c00/data" -dt "$TOPNAME.ngo" "$TOPNAME.ngd"|; +execute($c); + +my $tpmap = $TOPNAME . "_map" ; + +$c=qq|$lattice_path/ispfpga/bin/lin/map -retime -split_node -a $FAMILYNAME -p $DEVICENAME -t $PACKAGE -s $SPEEDGRADE "$TOPNAME.ngd" -pr "$TOPNAME.prf" -o "$tpmap.ncd" -mp "$TOPNAME.mrp" "$TOPNAME.lpf"|; +execute($c); + +system("rm $TOPNAME.ncd"); + + +$c=qq|$lattice_path/ispfpga/bin/lin/multipar -pr "$TOPNAME.prf" -o "mpar_$TOPNAME.rpt" -log "mpar_$TOPNAME.log" -p "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.ncd"|; +#$c=qq|$lattice_path/ispfpga/bin/lin/par -f "../$TOPNAME.p2t" "$tpmap.ncd" "$TOPNAME.ncd" "$TOPNAME.prf"|; +execute($c); + +# IOR IO Timing Report +# $c=qq|$lattice_path/ispfpga/bin/lin/iotiming -s "$TOPNAME.ncd" "$TOPNAME.prf"|; +# execute($c); + +# TWR Timing Report +$c=qq|$lattice_path/ispfpga/bin/lin/trce -c -v 15 -o "$TOPNAME.twr.setup" "$TOPNAME.ncd" "$TOPNAME.prf"|; +execute($c); + +$c=qq|$lattice_path/ispfpga/bin/lin/trce -hld -c -v 5 -o "$TOPNAME.twr.hold" "$TOPNAME.ncd" "$TOPNAME.prf"|; +execute($c); + +$c=qq|$lattice_path/ispfpga/bin/lin/ltxt2ptxt $TOPNAME.ncd|; +execute($c); + +$c=qq|$lattice_path/ispfpga/bin/lin/bitgen -w -g CfgMode:Disable -g RamCfg:Reset -g ES:No $TOPNAME.ncd $TOPNAME.bit $TOPNAME.prf|; +# $c=qq|$lattice_path/ispfpga/bin/lin/bitgen -w "$TOPNAME.ncd" "$TOPNAME.prf"|; +execute($c); + +chdir ".."; + +exit; + +sub execute { + my ($c, $op) = @_; + #print "option: $op \n"; + $op = "" if(!$op); + print "\n\ncommand to execute: $c \n"; + $r=system($c); + if($r) { + print "$!"; + if($op ne "do_not_exit") { + exit; + } + } + + return $r; + +} diff --git a/soda_source/project/SODA_source.ldf b/soda_source/project/SODA_source.ldf new file mode 100644 index 0000000..d704f73 --- /dev/null +++ b/soda_source/project/SODA_source.ldf @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soda_source/trb3_periph_sodasource.p2t b/soda_source/trb3_periph_sodasource.p2t new file mode 100644 index 0000000..5e8d0d9 --- /dev/null +++ b/soda_source/trb3_periph_sodasource.p2t @@ -0,0 +1,21 @@ +-w +-i 15 +-l 5 +-n 1 +-y +-s 12 +-t 24 +-c 1 +-e 2 +#-g guidefile.ncd +-m nodelist.txt +# -w +# -i 6 +# -l 5 +# -n 1 +# -t 1 +# -s 1 +# -c 0 +# -e 0 +# +-exp parCDP=1:parCDR=1:parPlcInLimit=0:parPlcInNeighborSize=1:parPathBased=ON:parHold=ON:parHoldLimit=10000:paruseNBR=1 diff --git a/soda_source/trb3_periph_sodasource.prj b/soda_source/trb3_periph_sodasource.prj new file mode 100644 index 0000000..7c4698d --- /dev/null +++ b/soda_source/trb3_periph_sodasource.prj @@ -0,0 +1,180 @@ + +# implementation: "workdir" +impl -add workdir -type fpga + +# device options +set_option -technology LATTICE-ECP3 +set_option -part LFE3_150EA +set_option -package FN672C +set_option -speed_grade -8 +set_option -part_companion "" + +# compilation/mapping options +set_option -default_enum_encoding sequential +set_option -symbolic_fsm_compiler 1 +set_option -top_module "trb3_periph_sodasource" +set_option -resource_sharing true + +# map options +set_option -frequency 200 +set_option -fanout_limit 100 +set_option -disable_io_insertion 0 +set_option -retiming 0 +set_option -pipe 0 +#set_option -force_gsr +set_option -force_gsr false +set_option -fixgatedclocks false #3 +set_option -fixgeneratedclocks false #3 +set_option -compiler_compatible true + + +# simulation options +set_option -write_verilog 0 +set_option -write_vhdl 1 + +# automatic place and route (vendor) options +set_option -write_apr_constraint 0 + +# set result format/file last +project -result_format "edif" +project -result_file "workdir/trb3_periph_sodasource.edf" + +#implementation attributes + +set_option -vlog_std v2001 +set_option -project_relative_includes 1 +impl -active "workdir" + +#################### + + + +#add_file options + +add_file -vhdl -lib work "version.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_std.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_components.vhd" +add_file -vhdl -lib "work" "../base/trb3_components.vhd" + +add_file -vhdl -lib work "../../trbnet/trb_net16_term_buf.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_CRC.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_CRC8.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_onewire.vhd" +add_file -vhdl -lib work "../../trbnet/basics/rom_16x8.vhd" +add_file -vhdl -lib work "../../trbnet/basics/ram.vhd" +add_file -vhdl -lib work "../../trbnet/basics/pulse_sync.vhd" +add_file -vhdl -lib work "../../trbnet/basics/state_sync.vhd" +add_file -vhdl -lib work "../../trbnet/basics/ram_16x8_dp.vhd" +add_file -vhdl -lib work "../../trbnet/basics/ram_16x16_dp.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_addresses.vhd" +add_file -vhdl -lib work "../../trbnet/basics/ram_dp.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_term.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_sbuf.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_sbuf5.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_sbuf6.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_sbuf.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_regIO.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_regio_bus_handler.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_priority_encoder.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_dummy_fifo.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_dummy_fifo.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_term_ibuf.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_priority_arbiter.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net_pattern_gen.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_obuf_nodata.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_obuf.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_ibuf.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_api_base.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_iobuf.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_io_multiplexer.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_trigger.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_ipudata.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_endpoint_hades_full.vhd" +add_file -vhdl -lib work "../../trbnet/basics/signal_sync.vhd" +add_file -vhdl -lib work "../../trbnet/basics/ram_dp_rw.vhd" +add_file -vhdl -lib work "../../trbnet/basics/pulse_stretch.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_hub_func.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_hub_base.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_hub_logic.vhd" + + +add_file -vhdl -lib work "../../trbnet/special/handler_lvl1.vhd" +add_file -vhdl -lib work "../../trbnet/special/handler_data.vhd" +add_file -vhdl -lib work "../../trbnet/special/handler_ipu.vhd" +add_file -vhdl -lib work "../../trbnet/special/handler_trigger_and_data.vhd" +add_file -vhdl -lib work "../../trbnet/special/trb_net_reset_handler.vhd" +add_file -vhdl -lib work "../../trbnet/trb_net16_endpoint_hades_full_handler.vhd" +add_file -vhdl -lib work "../../trbnet/special/fpga_reboot.vhd" +add_file -vhdl -lib work "../../trbnet/special/spi_flash_and_fpga_reload.vhd" + +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/lattice_ecp3_fifo_18x1k.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/trb_net16_fifo_arch.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/lattice_ecp3_fifo_16bit_dualport.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/trb_net_fifo_16bit_bram_dualport.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/lattice_ecp2m_fifo.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_36x256_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_36x512_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_36x1k_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_36x2k_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_36x4k_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_36x8k_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_36x16k_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_36x32k_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x256_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x512_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x1k_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_18x2k_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp2m/fifo/fifo_var_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/fifo/fifo_19x16_obuf.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/lattice_ecp3_fifo_16x16_dualport.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/lattice_ecp3_fifo_18x16_dualport.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/lattice_ecp3_fifo_18x16_dualport_oreg.vhd" +add_file -vhdl -lib work "../../trbnet/lattice/ecp3/spi_dpram_32_to_8.vhd" + +add_file -vhdl -lib work "../../trbnet/special/spi_slim.vhd" +add_file -vhdl -lib work "../../trbnet/special/spi_master.vhd" +add_file -vhdl -lib work "../../trbnet/special/spi_databus_memory.vhd" +add_file -vhdl -lib work "../../trbnet/special/spi_ltc2600.vhd" +add_file -vhdl -lib work "../../trbnet/optical_link/f_divider.vhd" + + +add_file -vhdl -lib work "../../trbnet/media_interfaces/sync/med_sync_define.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/sync/rx_control.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/sync/tx_control.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/sync/rx_reset_fsm.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/sync/tx_reset_fsm.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/ecp3_sfp/serdes_sync_0.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/med_ecp3_sfp_sync.vhd" + +add_file -vhdl -lib work "../../trbnet/media_interfaces/ecp3_sfp/sfp_1_200_int.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/ecp3_sfp/sfp_1_125_int.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/trb_net16_lsm_sfp.vhd" +add_file -vhdl -lib work "../../trbnet/media_interfaces/trb_net16_med_ecp3_sfp.vhd" + +add_file -vhdl -lib "work" "../base/cores/pll_in200_out100.vhd" + + + + +############### +#Change path to tdc release also in compile script! +############### +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/Adder_304.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/bit_sync.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/BusHandler.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/Channel.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/Channel_200.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/Encoder_304_Bit.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/FIFO_32x32_OutReg.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/LogicAnalyser.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/Readout.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/Reference_Channel_200.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/Reference_Channel.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/ROM_encoder_3.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/ROM_FIFO.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/ShiftRegisterSISO.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/TDC.vhd" +#add_file -vhdl -lib "work" "../tdc_releases/tdc_v1.1.1/up_counter.vhd" + +add_file -vhdl -lib "work" "trb3_periph_sodasource.vhd" + diff --git a/soda_source/trb3_periph_sodasource.vhd b/soda_source/trb3_periph_sodasource.vhd new file mode 100644 index 0000000..201f86f --- /dev/null +++ b/soda_source/trb3_periph_sodasource.vhd @@ -0,0 +1,567 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb_net16_hub_func.all; +use work.trb3_components.all; +use work.med_sync_define.all; +use work.version.all; + +entity trb3_periph_sodasource is + generic( + SYNC_MODE : integer range 0 to 1 := c_NO; --use the RX clock for internal logic and transmission. Should be NO for soda tests! + USE_125_MHZ : integer := c_NO; + CLOCK_FREQUENCY : integer := 100; + NUM_INTERFACES : integer := 2 + ); + port( + --Clocks + CLK_GPLL_LEFT : in std_logic; --Clock Manager 1/(2468), 125 MHz + CLK_GPLL_RIGHT : in std_logic; --Clock Manager 2/(2468), 200 MHz <-- MAIN CLOCK for FPGA + CLK_PCLK_LEFT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! + CLK_PCLK_RIGHT : in std_logic; --Clock Fan-out, 200/400 MHz <-- For TDC. Same oscillator as GPLL right! + + --Trigger + --TRIGGER_LEFT : in std_logic; --left side trigger input from fan-out + --TRIGGER_RIGHT : in std_logic; --right side trigger input from fan-out + --Serdes Clocks - do not use + --CLK_SERDES_INT_LEFT : in std_logic; --Clock Manager 1/(1357), off, 125 MHz possible + --CLK_SERDES_INT_RIGHT : in std_logic; --Clock Manager 2/(1357), 200 MHz, only in case of problems + + --serdes I/O - connect as you like, no real use + SERDES_ADDON_TX : out std_logic_vector(15 downto 0); + SERDES_ADDON_RX : in std_logic_vector(15 downto 0); + + --Inter-FPGA Communication + FPGA5_COMM : inout std_logic_vector(11 downto 0); + --Bit 0/1 input, serial link RX active + --Bit 2/3 output, serial link TX active + --others yet undefined + --Connection to AddOn + LED_LINKOK : out std_logic_vector(6 downto 1); + LED_RX : out std_logic_vector(6 downto 1); + LED_TX : out std_logic_vector(6 downto 1); + SFP_MOD0 : in std_logic_vector(6 downto 1); + SFP_TXDIS : out std_logic_vector(6 downto 1); + SFP_LOS : in std_logic_vector(6 downto 1); + --SFP_MOD1 : inout std_logic_vector(6 downto 1); + --SFP_MOD2 : inout std_logic_vector(6 downto 1); + --SFP_RATESEL : out std_logic_vector(6 downto 1); + --SFP_TXFAULT : in std_logic_vector(6 downto 1); + + --Flash ROM & Reboot + FLASH_CLK : out std_logic; + FLASH_CS : out std_logic; + FLASH_DIN : out std_logic; + FLASH_DOUT : in std_logic; + PROGRAMN : out std_logic; --reboot FPGA + + --Misc + TEMPSENS : inout std_logic; --Temperature Sensor + CODE_LINE : in std_logic_vector(1 downto 0); + LED_GREEN : out std_logic; + LED_ORANGE : out std_logic; + LED_RED : out std_logic; + LED_YELLOW : out std_logic; + SUPPL : in std_logic; --terminated diff pair, PCLK, Pads + + --Test Connectors + TEST_LINE : out std_logic_vector(15 downto 0) + ); + + + attribute syn_useioff : boolean; + --no IO-FF for LEDs relaxes timing constraints + attribute syn_useioff of LED_GREEN : signal is false; + attribute syn_useioff of LED_ORANGE : signal is false; + attribute syn_useioff of LED_RED : signal is false; + attribute syn_useioff of LED_YELLOW : signal is false; + attribute syn_useioff of TEMPSENS : signal is false; + attribute syn_useioff of PROGRAMN : signal is false; + attribute syn_useioff of CODE_LINE : signal is false; + attribute syn_useioff of LED_LINKOK : signal is false; + attribute syn_useioff of LED_TX : signal is false; + attribute syn_useioff of LED_RX : signal is false; + attribute syn_useioff of SFP_MOD0 : signal is false; + attribute syn_useioff of SFP_TXDIS : signal is false; + attribute syn_useioff of SFP_LOS : signal is false; + attribute syn_useioff of TEST_LINE : signal is false; + + --important signals _with_ IO-FF + attribute syn_useioff of FLASH_CLK : signal is true; + attribute syn_useioff of FLASH_CS : signal is true; + attribute syn_useioff of FLASH_DIN : signal is true; + attribute syn_useioff of FLASH_DOUT : signal is true; + attribute syn_useioff of FPGA5_COMM : signal is true; + + +end entity; + +architecture trb3_periph_sodasource_arch of trb3_periph_sodasource is + --Constants + constant REGIO_NUM_STAT_REGS : integer := 0; + constant REGIO_NUM_CTRL_REGS : integer := 2; + + attribute syn_keep : boolean; + attribute syn_preserve : boolean; + + constant USE_200_MHZ : integer := 1 - USE_125_MHZ; + + --Clock / Reset + signal clk_sys_i : std_logic; --clock for main logic, 100 MHz, via Clock Manager and internal PLL +-- signal clk_200_i : std_logic; --clock for logic at 200 MHz, via Clock Manager and bypassed PLL + signal pll_lock : std_logic; --Internal PLL locked. E.g. used to reset all internal logic. + signal clear_i : std_logic; + signal reset_i : std_logic; + signal GSR_N : std_logic; + attribute syn_keep of GSR_N : signal is true; + attribute syn_preserve of GSR_N : signal is true; + signal clk_sys_internal : std_logic; + signal clk_raw_internal : std_logic; + signal rx_clock_half : std_logic; + signal rx_clock_full : std_logic; + signal clk_tdc : std_logic; + signal time_counter, time_counter2 : unsigned(31 downto 0); + --Media Interface + signal med_stat_op : std_logic_vector (NUM_INTERFACES*16-1 downto 0); + signal med_ctrl_op : std_logic_vector (NUM_INTERFACES*16-1 downto 0); + signal med_stat_debug : std_logic_vector (NUM_INTERFACES*64-1 downto 0); + signal med_ctrl_debug : std_logic_vector (NUM_INTERFACES*64-1 downto 0); + signal med_data_out : std_logic_vector (NUM_INTERFACES*16-1 downto 0); + signal med_packet_num_out : std_logic_vector (NUM_INTERFACES* 3-1 downto 0); + signal med_dataready_out : std_logic_vector (NUM_INTERFACES* 1-1 downto 0); + signal med_read_out : std_logic_vector (NUM_INTERFACES* 1-1 downto 0); + signal med_data_in : std_logic_vector (NUM_INTERFACES*16-1 downto 0); + signal med_packet_num_in : std_logic_vector (NUM_INTERFACES* 3-1 downto 0); + signal med_dataready_in : std_logic_vector (NUM_INTERFACES* 1-1 downto 0); + signal med_read_in : std_logic_vector (NUM_INTERFACES* 1-1 downto 0); + + --Slow Control channel + signal common_stat_reg : std_logic_vector(std_COMSTATREG*32-1 downto 0); + signal common_ctrl_reg : std_logic_vector(std_COMCTRLREG*32-1 downto 0); + signal stat_reg : std_logic_vector(32*2**REGIO_NUM_STAT_REGS-1 downto 0); + signal ctrl_reg : std_logic_vector(32*2**REGIO_NUM_CTRL_REGS-1 downto 0); + signal common_stat_reg_strobe : std_logic_vector(std_COMSTATREG-1 downto 0); + signal common_ctrl_reg_strobe : std_logic_vector(std_COMCTRLREG-1 downto 0); + signal stat_reg_strobe : std_logic_vector(2**REGIO_NUM_STAT_REGS-1 downto 0); + signal ctrl_reg_strobe : std_logic_vector(2**REGIO_NUM_CTRL_REGS-1 downto 0); + + --RegIO + signal my_address : std_logic_vector (15 downto 0); + signal regio_addr_out : std_logic_vector (15 downto 0); + signal regio_read_enable_out : std_logic; + signal regio_write_enable_out : std_logic; + signal regio_data_out : std_logic_vector (31 downto 0); + signal regio_data_in : std_logic_vector (31 downto 0); + signal regio_dataready_in : std_logic; + signal regio_no_more_data_in : std_logic; + signal regio_write_ack_in : std_logic; + signal regio_unknown_addr_in : std_logic; + signal regio_timeout_out : std_logic; + + --Timer + signal global_time : std_logic_vector(31 downto 0); + signal local_time : std_logic_vector(7 downto 0); + signal time_since_last_trg : std_logic_vector(31 downto 0); + signal timer_ticks : std_logic_vector(1 downto 0); + + --Flash + signal spimem_read_en : std_logic; + signal spimem_write_en : std_logic; + signal spimem_data_in : std_logic_vector(31 downto 0); + signal spimem_addr : std_logic_vector(8 downto 0); + signal spimem_data_out : std_logic_vector(31 downto 0); + signal spimem_dataready_out : std_logic; + signal spimem_no_more_data_out : std_logic; + signal spimem_unknown_addr_out : std_logic; + signal spimem_write_ack_out : std_logic; + + --media interface + signal sci1_ack : std_logic; + signal sci1_write : std_logic; + signal sci1_read : std_logic; + signal sci1_data_in : std_logic_vector(7 downto 0); + signal sci1_data_out : std_logic_vector(7 downto 0); + signal sci1_addr : std_logic_vector(8 downto 0); + signal sci2_ack : std_logic; + signal sci2_nack : std_logic; + signal sci2_write : std_logic; + signal sci2_read : std_logic; + signal sci2_data_in : std_logic_vector(7 downto 0); + signal sci2_data_out : std_logic_vector(7 downto 0); + signal sci2_addr : std_logic_vector(8 downto 0); + + + --TDC + signal hit_in_i : std_logic_vector(63 downto 0); + + signal soda_rx_clock_half : std_logic; + signal soda_rx_clock_full : std_logic; + signal tx_dlm_i : std_logic; + signal rx_dlm_i : std_logic; + signal tx_dlm_word : std_logic_vector(7 downto 0); + signal rx_dlm_word : std_logic_vector(7 downto 0); + +begin +--------------------------------------------------------------------------- +-- Reset Generation +--------------------------------------------------------------------------- + + GSR_N <= pll_lock; + + THE_RESET_HANDLER : trb_net_reset_handler + generic map( + RESET_DELAY => x"FEEE" + ) + port map( + CLEAR_IN => '0', -- reset input (high active, async) + CLEAR_N_IN => '1', -- reset input (low active, async) + CLK_IN => clk_raw_internal, -- raw master clock, NOT from PLL/DLL! + SYSCLK_IN => clk_sys_i, -- PLL/DLL remastered clock + PLL_LOCKED_IN => pll_lock, -- master PLL lock signal (async) + RESET_IN => '0', -- general reset signal (SYSCLK) + TRB_RESET_IN => med_stat_op(13), -- TRBnet reset signal (SYSCLK) + CLEAR_OUT => clear_i, -- async reset out, USE WITH CARE! + RESET_OUT => reset_i, -- synchronous reset out (SYSCLK) + DEBUG_OUT => open + ); + + +--------------------------------------------------------------------------- +-- Clock Handling +--------------------------------------------------------------------------- +gen_200_PLL : if USE_125_MHZ = c_NO generate + THE_MAIN_PLL : pll_in200_out100 + port map( + CLK => CLK_GPLL_RIGHT, + CLKOP => clk_sys_internal, + CLKOK => clk_raw_internal, + LOCK => pll_lock + ); +end generate; + +gen_125 : if USE_125_MHZ = c_YES generate + clk_sys_internal <= CLK_GPLL_LEFT; + clk_raw_internal <= CLK_GPLL_LEFT; +end generate; + +gen_sync_clocks : if SYNC_MODE = c_YES generate + clk_sys_i <= rx_clock_half; +-- clk_200_i <= rx_clock_full; +end generate; + +gen_local_clocks : if SYNC_MODE = c_NO generate + clk_sys_i <= clk_sys_internal; +-- clk_200_i <= clk_raw_internal; +end generate; + + +--------------------------------------------------------------------------- +-- The TrbNet media interface (to other FPGA) +--------------------------------------------------------------------------- + THE_MEDIA_UPLINK : trb_net16_med_ecp3_sfp + generic map( + SERDES_NUM => 1, --number of serdes in quad + EXT_CLOCK => c_NO, --use internal clock + USE_200_MHZ => USE_200_MHZ, --run on 200 MHz clock + USE_125_MHZ => USE_125_MHZ, + USE_CTC => c_NO, + USE_SLAVE => SYNC_MODE + ) + port map( + CLK => clk_raw_internal, + SYSCLK => clk_sys_i, + RESET => reset_i, + CLEAR => clear_i, + CLK_EN => '1', + --Internal Connection + MED_DATA_IN => med_data_out(15 downto 0), + MED_PACKET_NUM_IN => med_packet_num_out(2 downto 0), + MED_DATAREADY_IN => med_dataready_out(0), + MED_READ_OUT => med_read_in(0), + MED_DATA_OUT => med_data_in(15 downto 0), + MED_PACKET_NUM_OUT => med_packet_num_in(2 downto 0), + MED_DATAREADY_OUT => med_dataready_in(0), + MED_READ_IN => med_read_out(0), + REFCLK2CORE_OUT => open, + CLK_RX_HALF_OUT => rx_clock_half, + CLK_RX_FULL_OUT => rx_clock_full, + + --SFP Connection + SD_RXD_P_IN => SERDES_ADDON_RX(2), + SD_RXD_N_IN => SERDES_ADDON_RX(3), + SD_TXD_P_OUT => SERDES_ADDON_TX(2), + SD_TXD_N_OUT => SERDES_ADDON_TX(3), + SD_REFCLK_P_IN => '0', + SD_REFCLK_N_IN => '0', + SD_PRSNT_N_IN => FPGA5_COMM(0), + SD_LOS_IN => FPGA5_COMM(0), + SD_TXDIS_OUT => FPGA5_COMM(2), + + SCI_DATA_IN => sci1_data_in, + SCI_DATA_OUT => sci1_data_out, + SCI_ADDR => sci1_addr, + SCI_READ => sci1_read, + SCI_WRITE => sci1_write, + SCI_ACK => sci1_ack, + -- Status and control port + STAT_OP => med_stat_op(15 downto 0), + CTRL_OP => med_ctrl_op(15 downto 0), + STAT_DEBUG => med_stat_debug(63 downto 0), + CTRL_DEBUG => (others => '0') + ); + +--------------------------------------------------------------------------- +-- Hub +--------------------------------------------------------------------------- + +THE_HUB : trb_net16_hub_base + generic map ( + HUB_USED_CHANNELS => (c_NO,c_NO,c_NO,c_YES), + IBUF_SECURE_MODE => c_YES, + MII_NUMBER => NUM_INTERFACES, + MII_IS_UPLINK => (0 => 1, others => 0), + MII_IS_DOWNLINK => (0 => 0, others => 1), + MII_IS_UPLINK_ONLY=> (0 => 1, others => 0), + INT_NUMBER => 0, + USE_ONEWIRE => c_YES, + COMPILE_TIME => std_logic_vector(to_unsigned(VERSION_NUMBER_TIME,32)), + HARDWARE_VERSION => x"91003200", + INIT_ENDPOINT_ID => x"0000", + INIT_ADDRESS => x"F355", + USE_VAR_ENDPOINT_ID => c_YES, + BROADCAST_SPECIAL_ADDR => x"45", + CLOCK_FREQUENCY => CLOCK_FREQUENCY + ) + port map ( + CLK => clk_sys_i, + RESET => reset_i, + CLK_EN => '1', + + --Media interfacces + MED_DATAREADY_OUT(NUM_INTERFACES*1-1 downto 0) => med_dataready_out, + MED_DATA_OUT(NUM_INTERFACES*16-1 downto 0) => med_data_out, + MED_PACKET_NUM_OUT(NUM_INTERFACES*3-1 downto 0) => med_packet_num_out, + MED_READ_IN(NUM_INTERFACES*1-1 downto 0) => med_read_in, + MED_DATAREADY_IN(NUM_INTERFACES*1-1 downto 0) => med_dataready_in, + MED_DATA_IN(NUM_INTERFACES*16-1 downto 0) => med_data_in, + MED_PACKET_NUM_IN(NUM_INTERFACES*3-1 downto 0) => med_packet_num_in, + MED_READ_OUT(NUM_INTERFACES*1-1 downto 0) => med_read_out, + MED_STAT_OP(NUM_INTERFACES*16-1 downto 0) => med_stat_op, + MED_CTRL_OP(NUM_INTERFACES*16-1 downto 0) => med_ctrl_op, + + COMMON_STAT_REGS => common_stat_reg, + COMMON_CTRL_REGS => common_ctrl_reg, + MY_ADDRESS_OUT => open, + --REGIO INTERFACE + REGIO_ADDR_OUT => regio_addr_out, + REGIO_READ_ENABLE_OUT => regio_read_enable_out, + REGIO_WRITE_ENABLE_OUT => regio_write_enable_out, + REGIO_DATA_OUT => regio_data_out, + REGIO_DATA_IN => regio_data_in, + REGIO_DATAREADY_IN => regio_dataready_in, + REGIO_NO_MORE_DATA_IN => regio_no_more_data_in, + REGIO_WRITE_ACK_IN => regio_write_ack_in, + REGIO_UNKNOWN_ADDR_IN => regio_unknown_addr_in, + REGIO_TIMEOUT_OUT => regio_timeout_out, + REGIO_VAR_ENDPOINT_ID(1 downto 0) => CODE_LINE, + REGIO_VAR_ENDPOINT_ID(15 downto 2) => (others => '0'), + ONEWIRE => TEMPSENS, + ONEWIRE_MONITOR_OUT => open, + --Status ports (for debugging) + MPLEX_CTRL => (others => '0'), + CTRL_DEBUG => (others => '0'), + STAT_DEBUG => open + ); + + + +--------------------------------------------------------------------------- +-- Bus Handler +--------------------------------------------------------------------------- + THE_BUS_HANDLER : trb_net16_regio_bus_handler + generic map( + PORT_NUMBER => 3, + PORT_ADDRESSES => (0 => x"d000", 1 => x"b000", 2 => x"b800", others => x"0000"), + PORT_ADDR_MASK => (0 => 9, 1 => 9, 2 => 9, others => 0) + ) + port map( + CLK => clk_sys_i, + RESET => reset_i, + + DAT_ADDR_IN => regio_addr_out, + DAT_DATA_IN => regio_data_out, + DAT_DATA_OUT => regio_data_in, + DAT_READ_ENABLE_IN => regio_read_enable_out, + DAT_WRITE_ENABLE_IN => regio_write_enable_out, + DAT_TIMEOUT_IN => regio_timeout_out, + DAT_DATAREADY_OUT => regio_dataready_in, + DAT_WRITE_ACK_OUT => regio_write_ack_in, + DAT_NO_MORE_DATA_OUT => regio_no_more_data_in, + DAT_UNKNOWN_ADDR_OUT => regio_unknown_addr_in, + + --Bus Handler (SPI Memory) + BUS_READ_ENABLE_OUT(0) => spimem_read_en, + BUS_WRITE_ENABLE_OUT(0) => spimem_write_en, + BUS_DATA_OUT(0*32+31 downto 0*32) => spimem_data_in, + BUS_ADDR_OUT(0*16+8 downto 0*16) => spimem_addr, + BUS_ADDR_OUT(0*16+15 downto 0*16+9) => open, + BUS_TIMEOUT_OUT(0) => open, + BUS_DATA_IN(0*32+31 downto 0*32) => spimem_data_out, + BUS_DATAREADY_IN(0) => spimem_dataready_out, + BUS_WRITE_ACK_IN(0) => spimem_write_ack_out, + BUS_NO_MORE_DATA_IN(0) => spimem_no_more_data_out, + BUS_UNKNOWN_ADDR_IN(0) => spimem_unknown_addr_out, + + + --SCI first Media Interface + BUS_READ_ENABLE_OUT(1) => sci1_read, + BUS_WRITE_ENABLE_OUT(1) => sci1_write, + BUS_DATA_OUT(1*32+7 downto 1*32) => sci1_data_in, + BUS_DATA_OUT(1*32+31 downto 1*32+8) => open, + BUS_ADDR_OUT(1*16+8 downto 1*16) => sci1_addr, + BUS_ADDR_OUT(1*16+15 downto 1*16+9) => open, + BUS_TIMEOUT_OUT(1) => open, + BUS_DATA_IN(1*32+7 downto 1*32) => sci1_data_out, + BUS_DATAREADY_IN(1) => sci1_ack, + BUS_WRITE_ACK_IN(1) => sci1_ack, + BUS_NO_MORE_DATA_IN(1) => '0', + BUS_UNKNOWN_ADDR_IN(1) => '0', + --SCI soda test Media Interface + BUS_READ_ENABLE_OUT(2) => sci2_read, + BUS_WRITE_ENABLE_OUT(2) => sci2_write, + BUS_DATA_OUT(2*32+7 downto 2*32) => sci2_data_in, + BUS_DATA_OUT(2*32+31 downto 2*32+8) => open, + BUS_ADDR_OUT(2*16+8 downto 2*16) => sci2_addr, + BUS_ADDR_OUT(2*16+15 downto 2*16+9) => open, + BUS_TIMEOUT_OUT(2) => open, + BUS_DATA_IN(2*32+7 downto 2*32) => sci2_data_out, + BUS_DATAREADY_IN(2) => sci2_ack, + BUS_WRITE_ACK_IN(2) => sci2_ack, + BUS_NO_MORE_DATA_IN(2) => '0', + BUS_UNKNOWN_ADDR_IN(2) => sci2_nack, + STAT_DEBUG => open + ); + + + +--------------------------------------------------------------------------- +-- SPI / Flash +--------------------------------------------------------------------------- + +THE_SPI_RELOAD : entity work.spi_flash_and_fpga_reload + port map( + CLK_IN => clk_sys_i, + RESET_IN => reset_i, + + BUS_ADDR_IN => spimem_addr, + BUS_READ_IN => spimem_read_en, + BUS_WRITE_IN => spimem_write_en, + BUS_DATAREADY_OUT => spimem_dataready_out, + BUS_WRITE_ACK_OUT => spimem_write_ack_out, + BUS_UNKNOWN_ADDR_OUT => spimem_unknown_addr_out, + BUS_NO_MORE_DATA_OUT => spimem_no_more_data_out, + BUS_DATA_IN => spimem_data_in, + BUS_DATA_OUT => spimem_data_out, + + DO_REBOOT_IN => common_ctrl_reg(15), + PROGRAMN => PROGRAMN, + + SPI_CS_OUT => FLASH_CS, + SPI_SCK_OUT => FLASH_CLK, + SPI_SDO_OUT => FLASH_DIN, + SPI_SDI_IN => FLASH_DOUT + ); + + +--------------------------------------------------------------------------- +-- The synchronous interface for Soda tests +--------------------------------------------------------------------------- + +THE_SODA_SOURCE : med_ecp3_sfp_sync + generic map( + SERDES_NUM => 0, --number of serdes in quad + IS_SYNC_SLAVE => c_NO + ) + port map( + CLK => clk_raw_internal, --clk_200_i, + SYSCLK => clk_sys_i, + RESET => reset_i, + CLEAR => clear_i, + --Internal Connection for TrbNet data -> not used a.t.m. + MED_DATA_IN => med_data_out(31 downto 16), + MED_PACKET_NUM_IN => med_packet_num_out(5 downto 3), + MED_DATAREADY_IN => med_dataready_out(1), + MED_READ_OUT => med_read_in(1), + MED_DATA_OUT => med_data_in(31 downto 16), + MED_PACKET_NUM_OUT => med_packet_num_in(5 downto 3), + MED_DATAREADY_OUT => med_dataready_in(1), + MED_READ_IN => med_read_out(1), + CLK_RX_HALF_OUT => soda_rx_clock_half, + CLK_RX_FULL_OUT => soda_rx_clock_full, + + RX_DLM => rx_dlm_i, + RX_DLM_WORD => rx_dlm_word, + TX_DLM => tx_dlm_i, + TX_DLM_WORD => tx_dlm_word, + --SFP Connection + SD_RXD_P_IN => SERDES_ADDON_RX(0), + SD_RXD_N_IN => SERDES_ADDON_RX(1), + SD_TXD_P_OUT => SERDES_ADDON_TX(0), + SD_TXD_N_OUT => SERDES_ADDON_TX(1), + SD_REFCLK_P_IN => '0', + SD_REFCLK_N_IN => '0', + SD_PRSNT_N_IN => SFP_MOD0(1), + SD_LOS_IN => SFP_LOS(1), + SD_TXDIS_OUT => SFP_TXDIS(1), + + SCI_DATA_IN => sci2_data_in, + SCI_DATA_OUT => sci2_data_out, + SCI_ADDR => sci2_addr, + SCI_READ => sci2_read, + SCI_WRITE => sci2_write, + SCI_ACK => sci2_ack, + SCI_NACK => sci2_nack, + -- Status and control port + STAT_OP => med_stat_op(31 downto 16), + CTRL_OP => med_ctrl_op(31 downto 16), + STAT_DEBUG => med_stat_debug(127 downto 64), + CTRL_DEBUG => (others => '0') + ); + + +--------------------------------------------------------------------------- +-- The Soda Source +--------------------------------------------------------------------------- + tx_dlm_i <= '0'; + tx_dlm_word <= x"00"; + + +--------------------------------------------------------------------------- +-- LED +--------------------------------------------------------------------------- + LED_ORANGE <= not reset_i when rising_edge(clk_sys_internal); + LED_YELLOW <= '1'; + LED_GREEN <= not med_stat_op(9); + LED_RED <= not (med_stat_op(10) or med_stat_op(11)); + +--------------------------------------------------------------------------- +-- Test Connector +--------------------------------------------------------------------------- +-- TEST_LINE(15 downto 0) <= (others => '0'); +--------------------------------------------------------------------------- +-- Test Circuits +--------------------------------------------------------------------------- + process + begin + wait until rising_edge(clk_sys_internal); + time_counter <= time_counter + 1; + end process; + + + + +end architecture; diff --git a/soda_source/trb3_periph_sodasource_constraints.lpf b/soda_source/trb3_periph_sodasource_constraints.lpf new file mode 100644 index 0000000..f0e271a --- /dev/null +++ b/soda_source/trb3_periph_sodasource_constraints.lpf @@ -0,0 +1,53 @@ +BLOCK RESETPATHS ; +BLOCK ASYNCPATHS ; +BLOCK RD_DURING_WR_PATHS ; + +################################################################# +# Basic Settings +################################################################# + + SYSCONFIG MCCLK_FREQ = 20; + + FREQUENCY PORT CLK_PCLK_RIGHT 200 MHz; + FREQUENCY PORT CLK_PCLK_LEFT 200 MHz; + FREQUENCY PORT CLK_GPLL_RIGHT 200 MHz; + FREQUENCY PORT CLK_GPLL_LEFT 125 MHz; + +################################################################# +# Reset Nets +################################################################# +GSR_NET NET "GSR_N"; + + + + +################################################################# +# Locate Serdes and media interfaces +################################################################# +LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_1_200_THE_SERDES/PCSD_INST" SITE "PCSA" ; +LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_1_200_ctc_THE_SERDES/PCSD_INST" SITE "PCSA" ; +LOCATE COMP "THE_MEDIA_UPLINK/gen_serdes_200/PCSD_INST" SITE "PCSA" ; + +LOCATE COMP "THE_SODA_SOURCE/THE_SERDES/PCSD_INST" SITE "PCSB" ; + + +REGION "MEDIA_UPLINK" "R90C95D" 13 25; +REGION "MEDIA_DOWNLINK" "R55C120D" 25 35; +REGION "REGION_SPI" "R13C150D" 12 16 DEVSIZE; +REGION "REGION_IOBUF" "R10C43D" 88 86 DEVSIZE; + +LOCATE UGROUP "THE_SPI_MASTER/SPI_group" REGION "REGION_SPI" ; +LOCATE UGROUP "THE_SPI_MEMORY/SPI_group" REGION "REGION_SPI" ; + +LOCATE UGROUP "THE_MEDIA_UPLINK/media_interface_group" REGION "MEDIA_UPLINK" ; +LOCATE UGROUP "THE_SODA_SOURCE/media_interface_group" REGION "MEDIA_DOWNLINK" ; + + +MULTICYCLE FROM CELL "THE_RESET_HANDLER/rese*" 20 ns; +MULTICYCLE TO CELL "THE_SODA_SOURCE/SCI_DATA_OUT*" 20 ns; +MULTICYCLE TO CELL "THE_SODA_SOURCE/sci*" 20 ns; +MULTICYCLE FROM CELL "THE_SODA_SOURCE/sci*" 20 ns; +MULTICYCLE TO CELL "THE_SODA_SOURCE/wa_pos*" 20 ns; + +MULTICYCLE TO CELL "THE_MEDIA_UPLINK/SCI_DATA_OUT*" 50 ns; + diff --git a/source/soda_d8crc8.vhd b/source/soda_d8crc8.vhd new file mode 100644 index 0000000..b49827e --- /dev/null +++ b/source/soda_d8crc8.vhd @@ -0,0 +1,97 @@ + +-- ######################################################################## +-- crc engine rtl design +-- copyright (c) www.electronicdesignworks.com +-- source code generated by electronicdesignworks ip generator (crc). +-- documentation can be downloaded from www.electronicdesignworks.com +-- ******************************** +--license +-- ******************************** +-- this source file may be used and distributed freely provided that this +-- copyright notice, list of conditions and the following disclaimer is +-- not removed from the file. +-- any derivative work should contain this copyright notice and associated disclaimer. +-- this source code file is provided "as is" and without any warranty, +-- without even the implied warranty of merchantability or fitness for a +-- particular purpose. +-- ******************************** +-- specification +-- ******************************** +-- file name : crc8_data8.vhd +-- description : crc engine entity +-- clock : positive edge +-- reset : active low +-- first serial: msb +-- data bus width: 8 bits +-- polynomial: (0 4 5 8) +-- date: 12-mar-2013 +-- version : 1.0 +-- ######################################################################## + +library ieee ; +use ieee.std_logic_1164.all ; +use ieee.std_logic_arith.all ; +use ieee.std_logic_unsigned.all ; +entity soda_d8crc8 is + port( + CLOCK : in std_logic; + RESET : in std_logic; + SOC : in std_logic; + DATA : in std_logic_vector(7 downto 0); + DATA_VALID : in std_logic; + EOC : in std_logic; + CRC : out std_logic_vector(7 downto 0); + CRC_VALID : out std_logic + ); +end soda_d8crc8; + +architecture behavioral of soda_d8crc8 is + signal crc_r: std_logic_vector(7 downto 0); + signal crc_c: std_logic_vector(7 downto 0); + signal crc_i: std_logic_vector(7 downto 0); + signal crc_const: std_logic_vector(7 downto 0) := "00000000"; + +begin + + + crc_i<= crc_const when soc = '1' else + crc_r; + + crc_c(0) <= DATA(0) xor DATA(3) xor DATA(4) xor crc_i(0) xor crc_i(4) xor DATA(6) xor crc_i(3) xor crc_i(6); + crc_c(1) <= data(1) xor DATA(4) xor DATA(5) xor crc_i(1) xor crc_i(5) xor DATA(7) xor crc_i(4) xor crc_i(7); + crc_c(2) <= DATA(2) xor DATA(5) xor DATA(6) xor crc_i(2) xor crc_i(6) xor crc_i(5); + crc_c(3) <= DATA(3) xor DATA(6) xor DATA(7) xor crc_i(3) xor crc_i(7) xor crc_i(6); + crc_c(4) <= DATA(0) xor DATA(7) xor crc_i(7) xor DATA(3) xor crc_i(0) xor DATA(6) xor crc_i(3) xor crc_i(6); + crc_c(5) <= DATA(0) xor DATA(1) xor crc_i(1) xor DATA(7) xor crc_i(7) xor DATA(3) xor crc_i(0) xor DATA(6) xor crc_i(3) xor crc_i(6); + crc_c(6) <= DATA(1) xor DATA(2) xor crc_i(2) xor DATA(4) xor crc_i(1) xor DATA(7) xor crc_i(4) xor crc_i(7); + crc_c(7) <= DATA(2) xor DATA(3) xor crc_i(3) xor DATA(5) xor crc_i(2) xor crc_i(5); + + + crc_gen_process : process(clock, reset) + begin + if(reset = '1') then + crc_r <= "00000000" ; + elsif rising_edge(clock) then + if(DATA_valid = '1') then + crc_r <= crc_c; + end if; + end if; + end process crc_gen_process; + + + crc_valid_gen : process(clock, reset) + begin + if(reset = '1') then + CRC_VALID <= '0'; + elsif rising_edge(clock) then + if(DATA_valid = '1' and EOC = '1') then + CRC_VALID <= '1'; + else + CRC_VALID <= '0'; + end if; + end if; + end process crc_valid_gen; + + CRC <= crc_r; + +end behavioral; \ No newline at end of file diff --git a/source/soda_packet_builder.vhd b/source/soda_packet_builder.vhd new file mode 100644 index 0000000..38ced54 --- /dev/null +++ b/source/soda_packet_builder.vhd @@ -0,0 +1,278 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb3_components.all; +--use work.med_sync_define.all; +--use work.version.all; + +entity soda_packet_builder is +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + SODA_CMD_STROBE_IN : in std_logic := '0'; -- + START_OF_SUPERBURST : in std_logic := '0'; + SUPER_BURST_NR_IN : in std_logic_vector(30 downto 0) := (others => '0'); + SODA_CMD_WORD_IN : in std_logic_vector(31 downto 0) := (others => '0'); --REGIO_CTRL_REG in trbnet handler is 32 bit + TX_DLM_OUT : out std_logic := '0'; -- + TX_DLM_WORD_OUT : out std_logic_vector(7 downto 0) := (others => '0') + ); +end soda_packet_builder; + +architecture Behavioral of soda_packet_builder is + +component soda_d8crc8 + port( + clock : in std_logic; + reset : in std_logic; + soc : in std_logic; + data : in std_logic_vector(7 downto 0); + data_valid : in std_logic; + eoc : in std_logic; + crc : out std_logic_vector(7 downto 0); + crc_valid : out std_logic + ); +end component; + +-- constant c_K287 : std_logic_vector(7 downto 0) := x"FB"; + + signal clk_S : std_logic; + signal rst_S : std_logic; + signal soda_cmd_strobe_S : std_logic; + signal start_of_superburst_S : std_logic; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal soda_cmd_word_S : std_logic_vector(31 downto 0) := (others => '0'); -- from slowcontrol + signal soda_pkt_word_S : std_logic_vector(7 downto 0) := (others => '0'); + signal soda_pkt_valid_S : std_logic; + + signal soc_S : std_logic; + signal eoc_S : std_logic; + signal crc_data_valid_S : std_logic; + signal crc_datain_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_tmp_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_out_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_valid_S : std_logic; + + type packet_state_type is ( c_RST, c_IDLE, c_ERROR, + c_STD1, c_STD2, c_STD3, c_STD4, c_STD5, c_STD6, c_STD7, c_STD8, + c_CMD1, c_CMD2, c_CMD3, c_CMD4, c_CMD5, c_CMD6, c_CMD7, c_CMD8 + ); + signal packet_state_S : packet_state_type := c_IDLE; +-- signal packet_state_S : packet_state_type := c_IDLE; + +begin + + tx_crc8: soda_d8crc8 + port map( + clock => clk_S, + reset => rst_S, + soc => soc_S, + data => crc_datain_S, + data_valid => crc_data_valid_S, + eoc => eoc_S, + crc => crc_out_S, + crc_valid => crc_valid_S + ); + + clk_S <= SYSCLK; + rst_S <= RESET; + soda_cmd_strobe_S <= SODA_CMD_STROBE_IN; + soda_cmd_word_S <= SODA_CMD_WORD_IN; + start_of_superburst_S <= START_OF_SUPERBURST; + super_burst_nr_S <= SUPER_BURST_NR_IN; + + TX_DLM_WORD_OUT <= soda_pkt_word_S; + TX_DLM_OUT <= soda_pkt_valid_S; + +-- packet_state_S <= packet_state_S; + + packet_fsm_proc : process(clk_S, rst_S, packet_state_S, crc_valid_S, start_of_superburst_S, soda_cmd_strobe_S) + begin + if rising_edge(clk_S) then + if (rst_S='1') then + packet_state_S <= c_RST; + else + case packet_state_S is + when c_RST => + if (start_of_superburst_S='1') then + packet_state_S <= c_STD1; + elsif (soda_cmd_strobe_S='1') then + packet_state_S <= c_CMD1; + else + packet_state_S <= c_IDLE; + end if; + when c_IDLE => + if (start_of_superburst_S='1') then + packet_state_S <= c_STD1; + elsif (soda_cmd_strobe_S='1') then + packet_state_S <= c_CMD1; + end if; + when c_STD1 => + packet_state_S <= c_STD2; + when c_STD2 => + packet_state_S <= c_STD3; + when c_STD3 => + packet_state_S <= c_STD4; + when c_STD4 => + packet_state_S <= c_STD5; + when c_STD5 => + packet_state_S <= c_STD6; + when c_STD6 => + packet_state_S <= c_STD7; + when c_STD7 => + packet_state_S <= c_STD8; + when c_STD8 => + if (soda_cmd_strobe_S='0') then + packet_state_S <= c_IDLE; + else + packet_state_S <= c_CMD1; + end if; + when c_CMD1 => + packet_state_S <= c_CMD2; + when c_CMD2 => + packet_state_S <= c_CMD3; + when c_CMD3 => + packet_state_S <= c_CMD4; + when c_CMD4 => + packet_state_S <= c_CMD5; + when c_CMD5 => + packet_state_S <= c_CMD6; + when c_CMD6 => + packet_state_S <= c_CMD7; + when c_CMD7 => + if (crc_valid_S = '0') then + packet_state_S <= c_ERROR; + else + packet_state_S <= c_CMD8; + end if; + when c_CMD8 => + packet_state_S <= c_IDLE; + when c_ERROR => + packet_state_S <= c_IDLE; + when others => + packet_state_S <= c_IDLE; + end case; + end if; + end if; + end process; + + soda_packet_fill_proc : process(clk_S, packet_state_S) + begin + if rising_edge(clk_S) then + case packet_state_S is + when c_IDLE => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + when c_STD1 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= '1' & super_burst_nr_S(30 downto 24); + when c_STD2 => + soda_pkt_valid_S <= '0'; + when c_STD3 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= super_burst_nr_S(23 downto 16); + when c_STD4 => + soda_pkt_valid_S <= '0'; + when c_STD5 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= super_burst_nr_S(15 downto 8); + when c_STD6 => + soda_pkt_valid_S <= '0'; + when c_STD7 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= super_burst_nr_S(7 downto 0); + when c_STD8 => + soda_pkt_valid_S <= '0'; + when c_CMD1 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= '0' & soda_cmd_word_S(30 downto 24); + when c_CMD2 => + soda_pkt_valid_S <= '0'; + when c_CMD3 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= soda_cmd_word_S(23 downto 16); + when c_CMD4 => + soda_pkt_valid_S <= '0'; + when c_CMD5 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= soda_cmd_word_S(15 downto 8); + when c_CMD6 => + soda_pkt_valid_S <= '0'; + when c_CMD7 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= crc_out_S; + when c_CMD8 => + soda_pkt_valid_S <= '0'; + when others => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + end case; + end if; + end process; + + + crc_gen_proc : process(clk_S, packet_state_S) + begin + if rising_edge(clk_S) then + case packet_state_S is + when c_IDLE => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '1'; + eoc_S <= '0'; + when c_CMD1 => + crc_data_valid_S <= '1'; + crc_datain_S <= '0' & soda_cmd_word_S(30 downto 24); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD2 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD3 => + crc_data_valid_S <= '1'; + crc_datain_S <= soda_cmd_word_S(23 downto 16); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD4 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD5 => + crc_data_valid_S <= '1'; + crc_datain_S <= soda_cmd_word_S(15 downto 8); + soc_S <= '0'; + eoc_S <= '1'; + when c_CMD6 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD7 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD8 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when others => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + end case; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/source/soda_packet_handler.vhd b/source/soda_packet_handler.vhd new file mode 100644 index 0000000..7ff2099 --- /dev/null +++ b/source/soda_packet_handler.vhd @@ -0,0 +1,273 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb3_components.all; +--use work.med_sync_define.all; +--use work.version.all; + +entity soda_packet_handler is +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + RX_DLM_IN : in std_logic; + RX_DLM_WORD_IN : in std_logic_vector(7 downto 0) := (others => '0') + ); +end soda_packet_handler; + +architecture Behavioral of soda_packet_handler is + + component soda_d8crc8 + port( + clock : in std_logic; + reset : in std_logic; + soc : in std_logic; + data : in std_logic_vector(7 downto 0); + data_valid : in std_logic; + eoc : in std_logic; + crc : out std_logic_vector(7 downto 0); + crc_valid : out std_logic + ); + end component; + + constant c_K287 : std_logic_vector(7 downto 0) := x"FB"; + + signal clk_S : std_logic; + signal rst_S : std_logic; + signal rx_dlm_in_S : std_logic; + signal rx_dlm_word_in_S : std_logic_vector(7 downto 0) := (others => '0'); + signal soda_cmd_strobe_S : std_logic; + signal start_of_superburst_S : std_logic; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal soda_cmd_word_S : std_logic_vector(30 downto 0) := (others => '0'); -- from slowcontrol + signal soda_pkt_word_S : std_logic_vector(31 downto 0) := (others => '0'); + signal soda_pkt_valid_S : std_logic; + + type packet_state_type is ( c_RST, c_IDLE, c_ERROR, + c_SODA_PKT1, c_SODA_PKT2, c_SODA_PKT3, c_SODA_PKT4, + c_SODA_PKT5, c_SODA_PKT6, c_SODA_PKT7, c_SODA_PKT8 + ); + signal packet_state_S : packet_state_type := c_IDLE; + + signal soc_S : std_logic := '1'; + signal eoc_S : std_logic := '0'; + signal crc_data_valid_S : std_logic := '0'; + signal crc_datain_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_tmp_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_out_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_valid_S : std_logic := '0'; + + signal crc_check_S : std_logic := '0'; + signal crc_check_valid_S : std_logic := '0'; + +begin + + rx_crc8: soda_d8crc8 + port map( + clock => clk_S, + reset => rst_S, + soc => soc_S, + data => crc_datain_S, + data_valid => crc_data_valid_S, + eoc => eoc_S, + crc => crc_out_S, + crc_valid => crc_valid_S + ); + + clk_S <= SYSCLK; + rst_S <= RESET; + +-- packet_state_S <= packet_state_S; + + rx_dlm_in_S <= RX_DLM_IN; + rx_dlm_word_in_S <= RX_DLM_WORD_IN; + + packet_fsm_proc : process(clk_S) + begin + if rising_edge(clk_S) then + if (rst_S='1') then + packet_state_S <= c_RST; + else + case packet_state_S is + when c_RST => + if (rx_dlm_in_S='1') then -- received K27.7 #1 + packet_state_S <= c_SODA_PKT1; + else + packet_state_S <= c_IDLE; + end if; + when c_IDLE => + if (rx_dlm_in_S='1') then -- received K27.7 #1 + packet_state_S <= c_SODA_PKT1; + else + packet_state_S <= c_IDLE; + end if; + when c_SODA_PKT1 => + if (rx_dlm_in_S='0') then -- possibly received data-byte + packet_state_S <= c_SODA_PKT2; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT2 => + if (rx_dlm_in_S='1') then -- received K27.7 #2 + packet_state_S <= c_SODA_PKT3; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT3 => + if (rx_dlm_in_S='0') then -- possibly received data-byte + packet_state_S <= c_SODA_PKT4; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT4 => + if (rx_dlm_in_S='1') then -- received K27.7 #3 + packet_state_S <= c_SODA_PKT5; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT5 => + if (rx_dlm_in_S='0') then -- possibly received data-byte + packet_state_S <= c_SODA_PKT6; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT6 => + if (rx_dlm_in_S='1') then -- received K27.7 #4 + packet_state_S <= c_SODA_PKT7; + else + packet_state_S <= c_ERROR; + -- else do nothing + end if; + when c_SODA_PKT7 => + if (rx_dlm_in_S='1') or (crc_valid_S = '0') or not(crc_out_S = RX_DLM_WORD_IN) then + packet_state_S <= c_ERROR; -- if there's an unexpected K27.7 or no valid CRC-output or the CRC-check doesn't match + else + packet_state_S <= c_SODA_PKT8; + end if; + when c_SODA_PKT8 => + if (rx_dlm_in_S='1') then -- received K27.7 #4+1... must be another packet coming in.... + packet_state_S <= c_SODA_PKT1; + else + packet_state_S <= c_IDLE; + end if; + when c_ERROR => + packet_state_S <= c_IDLE; -- TODO: Insert ERROR_HANDLER + when others => + packet_state_S <= c_IDLE; + end case; + end if; + end if; + end process; + + soda_packet_collector_proc : process(clk_S, packet_state_S) + begin + if rising_edge(clk_S) then + case packet_state_S is + when c_RST => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + when c_IDLE => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + when c_SODA_PKT1 => + soda_pkt_word_S(31 downto 24) <= RX_DLM_WORD_IN; + when c_SODA_PKT2 => + -- do nothing -- disregard k27.7 + when c_SODA_PKT3 => + soda_pkt_word_S(23 downto 16) <= RX_DLM_WORD_IN; + when c_SODA_PKT4 => + -- do nothing -- disregard k27.7 + when c_SODA_PKT5 => + soda_pkt_word_S(15 downto 8) <= RX_DLM_WORD_IN; + when c_SODA_PKT6 => + -- do nothing -- disregard k27.7 + when c_SODA_PKT7 => + soda_pkt_word_S(7 downto 0) <= RX_DLM_WORD_IN; -- get transmitted CRC + when c_SODA_PKT8 => + when others => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + end case; + + if (soda_pkt_valid_S ='1') then + if (soda_pkt_word_S(31) = '1') then + super_burst_nr_S <= soda_pkt_word_S(30 downto 0); + start_of_superburst_S <= '1'; + else + soda_cmd_word_S <= soda_pkt_word_S(30 downto 0); + soda_cmd_strobe_S <= '1'; + end if; + else + start_of_superburst_S <= '0'; + soda_cmd_strobe_S <= '0'; + end if; + end if; + end process; + + crc_check_proc : process(clk_S, packet_state_S) + begin + if rising_edge(clk_S) then + case packet_state_S is + when c_RST => + soc_S <= '1'; + eoc_S <= '0'; + crc_check_valid_S <= '0'; + when c_IDLE => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '1'; + eoc_S <= '0'; + when c_SODA_PKT1 => + crc_data_valid_S <= '1'; + crc_datain_S <= RX_DLM_WORD_IN; + soc_S <= '0'; + when c_SODA_PKT2 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + when c_SODA_PKT3 => + crc_data_valid_S <= '1'; + crc_datain_S <= RX_DLM_WORD_IN; + when c_SODA_PKT4 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + when c_SODA_PKT5 => + crc_data_valid_S <= '1'; + crc_datain_S <= RX_DLM_WORD_IN; + eoc_S <= '1'; + when c_SODA_PKT6 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + eoc_S <= '0'; + when c_SODA_PKT7 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + if ((crc_valid_S = '1') and (crc_out_S = RX_DLM_WORD_IN)) then + crc_check_S <= '1'; + else + crc_check_S <= '0'; + end if; + crc_check_valid_S <= '1'; + when c_SODA_PKT8 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + crc_check_S <= '0'; + crc_check_valid_S <= '0'; + when others => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + crc_check_valid_S <= '0'; + end case; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/source/soda_superburst_gen.vhd b/source/soda_superburst_gen.vhd new file mode 100644 index 0000000..ade1e6c --- /dev/null +++ b/source/soda_superburst_gen.vhd @@ -0,0 +1,54 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb3_components.all; +use work.med_sync_define.all; +use work.version.all; + +entity soda_packet_builder is +-- generic( +-- INTERCEPT_MODE : integer range 0 to 1 := c_NO --use the RX clock for internal logic and transmission. Should be NO for soda tests! +-- ); +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + START_OF_BURST : in std_logic := '0'; + SUPER_BURST_NR_OUT : out std_logic_vector(30 downto 0) := (others => '0'); + SUPER_BURST_NR_VALID : out std_logic + START_OF_SUPERBURST : out std_logic + ); +end soda_packet_builder; + +architecture Behavioral of soda_packet_builder is + constant c_K287 : std_logic_vector(7 downto 0) := x"FB"; + + signal clk_S : std_logic; + signal rst_S : std_logic; + signal soda_cmd_strobe_S : std_logic; + signal start_of_burst_S : std_logic; + signal start_of_superburst_S : std_logic; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal superburst_nr_valid_S : std_logic; + + signal burst_count_S : std_logic_vector(3 downto 0) := (others => '0'); + +begin + + clk_S <= SYSCLK; + rst_S <= RESET; + start_of_burst_S <= START_OF_BURST; + + SUPER_BURST_NR_OUT <= soda_pkt_word_S; + SUPER_BURST_NR_VALID <= soda_pkt_valid_S; + START_OF_SUPERBURST <= start_of_burst_S; + + + +end architecture; \ No newline at end of file diff --git a/source/super_burst_generator.vhd b/source/super_burst_generator.vhd new file mode 100644 index 0000000..db15df1 --- /dev/null +++ b/source/super_burst_generator.vhd @@ -0,0 +1,73 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use IEEE.STD_LOGIC_ARITH.ALL; +use ieee.std_logic_signed.all; + +--library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb3_components.all; +--use work.med_sync_define.all; +--use work.version.all; + +entity super_burst_generator is + generic( + BURST_COUNT : natural range 1 to 256 := 16 -- number of bursts to be counted between super-bursts + ); + port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + SODA_BURST_PULSE_IN : in std_logic := '0'; -- + START_OF_SUPERBURST : out std_logic := '0'; + SUPER_BURST_NR_OUT : out std_logic_vector(30 downto 0) := (others => '0') + ); +end super_burst_generator; + +architecture Behavioral of super_burst_generator is + + constant cBURST_COUNT : std_logic_vector(7 downto 0) := conv_std_logic_vector(BURST_COUNT - 1,8); + + signal clk_S : std_logic; + signal rst_S : std_logic; + signal soda_burst_pulse_S : std_logic := '0'; + signal start_of_superburst_S : std_logic := '0'; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal burst_counter_S : std_logic_vector(7 downto 0) := (others => '0'); -- from super-burst-nr-generator + + +begin + + clk_S <= SYSCLK; + rst_S <= RESET; + START_OF_SUPERBURST <= start_of_superburst_S; + SUPER_BURST_NR_OUT <= super_burst_nr_S; + + burst_pulse_edge_proc : process(clk_S, rst_S, SODA_BURST_PULSE_IN, soda_burst_pulse_S, burst_counter_S) + begin + if rising_edge(clk_S) then + soda_burst_pulse_S <= SODA_BURST_PULSE_IN; + if (rst_S='1') then + burst_counter_S <= cBURST_COUNT; + start_of_superburst_S <= '0'; + super_burst_nr_S <= (others => '0'); + elsif ((SODA_BURST_PULSE_IN = '1') and (soda_burst_pulse_S = '0')) then + if (burst_counter_S = x"00") then + start_of_superburst_S <= '1'; + super_burst_nr_S <= super_burst_nr_S + 1; + burst_counter_S <= cBURST_COUNT; + else + start_of_superburst_S <= '0'; + burst_counter_s <= burst_counter_s - 1; + end if; + else + start_of_superburst_S <= '0'; + end if; + end if; + end process; + + +end Behavioral; \ No newline at end of file diff --git a/source/tb/TB_soda_source.vhd b/source/tb/TB_soda_source.vhd new file mode 100644 index 0000000..d1b5b46 --- /dev/null +++ b/source/tb/TB_soda_source.vhd @@ -0,0 +1,162 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb3_components.all; +--use work.med_sync_define.all; +--use work.version.all; + +entity TB_soda_source is +end entity; + +architecture TestBench of TB_soda_source is + + -- Clock period definitions + constant clk_period : time := 4ns; + + +component super_burst_generator + generic( + BURST_COUNT : integer range 1 to 64 := 16 -- number of bursts to be counted between super-bursts + ); +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + SODA_BURST_PULSE_IN : in std_logic := '0'; -- + START_OF_SUPERBURST : out std_logic := '0'; + SUPER_BURST_NR_OUT : out std_logic_vector(30 downto 0) := (others => '0') + ); +end component; + +component soda_packet_builder + port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + SODA_CMD_STROBE_IN : in std_logic := '0'; -- + START_OF_SUPERBURST : in std_logic := '0'; + SUPER_BURST_NR_IN : in std_logic_vector(30 downto 0) := (others => '0'); + SODA_CMD_WORD_IN : in std_logic_vector(31 downto 0) := (others => '0'); --REGIO_CTRL_REG in trbnet handler is 32 bit + TX_DLM_OUT : out std_logic := '0'; -- + TX_DLM_WORD_OUT : out std_logic_vector(7 downto 0) := (others => '0') + ); +end component; + +component soda_packet_handler +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + RX_DLM_WORD_IN : in std_logic_vector(7 downto 0) := (others => '0'); + RX_DLM_IN : in std_logic + ); +end component; + +--Inputs + signal rst_S : std_logic; + signal clk_S : std_logic; + signal enable_S : std_logic := '0'; + signal soda_cmd_word_S : std_logic_vector(31 downto 0) := (others => '0'); + signal soda_cmd_strobe_S : std_logic := '0'; + signal SOS_S : std_logic := '0'; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal SOB_S : std_logic := '0'; + signal dlm_word_S : std_logic_vector(7 downto 0) := (others => '0'); + signal dlm_valid_S : std_logic; + +begin + + superburst_gen : super_burst_generator + generic map(BURST_COUNT => 16) + port map( + SYSCLK => clk_S, + RESET => rst_S, + CLEAR => '0', + CLK_EN => '0', + --Internal Connection + SODA_BURST_PULSE_IN => SOB_S, + START_OF_SUPERBURST => SOS_S, + SUPER_BURST_NR_OUT => super_burst_nr_S + ); + + packet_builder : soda_packet_builder + port map( + SYSCLK => clk_S, + RESET => rst_S, + CLEAR => '0', + CLK_EN => '0', + --Internal Connection + SODA_CMD_STROBE_IN => soda_cmd_strobe_S, + START_OF_SUPERBURST => SOS_S, + SUPER_BURST_NR_IN => super_burst_nr_S, + SODA_CMD_WORD_IN => soda_cmd_word_S, + TX_DLM_OUT => dlm_valid_S, + TX_DLM_WORD_OUT => dlm_word_S + + ); + + packet_handler : soda_packet_handler + port map( + SYSCLK => clk_S, + RESET => rst_S, + CLEAR => '0', + CLK_EN => '0', + --Internal Connection + RX_DLM_IN => dlm_valid_S, + RX_DLM_WORD_IN => dlm_word_S + ); + +------------------------------------------------------------------------------------------------------------ + -- SODA command packet +------------------------------------------------------------------------------------------------------------ + cmd_proc :process + begin + wait for 2us; + soda_cmd_word_S <= x"40000000"; + soda_cmd_strobe_S <= '1'; + wait for clk_period; + soda_cmd_strobe_S <= '0'; + wait; + end process; + +------------------------------------------------------------------------------------------------------------ + -- Clock process definitions +------------------------------------------------------------------------------------------------------------ + clk_proc :process + begin + clk_S <= '0'; + wait for clk_period/2; + clk_S <= '1'; + wait for clk_period/2; + end process; + + -- reset process + reset_proc: process + begin + rst_S <= '1'; + wait for clk_period * 5; + rst_S <= '0'; + wait; + end process; + + burst_proc :process + begin + SOB_S <= '0'; + wait for 2.35us; + SOB_S <= '1'; + wait for 50ns; + end process; + + +end TestBench; + -- 2.43.0