Commit f862dbf7 authored by David Cussans's avatar David Cussans

Adding last of PCB files and some of firmware

git-svn-id: https://svn2.phy.bris.ac.uk/svn/uob-hep-pc049a/trunk@16 e1591323-3689-4d5a-aa31-d1a7cbdc5706
parent c879f7f8
{ Machine generated file created by SPI }
{ Last modified was 15:22:02 Wednesday, May 07, 2014 }
{ NOTE: Do not modify the contents of this file. If this is regenerated by }
{ SPI, your modifications will be overwritten. }
START_GLOBAL
view_pcb './worklib/pc049a_4lemos/physical'
design_name 'pc049a_4lemos'
design_library 'uob_hep_pc049a_lib'
library 'uob_hep_pc049a_lib' 'bris_cds_analogue' 'bris_cds_connectors' 'bris_cds_discrete' 'bris_cds_logic' 'bris_cds_memory' 'bris_cds_pld' 'bris_cds_special' 'bris_cds_standard' 'bris_cds_switches' 'cn74lv' 'cn74tiac' 'cn75als' 'cncmos' 'cnconnector' 'cndiscrete' 'cnpassive' 'cnpld' 'cnpower' 'cnspecial' 'cnstandard' 'cnvlsi' 'standard' 'cnlinear'
temp_dir 'temp'
cpm_version '16.5'
session_name 'ProjectMgr58303345'
ppt '$BRIS_CDSLIB/cds_analogue/cds_analogue.ptf' '$BRIS_CDSLIB/cds_connectors/cds_connectors.ptf' '$BRIS_CDSLIB/cds_logic/cds_logic.ptf' '$BRIS_CDSLIB/cds_pld/cds_pld.ptf' '$BRIS_CDSLIB/cds_special/cds_special.ptf' '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cnconnector.ptf' '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cndiscrete.ptf' '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cnpassive.ptf'
EXCLUDE_PPT
INCLUDE_PPT
cdsprop_file ''
log_file ''
physical_path './worklib/pc049a_4lemos/physical'
expand_with_errors 'OFF'
END_GLOBAL
START_CONCEPTHDL
LOGIC_GRID_SIZE '0.050'
DOC_GRID_SIZE '0.050'
CHECK_VOLTAGE_ON_HDL 'OFF'
PLOT_FIT_TO_PAGE 'ON'
PLOT_FONT 'Arial'
HPF_PLOTTER 'postscriptbw'
HPF_FONT 'native'
HPF_SPEC_PLOT_PAGESIZE 'YES'
HPF_BATCH 'YES'
HPF_PLOT_FILE_LOCATION '/home/phdgc'
HPF_PLOT_FILE_NAME 'pc049a_4lemos1.ps'
PLOTTER_FACILITY 'HPF'
PLOT_EDGE_TO_EDGE 'ON'
PAPER_SIZE '9'
PAPER_ORIENTATION '1'
PAPER_SOURCE '15'
WPLOTTER_NAME ''
HPF_PLOT_PAGESIZE 'A4'
HPF_PAGESCALETYPE 'PAGESIZE'
HPF_PAGESIZE 'A4'
HPF_SCALEFACTOR '0.000000'
END_CONCEPTHDL
START_PKGRXL
comp_def_prop 'ALT_SYMBOLS' 'JEDEC_TYPE' 'MERGE_NC_PINS' 'MERGE_POWER_PINS' 'NC_PINS' 'PINCOUNT' 'POWER_GROUP' 'POWER_PINS'
comp_inst_prop 'DEFAULT_SIGNAL_MODEL' 'GROUP' 'REUSE_ID' 'REUSE_INSTANCE' 'REUSE_NAME' 'ROOM' 'SIGNAL_MODEL' 'VOLT_TEMP_SIGNAL_MODEL'
regenerate_physical_net_name 'OFF'
electrical_constraints 'ON'
overwrite_constraints 'OFF'
USE_SUBDESIGN
FORCE_SUBDESIGN
GEN_SUBDESIGN 'pc049a_4lemos'
FILTER_PROPERTY
PASS_PROPERTY
FILTER_CONFLICTING_PROP
END_PKGRXL
START_DESIGNSYNC
replace_symbol '1'
etch_removal 'NO'
ignore_fixed 'NO'
create_user_prop 'NO'
run_packager 'YES'
run_netrev 'YES'
backannotate_forward 'NO'
last_board_file 'pc049a_4lemos_03.brd'
run_feedback 'YES'
run_genfeedformat 'YES'
backannotate_feedback 'NO'
END_DESIGNSYNC
START_BOMHDL
last_output_file '/projects/HEP_Instrumentation/cad/designs/uob_hep_pc049a/trunk/design_files/worklib/pc049a_4lemos/bom/pc049a_4lemos.csv'
last_template_file '/projects/HEP_Instrumentation/cad/tools/cadence_templates/spreadsheet-format.bom'
last_standard_option '1'
last_what_to_output '0'
last_variant_file ''
last_ss_delimiter 'Colon :'
use_filters '0'
last_callout_file ''
last_variant ''
END_BOMHDL
START_VXL
run_directory './worklib/pc049a_4lemos/cfg_verilog/sim1'
END_VXL
START_ECSET_MODELS
retain_existing_xnets_and_diffpairs 'NO'
END_ECSET_MODELS
START_VARIANT
last_variant_file 'variant.dat'
last_edit_type '2'
last_sorted_column 'REFDES'
pref_status_name 'Pref'
sort_style '0'
annotation_property_name 'VARIANT'
annotation_property_value '*'
annotation_DNIproperty_value 'DNI'
columns 'REFDES' 'CDS_VAR_STATUS' 'PART_NAME' 'PART_NUMBER'
END_VARIANT
START_ALLEGRO
hdl_padpath '.' 'symbols' '..' '../symbols' '$CADENCE_INST_DIR/share/pcb/pcb_lib/symbols' '$CADENCE_INST_DIR/share/pcb/allegrolib/symbols' '/projects/HEP_Instrumentation/cad/ral_cdslib/lib_psd15.x/pads' '/projects/HEP_Instrumentation/cad/bris_cdslib/lib_psd14.x/pads' '/projects/HEP_Instrumentation/cad/cern_cdslib/lib_psd16.x/allegro_libs/pe_allegro_lib/padstacks/padstack_smd' '/projects/HEP_Instrumentation/cad/cern_cdslib/lib_psd16.x/allegro_libs/pe_allegro_lib/padstacks/padstacks/padstack3'
hdl_psmpath '.' 'symbols' '..' '../symbols' '$CADENCE_INST_DIR/share/pcb/pcb_lib/symbols' '$CADENCE_INST_DIR/share/pcb/allegrolib/symbols' '/projects/HEP_Instrumentation/cad/ral_cdslib/lib_psd15.x/symbols' '/projects/HEP_Instrumentation/cad/bris_cdslib/lib_psd14.x/symbols' '/projects/HEP_Instrumentation/cad/cern_cdslib/lib_psd16.x/allegro_libs/pe_allegro_lib/symbols/connector' '/projects/HEP_Instrumentation/cad/cern_cdslib/lib_psd16.x/allegro_libs/pe_allegro_lib/symbols/discrete'
hdl_topology_template_path '.' 'templates' '..' '../templates' '$CADENCE_INST_DIR/share/pcb/pcb_lib/templates' '$CADENCE_INST_DIR/share/pcb/allegrolib/templates'
END_ALLEGRO
{ Machine generated file created by SPI }
{ Last modified was 15:05:37 Monday, March 17, 2014 }
{ NOTE: Do not modify the contents of this file. If this is regenerated by }
{ SPI, your modifications will be overwritten. }
START_GLOBAL
view_pcb './worklib/pc049a_lemo_daughter_board/physical'
design_name 'pc049a_lemo_daughter_board'
design_library 'uob_hep_pc049a_lib'
library 'uob_hep_pc049a_lib' 'bris_cds_analogue' 'bris_cds_connectors' 'bris_cds_discrete' 'bris_cds_logic' 'bris_cds_memory' 'bris_cds_pld' 'bris_cds_special' 'bris_cds_standard' 'bris_cds_switches' 'cn74lv' 'cn74tiac' 'cn75als' 'cncmos' 'cnconnector' 'cndiscrete' 'cnpassive' 'cnpld' 'cnpower' 'cnspecial' 'cnstandard' 'cnvlsi' 'standard' 'cnlinear'
temp_dir 'temp'
cpm_version '16.5'
session_name 'ProjectMgr58303345'
ppt '$BRIS_CDSLIB/cds_analogue/cds_analogue.ptf' '$BRIS_CDSLIB/cds_connectors/cds_connectors.ptf' '$BRIS_CDSLIB/cds_logic/cds_logic.ptf' '$BRIS_CDSLIB/cds_pld/cds_pld.ptf' '$BRIS_CDSLIB/cds_special/cds_special.ptf' '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cnconnector.ptf' '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cndiscrete.ptf' '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cnpassive.ptf'
EXCLUDE_PPT
INCLUDE_PPT
cdsprop_file ''
log_file ''
physical_path './worklib/pc049a_lemo_daughter_board/physical'
expand_with_errors 'OFF'
END_GLOBAL
START_CONCEPTHDL
LOGIC_GRID_SIZE '0.050'
DOC_GRID_SIZE '0.050'
CHECK_VOLTAGE_ON_HDL 'OFF'
PLOT_FIT_TO_PAGE 'ON'
PLOT_FONT 'Arial'
HPF_PLOTTER 'postscriptbw'
HPF_FONT 'native'
HPF_SPEC_PLOT_PAGESIZE 'YES'
HPF_BATCH 'YES'
HPF_PLOT_FILE_LOCATION '/home/phdgc'
HPF_PLOT_FILE_NAME 'pc049a_lemo_daughter_board1.ps'
PLOTTER_FACILITY 'HPF'
PLOT_EDGE_TO_EDGE 'ON'
PAPER_SIZE '9'
PAPER_ORIENTATION '1'
PAPER_SOURCE '15'
WPLOTTER_NAME ''
HPF_PLOT_PAGESIZE 'A4'
HPF_PAGESCALETYPE 'PAGESIZE'
HPF_PAGESIZE 'A4'
HPF_SCALEFACTOR '0.000000'
END_CONCEPTHDL
START_PKGRXL
comp_def_prop 'ALT_SYMBOLS' 'JEDEC_TYPE' 'MERGE_NC_PINS' 'MERGE_POWER_PINS' 'NC_PINS' 'PINCOUNT' 'POWER_GROUP' 'POWER_PINS'
comp_inst_prop 'DEFAULT_SIGNAL_MODEL' 'GROUP' 'REUSE_ID' 'REUSE_INSTANCE' 'REUSE_NAME' 'ROOM' 'SIGNAL_MODEL' 'VOLT_TEMP_SIGNAL_MODEL'
repackage 'ON'
regenerate_physical_net_name 'OFF'
electrical_constraints 'OFF'
overwrite_constraints 'OFF'
USE_SUBDESIGN 'pc049a_4lemos'
FORCE_SUBDESIGN
GEN_SUBDESIGN
FILTER_PROPERTY
PASS_PROPERTY
FILTER_CONFLICTING_PROP
END_PKGRXL
START_DESIGNSYNC
replace_symbol '2'
etch_removal 'NO'
ignore_fixed 'NO'
create_user_prop 'NO'
run_packager 'YES'
run_netrev 'YES'
backannotate_forward 'NO'
last_board_file 'pc049a_lemo_daughter_board_27.brd'
run_feedback 'YES'
run_genfeedformat 'YES'
backannotate_feedback 'NO'
END_DESIGNSYNC
START_BOMHDL
last_output_file '/projects/HEP_Instrumentation/cad/designs/uob_hep_pc049a/trunk/design_files/worklib/pc049a_lemo_daughter_board/bom/pc049a_lemo_daughter_board.csv'
last_template_file '/projects/HEP_Instrumentation/cad/tools/cadence_templates/spreadsheet-format.bom'
last_standard_option '1'
last_what_to_output '0'
last_variant_file ''
last_ss_delimiter 'Colon :'
use_filters '0'
last_callout_file ''
last_variant ''
END_BOMHDL
START_VXL
run_directory './worklib/pc049a_lemo_daughter_board/cfg_verilog/sim1'
END_VXL
START_ECSET_MODELS
retain_existing_xnets_and_diffpairs 'NO'
END_ECSET_MODELS
START_VARIANT
last_variant_file 'variant.dat'
last_edit_type '2'
last_sorted_column 'REFDES'
pref_status_name 'Pref'
sort_style '0'
annotation_property_name 'VARIANT'
annotation_property_value '*'
annotation_DNIproperty_value 'DNI'
columns 'REFDES' 'CDS_VAR_STATUS' 'PART_NAME' 'PART_NUMBER'
END_VARIANT
START_ALLEGRO
hdl_padpath '.' 'symbols' '..' '../symbols' '$CADENCE_INST_DIR/share/pcb/pcb_lib/symbols' '$CADENCE_INST_DIR/share/pcb/allegrolib/symbols' '/projects/HEP_Instrumentation/cad/ral_cdslib/lib_psd15.x/pads' '/projects/HEP_Instrumentation/cad/bris_cdslib/lib_psd14.x/pads' '/projects/HEP_Instrumentation/cad/cern_cdslib/lib_psd16.x/allegro_libs/pe_allegro_lib/padstacks/padstack_smd' '/projects/HEP_Instrumentation/cad/cern_cdslib/lib_psd16.x/allegro_libs/pe_allegro_lib/padstacks/padstacks/padstack3'
hdl_psmpath '.' 'symbols' '..' '../symbols' '$CADENCE_INST_DIR/share/pcb/pcb_lib/symbols' '$CADENCE_INST_DIR/share/pcb/allegrolib/symbols' '/projects/HEP_Instrumentation/cad/ral_cdslib/lib_psd15.x/symbols' '/projects/HEP_Instrumentation/cad/bris_cdslib/lib_psd14.x/symbols' '/projects/HEP_Instrumentation/cad/cern_cdslib/lib_psd16.x/allegro_libs/pe_allegro_lib/symbols/connector' '/projects/HEP_Instrumentation/cad/cern_cdslib/lib_psd16.x/allegro_libs/pe_allegro_lib/symbols/discrete'
hdl_topology_template_path '.' 'templates' '..' '../templates' '$CADENCE_INST_DIR/share/pcb/pcb_lib/templates' '$CADENCE_INST_DIR/share/pcb/allegrolib/templates'
END_ALLEGRO
{ Machine generated file created by SPI }
{ Last modified was 12:25:02 Thursday, May 08, 2014 }
{ NOTE: Do not modify the contents of this file. If this is regenerated by }
{ SPI, your modifications will be overwritten. }
START_GLOBAL
design_name 'pc049a_db'
design_library 'uob_hep_pc049a_lib'
library 'uob_hep_pc049a_lib' 'cnpassive' 'cndiscrete' 'cnconnector' 'bris_cds_standard' 'cnpower' 'cnstandard' 'standard'
temp_dir 'temp'
cpm_version '16.5'
session_name 'ProjectMgr27973'
ppt '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cnconnector.ptf' '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cnpassive.ptf' '$CERN_CDSLIB/lib_psd16.x/concept_libs/pe16/pe_cern_lib/parttables/cndiscrete.ptf'
physical_path './worklib/pc049a_db/physical'
cdsprop_file ''
END_GLOBAL
START_PKGRXL
regenerate_physical_net_name 'OFF'
electrical_constraints 'ON'
overwrite_constraints 'OFF'
force_subdesign 'pc049a_4lemos'
END_PKGRXL
START_DESIGNSYNC
replace_symbol '1'
etch_removal 'NO'
ignore_fixed 'NO'
create_user_prop 'NO'
run_packager 'YES'
run_netrev 'YES'
backannotate_forward 'NO'
last_board_file 'pc049a_lemo_db_08.brd'
END_DESIGNSYNC
START_CONSTRAINT_MGR
EDIT_PHYSICAL_SPACING_CONSTRAINTS 'ON'
END_CONSTRAINT_MGR
{ Machine generated file created by SPI }
{ Last modified was 09:32:14 Friday, January 17, 2014 }
{ NOTE: Do not modify the contents of this file. If this is regenerated by }
{ SPI, your modifications will be overwritten. }
START_GLOBAL
design_name 'pc049a_test'
design_library 'uob_hep_pc049a_lib'
library 'bris_cds_analogue' 'bris_cds_connectors' 'bris_cds_discrete' 'bris_cds_logic' 'bris_cds_memory' 'bris_cds_pld' 'bris_cds_special' 'bris_cds_standard' 'bris_cds_switches' 'cn100e' 'cn10e' 'cn10el' 'cn10k' 'cn10kh' 'cn74lv' 'cn74tiac' 'cn75als' 'cncmos' 'cnconnector' 'cndiscrete' 'cnfast' 'cngaas' 'cninterface' 'cnlinear' 'cnmech' 'cnmemory' 'cnmicro' 'cnpassive' 'cnpld' 'cnpower' 'cnspecial' 'cnstandard' 'cnvlsi' 'standard' 'uob_hep_pc049a_lib'
temp_dir 'temp'
cpm_version '16.5'
session_name 'ProjectMgr4478'
END_GLOBAL
START_CONSTRAINT_MGR
EDIT_PHYSICAL_SPACING_CONSTRAINTS 'ON'
END_CONSTRAINT_MGR
--
-- Dummy block for data I/O
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
-- Packages for IPBus
LIBRARY work;
USE work.ipbus.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity ExpansionIO is
generic (
g_NEXPANSION_BITS : positive := 16);
port (
-- IPBus
ipbus_clk_i: in STD_LOGIC;
ipbus_reset_i: in STD_LOGIC;
ipbus_wbus_i: in ipb_wbus;
ipbus_rbus_o: out ipb_rbus;
-- Data....
lvds_left_data_p_b, lvds_left_data_n_b : out std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
lvds_left_clk_p_b, lvds_left_clk_n_b : in std_logic; -- clock for data on left hand I/O
lvds_right_data_p_b, lvds_right_data_n_b : out std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
lvds_right_clk_p_b, lvds_right_clk_n_b : in std_logic -- clock for data on left hand I/O
);
end entity ExpansionIO;
architecture rtl of ExpansionIO is
signal s_spydata, s_ctrl_reg: std_logic_vector(31 downto 0);
signal s_data_direction : std_logic := '0'; -- 1 = left to right ( left rx,
-- right tx ),
-- 0 = right to left ( right rx
-- left tx )
signal s_left_counter , s_right_counter : unsigned( g_NEXPANSION_BITS-1 downto 0) := ( others => '0');
signal s_data_right_from_connector ,
s_data_right_to_connector ,
s_data_left_from_connector ,
s_data_left_to_connector ,
s_data_r1 , s_data_r2 , s_data_r3: std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
signal s_right_clk_from_connector,
s_right_clk_to_connector,
s_left_clk_from_connector,
s_left_clk_to_connector , s_data_clk : std_logic;
begin -- architecture rtl
controlReg: entity work.ipbus_ctrlreg
port map(
clk => ipbus_clk_i,
reset => ipbus_reset_i,
ipbus_in => ipbus_wbus_i,
ipbus_out => ipbus_rbus_o,
d => s_spydata,
q => s_ctrl_reg
);
s_data_direction <= s_ctrl_reg(0);
--
gen_iobuf: for dataBit in 0 to g_NEXPANSION_BITS-1 generate
cmp_IOBUFDS_left : OBUFDS
generic map (
IOSTANDARD => "DEFAULT"
)
port map (
O => lvds_left_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
OB => lvds_left_data_n_b(dataBit), -- Diff_n inout (connect directly to top-level port)
I => s_data_left_to_connector(dataBit) -- Buffer input
);
cmp_IOBUFDS_right : OBUFDS
generic map (
IOSTANDARD => "DEFAULT"
)
port map (
O => lvds_right_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
OB => lvds_right_data_n_b(dataBit), -- Diff_n inout (connect directly to top-level port)
I => s_data_right_to_connector(dataBit) -- Buffer input
);
end generate gen_iobuf;
cmp_IOBUFDS_left_clk : IBUFGDS
generic map (
IOSTANDARD => "DEFAULT",
DIFF_TERM => TRUE
)
port map (
O => s_left_clk_from_connector, -- Buffer output
I => lvds_left_clk_p_b, -- Diff_p inout (connect directly to top-level port)
IB => lvds_left_clk_n_b -- Diff_n inout (connect directly to top-level port)
);
cmp_IOBUFDS_right_clk : IBUFGDS
generic map (
IOSTANDARD => "DEFAULT",
DIFF_TERM => TRUE
)
port map (
O => s_right_clk_from_connector, -- Buffer output
I => lvds_right_clk_p_b, -- Diff_p inout (connect directly to top-level port)
IB => lvds_right_clk_n_b -- Diff_n inout (connect directly to top-level port)
);
-- purpose: output counter
-- type : combinational
-- inputs : s_left_clk_from_connector
-- outputs:
p_register_left_data: process (s_left_clk_from_connector) is
begin -- process p_register_data
if rising_edge(s_left_clk_from_connector) then
s_left_counter <= s_left_counter + 1;
s_data_left_to_connector <= std_logic_vector(s_left_counter);
end if;
end process p_register_left_data;
-- purpose: output counter
-- type : combinational
-- inputs : s_left_clk_from_connector
-- outputs:
p_register_right_data: process (s_right_clk_from_connector) is
begin -- process p_register_data
if rising_edge(s_right_clk_from_connector) then
s_right_counter <= s_right_counter + 1;
s_data_right_to_connector <= std_logic_vector(s_right_counter);
end if;
end process p_register_right_data;
end architecture rtl;
--
-- Dummy block for data I/O
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
-- Packages for IPBus
LIBRARY work;
USE work.ipbus.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity ExpansionIO is
generic (
g_NEXPANSION_BITS : positive := 16);
port (
-- IPBus
ipbus_clk_i: in STD_LOGIC;
ipbus_reset_i: in STD_LOGIC;
ipbus_wbus_i: in ipb_wbus;
ipbus_rbus_o: out ipb_rbus;
-- Data....
lvds_left_data_p_b, lvds_left_data_n_b : out std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
lvds_left_clk_p_b, lvds_left_clk_n_b : in std_logic; -- clock for data on left hand I/O
lvds_right_data_p_b, lvds_right_data_n_b : out std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
lvds_right_clk_p_b, lvds_right_clk_n_b : in std_logic -- clock for data on left hand I/O
);
end entity ExpansionIO;
architecture rtl of ExpansionIO is
signal s_spydata, s_ctrl_reg: std_logic_vector(31 downto 0);
signal s_data_direction : std_logic := '0'; -- 1 = left to right ( left rx,
-- right tx ),
-- 0 = right to left ( right rx
-- left tx )
signal s_data_right_from_connector ,
s_data_right_to_connector ,
s_data_left_from_connector ,
s_data_left_to_connector ,
s_data_r1 , s_data_r2 , s_data_r3: std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
signal s_right_clk_from_connector,
s_right_clk_to_connector,
s_left_clk_from_connector,
s_left_clk_to_connector , s_data_clk : std_logic;
begin -- architecture rtl
controlReg: entity work.ipbus_ctrlreg
port map(
clk => ipbus_clk_i,
reset => ipbus_reset_i,
ipbus_in => ipbus_wbus_i,
ipbus_out => ipbus_rbus_o,
d => s_spydata,
q => s_ctrl_reg
);
s_data_direction <= s_ctrl_reg(0);
--
gen_iobuf: for dataBit in 0 to g_NEXPANSION_BITS-1 generate
-- -- Take T low and output is enabled, ie. is output
--cmp_IOBUFDS_left : IOBUFDS
-- generic map (
-- IOSTANDARD => "BLVDS_25",
-- DIFF_TERM => TRUE
-- )
-- port map (
-- O => s_data_left_from_connector(dataBit), -- Buffer output
-- IO => lvds_left_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
-- IOB => lvds_left_data_n_b(dataBit), -- Diff_n inout (connect directly to top-level port)
-- I => s_data_left_to_connector(dataBit), -- Buffer input
-- T => s_data_direction -- 3-state enable input. Take high to be a
-- -- receiver only.
-- );
--cmp_IOBUFDS_right : IOBUFDS
-- generic map (
-- IOSTANDARD => "BLVDS_25",
-- DIFF_TERM => TRUE
-- )
-- port map (
-- O => s_data_right_from_connector(dataBit), -- Buffer output
-- IO => lvds_right_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
-- IOB => lvds_right_data_n_b(dataBit), -- Diff_n inout (connect directly to top-level port)
-- I => s_data_right_to_connector(dataBit), -- Buffer input
-- T => not s_data_direction -- 3-state enable input. Take high to be a
-- -- receiver only.
-- );
cmp_IOBUFDS_left : IBUFDS
generic map (
IOSTANDARD => "DEFAULT",
DIFF_TERM => TRUE
)
port map (
O => s_data_left_from_connector(dataBit), -- Buffer output
I => lvds_left_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
IB => lvds_left_data_n_b(dataBit) -- Diff_n inout (connect directly to top-level port)
);
cmp_IOBUFDS_right : OBUFDS
generic map (
IOSTANDARD => "DEFAULT"
)
port map (
O => lvds_right_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
OB => lvds_right_data_n_b(dataBit), -- Diff_n inout (connect directly to top-level port)
I => s_data_right_to_connector(dataBit) -- Buffer input
);
end generate gen_iobuf;
--cmp_IOBUFDS_left_clk : IOBUFDS
-- generic map (
-- IOSTANDARD => "BLVDS_25",
-- DIFF_TERM => TRUE
-- )
-- port map (
-- O => s_left_clk_from_connector, -- Buffer output
-- IO => lvds_left_clk_p_b, -- Diff_p inout (connect directly to top-level port)
-- IOB => lvds_left_clk_n_b, -- Diff_n inout (connect directly to top-level port)
-- I => s_left_clk_to_connector, -- Buffer input
-- T => s_data_direction -- 3-state enable input. Take high to be a
-- -- receiver only.
-- );
-- cmp_IOBUFDS_right_clk : IOBUFDS
-- generic map (
-- IOSTANDARD => "BLVDS_25",
-- DIFF_TERM => TRUE
-- )
-- port map (
-- O => s_right_clk_from_connector, -- Buffer output
-- IO => lvds_right_clk_p_b, -- Diff_p inout (connect directly to top-level port)
-- IOB => lvds_right_clk_n_b, -- Diff_n inout (connect directly to top-level port)
-- I => s_right_clk_to_connector, -- Buffer input
-- T => not s_data_direction -- 3-state enable input. Take high to be a
-- -- receiver only.
-- );
cmp_IOBUFDS_left_clk : IBUFDS
generic map (
IOSTANDARD => "DEFAULT",
DIFF_TERM => TRUE
)
port map (
O => s_left_clk_from_connector, -- Buffer output
I => lvds_left_clk_p_b, -- Diff_p inout (connect directly to top-level port)
IB => lvds_left_clk_n_b -- Diff_n inout (connect directly to top-level port)
);
cmp_IOBUFDS_right_clk : OBUFDS
generic map (
IOSTANDARD => "DEFAULT"
)
port map (
O => lvds_right_clk_p_b, -- Diff_p inout (connect directly to top-level port)
OB => lvds_right_clk_n_b, -- Diff_n inout (connect directly to top-level port)
I => s_right_clk_to_connector -- Buffer input
);
-- multiplex the clocks....
-- 0 = take data from right I/O ( right = rx )
--BUFGMUX_inst: BUFGMUX
--generic map
--(
-- CLK_SEL_TYPE => "SYNC" Glitchles ("SYNC") or fast ("ASYNC") clock switch-over
-- )
--port map
--(O => s_data_clk,
-- I0 => s_right_clk_from_connector, (S=0)
-- I1 => s_left_clk_from_connector, (S=1)
-- S => s_data_direction Clock buffer select
-- );
s_data_clk <= s_left_clk_from_connector;
-- purpose: register data and transfer from left <--> right connector
-- type : combinational
-- inputs : s_data_clk
-- outputs:
p_register_data: process (s_data_clk) is
begin -- process p_register_data
if rising_edge(s_data_clk) then
case s_data_direction is
-- 0 => right is rx, left is tx
when '0' =>
s_data_r1 <= s_data_right_from_connector;
s_data_left_to_connector <= s_data_r3;
-- 1 => left is rx , right is tx
when '1' =>
s_data_r1 <= s_data_left_from_connector;
s_data_right_to_connector <= s_data_r3;
when others => null;
end case;
s_data_r2 <= s_data_r1;
s_data_r3 <= s_data_r2;
end if;
end process p_register_data;
end architecture rtl;
--
-- Dummy block for data I/O
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- Packages for IPBus
LIBRARY work;
USE work.ipbus.all;
library UNISIM;
use UNISIM.vcomponents.all;
entity ExpansionIO is
generic (
g_NEXPANSION_BITS : positive := 16);
port (
-- IPBus
ipbus_clk_i: in STD_LOGIC;
ipbus_reset_i: in STD_LOGIC;
ipbus_wbus_i: in ipb_wbus;
ipbus_rbus_o: out ipb_rbus;
-- Data....
lvds_left_data_p_b, lvds_left_data_n_b : in std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
lvds_left_clk_p_b, lvds_left_clk_n_b : in std_logic; -- clock for data on left hand I/O
lvds_right_data_p_b, lvds_right_data_n_b : out std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
lvds_right_clk_p_b, lvds_right_clk_n_b : out std_logic -- clock for data on left hand I/O
);
end entity ExpansionIO;
architecture rtl of ExpansionIO is
signal s_spydata, s_ctrl_reg: std_logic_vector(31 downto 0);
signal s_data_direction : std_logic := '0'; -- 1 = left to right ( left rx,
-- right tx ),
-- 0 = right to left ( right rx
-- left tx )
signal s_data_right_from_connector ,
s_data_right_to_connector ,
s_data_left_from_connector ,
s_data_left_to_connector ,
s_data_r1 , s_data_r2 , s_data_r3: std_logic_vector(g_NEXPANSION_BITS-1 downto 0);
signal s_right_clk_from_connector,
s_right_clk_to_connector,
s_left_clk_from_connector,
s_left_clk_to_connector , s_data_clk : std_logic;
begin -- architecture rtl
controlReg: entity work.ipbus_ctrlreg
port map(
clk => ipbus_clk_i,
reset => ipbus_reset_i,
ipbus_in => ipbus_wbus_i,
ipbus_out => ipbus_rbus_o,
d => s_spydata,
q => s_ctrl_reg
);
s_data_direction <= s_ctrl_reg(0);
--
gen_iobuf: for dataBit in 0 to g_NEXPANSION_BITS-1 generate
-- -- Take T low and output is enabled, ie. is output
--cmp_IOBUFDS_left : IOBUFDS
-- generic map (
-- IOSTANDARD => "BLVDS_25",
-- DIFF_TERM => TRUE
-- )
-- port map (
-- O => s_data_left_from_connector(dataBit), -- Buffer output
-- IO => lvds_left_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
-- IOB => lvds_left_data_n_b(dataBit), -- Diff_n inout (connect directly to top-level port)
-- I => s_data_left_to_connector(dataBit), -- Buffer input
-- T => s_data_direction -- 3-state enable input. Take high to be a
-- -- receiver only.
-- );
--cmp_IOBUFDS_right : IOBUFDS
-- generic map (
-- IOSTANDARD => "BLVDS_25",
-- DIFF_TERM => TRUE
-- )
-- port map (
-- O => s_data_right_from_connector(dataBit), -- Buffer output
-- IO => lvds_right_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
-- IOB => lvds_right_data_n_b(dataBit), -- Diff_n inout (connect directly to top-level port)
-- I => s_data_right_to_connector(dataBit), -- Buffer input
-- T => not s_data_direction -- 3-state enable input. Take high to be a
-- -- receiver only.
-- );
cmp_IOBUFDS_left : IBUFDS
generic map (
IOSTANDARD => "DEFAULT",
DIFF_TERM => TRUE
)
port map (
O => s_data_left_from_connector(dataBit), -- Buffer output
I => lvds_left_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
IB => lvds_left_data_n_b(dataBit) -- Diff_n inout (connect directly to top-level port)
);
cmp_IOBUFDS_right : OBUFDS
generic map (
IOSTANDARD => "DEFAULT"
)
port map (
O => lvds_right_data_p_b(dataBit), -- Diff_p inout (connect directly to top-level port)
OB => lvds_right_data_n_b(dataBit), -- Diff_n inout (connect directly to top-level port)
I => s_data_right_to_connector(dataBit) -- Buffer input
);
end generate gen_iobuf;
--cmp_IOBUFDS_left_clk : IOBUFDS
-- generic map (
-- IOSTANDARD => "BLVDS_25",
-- DIFF_TERM => TRUE
-- )
-- port map (
-- O => s_left_clk_from_connector, -- Buffer output
-- IO => lvds_left_clk_p_b, -- Diff_p inout (connect directly to top-level port)
-- IOB => lvds_left_clk_n_b, -- Diff_n inout (connect directly to top-level port)
-- I => s_left_clk_to_connector, -- Buffer input
-- T => s_data_direction -- 3-state enable input. Take high to be a
-- -- receiver only.
-- );
-- cmp_IOBUFDS_right_clk : IOBUFDS
-- generic map (
-- IOSTANDARD => "BLVDS_25",
-- DIFF_TERM => TRUE
-- )
-- port map (
-- O => s_right_clk_from_connector, -- Buffer output
-- IO => lvds_right_clk_p_b, -- Diff_p inout (connect directly to top-level port)
-- IOB => lvds_right_clk_n_b, -- Diff_n inout (connect directly to top-level port)
-- I => s_right_clk_to_connector, -- Buffer input
-- T => not s_data_direction -- 3-state enable input. Take high to be a
-- -- receiver only.
-- );
cmp_IOBUFDS_left_clk : IBUFDS
generic map (
IOSTANDARD => "DEFAULT",
DIFF_TERM => TRUE
)
port map (
O => s_left_clk_from_connector, -- Buffer output
I => lvds_left_clk_p_b, -- Diff_p inout (connect directly to top-level port)
IB => lvds_left_clk_n_b -- Diff_n inout (connect directly to top-level port)
);
cmp_IOBUFDS_right_clk : OBUFDS
generic map (
IOSTANDARD => "DEFAULT"
)
port map (
O => lvds_right_clk_p_b, -- Diff_p inout (connect directly to top-level port)
OB => lvds_right_clk_n_b, -- Diff_n inout (connect directly to top-level port)
I => s_right_clk_to_connector -- Buffer input
);
-- multiplex the clocks....
-- 0 = take data from right I/O ( right = rx )
--BUFGMUX_inst: BUFGMUX
--generic map
--(
-- CLK_SEL_TYPE => "SYNC" Glitchles ("SYNC") or fast ("ASYNC") clock switch-over
-- )
--port map
--(O => s_data_clk,
-- I0 => s_right_clk_from_connector, (S=0)
-- I1 => s_left_clk_from_connector, (S=1)
-- S => s_data_direction Clock buffer select
-- );
s_data_clk <= s_left_clk_from_connector;
-- purpose: register data and transfer from left <--> right connector
-- type : combinational
-- inputs : s_data_clk
-- outputs:
p_register_data: process (s_data_clk) is
begin -- process p_register_data
if rising_edge(s_data_clk) then
case s_data_direction is
-- 0 => right is rx, left is tx
when '0' =>
s_data_r1 <= s_data_right_from_connector;
s_data_left_to_connector <= s_data_r3;
-- 1 => left is rx , right is tx
when '1' =>
s_data_r1 <= s_data_left_from_connector;
s_data_right_to_connector <= s_data_r3;
when others => null;
end case;
s_data_r2 <= s_data_r1;
s_data_r3 <= s_data_r2;
end if;
end process p_register_data;
end architecture rtl;
--=============================================================================
--! @file IPBusInterfaceGTP_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture fmc_mTLU_lib.IPBusInterfaceGTP.rtl
--
--! @brief \n
--! \n
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 16:06:57 11/09/12
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
-- Created using using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE work.ipbus.all;
use work.emac_hostbus_decl.all;
ENTITY IPBusInterfaceGTP IS
GENERIC(
NUM_EXT_SLAVES : positive := 5
);
PORT(
-- Connections to GTP Spartan6
-- Gigabit transceiver
gtp_clkp, gtp_clkn: in std_logic;
gtp_txp, gtp_txn: out std_logic;
gtp_rxp, gtp_rxn: in std_logic;
sfp_los: in std_logic;
sfp_scl_o : out std_logic;
sfp_scl_i : in std_logic := '1';
sfp_sda_o : out std_logic;
sfp_sda_i : in std_logic := '1';
sfp_det_i : in std_logic;
-- Gigabit connections for SATA connector
gtp_aux_txp, gtp_aux_txn: out std_logic;
gtp_aux_rxp, gtp_aux_rxn: in std_logic;
ipbr_i : IN ipb_rbus_array (NUM_EXT_SLAVES-1 DOWNTO 0); -- ! IPBus read signals
sysclk_i : IN std_logic; -- ! 125 MHz xtal clock
clocks_locked_o : OUT std_logic;
ipb_clk_o : OUT std_logic; -- ! IPBus clock to slaves
ipb_rst_o : OUT std_logic; -- ! IPBus reset to slaves
ipbw_o : OUT ipb_wbus_array (NUM_EXT_SLAVES-1 DOWNTO 0); -- ! IBus write signals
onehz_o : OUT std_logic;
phy_rstb_o : OUT std_logic;
dip_switch_i : IN std_logic_vector (3 DOWNTO 0);
clk_logic_xtal_o : OUT std_logic
);
-- Declarations
END ENTITY IPBusInterfaceGTP ;
--
ARCHITECTURE rtl OF IPBusInterfaceGTP IS
--! Number of slaves inside the IPBusInterfaceGTP block.
constant c_NUM_INTERNAL_SLAVES : positive := 1;
signal clk125, locked, rst_125, rst_ipb: STD_LOGIC;
signal mac_txd, mac_rxd : STD_LOGIC_VECTOR(7 downto 0);
signal mac_txdvld, mac_txack, mac_rxclko, mac_rxdvld, mac_rxgoodframe, mac_rxbadframe : STD_LOGIC;
signal ipb_master_out : ipb_wbus;
signal ipb_master_in : ipb_rbus;
signal mac_addr: std_logic_vector(47 downto 0);
signal mac_tx_data, mac_rx_data: std_logic_vector(7 downto 0);
signal mac_tx_valid, mac_tx_last, mac_tx_error, mac_tx_ready, mac_rx_valid, mac_rx_last, mac_rx_error: std_logic;
signal ip_addr: std_logic_vector(31 downto 0);
signal s_ipb_clk : std_logic;
signal s_ipbw_internal: ipb_wbus_array (NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1 DOWNTO 0);
signal s_ipbr_internal: ipb_rbus_array (NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1 DOWNTO 0);
signal s_sysclk : std_logic;
signal pkt_rx, pkt_tx, pkt_rx_led, pkt_tx_led, sys_rst: std_logic;
BEGIN
-- FIXME - connect SFP control signals
sfp_scl_o <= '0';
sfp_sda_o <= sfp_det_i;
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clocks_s6_basex port map(
sysclk_i => sysclk_i,
clki_125 => clk125,
clko_ipb => s_ipb_clk,
sysclko => s_sysclk,
locked => locked,
nuke => sys_rst,
rsto_125 => rst_125,
rsto_ipb => rst_ipb,
onehz => onehz_o
);
-- Connect IPBus clock and reset to output ports.
ipb_clk_o <= s_ipb_clk;
ipb_rst_o <= rst_ipb;
-- leds <= ('0', '0', locked, onehz);
-- Ethernet MAC core and PHY interface
-- In this version, consists of hard MAC core + GTP transceiver
-- Can be replaced by any other MAC / PHY combination
eth: entity work.eth_s6_1000basex port map(
gtp_clkp => gtp_clkp,
gtp_clkn => gtp_clkn,
gtp_txp => gtp_txp,
gtp_txn => gtp_txn,
gtp_rxp => gtp_rxp,
gtp_rxn => gtp_rxn,
gtp_aux_txp => gtp_aux_txp,
gtp_aux_txn => gtp_aux_txn,
gtp_aux_rxp => gtp_aux_rxp,
gtp_aux_rxn => gtp_aux_rxn,
clk125_out => clk125,
locked => locked,
rst => rst_125,
tx_data => mac_tx_data,
tx_valid => mac_tx_valid,
tx_last => mac_tx_last,
tx_error => mac_tx_error,
tx_ready => mac_tx_ready,
rx_data => mac_rx_data,
rx_valid => mac_rx_valid,
rx_last => mac_rx_last,
rx_error => mac_rx_error
);
phy_rstb_o <= '1';
-- ipbus control logic
ipbus: entity work.ipbus_ctrl
generic map (
BUFWIDTH => 2)
port map(
mac_clk => clk125,
rst_macclk => rst_125,
ipb_clk => s_ipb_clk,
rst_ipb => rst_ipb,
mac_rx_data => mac_rx_data,
mac_rx_valid => mac_rx_valid,
mac_rx_last => mac_rx_last,
mac_rx_error => mac_rx_error,
mac_tx_data => mac_tx_data,
mac_tx_valid => mac_tx_valid,
mac_tx_last => mac_tx_last,
mac_tx_error => mac_tx_error,
mac_tx_ready => mac_tx_ready,
ipb_out => ipb_master_out,
ipb_in => ipb_master_in,
mac_addr => mac_addr,
ip_addr => ip_addr,
pkt_rx => pkt_rx,
pkt_tx => pkt_tx,
pkt_rx_led => pkt_rx_led,
pkt_tx_led => pkt_tx_led
);
mac_addr <= X"020ddba115" & dip_switch_i & X"0"; -- Careful here, arbitrary addresses do not always work
ip_addr <= X"c0a8c8" & dip_switch_i & X"0"; -- 192.168.200.X
fabric: entity work.ipbus_fabric
generic map(NSLV => NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES)
port map(
ipb_in => ipb_master_out,
ipb_out => ipb_master_in,
ipb_to_slaves => s_ipbw_internal,
ipb_from_slaves => s_ipbr_internal
);
ipbw_o <= s_ipbw_internal(NUM_EXT_SLAVES-1 downto 0);
s_ipbr_internal(NUM_EXT_SLAVES-1 downto 0) <= ipbr_i;
-- Slave: firmware ID
firmware_id: entity work.ipbus_ver
port map(
ipbus_in => s_ipbw_internal(NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1),
ipbus_out => s_ipbr_internal(NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1)
);
END ARCHITECTURE rtl;
--=============================================================================
--! @file IPBusInterfaceGTP_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture fmc_mTLU_lib.IPBusInterfaceGTP.rtl
--
--! @brief \n
--! \n
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 16:06:57 11/09/12
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
-- Created using using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE work.ipbus.all;
use work.emac_hostbus_decl.all;
ENTITY IPBusInterfaceGTP IS
GENERIC(
NUM_EXT_SLAVES : positive := 5
);
PORT(
-- Connections to GTP Spartan6
-- Gigabit transceiver
gtp_clkp, gtp_clkn: in std_logic;
gtp_txp, gtp_txn: out std_logic;
gtp_rxp, gtp_rxn: in std_logic;
sfp_los: in std_logic;
-- Gigabit connections for SATA connector
gtp_aux_txp, gtp_aux_txn: out std_logic;
gtp_aux_rxp, gtp_aux_rxn: in std_logic;
ipbr_i : IN ipb_rbus_array (NUM_EXT_SLAVES-1 DOWNTO 0); -- ! IPBus read signals
sysclk_i : IN std_logic; -- ! 125 MHz xtal clock
clocks_locked_o : OUT std_logic;
ipb_clk_o : OUT std_logic; -- ! IPBus clock to slaves
ipb_rst_o : OUT std_logic; -- ! IPBus reset to slaves
ipbw_o : OUT ipb_wbus_array (NUM_EXT_SLAVES-1 DOWNTO 0); -- ! IBus write signals
onehz_o : OUT std_logic;
phy_rstb_o : OUT std_logic;
dip_switch_i : IN std_logic_vector (3 DOWNTO 0);
clk_logic_xtal_o : OUT std_logic
);
-- Declarations
END ENTITY IPBusInterfaceGTP ;
--
ARCHITECTURE rtl OF IPBusInterfaceGTP IS
--! Number of slaves inside the IPBusInterfaceGTP block.
constant c_NUM_INTERNAL_SLAVES : positive := 1;
signal clk125, locked, rst_125, rst_ipb: STD_LOGIC;
signal mac_txd, mac_rxd : STD_LOGIC_VECTOR(7 downto 0);
signal mac_txdvld, mac_txack, mac_rxclko, mac_rxdvld, mac_rxgoodframe, mac_rxbadframe : STD_LOGIC;
signal ipb_master_out : ipb_wbus;
signal ipb_master_in : ipb_rbus;
signal mac_addr: std_logic_vector(47 downto 0);
signal mac_tx_data, mac_rx_data: std_logic_vector(7 downto 0);
signal mac_tx_valid, mac_tx_last, mac_tx_error, mac_tx_ready, mac_rx_valid, mac_rx_last, mac_rx_error: std_logic;
signal ip_addr: std_logic_vector(31 downto 0);
signal s_ipb_clk : std_logic;
signal s_ipbw_internal: ipb_wbus_array (NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1 DOWNTO 0);
signal s_ipbr_internal: ipb_rbus_array (NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1 DOWNTO 0);
signal s_sysclk : std_logic;
signal pkt_rx, pkt_tx, pkt_rx_led, pkt_tx_led, sys_rst: std_logic;
BEGIN
-- DCM clock generation for internal bus, ethernet
clocks: entity work.clocks_s6_basex port map(
sysclk_i => sysclk_i,
clki_125 => clk125,
clko_ipb => s_ipb_clk,
sysclko => s_sysclk,
locked => locked,
nuke => sys_rst,
rsto_125 => rst_125,
rsto_ipb => rst_ipb,
onehz => onehz_o
);
-- Connect IPBus clock and reset to output ports.
ipb_clk_o <= s_ipb_clk;
ipb_rst_o <= rst_ipb;
-- leds <= ('0', '0', locked, onehz);
-- Ethernet MAC core and PHY interface
-- In this version, consists of hard MAC core + GTP transceiver
-- Can be replaced by any other MAC / PHY combination
eth: entity work.eth_s6_1000basex port map(
gtp_clkp => gtp_clkp,
gtp_clkn => gtp_clkn,
gtp_txp => gtp_txp,
gtp_txn => gtp_txn,
gtp_rxp => gtp_rxp,
gtp_rxn => gtp_rxn,
gtp_aux_txp => gtp_aux_txp,
gtp_aux_txn => gtp_aux_txn,
gtp_aux_rxp => gtp_aux_rxp,
gtp_aux_rxn => gtp_aux_rxn,
clk125_out => clk125,
locked => locked,
rst => rst_125,
tx_data => mac_tx_data,
tx_valid => mac_tx_valid,
tx_last => mac_tx_last,
tx_error => mac_tx_error,
tx_ready => mac_tx_ready,
rx_data => mac_rx_data,
rx_valid => mac_rx_valid,
rx_last => mac_rx_last,
rx_error => mac_rx_error
);
phy_rstb_o <= '1';
-- ipbus control logic
ipbus: entity work.ipbus_ctrl
generic map (
BUFWIDTH => 2)
port map(
mac_clk => clk125,
rst_macclk => rst_125,
ipb_clk => s_ipb_clk,
rst_ipb => rst_ipb,
mac_rx_data => mac_rx_data,
mac_rx_valid => mac_rx_valid,
mac_rx_last => mac_rx_last,
mac_rx_error => mac_rx_error,
mac_tx_data => mac_tx_data,
mac_tx_valid => mac_tx_valid,
mac_tx_last => mac_tx_last,
mac_tx_error => mac_tx_error,
mac_tx_ready => mac_tx_ready,
ipb_out => ipb_master_out,
ipb_in => ipb_master_in,
mac_addr => mac_addr,
ip_addr => ip_addr,
pkt_rx => pkt_rx,
pkt_tx => pkt_tx,
pkt_rx_led => pkt_rx_led,
pkt_tx_led => pkt_tx_led
);
mac_addr <= X"020ddba115" & dip_switch_i & X"0"; -- Careful here, arbitrary addresses do not always work
ip_addr <= X"c0a8c8" & dip_switch_i & X"0"; -- 192.168.200.X
fabric: entity work.ipbus_fabric
generic map(NSLV => NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES)
port map(
ipb_in => ipb_master_out,
ipb_out => ipb_master_in,
ipb_to_slaves => s_ipbw_internal,
ipb_from_slaves => s_ipbr_internal
);
ipbw_o <= s_ipbw_internal(NUM_EXT_SLAVES-1 downto 0);
s_ipbr_internal(NUM_EXT_SLAVES-1 downto 0) <= ipbr_i;
-- Slave: firmware ID
firmware_id: entity work.ipbus_ver
port map(
ipbus_in => s_ipbw_internal(NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1),
ipbus_out => s_ipbr_internal(NUM_EXT_SLAVES+c_NUM_INTERNAL_SLAVES-1)
);
END ARCHITECTURE rtl;
This diff is collapsed.
--=============================================================================
--! @file ISERDES_cal_fsm_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture work.ISERDES_cal_fsm.rtl
--
--! @brief State machine to control reset and calibration of Input deserializers--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 15/May/2013
--
--! @version v0.1
--
--! @details
--! See Spartan-6 IOSERDES2 documentation from Xilinx
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo Implement a periodic calibration sequence\n
--! <another thing to do> \n
--
--------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
entity ISERDES_cal_fsm is
port (
clk_i : in std_logic; --! Rising edge active.
reset_i : in std_logic;
--! Take high for at least on clock cycle to force reset/calibration
busy_prompt_i : in std_logic;
busy_delayed_i : in std_logic;
reset_o : out std_logic; --! To ISERDES reset pin
cal_o : out std_logic --! To ISERDES calibration pin
);
end ISERDES_cal_fsm;
architecture rtl of ISERDES_cal_fsm is
signal s_reset_d1 ,s_reset_d2 : std_logic := '0';
-- ! Register reset signal onto IDELAY / ISERDES clock
-- signal s_rst_FSM : std_logic := '0'; -- IODELAY reset
-- signal s_Enable : std_logic := '0'; -- IODELAY Enable
--
-- --! Calibration FSM state values
-- type state_values is (st0, st1, st2, st3, st4);
-- signal pres_state, next_state: state_values := st0;
begin -- rtl
-- --! Calibration start condition
-- s_Enable <= '1'; --serdes_reset_i; -- and (not s_busy_idelay);
-- s_rst <= s_rst_FSM or serdes_reset_i;
--
-- --! Calibration FSM register
-- statereg: process(fabricClk_i, serdes_reset_i)
-- begin
-- if serdes_reset_i = '1' then
-- pres_state <= st0; -- Move to st0 - INITIAL STATE
--
-- elsif rising_edge(fabricClk_i) then
-- pres_state <= next_state; -- Move to next state
--
-- end if;
-- end process statereg;
--
--
-- --! Calibration FSM combinational block
-- fsm: process(pres_state, s_Enable, s_busy_idelay_m)
-- begin
-- next_state <= pres_state;
-- -- Default values
-- s_Rst_FSM <= '0';
-- s_cal_idelay <= '0';
--
-- case pres_state is
--
-- -- st0 - INITIAL STATE
-- when st0=>
-- if (s_Enable = '1') then
-- next_state <= st1; -- Next state is "st1 - CALIBRATION STATE step 1"
-- end if;
--
-- -- st1 - CALIBRATION STATE step 1
-- when st1=>
-- s_cal_idelay <= '1';
-- if s_busy_idelay_m = '1' then
-- next_state <= st2; -- Next state is "st2 - CALIBRATION STATE step 2"
-- end if;
--
-- -- st2 - CALIBRATION STATE step 2
-- when st2=>
-- if s_busy_idelay_m = '0' then
-- next_state <= st3; -- Next state is "st3 - RESET STATE"
-- end if;
--
-- -- st3 - RESET STATE
-- when st3=>
-- s_Rst_FSM <= '1';
-- next_state <= st4; -- Next state is "st4 - WAIT"
--
-- -- st4 - WAIT
-- when st4=>
-- next_state <= st4; -- Next state is "st4 - WAIT"
-- end case;
--
-- For now, just pass the reset signal straight to the output
p_register_reset: process (clk_i)
begin -- process p_register_reset
if rising_edge(clk_i) then -- rising clock edge
s_reset_d1 <= reset_i;
s_reset_d2 <= s_reset_d1;
reset_o <= s_reset_d2;
end if;
end process p_register_reset;
-- Tie calibration signal low.
cal_o <= '0';
end rtl;
files = [
"IPBusInterfaceGTP_rtl.vhd",
"marocInterface_rtl.vhd",
"ipbus_ver.vhd" ,
"ipbusMarocADC_rtl.vhd" ,
"arrivalTimeLUT_rtl.vhd" ,
# "clocks_s6_extclk.vhd" ,
"clocks_s6_basex.vhd" ,
"counterWithReset_rtl.vhd" ,
"fineTimeStamp_rtl.vhd" ,
"marocTriggerGenerator_rtl.vhd" ,
# "generate_test_signals.vhd" ,
"ipbus_addr_decode.vhd" ,
"ipbusMarocADC_rtl.vhd" ,
"ipbusMarocShiftReg_rtl.vhd" ,
"ipbusMarocTriggerGenerator_rtl.vhd" ,
"ipbus_pulseout_datain.vhd" ,
"ipbus_pulser.vhd" ,
"ipbus_reg.vhd" ,
"ipbus_ver.vhd" ,
"ISERDES_1to2_rtl.vhd" ,
"ISERDES_cal_fsm_rtl.vhd" ,
"marocADCFSM_rtl.vhd" ,
"marocADC_rtl.vhd" ,
"marocHoldFSM_rtl.vhd" ,
"maroc_pkg.vhd" ,
"marocShiftRegFSM_rtl.vhd" ,
"marocShiftReg_rtl.vhd" ,
"multiCounterWithReset_rtl.vhd" ,
"neighbourTriggerIO_rtl.vhd" ,
# "reset_pll.vhd" ,
"singleFineTimeStamp_rtl.vhd" ,
"stretchPulse_rtl.vhd" ,
"timeStampDPRAM_rtl.vhd",
# "dpram.vhdl" ,
"ipbusDPRAM.vhdl"
]
files = [
"IPBusInterfaceGTP_rtl.vhd",
"marocInterface_rtl.vhd",
"ipbus_ver.vhd" ,
"ipbusMarocADC_rtl.vhd" ,
"arrivalTimeLUT_rtl.vhd" ,
"clocks_s6_extclk.vhd" ,
"counterWithReset_rtl.vhd" ,
"fineTimeStamp_rtl.vhd" ,
"marocTriggerGenerator_rtl.vhd" ,
"generate_hdmi.vhd" ,
"generate_test_signals.vhd" ,
"ipbus_addr_decode.vhd" ,
"ipbusMarocADC_rtl.vhd" ,
"ipbusMarocShiftReg_rtl.vhd" ,
"ipbusMarocTriggerGenerator_rtl.vhd" ,
"ipbus_pulseout_datain.vhd" ,
"ipbus_pulser.vhd" ,
"ipbus_reg.vhd" ,
"ipbus_ver.vhd" ,
"ISERDES_1to2_rtl.vhd" ,
"ISERDES_cal_fsm_rtl.vhd" ,
"marocADCFSM_rtl.vhd" ,
"marocADC_rtl.vhd" ,
"marocHoldFSM_rtl.vhd" ,
"maroc_pkg.vhd" ,
"marocShiftRegFSM_rtl.vhd" ,
"marocShiftReg_rtl.vhd" ,
"multiCounterWithReset_rtl.vhd" ,
"neighbourTriggerIO_rtl.vhd" ,
"reset_pll.vhd" ,
"singleFineTimeStamp_rtl.vhd" ,
"stretchPulse_rtl.vhd" ,
"timeStampDPRAM_rtl.vhd",
"dpram.vhdl" ,
"ipbusDPRAM.vhdl"
]
--=============================================================================
--! @file arrivalTimeLUT_rtl.vhd
--=============================================================================
--
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- VHDL Architecture work.ArivalTimeLUT.rtl
--
--! @brief Uses a look-up-table to convert the eight bits from the two 1:4 deserializers\n
--! configured as two 1:2 deserializers into into a 2-bit time
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 12:46:34 11/21/12
--
--! @version v0.1
--
--! @details
--! Based on arrivalTimeLUT_rtl from AIDA TLU code.
--! Rising and falling edge times encoded as a LUT. Contents:
--! MRFrrff ( MSb ... LSB )
--! M = multiple edges present ( more then one rising or falling edge)
--! R = at least one rising edge present
--! F = at least one falling edge present.
--!
--! <b>Dependencies:</b>\n
--!
--! <b>References:</b>\n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo \n
--! <another thing to do> \n
--
--------------------------------------------------------------------------------
--
-- Created using using Mentor Graphics HDL Designer(TM) 2010.3 (Build 21)
--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY arrivalTimeLUT IS
GENERIC(
g_NUM_FINE_BITS : positive := 2
);
PORT(
clk_i : IN std_logic; --! Rising edge active. 8 x IPBus clk
deserialized_data_i : IN std_logic_vector (7 DOWNTO 0); -- Output from the two 4-bit deserializers, concatenated with most recent bit of previous clock cycle. Clocked by clk_i . bit-8 is the most recent data
first_rising_edge_time_o : OUT std_logic_vector (g_NUM_FINE_BITS-1 DOWNTO 0); -- Position of rising edge w.r.t. 40MHz strobe. Clocked by clk_4x_logic_i
last_falling_edge_time_o : OUT std_logic_vector (g_NUM_FINE_BITS-1 DOWNTO 0); -- Position of rising edge w.r.t. 40MHz strobe. Clocked by clk_4x_logic_i
rising_edge_o : OUT std_logic; -- goes high if there is a rising edge in the data. Clocked by clk_4x_logic_i
falling_edge_o : OUT std_logic; -- goes high if there is a falling edge in the data.Clocked by clk_4x_logic_i
multiple_edges_o : OUT std_logic -- there is more than one rising or falling edge transition.
);
-- Declarations
END ENTITY arrivalTimeLUT ;
--
ARCHITECTURE rtl OF arrivalTimeLUT IS
constant c_FALLING_EDGE_BIT : positive := 2*g_NUM_FINE_BITS; --! Bit position of bit set when falling edge detected
constant c_RISING_EDGE_BIT : positive := 2*g_NUM_FINE_BITS+1; --! Bit position of bit set when rising edge detected
constant c_MULTI_EDGE_BIT : positive := 2*g_NUM_FINE_BITS+2; --! Bit position of bit set when rising edge detected
signal s_LUT_entry : std_logic_vector(g_NUM_FINE_BITS*2 +3-1 downto 0); -- stores intermediate LUT value.
signal s_LUT_entry_pointer : integer; --! Entry in LUT pointed to by deserialized data
type t_LUT is array (natural range <>) of std_logic_vector(g_NUM_FINE_BITS*2 + 3 -1 downto 0);
--! Lookup table for arrival time and rising/falling edge detection (3bits
--! for position in 8-bit deserialized data plus two bits for rising/falling
-- For now just bodge it up .....
constant c_LUT : t_LUT(0 to 31) := (
"0000000" ,
"0010000" ,
"0110001" ,
"0010001" ,
"0110110" ,
"1110110" ,
"0110010" ,
"0011010" ,
"0101011" ,
"1111011" ,
"1110011" ,
"1111011" ,
"0110111" ,
"1110111" ,
"0110011" ,
"0010011" ,
"0101100" ,
"1111100" ,
"1110001" ,
"1111101" ,
"1110110" ,
"1110110" ,
"1110010" ,
"1111110" ,
"0101000" ,
"1111000" ,
"1110001" ,
"1111001" ,
"0100100" ,
"1110100" ,
"0100000" ,
"0000000"
--"0000000", -- 0
-- "0000000",
-- "0000000",
-- "0000000", -- 3
-- "0000000",
-- "0000000",
-- "0000000",
-- "0000000", -- 7
-- "0000000",
-- "0000000",
-- "0000000",
-- "0000000", -- 11
-- "0000000",
-- "0000000",
-- "0000000", -- 14
-- "0000000", -- 15
-- "0101100", -- 16
-- "0000000",
-- "0000000",
-- "0000000",
-- "0000000",
-- "0000000",
-- "0000000",
-- "0000000",
-- "0101000", -- 24
-- "0000000",
-- "0000000",
-- "0000000",
-- "0100100", -- 28
-- "0000000",
-- "0100000", -- 30
-- "0000000" -- 31
);
BEGIN
-- purpose: uses the deserialized data as a index into
-- a lookup table holding the position of the first rising edge (if any)
-- and if there is a rising or falling edge
-- type : combinational
-- inputs : clk_i
-- outputs: arrival_time_o , rising_edge_o , falling_edge_o
examine_lut: process (clk_i , deserialized_data_i)
variable v_LUT_entry_pointer : integer; --! Entry in LUT pointed to by deserialized data
begin -- process examine_lut
v_LUT_entry_pointer := to_integer(unsigned(deserialized_data_i(7 downto 3)));
s_LUT_entry_pointer <= to_integer(unsigned(deserialized_data_i(7 downto 3)));
if rising_edge(clk_i) then
-- s_LUT_entry <= c_LUT(to_integer(unsigned(deserialized_data_i(7 downto 3))));
s_LUT_entry <= c_LUT(v_LUT_entry_pointer);
first_rising_edge_time_o <= s_LUT_ENTRY(g_NUM_FINE_BITS*2-1 downto g_NUM_FINE_BITS);
last_falling_edge_time_o <= s_LUT_ENTRY(g_NUM_FINE_BITS-1 downto 0);
rising_edge_o <= s_LUT_ENTRY(c_RISING_EDGE_BIT);
falling_edge_o <= s_LUT_ENTRY(c_FALLING_EDGE_BIT);
multiple_edges_o <= s_LUT_ENTRY(c_MULTI_EDGE_BIT);
end if;
end process examine_lut;
END ARCHITECTURE rtl;
-- clocks_s6_basex
--
-- Generates a 25MHz ipbus clock from 200MHz xtal reference
-- Includes reset logic for ipbus
--
-- Dave Newbold, April 2011
--
-- $Id$
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.VComponents.all;
entity clocks_s6_basex is port(
sysclk_i: in std_logic;
clki_125: in std_logic;
clko_ipb: out std_logic;
sysclko: out std_logic;
locked: out std_logic;
nuke: in std_logic;
rsto_125: out std_logic;
rsto_ipb: out std_logic;
onehz: out std_logic
);
end clocks_s6_basex;
architecture rtl of clocks_s6_basex is
signal clk_ipb_i, clk_ipb_b, d17, d17_d, dcm_locked, sysclk, sysclk_ub: std_logic;
signal nuke_i, nuke_d, nuke_d2: std_logic := '0';
signal rst, rst_ipb, rst_125: std_logic := '1';
begin
sysclko <= sysclk_i;
clko_ipb <= clk_ipb_b;
bufg_ipb: BUFG port map(
i => clk_ipb_i,
o => clk_ipb_b
);
dcm0: DCM_CLKGEN
generic map(
CLKIN_PERIOD => 5.0,
CLKFX_MULTIPLY => 2,
CLKFX_DIVIDE => 16
)
port map(
clkin => sysclk_i,
clkfx => clk_ipb_i,
locked => dcm_locked,
rst => '0'
);
clkdiv: entity work.clock_div port map(
clk => sysclk_i,
d17 => d17,
d28 => onehz
);
process(sysclk_i)
begin
if rising_edge(sysclk_i) then
d17_d <= d17;
if d17='1' and d17_d='0' then
rst <= nuke_d2 or not dcm_locked;
nuke_d <= nuke_i; -- Time bomb (allows return packet to be sent)
nuke_d2 <= nuke_d;
end if;
end if;
end process;
locked <= dcm_locked;
process(clk_ipb_b)
begin
if rising_edge(clk_ipb_b) then
rst_ipb <= rst;
nuke_i <= nuke;
end if;
end process;
rsto_ipb <= rst_ipb;
process(clki_125)
begin
if rising_edge(clki_125) then
rst_125 <= rst;
end if;
end process;
rsto_125 <= rst_125;
end rtl;
-- clocks_s6_basex
--
-- Generates a 25MHz ipbus clock from 200MHz xtal reference
-- Includes reset logic for ipbus
--
-- Dave Newbold, April 2011
--
-- $Id$
library ieee;
use ieee.std_logic_1164.all;
library unisim;
use unisim.VComponents.all;
entity clocks_s6_basex is port(
sysclk_p: in std_logic;
sysclk_n: in std_logic;
clki_125: in std_logic;
clko_ipb: out std_logic;
sysclko: out std_logic;
locked: out std_logic;
nuke: in std_logic;
rsto_125: out std_logic;
rsto_ipb: out std_logic;
onehz: out std_logic
);
end clocks_s6_basex;
architecture rtl of clocks_s6_basex is
signal clk_ipb_i, clk_ipb_b, d17, d17_d, dcm_locked, sysclk, sysclk_ub: std_logic;
signal nuke_i, nuke_d, nuke_d2: std_logic := '0';
signal rst, rst_ipb, rst_125: std_logic := '1';
begin
ibufgds0: IBUFGDS port map(
i => sysclk_p,
ib => sysclk_n,
o => sysclk
);
sysclko <= sysclk;
clko_ipb <= clk_ipb_b;
bufg_ipb: BUFG port map(
i => clk_ipb_i,
o => clk_ipb_b
);
dcm0: DCM_CLKGEN
generic map(
CLKIN_PERIOD => 5.0,
CLKFX_MULTIPLY => 2,
CLKFX_DIVIDE => 16
)
port map(
clkin => sysclk,
clkfx => clk_ipb_i,
locked => dcm_locked,
rst => '0'
);
clkdiv: entity work.clock_div port map(
clk => sysclk,
d17 => d17,
d28 => onehz
);
process(sysclk)
begin
if rising_edge(sysclk) then
d17_d <= d17;
if d17='1' and d17_d='0' then
rst <= nuke_d2 or not dcm_locked;
nuke_d <= nuke_i; -- Time bomb (allows return packet to be sent)
nuke_d2 <= nuke_d;
end if;
end if;
end process;
locked <= dcm_locked;
process(clk_ipb_b)
begin
if rising_edge(clk_ipb_b) then
rst_ipb <= rst;
nuke_i <= nuke;
end if;
end process;
rsto_ipb <= rst_ipb;
process(clki_125)
begin
if rising_edge(clki_125) then
rst_125 <= rst;
end if;
end process;
rsto_125 <= rst_125;
end rtl;
--=============================================================================
--! @file clocks_s6_extclk.vhd
--=============================================================================
--@brief Generates a 125MHz ethernet clock , 250MHz fast clock and
--!31.25MHz ipbus clock from a 25MHz reference
--!Includes reset logic for ipbus
--
--! Produced using Xilinx clock wizard.
------------------------------------------------------------------------------
-- "Output Output Phase Duty Pk-to-Pk Phase"
-- "Clock Freq (MHz) (degrees) Cycle (%) Jitter (ps) Error (ps)"
------------------------------------------------------------------------------
-- CLK_OUT1___125.000______0.000______50.0______302.457____260.517
-- CLK_OUT2____31.250______0.000______50.0______428.143____260.517
-- CLK_OUT3___250.000______0.000______50.0______260.138____260.517
--
------------------------------------------------------------------------------
-- "Input Clock Freq (MHz) Input Jitter (UI)"
------------------------------------------------------------------------------
-- __primary__________25.000____________0.010
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
entity clocks_s6_extclk is
port
(-- Clock in ports
extclk_P : in std_logic;
extclk_N : in std_logic;
-- Clock out ports
clko_125 : out std_logic;
clko_ipb : out std_logic;
clko_ipb_n : out std_logic;
clko_fast : out std_logic;
clko_2x_fast : out std_logic; --! twice speed of fast clock
clko_fast_strobe : out std_logic; --! strobes every other clko_2x_fast cycle. Use for ISERDES
-- Status and control signals
LOCKED : out std_logic;
rsto_125 : out std_logic;
rsto_ipb : out std_logic;
onehz : out std_logic
);
end clocks_s6_extclk;
architecture rtl of clocks_s6_extclk is
-- Input clock buffering / unused connectors
signal extclk : std_logic;
-- Output clock buffering / unused connectors
signal clkfbout : std_logic;
signal clk_125_s : std_logic;
signal clk_ipb_s , clk_ipb_n_s : std_logic;
signal clk_fast_s , clk_2x_fast_s , clk_fast_internal : std_logic;
signal clk_2x_fast_internal : std_logic;
signal s_clkfbin_buf : std_logic;
signal clkout5_unused : std_logic;
signal d25, d25_d, pll_locked , bufpll_locked: std_logic;
signal rst: std_logic := '1';
signal clk_ipb_b, clk_ipb_n_b , clk_125_b: std_logic;
component clock_divider_s6 port(
clk: in std_logic;
d25: out std_logic;
d28: out std_logic
);
end component;
begin
-- Input buffering
--------------------------------------
extclk_buf : IBUFGDS
port map
(O => extclk,
I => extclk_P,
IB => extclk_N);
-- Clocking primitive
--------------------------------------
-- Instantiation of the PLL primitive
-- * Unused inputs are tied off
-- * Unused outputs are labeled unused
pll_base_inst : PLL_BASE
generic map
(BANDWIDTH => "OPTIMIZED",
CLK_FEEDBACK => "CLKFBOUT",
COMPENSATION => "SYSTEM_SYNCHRONOUS",
DIVCLK_DIVIDE => 1,
CLKFBOUT_MULT => 20,
CLKFBOUT_PHASE => 0.000,
CLKOUT0_DIVIDE => 2, -- 250 MHz
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT1_DIVIDE => 1, -- 500 MHz
CLKOUT1_PHASE => 0.000,
CLKOUT1_DUTY_CYCLE => 0.500,
CLKOUT2_DIVIDE => 16, -- 31.25 MHz, 0 deg
CLKOUT2_PHASE => 0.000,
CLKOUT2_DUTY_CYCLE => 0.500,
CLKOUT3_DIVIDE => 16, -- 31.25 MHz, 180 deg
CLKOUT3_PHASE => 180.000,
CLKOUT3_DUTY_CYCLE => 0.500,
CLKOUT4_DIVIDE => 4, -- 125MHz
CLKOUT4_PHASE => 0.000,
CLKOUT4_DUTY_CYCLE => 0.500,
CLKIN_PERIOD => 40.0,
REF_JITTER => 0.010)
port map
-- Output clocks
(CLKFBOUT => clkfbout,
CLKOUT0 => clk_fast_s, -- 250 MHz
CLKOUT1 => clk_2x_fast_s, -- 500 MHz
CLKOUT2 => clk_ipb_s, -- 31.25 MHz
CLKOUT3 => clk_ipb_n_s,
CLKOUT4 => clk_125_s,
CLKOUT5 => clkout5_unused,
-- Status and control signals
LOCKED => pll_locked,
RST => '0',
-- Input clock control
CLKFBIN => clkfbout, -- s_clkfbin_buf,
CLKIN => extclk);
-- Feedback buffer
-----------------------------------------------------------------------------
-- clkfb_buf : BUFIO2FB
-- port map (
-- O => s_clkfbin_buf, -- 1-bit output: Output feedback clock (connect to feedback input of DCM/PLL)
-- I => clk_2x_fast_internal -- 1-bit input: Feedback clock input (connect to input port)
-- );
-- Output buffering
-------------------------------------
clk125_buf : BUFG
port map
(O => clk_125_b,
I => clk_125_s);
clko_125 <= clk_125_b;
clkipb_buf : BUFG
port map
(O => clk_ipb_b,
I => clk_ipb_s);
clko_ipb <= clk_ipb_b;
clk_fast_buf : BUFG
port map
(O => clk_fast_internal,
I => clk_fast_s);
clko_fast <= clk_fast_internal;
clkipb_n_buf : BUFG
port map
(O => clk_ipb_n_b,
I => clk_ipb_n_s);
clko_ipb_n <= clk_ipb_n_b;
-- Set up the clock for use in the serdes
-- cmp_bufio2 : BUFIO2
-- generic map (
-- DIVIDE_BYPASS => FALSE,
-- I_INVERT => FALSE,
-- USE_DOUBLER => FALSE,
-- DIVIDE => 2)
-- port map (
-- DIVCLK => clk_fast_s,
-- IOCLK => clko_2x_fast,
-- SERDESSTROBE => clko_fast_strobe,
-- I => clk_2x_fast_s);
-- Use a BUFPLL to generate SERDES strobe.
cmp_bufpll : BUFPLL
generic map (
DIVIDE => 2)
port map (
IOCLK => clk_2x_fast_internal, -- output, I/O clock
LOCK => bufpll_locked, -- locked output
SERDESSTROBE => clko_fast_strobe, -- output to ISERDES2
GCLK => clk_fast_internal,
LOCKED => pll_locked , -- input from PLL
PLLIN => clk_2x_fast_s -- BUFG input
);
clko_2x_fast <= clk_2x_fast_internal;
clkdiv: clock_divider_s6 port map(
clk => clk_ipb_s,
d25 => d25,
d28 => onehz
);
process(extclk)
begin
if rising_edge(extclk) then
d25_d <= d25;
if d25='1' and d25_d='0' then
rst <= not pll_locked;
end if;
end if;
end process;
locked <= pll_locked;
process(clk_ipb_b)
begin
if rising_edge(clk_ipb_b) then
rsto_ipb <= rst;
end if;
end process;
process(clk_125_b)
begin
if rising_edge(clk_125_b) then
rsto_125 <= rst;
end if;
end process;
end rtl;
--=============================================================================
--! @file counterWithReset_rtl.vhd
--=============================================================================
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- unit name: counterWithReset (counterWithReset / rtl)
--
--! @brief Simple counter with synchronous reset
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date Feb\2012
--
--! @version v0.1
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! None
--!
--! <b>References:</b>\n
--! referenced by ipBusMarocTriggerGenerator \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 5/Mar/12 DGC Changed to use numeric_std\n
--!
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
---------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for counterWithReset
--============================================================================
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY counterWithReset IS
GENERIC (g_COUNTER_WIDTH : integer := 32);
PORT
(
clock_i: IN STD_LOGIC; --! rising edge active clock
reset_i: IN STD_LOGIC; --! syncronous with rising clk
enable_i: IN STD_LOGIC; --! counts when enable=1
result_o: OUT STD_LOGIC_VECTOR ( g_COUNTER_WIDTH-1 downto 0) --! Unsigned integer output
);
END counterWithReset;
ARCHITECTURE rtl OF counterWithReset IS
SIGNAL s_result_reg : UNSIGNED ( g_COUNTER_WIDTH-1 downto 0);
BEGIN
PROCESS (clock_i)
BEGIN
IF (clock_i'event AND clock_i = '1' ) THEN
IF (reset_i = '1') THEN
s_result_reg <= (others => '0');
ELSIF (enable_i='1') THEN
s_result_reg <= s_result_reg + 1;
END IF;
END IF;
END PROCESS;
result_o <= STD_LOGIC_VECTOR(s_result_reg);
END rtl;
--! @file
--! @brief A Dual-Port RAM with configurable width and number of entries. No Xilinx specific entities.
--! @author David Cussans
--! Institute: University of Bristol
--! @date 26 April 2011
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dpram is
generic (
DATA_WIDTH : integer := 32; --! Width of word
RAM_ADDRESS_WIDTH : integer := 10; --! size of RAM = 2^ram_address_width
g_USECOREGEN : boolean := True --! Set to True to use COREGEN DPR.
); -- default is 512 locations deep
port (
clk : in std_logic; --! rising edge active
-- read/write port
wren_a : in std_logic; --! write enable, active high
address_a : in std_logic_vector(ram_address_width-1 downto 0); --! write (port-A) address
data_a : in std_logic_vector(DATA_WIDTH-1 downto 0); --! data input -port A
q_a : out std_logic_vector(DATA_WIDTH-1 downto 0); --! data output - port A
-- secondary port
address_b : in std_logic_vector(ram_address_width-1 downto 0); --! read (port-B) address
q_b : out std_logic_vector(DATA_WIDTH-1 downto 0) --! Data output - port B
);
end dpram;
architecture syn of dpram is
type ram_type is array (2**ram_address_width - 1 downto 0) of std_logic_vector (DATA_WIDTH-1 downto 0);
signal RAM : ram_type;
signal read_dpra : std_logic_vector(ram_address_width-1 downto 0);
signal read_dprb : std_logic_vector(ram_address_width-1 downto 0);
signal s_wea : std_logic_vector(0 downto 0) := "0"; -- ! write enable for coregen DPR
begin
-- Use VHDL array to implement a dual-port-ram
gen_dpr: if g_USECOREGEN=False generate
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (wren_a = '1') then
RAM(TO_INTEGER(unsigned(address_a))) <= data_a;
end if;
q_b <= RAM(to_integer(unsigned(read_dprb)));
q_a <= RAM(to_integer(unsigned(read_dpra)));
end if;
end process;
read_dprb <= address_b;
read_dpra <= address_a;
end generate gen_dpr;
-- Use a DPR produced by Coregen
gen_coregendpr: if g_USECOREGEN=True generate
begin
assert DATA_WIDTH=32 report "Data width must be 32 for Coregen DPR" severity failure;
assert RAM_ADDRESS_WIDTH=9 report "Address width must be 9 for Coregen DPR" severity failure;
-- report "Using COREGEN DPR" severity note;
s_wea(0) <= wren_a; --! Xilinx coregen DPR write enable actually a bus of
--! width 1.
cmp_coregendDPR : entity work.dpram_coregen
PORT MAP (
clka => clk,
wea => s_wea,
addra => address_a,
dina => data_a,
clkb => clk,
addrb => address_b,
doutb => q_b
);
end generate gen_coregendpr;
end syn;
--=============================================================================
--! @file fineTimeStamp_rtl.vhd
--=============================================================================
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
--
--! @brief Measures arrival time using ISERDES and IDELAY primitives.
--! outputs trigger synchronized to 1x clock and 8x clock.
--! when an event trigger is received the fine-grain timestamps
--! are captured.
--! N.B. Have to compile with VHDL-2008 ( if/else generate)
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 25\2\2013
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--! Instantiates dualSERDES_1to2
--!
--! <b>References:</b>\n
--! referenced by ipbusFiveMarocTriggerGenerator \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
-------------------------------------------------------------------------------
--
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.ALL;
use work.maroc.all;
--! Package containing type definition and constants for IPBUS
use work.ipbus.all;
entity fineTimeStamp is
generic (
g_BUSWIDTH : positive := 32;
g_ADDR_WIDTH : positive := 10;
g_NMAROC : positive := 5;
g_NTIMESTAMP_BITS: positive := 5;
g_NCLKS : positive := 3;
-- 0 , 1 , 2 , 3 , 4
-- 5 , 6 , 7 , 8 , 9
g_CLOCK_DOMAIN : t_integer_array(0 to 9) := ( 0 , 0 , 0 , 1 , 2
, 1 , 0 , 0 , 0 , 3);
g_DUAL_SERDES_FLAG : t_bool_array(0 to 9) := ( true , true , true , true , false
, false , true , true , true , false)
);
port (
clk_1x_i : in std_logic; --! IPBus clock ( 31.25MHz )
clk_8x_i : in std_logic; --! 4 x IPBus clock ( 250 MHz )
--clk_8x_strobe_i : in std_logic; --! Strobes every other cycle of clk_8x
--clk_16x_i : in std_logic; --! eight time IPBus clock freq
clk_8x_strobe_i : in std_logic_vector(g_NCLKS-1 downto 0); --! Strobes every other cycle of clk_8x
clk_16x_i : in std_logic_vector(g_NCLKS-1 downto 0); --! eight time IPBus clock freq
reset_i : in std_logic; --! Resets pointers, active high, synchronous with clk_1x
event_trig_i : in std_logic; --! Goes high for one cycle of clk_1x for each event. Causes fine timestamps to be written to buffer
trigger_number_i : in std_logic_vector(g_BUSWIDTH-1 downto 0); --!Current trigger number
coarse_timestamp_i : in std_logic_vector(g_BUSWIDTH-1 downto 0); --! Timestamp clocked with clk_1x_i
trig_in_a_i : in std_logic_vector(g_NMAROC-1 downto 0); --! async trigger inputs
trig_out_8x_o : out std_logic_vector(g_NMAROC-1 downto 0); --! trigger syncronized onto clk_8x
trig_out_1x_o : out std_logic_vector(g_NMAROC-1 downto 0); --! trigger syncronized onto clk_1x
write_address_o : out std_logic_vector(g_ADDR_WIDTH-1 downto 0); --! next location in dual-port buffer memory that will get written to
-- IPBus for access to DPR
ipbus_i : in ipb_wbus;
ipbus_o : out ipb_rbus
);
end fineTimeStamp;
architecture rtl of fineTimeStamp is
subtype t_finetimestamp_value is std_logic_vector(g_NTIMESTAMP_BITS-1 downto 0) ; -- ! Subtype to allow an array of timestamps
type t_finetimestamp_array is array (0 to g_NMAROC-1) of t_finetimestamp_value; -- ! Type for array of finetimestamps
signal s_finetimestamps : t_finetimestamp_array;
-- subtype t_timestamp_value is std_logic_vector(g_BUSWIDTH-1 downto 0); -- ! Subtype to allow an array of timestamps
-- type t_timestamp_array is array (0 to g_NMAROC-1) of t_timestamp_value; -- ! Type for array of timestamps
signal s_timestamps : t_dual_timestamp_array;
signal s_trig_out_1x : std_logic_vector(trig_out_1x_o'range) := ( others => '0') ;
-- internal copy of trigger on 1x clock domain. Needed since can't read output port...
begin -- rtl
-----------------------------------------------------------------------------
-- Start of generate loop
gen_inputs: for iMaroc in 0 to g_NMAROC-1 generate
begin
-- Instantiate an input time-stamping circuit. Because of limitations in
-- FPGA fabric need different clock domains and not all input circuits
-- can use two ISERDES.
cmp_singleFineTimeStamp : entity work.singleFineTimeStamp
generic map (
g_BUSWIDTH => g_BUSWIDTH,
g_DUAL_ISERDES => g_DUAL_SERDES_FLAG(iMaroc)
)
port map (
clk_1x_i => clk_1x_i,
clk_8x_i => clk_8x_i,
clk_8x_strobe_i => clk_8x_strobe_i( g_CLOCK_DOMAIN(iMaroc) ),
clk_16x_i => clk_16x_i( g_CLOCK_DOMAIN(iMaroc) ),
reset_i => reset_i,
timestamp_o => s_finetimestamps(iMaroc),
trig_in_a_i => trig_in_a_i(iMaroc),
trig_out_8x_o => trig_out_8x_o(iMaroc),
trig_out_1x_o => s_trig_out_1x(iMaroc)
);
-- purpose: combines the coarse timestamp (32ns resolution) with the fine-grain timestamp (1ns resolution)
-- type : combinational
-- inputs : clk_1x_i , s_finetimestamps
-- outputs: s_timestamps
proc_combine_coarse_fine: process (clk_1x_i)
begin -- process proc_combine_coarse_fine
if rising_edge(clk_1x_i) and (s_trig_out_1x(iMaroc)='1') then
s_timestamps(iMaroc) <= coarse_timestamp_i( (g_BUSWIDTH-g_NTIMESTAMP_BITS-1) downto 0) & s_finetimestamps(iMaroc) ;
end if;
end process proc_combine_coarse_fine;
end generate gen_inputs;
-------------------------------------------------------------------------------
trig_out_1x_o <= s_trig_out_1x;
-- Instantiate a buffer to store timestamps.
cmp_timeStampDPRAM : entity work.timeStampDPRAM
generic map (
g_BUSWIDTH => g_BUSWIDTH,
g_ADDRWIDTH => g_ADDR_WIDTH)
port map (
clk_i => clk_1x_i,
reset_i => reset_i,
event_trigger_i => event_trig_i,
trigger_number_i=> trigger_number_i,
timestamp_i => s_timestamps,
event_timestamp_i => coarse_timestamp_i,
write_pointer_o => write_address_o,
ipbus_i => ipbus_i,
ipbus_o => ipbus_o
);
end rtl;
--=============================================================================
--! @file fineTimeStamp_rtl.vhd
--=============================================================================
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
--
--! @brief Measures arrival time using ISERDES and IDELAY primitives.
--! outputs trigger synchronized to 1x clock and 8x clock.
--! when an event trigger is received the fine-grain timestamps
--! are captured.
--! N.B. Have to compile with VHDL-2008 ( if/else generate)
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 25\2\2013
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--! Instantiates dualSERDES_1to2
--!
--! <b>References:</b>\n
--! referenced by ipbusFiveMarocTriggerGenerator \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
-------------------------------------------------------------------------------
--
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.ALL;
use work.fiveMaroc.all;
--! Package containing type definition and constants for IPBUS
use work.ipbus.all;
entity fineTimeStamp is
generic (
g_BUSWIDTH : positive := 32;
g_ADDR_WIDTH : positive := 10;
g_NMAROC : positive := 5;
g_NTIMESTAMP_BITS: positive := 5;
g_NCLKS : positive := 3;
-- 0 , 1 , 2 , 3 , 4
-- 5 , 6 , 7 , 8 , 9
g_CLOCK_DOMAIN : t_integer_array(0 to 9) := ( 0 , 0 , 0 , 1 , 2
, 1 , 0 , 0 , 0 , 3);
g_DUAL_SERDES_FLAG : t_bool_array(0 to 9) := ( true , true , true , true , false
, false , true , true , true , false)
);
port (
clk_1x_i : in std_logic; --! IPBus clock ( 31.25MHz )
clk_8x_i : in std_logic; --! 4 x IPBus clock ( 250 MHz )
--clk_8x_strobe_i : in std_logic; --! Strobes every other cycle of clk_8x
--clk_16x_i : in std_logic; --! eight time IPBus clock freq
clk_8x_strobe_i : in std_logic_vector(g_NCLKS-1 downto 0); --! Strobes every other cycle of clk_8x
clk_16x_i : in std_logic_vector(g_NCLKS-1 downto 0); --! eight time IPBus clock freq
reset_i : in std_logic; --! Resets pointers, active high, synchronous with clk_1x
event_trig_i : in std_logic; --! Goes high for one cycle of clk_1x for each event. Causes fine timestamps to be written to buffer
trigger_number_i : in std_logic_vector(g_BUSWIDTH-1 downto 0); --!Current trigger number
coarse_timestamp_i : in std_logic_vector(g_BUSWIDTH-1 downto 0); --! Timestamp clocked with clk_1x_i
trig_in_a_i : in std_logic_vector(g_NMAROC-1 downto 0); --! async trigger inputs
trig_out_8x_o : out std_logic_vector(g_NMAROC-1 downto 0); --! trigger syncronized onto clk_8x
trig_out_1x_o : out std_logic_vector(g_NMAROC-1 downto 0); --! trigger syncronized onto clk_1x
write_address_o : out std_logic_vector(g_ADDR_WIDTH-1 downto 0); --! next location in dual-port buffer memory that will get written to
-- IPBus for access to DPR
ipbus_i : in ipb_wbus;
ipbus_o : out ipb_rbus
);
end fineTimeStamp;
architecture rtl of fineTimeStamp is
subtype t_finetimestamp_value is std_logic_vector(g_NTIMESTAMP_BITS-1 downto 0) ; -- ! Subtype to allow an array of timestamps
type t_finetimestamp_array is array (0 to g_NMAROC-1) of t_finetimestamp_value; -- ! Type for array of finetimestamps
signal s_finetimestamps : t_finetimestamp_array;
-- subtype t_timestamp_value is std_logic_vector(g_BUSWIDTH-1 downto 0); -- ! Subtype to allow an array of timestamps
-- type t_timestamp_array is array (0 to g_NMAROC-1) of t_timestamp_value; -- ! Type for array of timestamps
signal s_timestamps : t_dual_timestamp_array;
signal s_trig_out_1x : std_logic_vector(trig_out_1x_o'range) := ( others => '0') ;
-- internal copy of trigger on 1x clock domain. Needed since can't read output port...
begin -- rtl
-----------------------------------------------------------------------------
-- Start of generate loop
gen_inputs: for iMaroc in 0 to g_NMAROC-1 generate
begin
-- Instantiate an input time-stamping circuit. Because of limitations in
-- FPGA fabric need different clock domains and not all input circuits
-- can use two ISERDES.
cmp_singleFineTimeStamp : entity work.singleFineTimeStamp
generic map (
g_BUSWIDTH => g_BUSWIDTH,
g_DUAL_ISERDES => g_DUAL_SERDES_FLAG(iMaroc)
)
port map (
clk_1x_i => clk_1x_i,
clk_8x_i => clk_8x_i,
clk_8x_strobe_i => clk_8x_strobe_i( g_CLOCK_DOMAIN(iMaroc) ),
clk_16x_i => clk_16x_i( g_CLOCK_DOMAIN(iMaroc) ),
reset_i => reset_i,
timestamp_o => s_finetimestamps(iMaroc),
trig_in_a_i => trig_in_a_i(iMaroc),
trig_out_8x_o => trig_out_8x_o(iMaroc),
trig_out_1x_o => s_trig_out_1x(iMaroc)
);
-- purpose: combines the coarse timestamp (32ns resolution) with the fine-grain timestamp (1ns resolution)
-- type : combinational
-- inputs : clk_1x_i , s_finetimestamps
-- outputs: s_timestamps
proc_combine_coarse_fine: process (clk_1x_i)
begin -- process proc_combine_coarse_fine
if rising_edge(clk_1x_i) and (s_trig_out_1x(iMaroc)='1') then
s_timestamps(iMaroc) <= coarse_timestamp_i( (g_BUSWIDTH-g_NTIMESTAMP_BITS-1) downto 0) & s_finetimestamps(iMaroc) ;
end if;
end process proc_combine_coarse_fine;
end generate gen_inputs;
-------------------------------------------------------------------------------
trig_out_1x_o <= s_trig_out_1x;
-- Instantiate a buffer to store timestamps.
cmp_timeStampDPRAM : entity work.timeStampDPRAM
generic map (
g_BUSWIDTH => g_BUSWIDTH,
g_ADDRWIDTH => g_ADDR_WIDTH)
port map (
clk_i => clk_1x_i,
reset_i => reset_i,
event_trigger_i => event_trig_i,
trigger_number_i=> trigger_number_i,
timestamp_i => s_timestamps,
event_timestamp_i => coarse_timestamp_i,
write_pointer_o => write_address_o,
ipbus_i => ipbus_i,
ipbus_o => ipbus_o
);
end rtl;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
-- Xilinx lib for differential output buffers
Library UNISIM;
use UNISIM.vcomponents.all;
use work.fiveMaroc.all;
entity generate_hdmi is
port (
clk_i : in std_logic;
hdmi_input_signals: in hdmi_input_signals;
hdmi_output_signals: out hdmi_output_signals
);
end generate_hdmi;
architecture rtl of generate_hdmi is
-- signal hdmi0_clk : std_logic;
-- signal hdmi0_data : std_logic_vector(2 downto 0);
-- signal hdmi0_clk : std_logic;
-- signal hdmi0_data : std_logic_vector(2 downto 0);
signal counter : unsigned(7 downto 0) := to_unsigned(0,8);
begin -- rtl
-- need to buffer all output signals => => => => .
-----------------------------------------------------------------------------
-- Connections to HDMI0
-----------------------------------------------------------------------------
obufds_hdmi0_clk : obufds
generic map (
iostandard => "DEFAULT")
port map (
o => hdmi_output_signals.hdmi0_clk_p,
ob => hdmi_output_signals.hdmi0_clk_n,
i => counter(0)
);
obufds_hdmi0_data0 : obufds
generic map (
iostandard => "DEFAULT")
port map (
o => hdmi_output_signals.hdmi0_data_p(0),
ob => hdmi_output_signals.hdmi0_data_n(0),
i => counter(1)
);
obufds_hdmi0_data1 : obufds
generic map (
iostandard => "DEFAULT")
port map (
o => hdmi_output_signals.hdmi0_data_p(1),
ob => hdmi_output_signals.hdmi0_data_n(1),
i => counter(2)
);
obufds_hdmi0_data2 : obufds
generic map (
iostandard => "DEFAULT")
port map (
o => hdmi_output_signals.hdmi0_data_p(2),
ob => hdmi_output_signals.hdmi0_data_n(2),
i => counter(3)
);
-----------------------------------------------------------------------------
-- Connections to HDMI1
-----------------------------------------------------------------------------
obufds_hdmi1_clk : obufds
generic map (
iostandard => "DEFAULT")
port map (
o => hdmi_output_signals.hdmi1_clk_p,
ob => hdmi_output_signals.hdmi1_clk_n,
i => counter(4)
);
obufds_hdmi1_data0 : obufds
generic map (
iostandard => "DEFAULT")
port map (
o => hdmi_output_signals.hdmi1_data_p(0),
ob => hdmi_output_signals.hdmi1_data_n(0),
i => counter(5)
);
obufds_hdmi1_data1 : obufds
generic map (
iostandard => "DEFAULT")
port map (
o => hdmi_output_signals.hdmi1_data_p(1),
ob => hdmi_output_signals.hdmi1_data_n(1),
i => counter(6)
);
obufds_hdmi1_data2 : obufds
generic map (
iostandard => "DEFAULT")
port map (
o => hdmi_output_signals.hdmi1_data_p(2),
ob => hdmi_output_signals.hdmi1_data_n(2),
i => counter(7)
);
-----------------------------------------------------------------------------
--
-----------------------------------------------------------------------------
count: process (clk_i)
begin -- process count
if rising_edge(clk_i) then
counter <= counter +1 ;
end if;
end process count;
end rtl;
--============================================================================
--! @file generate_test_signals.vhd
--============================================================================
-- @brief Given a 200MHz clock generates a 25MHz clock and trigger pulses
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
Library UNISIM;
use UNISIM.vcomponents.all;
entity generate_test_signals is
generic (
TRIGGER_DIVIDER : positive := 15; --! Number of 25MHz clock ticks between
--each trigger pulse is 2^TRIGGER_DIVIDER
TRIGGER_WIDTH : positive := 3); --! width in 25mHz clock cycles
port (
sysclk : in std_logic; -- ! system clock ( 200MHz )
test_clk_25M : out std_logic; -- ! Generated from system clock
test_trigger : out std_logic; -- ! periodic , regular pulses, sync with 25MHz clock
dcm_locked : out std_logic --! Connected to locked pin of DCM
);
end generate_test_signals;
architecture rtl of generate_test_signals is
signal clkfb : std_logic;
signal clk0 : std_logic;
signal clkfx,clkfx_n : std_logic;
signal clkfbout : std_logic;
--signal locked_internal : std_logic;
signal status_internal : std_logic_vector(7 downto 0);
signal trigger_scaler : unsigned( TRIGGER_DIVIDER downto 0) := (others => '0'); -- counter to produce triggers at uniform interval
signal trigger_squarewave : std_logic;
signal trigger_squarewave_d1 , trigger_squarewave_d2 : std_logic; --! delayed trigger
begin -- rtl
-- expects a 200MHz input clock ( sysclk )
-- generates a 25MHz output clock
dcm_sp_inst: DCM_SP
generic map
(CLKDV_DIVIDE => 2.000,
CLKFX_DIVIDE => 16,
CLKFX_MULTIPLY => 2,
CLKIN_DIVIDE_BY_2 => FALSE,
CLKIN_PERIOD => 5.0,
CLKOUT_PHASE_SHIFT => "NONE",
-- CLK_FEEDBACK => "NONE",
CLK_FEEDBACK => "1X",
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
PHASE_SHIFT => 0,
STARTUP_WAIT => FALSE)
port map
-- Input clock
(CLKIN => sysclk,
CLKFB => clkfb,
-- Output clocks
CLK0 => clk0,
CLK90 => open,
CLK180 => open,
CLK270 => open,
CLK2X => open,
CLK2X180 => open,
CLKFX => clkfx,
CLKFX180 => clkfx_n,
CLKDV => open,
-- Ports for dynamic phase shift
PSCLK => '0',
PSEN => '0',
PSINCDEC => '0',
PSDONE => open,
-- Other control and status signals
LOCKED => dcm_locked,
STATUS => status_internal,
RST => '0',
-- Unused pin, tie low
DSSEN => '0');
-- no phase alignment active, connect clock feedback to ground
clkfb <= clk0 ; -- '0';
-- trying to connect up a global clock net straight to an output pin
-- generally doesn't give good results, so use a DDR output register...
clock_output_register : ODDR2
port map (
Q => test_clk_25M, -- 1-bit output data
C0 => clkfx, -- 1-bit clock input
C1 => clkfx_n, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
D0 => '0', -- 1-bit data input (associated with C0)
D1 => '1', -- 1-bit data input (associated with C1)
R => '0', -- 1-bit reset input
S => '0' -- 1-bit set input
);
-- Generate trigger pulses....
-- purpose: generates a square wave, shaped to be trigger pulses
-- type : sequential
-- inputs : clkfx, <reset>
-- outputs: test_trigger
generate_triggers: process (clkfx)
begin -- process generate_triggers
if rising_edge(clkfx) then -- rising clock edge
trigger_scaler <= trigger_scaler +1 ;
trigger_squarewave <= trigger_scaler(TRIGGER_DIVIDER);
trigger_squarewave_d1 <= trigger_squarewave;
trigger_squarewave_d2 <= trigger_squarewave_d1;
test_trigger <= trigger_squarewave and not trigger_squarewave_d2;
end if;
end process generate_triggers;
end rtl;
--! @file
--! @brief A Dual-Port RAM with configurable width and number of entries. No Xilinx specific entities.
--! @author David Cussans
--! Institute: University of Bristol
--! @date 26 April 2011
--
--! Modifications:
--! 10/May/13 - re-write to have an IPBus output port.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.ipbus.all;
entity ipbusDPRAM is
generic (
DATA_WIDTH : integer := 32; --! Width of word
RAM_ADDRESS_WIDTH : integer := 10 --! size of RAM = 2^ram_address_width
); -- default is 512 locations deep
port (
clk : in std_logic; --! rising edge active
-- write port
wren_a : in std_logic; --! write enable, active high
address_a : in std_logic_vector(ram_address_width-1 downto 0); --! write (port-A) address
data_a : in std_logic_vector(DATA_WIDTH-1 downto 0); --! data input -port A
-- IPBus for read-port
ipbus_i : in ipb_wbus;
ipbus_o : out ipb_rbus
);
end ipbusDPRAM;
architecture rtl of ipbusDPRAM is
type ram_type is array (2**ram_address_width - 1 downto 0) of std_logic_vector (DATA_WIDTH-1 downto 0);
signal RAM : ram_type;
signal s_ack : std_logic := '0'; --! IPBus ack
signal s_readAddress , s_writeAddress : integer := 0;
begin
s_readAddress <= to_integer(unsigned(ipbus_i.ipb_addr(ram_address_width-1 downto 0)));
s_writeAddress <= TO_INTEGER(unsigned(address_a));
process (clk)
begin
if rising_edge(clk) then
-- If write enable high then write into RAM
if (wren_a = '1') then
RAM(s_writeAddress) <= data_a;
end if;
ipbus_o.ipb_rdata <= RAM(s_readAddress);
s_ack <= ipbus_i.ipb_strobe and not s_ack;
end if;
end process;
ipbus_o.ipb_ack <= s_ack;
ipbus_o.ipb_err <= '0';
end rtl;
This diff is collapsed.
--=============================================================================
--! @file ipbusMarocADC_rtl.vhd
--=============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
--! Package containing type definition and constants for MAROC interface
use work.maroc.all;
--! Package containing type definition and constants for IPBUS
use work.ipbus.all;
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- unit name: ipbusMarocADC_rtl (ipbusMarocADC / rtl)
--
--! @brief Interfaces between IPBus and Maroc ADC\n
--! Addresses ( with respect to base address)\n
--! 0x00 - 0x2FF : ADC data ( ro )\n
--! 0x200 : control/status.
--! Writing '1' to bit-0 starts conversion.\n
--! Reading bit-0 returns high if conversion is in progress\n
--! Writing '1' to bit-1 resets write pointer\n
--! 0x201 : returns the number of bits shifted out by MAROC ADC\n
--! during last conversion ( ro )\n
--! 0x202 : DPRAM write-pointer (next address to be written to ( ro )\n
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 4\Jan\2012
--
--! @version v0.3
--
--! @details
--! This module provides input/output to Maroc ADC pins.
--! An ADC conversion can be initiated either by writing to bit-1 of 0x401 or
--! (usually) by a pulse on the input port adcConversionStart_i
--!
--! There are two ways to trigger an ADC conversion:
--! a) A pulse on adcConversionStart_i
--! b) Writing to bit-0 of address 0x20
--!
--! As serial data arrives from ADC the earliest data ends up in highest bits of
--! the lowest words in the DPRAM.
--!
--! Data are written to a DPRAM. Address 0x402 stores the location that the next
--! word that will be written (the "write pointer").
--! The ADC data are preceeded by a trigger number word
--! and a timestamp word. Hence with the Maroc set to 12-bit samples the total
--! number of 32-bit words = (64 * 12)/32 + 2 = 26
--!
--! NB. There is no attempt to throttle the input data if the write pointer overtakes
--! the read pointer on the IPBus host.
--!
--! <b>Dependencies:</b>\n
--! Instantiates marocADC ( which contains the DPRAM )
--!
--! <b>References:</b>\n
--! referenced by slaves \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 18/Jan/2012 DGC Fixed bug so that writing to control register only triggers
--! a single ADC conversion.\n
--! 25/Jan/2012 DGC Added FIFO\n
--! 17/Feb/2012 DGC Changed marocADC to use Dual-port RAM rather than shift-reg\
--! need to change ports accordingly\n
--! 7/March/2012 DGC Got rid of FIFO and make DPRAM big enough to act as a
--! circular buffer\n
--! 17/March/2012 DGC Add internal reset, to reset state of ADC\n
--! 9/May/2013 DGC Reduced buffer size to 512 words
-------------------------------------------------------------------------------
--! @todo
---------------------------------------------------------------------------------
--
entity ipbusMarocADC is
generic(
g_ADDRWIDTH : positive := 9; --! Number of words in the data buffer
--! is 2^g_ADDRWIDTH
g_BUSWIDTH : positive := 32; --! Width of data bus
g_IDENT : std_logic_vector(31 downto 0) := X"DEADBEEF"
);
port(
clk_i : in std_logic; --! IPBus clock. Active high
reset_i : in std_logic; --! Active high
control_ipbus_i : in ipb_wbus; --! Signals from IPBus master for control/status
control_ipbus_o : out ipb_rbus; --! Signals to IPBus master
data_ipbus_i : in ipb_wbus; --! Signals from IBus master for data
data_ipbus_o : out ipb_rbus; --! Signals to IPBus master
logic_reset_i : in std_logic; --! Reset logic signal. High for one cycle of ipbus clock
-- Signals to trigger controller
adcConversionStart_i : in std_logic; --! Signal from trigger generator. an ADC conversion is started when pulses high
adcStatus_o : out std_logic; --! goes high when ADC is in progres.
triggerNumber_i : in std_logic_vector(g_BUSWIDTH-1 downto 0);
timeStamp_i : in std_logic_vector(g_BUSWIDTH-1 downto 0);
-- Signals to MAROC
START_ADC_N_O : out std_logic; --! Signal to MAROC. Drops low to initiate ADC conversion
RST_ADC_N_O : out std_logic; --! Signal to MAROC. Drops low to reset ADC
ADC_DAV_I : in std_logic; --! Signal from MAROC. Goes high during data transmission
OUT_ADC_I : in std_logic --! Data from MAROC. Clocked by clk_i
);
end ipbusMarocADC;
architecture rtl of ipbusMarocADC is
--signal s_adc_data : std_logic_vector(g_BUSWIDTH-1 downto 0);
--signal s_adc_dpr_address : std_logic_vector(g_ADDRWIDTH-1 downto 0);
--signal s_adc_dpr_addr_from_fifo : std_logic_vector(g_ADDRWIDTH-1 downto 0);
signal s_adc_dpr_write_pointer : std_logic_vector(g_ADDRWIDTH-1 downto 0);
-- signal s_sel: integer;
signal s_ack : std_logic := '0'; -- , s_ack_d1 : std_logic;
signal s_start_p : std_logic; --! Control line to ADC interface. Pulses high to start conversion manually
--! Generated by IPBus. ADC starts if either internal or external signal goes high
signal s_internal_start_p : std_logic;
signal s_internal_reset , s_reset : std_logic;
signal s_status : std_logic; --! Control line from ADC interface. Goes high when conversion in progress
signal s_status_d1 : std_logic; --! s_status delayed by 1 cycle
signal s_bitcount : std_logic_vector(9 downto 0); --! Number of bits output by ADC during last conversion
begin
-- read/write to registers storing data to/from MAROC and to control reg.
p_register_data : process(clk_i)
begin
-- Register the counters and status
if rising_edge(clk_i) then
case control_ipbus_i.ipb_addr(1 downto 0) is
when "00" =>
-- We are reading the control/status register. s_start_p is
-- handled a separate process, so just do read here.
control_ipbus_o.ipb_rdata(0) <= s_status;
control_ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto 1) <= (others => '0');
when "01" =>
-- We are reading the bit counter
control_ipbus_o.ipb_rdata(s_bitcount'range) <= s_bitcount;
control_ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto s_bitcount'high+1) <=
(others => '0');
when "10" =>
-- We are reading the ADC write pointer
control_ipbus_o.ipb_rdata(s_adc_dpr_write_pointer'range) <=
s_adc_dpr_write_pointer;
control_ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto s_adc_dpr_write_pointer'high+1) <=
(others => '0');
when "11" =>
-- test location
control_ipbus_o.ipb_rdata <= g_IDENT;
when others => null;
end case;
end if;
end process; -- p_register_data
p_ipbus_ack : process (clk_i)
begin -- process p_ipbus_ack
if rising_edge(clk_i) then -- rising clock edge
s_ack <= control_ipbus_i.ipb_strobe and not s_ack;
end if;
end process p_ipbus_ack;
control_ipbus_o.ipb_ack <= s_ack;
control_ipbus_o.ipb_err <= '0';
--! purpose: Controls state of s_start_p and s_internal_reset
--! type : combinational
--! inputs : clk_i , control_ipbus_i
--! outputs:
p_start_control : process (clk_i , control_ipbus_i)
begin -- process p_start_control
if rising_edge(clk_i) then
if control_ipbus_i.ipb_strobe = '1' and control_ipbus_i.ipb_write = '1' and
control_ipbus_i.ipb_addr(g_ADDRWIDTH) = '1' and
control_ipbus_i.ipb_addr(1 downto 0) = "00"
then
s_internal_start_p <= control_ipbus_i.ipb_wdata(0);
s_internal_reset <= control_ipbus_i.ipb_wdata(1);
else
s_internal_start_p <= '0';
s_internal_reset <= '0';
end if;
s_start_p <= s_internal_start_p or adcConversionStart_i;
end if;
end process p_start_control;
--! Sigh.... can't read from an out-port so take a local copy...
adcStatus_o <= s_status;
--! Fire a reset either from IPBus
--master, or by writing to bit-1 of
--ctrl reg or external logic reset
s_reset <= reset_i or s_internal_reset or logic_reset_i;
-- Instantiate the ADC interface
cmp_ADCInterface : entity work.marocADC
generic map (
g_ADDRWIDTH => g_ADDRWIDTH
)
port map (
clk_i => clk_i ,
reset_i => s_reset,
start_p_i => s_start_p , --! Pulse high to start conversion.
status_o => s_status ,
write_pointer_o => s_adc_dpr_write_pointer, --! Next address to be written
bitcount_o => s_bitcount ,
-- IPBus port to read data.
--data_o => s_adc_data , --! 32 bit word from DPR
--addr_i => s_adc_dpr_address , --! Read port address into DPR
ipbus_i => data_ipbus_i,
ipbus_o => data_ipbus_o,
-- Timestamp and trigger number
triggerNumber_i => triggerNumber_i ,
timeStamp_i => timeStamp_i ,
-- Signals to MAROC
START_ADC_N_O => START_ADC_N_O ,
RST_ADC_N_O => RST_ADC_N_O,
ADC_DAV_I => ADC_DAV_I,
OUT_ADC_I => OUT_ADC_I
);
end rtl;
--=============================================================================
--! @file ipbusMarocShiftReg_rtl.vhd
--=============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.ALL;
--! Package containing type definition and constants for MAROC interface
use work.maroc.ALL;
--! Package containing type definition and constants for IPBUS
use work.ipbus.all;
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- unit name: ipbusMarocShiftReg_rtl (ipbusMarocShiftReg / rtl)
--
--! @brief Interfaces between IPBus and Maroc shift register.\n
--! addresses 0x00 - 0x1F : data to be written to MAROC ( r/w )\n
--! addresses 0x20 - 0x3F : data returned from MAROC ( ro )\n
--! address 0x40 : control/status. Writing to bit-0 starts transfer.
--! Reading bit-0 returns high if transfer is in progress\n
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 4\1\2011
--
--! @version v0.1
--
--! @details
--!
--! <b>Based on ipbus_ram by Dave Newbold.<b>\n
--!
--! <b>Dependencies:</b>\n
--! Instantiates marocShiftReg
--!
--! <b>References:</b>\n
--! referenced by slaves \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! Friday 13/Jan/2012 DGC - Now only starts Shifting if data bit zero of is high\n
--! <extended description>
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
---------------------------------------------------------------------------------
--
-- $Id: ipbus_ram.vhd 324 2011-04-25 19:37:43Z phdmn $
entity ipbusMarocShiftReg is
generic(
g_ADDRWIDTH : positive;
g_NBITS : positive := c_NBITS; --! Number of bits to shift out to MAROC
g_NWORDS : positive := c_NWORDS; --! Number of words in IPBUS space to store data
g_BUSWIDTH : positive := c_BUSWIDTH; --! Number of bits in each word
g_CLKDIVISION : positive := 4 --! Number of bits in clock divider between system clock and clock to shift reg
);
port(
clk_i : in STD_LOGIC;
reset_i : in STD_LOGIC;
ipbus_i : in ipb_wbus;
ipbus_o : out ipb_rbus;
clk_sr_o : out std_logic; --! Clock out to shift-register
d_sr_o : out std_logic; --! Data being output to shift reg.
q_sr_i : in std_logic; --! input back from shift reg
rst_sr_n_o : out std_logic --! reset* to shift reg
);
end ipbusMarocShiftReg;
architecture rtl of ipbusMarocShiftReg is
type t_reg_array is array(2**g_ADDRWIDTH-1 downto 0) of std_logic_vector(31 downto 0);
signal s_reg_out: t_reg_array;
signal s_reg_in: t_reg_array;
signal s_sel: integer;
signal s_ack: std_logic;
signal s_start_p : std_logic := '0'; --! Control signal to shift reg controller. Take high for one cycle to start transfer
signal s_status : std_logic ; --! From shift reg controller. Goes high while transfer in progress
signal s_data_to_maroc , s_data_from_maroc : std_logic_vector( (g_NWORDS*g_BUSWIDTH)-1 downto 0) := (others => '0'); --! register storing data going to/from MAROC shift reg.
begin
s_sel <= to_integer(unsigned(ipbus_i.ipb_addr(g_ADDRWIDTH-1 downto 0)));
-- read/write to registers storing data to/from MAROC and to control reg.
p_register_data: process(clk_i)
begin
if rising_edge(clk_i) then
-- If the bit g_ADDRWIDTH+1 is low then read/write to register storing
-- data going to/from maroc
if ipbus_i.ipb_addr(g_ADDRWIDTH+1)='0' then
-- If ipb_addr(g_ADDRWIDTH) low then read/write register storing data *to* Maroc
if ipbus_i.ipb_addr(g_ADDRWIDTH)='0' then
if ipbus_i.ipb_strobe='1' and ipbus_i.ipb_write='1' then
s_reg_out(s_sel) <= ipbus_i.ipb_wdata;
end if;
ipbus_o.ipb_rdata <= s_reg_out(s_sel);
else
-- else if ipb_addr(g_ADDRWIDTH) high then read/write register storing data *from* Maroc
ipbus_o.ipb_rdata <= s_reg_in(s_sel);
end if;
else
-- ipb_addr(g_ADDRWIDTH+1) is high, so we are addressing the
-- control/status register
-- writing to s_start_p is handled in separate proccess
-- just do read here
ipbus_o.ipb_rdata(0) <= s_status;
end if;
s_ack <= ipbus_i.ipb_strobe and not s_ack;
end if;
end process; -- p_register_data
--! purpose: Controls state of s_start_p
--! type : combinational
--! inputs : clk_i , ipbus_i
--! outputs:
p_start_control: process (clk_i , ipbus_i )
begin -- process p_start_control
if rising_edge(clk_i) then
if ipbus_i.ipb_strobe='1' and ipbus_i.ipb_write='1' and
ipbus_i.ipb_addr(g_ADDRWIDTH+1)='1'
then
s_start_p <= ipbus_i.ipb_wdata(0) ;
else
s_start_p <= '0';
end if;
end if;
end process p_start_control;
ipbus_o.ipb_ack <= s_ack;
ipbus_o.ipb_err <= '0';
--! Copy data to input/output shift registers
-- Hopefully synthesis tool will not generate an additional pair of registers.
l_copywords: for iword in 0 to g_NWORDS-1 generate
s_data_to_maroc( (((iword+1)*g_BUSWIDTH)-1) downto iword*g_BUSWIDTH ) <= s_reg_out(iword);
s_reg_in(iword) <= s_data_from_maroc((((iword+1)*g_BUSWIDTH)-1) downto iword*g_BUSWIDTH );
end generate l_copywords;
--! Instantiate a shift register controller
cmp_shiftRegController: entity work.marocShiftReg
generic map (
g_NBITS => g_NBITS)
PORT MAP (
clk_system_i => clk_i,
rst_i => reset_i,
start_p_i => s_start_p,
data_i => s_data_to_maroc,
data_o => s_data_from_maroc,
clk_sr_o => clk_sr_o,
d_sr_o => d_sr_o,
q_sr_i => q_sr_i,
rst_sr_n_o => rst_sr_n_o,
status_o => s_status
);
end rtl;
--=============================================================================
--! @file ipbusMarocTriggerGenerator_rtl.vhd
--=============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.ALL;
--! Package containing type definition and constants for MAROC interface
use work.maroc.ALL;
--! Package containing type definition and constants for IPBUS
use work.ipbus.all;
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- unit name: ipbusMarocTriggerGenerator_rtl (ipbusMarocTriggerGenerator / rtl)
--
--! @brief Interfaces between IPBus and Maroc TriggerGenerator\n
--! Addresses ( with respect to base address)\n
--! 0x00 : Status register. Writing 1 to bit-0 resets trigger and timestamp counters\n
--! 0x01 : Manual trigger register. Write 1 to bit 0 to cause internal trigger\n
--! 0x02 : HOLD1 delay. 5 bits, 5ns ticks\n
--! 0x03 : HOLD2 delay. 5 bits, 5ns ticks\n
--! 0x04 : Trigger select register. 4 bits.\n
--! bit 0 = internal-trigger , 1 = external-trigger\n, bit2 = or1 , bit3=or2\n
--! 0x05 : Conversion counter - read = number of ADC conversions since last reset.\n
--! 0x06 : Timestamp - read = number of clock cycles since last reset
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 21\1\2012
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--! Instantiates marocTriggerGenerator
--!
--! <b>References:</b>\n
--! referenced by slaves \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 9/March/2012 DGC Adding trigger counter and timestamp\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
---------------------------------------------------------------------------------
--
entity ipbusMarocTriggerGenerator is
generic(
g_BUSWIDTH : positive := 32
);
port(
clk_i : in STD_LOGIC;
reset_i : in STD_LOGIC;
ipbus_i : in ipb_wbus;
ipbus_o : out ipb_rbus;
logic_reset_i : in STD_LOGIC; --! Reset logic signal. High for one
-- Signals to MAROC and ADC controller
adcConversionEnd_i : in std_logic;
adcConversionStart_o : out std_logic;
triggerNumber_o : out std_logic_vector(g_BUSWIDTH-1 downto 0);
timeStamp_o : out std_logic_vector(g_BUSWIDTH-1 downto 0);
clk_fast_i : in std_logic;
externalTrigger_a_i: in std_logic;
externalTrigger_o: out std_logic;
or1_a_i : in std_logic;
or2_a_i : in std_logic;
hold1_o : out std_logic;
hold2_o : out std_logic;
CTEST_O: out STD_LOGIC_VECTOR(5 downto 0) -- 4-bit R/2R DAC
);
end ipbusMarocTriggerGenerator;
architecture rtl of ipbusMarocTriggerGenerator is
signal s_internalTrigger_p : std_logic;
signal s_triggerSourceSelect : std_logic_vector(3 downto 0) := (others => '0');
signal s_hold1Delay , s_hold2Delay : std_logic_vector(4 downto 0);
signal s_ack: std_logic;
signal s_counter_reset , s_counter_reset_ipb : std_logic;
signal s_conversion_counter : std_logic_vector(g_BUSWIDTH-1 downto 0) := (others => '0');
signal s_timeStamp : std_logic_vector(g_BUSWIDTH-1 downto 0) := (others => '0');
signal s_adcConversionStart : std_logic; -- internal coopy of adcConversionStart_o
begin
-- read/write to registers storing data to/from MAROC and to control reg.
p_addressDecode: process(clk_i)
begin
if rising_edge(clk_i) then
case ipbus_i.ipb_addr(2 downto 0) is
when "000" => -- status register
ipbus_o.ipb_rdata(0) <= '0' ; --dummy for now
when "010" => -- hold1 delay
ipbus_o.ipb_rdata(s_hold1Delay'range) <= s_hold1Delay ;
ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto s_hold1Delay'high+1)
<= (others => '0');
when "011" => -- hold2 delay
ipbus_o.ipb_rdata(s_hold2Delay'range) <= s_hold2Delay ;
ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto s_hold2Delay'high+1)
<= (others => '0');
when "100" => -- triger source select
ipbus_o.ipb_rdata(s_triggerSourceSelect'range)
<= s_triggerSourceSelect ;
ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto s_triggerSourceSelect'high+1)
<= (others => '0');
when "101" =>
ipbus_o.ipb_rdata <= s_conversion_counter;
when "110" =>
ipbus_o.ipb_rdata <= s_conversion_counter;
when others => null;
end case;
-- Handle writing
if ipbus_i.ipb_strobe='1' and ipbus_i.ipb_write='1' then
case ipbus_i.ipb_addr(2 downto 0) is
when "010" => -- hold1 delay
s_hold1Delay <= ipbus_i.ipb_wdata(s_hold1Delay'range);
when "011" => -- hold2 delay
s_hold2Delay <= ipbus_i.ipb_wdata(s_hold2Delay'range);
when "100" => -- triger source select
s_triggerSourceSelect <=
ipbus_i.ipb_wdata(s_triggerSourceSelect'range);
when others => null;
end case;
end if;
s_ack <= ipbus_i.ipb_strobe and not s_ack;
end if;
end process; -- p_addressDecode
--! purpose: Controls state of s_internalTrigger
--! inputs : clk_i , ipbus_i
--! outputs:
p_internalTrigger: process (clk_i , ipbus_i )
begin -- process p_internalTrigger
if rising_edge(clk_i) then
if ipbus_i.ipb_strobe='1' and ipbus_i.ipb_write='1' and
ipbus_i.ipb_addr(2 downto 0)="001"
then
s_internalTrigger_p <= ipbus_i.ipb_wdata(0) ;
ctest_o <= ipbus_i.ipb_wdata(6 downto 1);
else
s_internalTrigger_p <= '0';
ctest_o <= ( others => '0');
end if;
end if;
end process p_internalTrigger;
--! purpose: Controls state of s_counter_reset
--! inputs : clk_i , ipbus_i
--! outputs:
p_resetCounter: process (clk_i , ipbus_i )
begin -- process p_resetCounter
if rising_edge(clk_i) then
if ipbus_i.ipb_strobe='1' and ipbus_i.ipb_write='1' and
ipbus_i.ipb_addr(2 downto 0)="000"
then
s_counter_reset_ipb <= ipbus_i.ipb_wdata(0) ;
else
s_counter_reset_ipb <= '0';
end if;
end if;
end process p_resetCounter;
ipbus_o.ipb_ack <= s_ack;
ipbus_o.ipb_err <= '0';
s_counter_reset <= s_counter_reset_ipb or logic_reset_i or reset_i;
-- Instantiate the TriggerGenerator
cmp_TriggerGeneratorInterface: entity work.marocTriggerGenerator
generic map (
g_BUSWIDTH => g_BUSWIDTH)
port map (
adcConversionEnd_i => adcConversionEnd_i,
clk_fast_i => clk_fast_i,
clk_sys_i => clk_i,
reset_i => s_counter_reset,
-- conversion_counter_o => s_conversion_counter,
externalTrigger_a_i => externalTrigger_a_i ,
internalTrigger_i => s_internalTrigger_p,
triggerSourceSelect_i=> s_triggerSourceSelect,
hold1Delay_i => s_hold1Delay,
hold2Delay_i => s_hold2Delay,
or1_a_i => or1_a_i,
or2_a_i => or2_a_i,
adcConversionStart_o => s_adcConversionStart,
externalTrigger_o => externalTrigger_o,
hold1_o => hold1_o,
hold2_o => hold2_o
);
adcConversionStart_o <= s_adcConversionStart;
--! For now just count conversions, not triggers....
triggerNumber_o <= s_conversion_counter;
timeStamp_o <= s_TimeStamp;
--! Instantiate a counter for ADC conversions.
cmp_triggerCounter : entity work.counterWithReset
generic map (
g_COUNTER_WIDTH => g_BUSWIDTH)
port map (
clock_i => clk_i,
reset_i => s_counter_reset,
enable_i => s_adcConversionStart,
result_o => s_conversion_counter );
--! Instantiate a counter for ADC conversions.
cmp_timeStamp : entity work.counterWithReset
generic map (
g_COUNTER_WIDTH => g_BUSWIDTH)
port map (
clock_i => clk_i,
reset_i => s_counter_reset,
enable_i => '1',
result_o => s_timeStamp );
end rtl;
--=============================================================================
--! @file ipbusMarocTriggerGenerator_rtl.vhd
--=============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.ALL;
--! Package containing type definition and constants for MAROC interface
use work.maroc.ALL;
--! Package containing type definition and constants for IPBUS
use work.ipbus.all;
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- unit name: ipbusMarocTriggerGenerator_rtl (ipbusMarocTriggerGenerator / rtl)
--
--! @brief Interfaces between IPBus and Maroc TriggerGenerator\n
--! Addresses ( with respect to base address)\n
--! 0x00 : Status register. Writing 1 to bit-0 resets trigger and timestamp counters\n
--! 0x01 : Manual trigger register. Write 1 to bit 0 to cause internal trigger\n
--! 0x02 : HOLD1 delay. 5 bits, 5ns ticks\n
--! 0x03 : HOLD2 delay. 5 bits, 5ns ticks\n
--! 0x04 : Trigger select register. 4 bits.\n
--! bit 0 = internal-trigger , 1 = external-trigger\n, bit2 = or1 , bit3=or2\n
--! 0x05 : Conversion counter - read = number of ADC conversions since last reset.\n
--! 0x06 : Timestamp - read = number of clock cycles since last reset
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 21\1\2012
--
--! @version v0.1
--
--! @details
--!
--!
--! <b>Dependencies:</b>\n
--! Instantiates marocTriggerGenerator
--!
--! <b>References:</b>\n
--! referenced by slaves \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 9/March/2012 DGC Adding trigger counter and timestamp\n
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
---------------------------------------------------------------------------------
--
entity ipbusMarocTriggerGenerator is
generic(
g_BUSWIDTH : positive := 32
);
port(
clk_i : in STD_LOGIC;
reset_i : in STD_LOGIC;
ipbus_i : in ipb_wbus;
ipbus_o : out ipb_rbus;
logic_reset_i : in STD_LOGIC; --! Reset logic signal. High for one
-- Signals to MAROC and ADC controller
adcConversionEnd_i : in std_logic;
adcConversionStart_o : out std_logic;
triggerNumber_o : out std_logic_vector(g_BUSWIDTH-1 downto 0);
timeStamp_o : out std_logic_vector(g_BUSWIDTH-1 downto 0);
clk_fast_i : in std_logic;
externalTrigger_a_i: in std_logic;
externalTrigger_o: out std_logic;
or1_a_i : in std_logic;
or2_a_i : in std_logic;
hold1_o : out std_logic;
hold2_o : out std_logic;
CTEST_O: out STD_LOGIC_VECTOR(3 downto 0) -- 4-bit R/2R DAC
);
end ipbusMarocTriggerGenerator;
architecture rtl of ipbusMarocTriggerGenerator is
signal s_internalTrigger_p : std_logic;
signal s_triggerSourceSelect : std_logic_vector(3 downto 0) := (others => '0');
signal s_hold1Delay , s_hold2Delay : std_logic_vector(4 downto 0);
signal s_ack: std_logic;
signal s_counter_reset , s_counter_reset_ipb : std_logic;
signal s_conversion_counter : std_logic_vector(g_BUSWIDTH-1 downto 0) := (others => '0');
signal s_timeStamp : std_logic_vector(g_BUSWIDTH-1 downto 0) := (others => '0');
signal s_adcConversionStart : std_logic; -- internal coopy of adcConversionStart_o
begin
-- read/write to registers storing data to/from MAROC and to control reg.
p_addressDecode: process(clk_i)
begin
if rising_edge(clk_i) then
case ipbus_i.ipb_addr(2 downto 0) is
when "000" => -- status register
ipbus_o.ipb_rdata(0) <= '0' ; --dummy for now
when "010" => -- hold1 delay
ipbus_o.ipb_rdata(s_hold1Delay'range) <= s_hold1Delay ;
ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto s_hold1Delay'high+1)
<= (others => '0');
when "011" => -- hold2 delay
ipbus_o.ipb_rdata(s_hold2Delay'range) <= s_hold2Delay ;
ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto s_hold2Delay'high+1)
<= (others => '0');
when "100" => -- triger source select
ipbus_o.ipb_rdata(s_triggerSourceSelect'range)
<= s_triggerSourceSelect ;
ipbus_o.ipb_rdata(g_BUSWIDTH-1 downto s_triggerSourceSelect'high+1)
<= (others => '0');
when "101" =>
ipbus_o.ipb_rdata <= s_conversion_counter;
when "110" =>
ipbus_o.ipb_rdata <= s_conversion_counter;
when others => null;
end case;
-- Handle writing
if ipbus_i.ipb_strobe='1' and ipbus_i.ipb_write='1' then
case ipbus_i.ipb_addr(2 downto 0) is
when "010" => -- hold1 delay
s_hold1Delay <= ipbus_i.ipb_wdata(s_hold1Delay'range);
when "011" => -- hold2 delay
s_hold2Delay <= ipbus_i.ipb_wdata(s_hold2Delay'range);
when "100" => -- triger source select
s_triggerSourceSelect <=
ipbus_i.ipb_wdata(s_triggerSourceSelect'range);
when others => null;
end case;
end if;
s_ack <= ipbus_i.ipb_strobe and not s_ack;
end if;
end process; -- p_addressDecode
--! purpose: Controls state of s_internalTrigger
--! inputs : clk_i , ipbus_i
--! outputs:
p_internalTrigger: process (clk_i , ipbus_i )
begin -- process p_internalTrigger
if rising_edge(clk_i) then
if ipbus_i.ipb_strobe='1' and ipbus_i.ipb_write='1' and
ipbus_i.ipb_addr(2 downto 0)="001"
then
s_internalTrigger_p <= ipbus_i.ipb_wdata(0) ;
ctest_o <= ipbus_i.ipb_wdata(4 downto 1);
else
s_internalTrigger_p <= '0';
ctest_o <= ( others => '0');
end if;
end if;
end process p_internalTrigger;
--! purpose: Controls state of s_counter_reset
--! inputs : clk_i , ipbus_i
--! outputs:
p_resetCounter: process (clk_i , ipbus_i )
begin -- process p_resetCounter
if rising_edge(clk_i) then
if ipbus_i.ipb_strobe='1' and ipbus_i.ipb_write='1' and
ipbus_i.ipb_addr(2 downto 0)="000"
then
s_counter_reset_ipb <= ipbus_i.ipb_wdata(0) ;
else
s_counter_reset_ipb <= '0';
end if;
end if;
end process p_resetCounter;
ipbus_o.ipb_ack <= s_ack;
ipbus_o.ipb_err <= '0';
s_counter_reset <= s_counter_reset_ipb or logic_reset_i or reset_i;
-- Instantiate the TriggerGenerator
cmp_TriggerGeneratorInterface: entity work.marocTriggerGenerator
generic map (
g_BUSWIDTH => g_BUSWIDTH)
port map (
adcConversionEnd_i => adcConversionEnd_i,
clk_fast_i => clk_fast_i,
clk_sys_i => clk_i,
reset_i => s_counter_reset,
-- conversion_counter_o => s_conversion_counter,
externalTrigger_a_i => externalTrigger_a_i ,
internalTrigger_i => s_internalTrigger_p,
triggerSourceSelect_i=> s_triggerSourceSelect,
hold1Delay_i => s_hold1Delay,
hold2Delay_i => s_hold2Delay,
or1_a_i => or1_a_i,
or2_a_i => or2_a_i,
adcConversionStart_o => s_adcConversionStart,
externalTrigger_o => externalTrigger_o,
hold1_o => hold1_o,
hold2_o => hold2_o
);
adcConversionStart_o <= s_adcConversionStart;
--! For now just count conversions, not triggers....
triggerNumber_o <= s_conversion_counter;
timeStamp_o <= s_TimeStamp;
--! Instantiate a counter for ADC conversions.
cmp_triggerCounter : entity work.counterWithReset
generic map (
g_COUNTER_WIDTH => g_BUSWIDTH)
port map (
clock_i => clk_i,
reset_i => s_counter_reset,
enable_i => s_adcConversionStart,
result_o => s_conversion_counter );
--! Instantiate a counter for ADC conversions.
cmp_timeStamp : entity work.counterWithReset
generic map (
g_COUNTER_WIDTH => g_BUSWIDTH)
port map (
clock_i => clk_i,
reset_i => s_counter_reset,
enable_i => '1',
result_o => s_timeStamp );
end rtl;
--! @file
--
--! @brief Address decode logic for ipbus fabric. Given an address it returns which slave is addressed.
--
--! @details
--! This file has been AUTOGENERATED from the address table - do not hand edit
--!
--! We assume the synthesis tool is clever enough to recognise
--! exclusive conditions in the if statement.
--
--! @author Dave Newbold
--! @date February 2011
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
use work.ipbus.all;
package ipbus_addr_decode is
function ipbus_addr_sel(signal addr : in std_logic_vector(31 downto 0)) return integer;
end ipbus_addr_decode;
package body ipbus_addr_decode is
function ipbus_addr_sel(signal addr : in std_logic_vector(31 downto 0)) return integer is
variable sel : integer;
begin
if std_match(addr, "-----------------000--000----000") then
sel := 0; -- firmwareid / base 00000000 / mask 00000000
elsif std_match(addr, "-----------------000--000----001") then
sel := 1; -- gpio / base 00000001 / mask 00000000
elsif std_match(addr, "-----------------000--000----010") then
sel := 2; -- select / base 00000002 / mask 00000000
elsif std_match(addr, "-----------------000--000----011") then
sel := 3; -- mask / base 00000003 / mask 00000000
elsif std_match(addr, "-----------------000--000----100") then
sel := 4; -- reset / base 00000004 / mask 00000000
elsif std_match(addr, "-----------------000--001-------") then
sel := 5; -- scshiftreg / base 00000080 / mask 0000007f
elsif std_match(addr, "-----------------000--010-------") then
sel := 6; -- rshiftreg / base 00000100 / mask 0000007f
elsif std_match(addr, "-----------------111--0---------") then
sel := 7; -- triggerctrl / base 00007000 / mask 00000fff
elsif std_match(addr, "-----------------111--1---------") then
sel := 8; -- triggerdata / base 00007200 / mask 00000fff
elsif std_match(addr, "-----------------001--1---------") then
sel := 10; -- adcctrl0 / base 00001200 / mask 00000fff
elsif std_match(addr, "-----------------001--0---------") then
sel := 11; -- adcdata0 / base 00001000 / mask 00000fff
elsif std_match(addr, "-----------------010--1---------") then
sel := 12; -- adcctrl1 / base 00002200 / mask 00000fff
elsif std_match(addr, "-----------------010--0---------") then
sel := 13; -- adcdata1 / base 00002000 / mask 00000fff
elsif std_match(addr, "-----------------011--1---------") then
sel := 14; -- adcctrl2 / base 00003200 / mask 00000fff
elsif std_match(addr, "-----------------011--0---------") then
sel := 15; -- adcdata2 / base 00003000 / mask 00000fff
elsif std_match(addr, "-----------------100--1---------") then
sel := 16; -- adcctrl3 / base 00004200 / mask 00000fff
elsif std_match(addr, "-----------------100--0---------") then
sel := 17; -- adcdata3 / base 00004000 / mask 00000fff
elsif std_match(addr, "-----------------101--1---------") then
sel := 18; -- adcctrl4 / base 00005200 / mask 00000fff
elsif std_match(addr, "-----------------101--0---------") then
sel := 19; -- adcdata4 / base 00005000 / mask 00000fff
elsif std_match(addr, "-----------------110------------") then
sel := 9; -- hostemac / base 00006000 / mask 00000fff
else
sel := 99;
end if;
return sel;
end ipbus_addr_sel;
end ipbus_addr_decode;
--@file ipbus_pulseout_datain
--
-- @brief
-- When written to produces a single cycle pulse on one or more bits, as
-- dictated by q_out.
-- When read from returns the value of d_in
--
--
-- David Cussans, May 2013
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
entity ipbus_pulseout_datain is
generic(g_BUSWIDTH : natural := 32);
port(
clk: in STD_LOGIC;
ipbus_in: in ipb_wbus;
ipbus_out: out ipb_rbus;
q_out: out STD_LOGIC_VECTOR(g_BUSWIDTH-1 downto 0);
d_in: in STD_LOGIC_VECTOR(g_BUSWIDTH-1 downto 0)
);
end ipbus_pulseout_datain;
architecture rtl of ipbus_pulseout_datain is
signal reg: std_logic_vector(g_BUSWIDTH-1 downto 0);
signal ack: std_logic;
signal s_datain : std_logic_vector(d_in'range) := (others => '0');
begin
process(clk)
begin
if rising_edge(clk) then
reg <= ( others => '0');
if ipbus_in.ipb_strobe='1' and ipbus_in.ipb_write='1' then
reg <= ipbus_in.ipb_wdata; -- register is set high for one cycle
-- then returns low.
end if;
-- Register input data
s_datain <= d_in;
ipbus_out.ipb_rdata <= s_datain;
ack <= ipbus_in.ipb_strobe and not ack;
end if;
end process;
ipbus_out.ipb_ack <= ack;
ipbus_out.ipb_err <= '0';
q_out <= reg;
end rtl;
-- Produces a single cycle pulse on one or more bits. Write only.
--
-- generic addr_width defines number of significant address bits
--
-- David Cussans, December 2012
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
entity ipbus_pulser is
generic(g_ipbus_data_width : natural := 32);
port(
clk: in STD_LOGIC;
ipbus_in: in ipb_wbus;
ipbus_out: out ipb_rbus;
q: out STD_LOGIC_VECTOR(g_ipbus_data_width-1 downto 0)
);
end ipbus_pulser;
architecture rtl of ipbus_pulser is
signal reg: std_logic_vector(g_ipbus_data_width-1 downto 0);
signal ack: std_logic;
begin
process(clk)
begin
if rising_edge(clk) then
reg <= ( others => '0');
if ipbus_in.ipb_strobe='1' and ipbus_in.ipb_write='1' then
reg <= ipbus_in.ipb_wdata; -- register is set high for one cycle
-- then returns low.
end if;
ipbus_out.ipb_rdata <= reg;
ack <= ipbus_in.ipb_strobe and not ack;
end if;
end process;
ipbus_out.ipb_ack <= ack;
ipbus_out.ipb_err <= '0';
q <= reg;
end rtl;
-- Generic ipbus slave config register for testing
--
-- generic addr_width defines number of significant address bits
--
-- We use one cycle of read / write latency to ease timing (probably not necessary)
-- The q outputs change immediately on write (no latency).
--
-- Dave Newbold, March 2011
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use work.ipbus.all;
entity ipbus_reg is
generic(addr_width : natural := 0);
port(
clk: in STD_LOGIC;
reset: in STD_LOGIC;
ipbus_in: in ipb_wbus;
ipbus_out: out ipb_rbus;
q: out STD_LOGIC_VECTOR(2**addr_width*32-1 downto 0)
);
end ipbus_reg;
architecture rtl of ipbus_reg is
type reg_array is array(2**addr_width-1 downto 0) of std_logic_vector(31 downto 0);
signal reg: reg_array;
signal sel: integer;
signal ack: std_logic;
begin
sel <= to_integer(unsigned(ipbus_in.ipb_addr(addr_width downto 0))) when addr_width>0 else 0;
process(clk)
begin
if rising_edge(clk) then
if reset='1' then
reg <= (others=>(others=>'0'));
elsif ipbus_in.ipb_strobe='1' and ipbus_in.ipb_write='1' then
reg(sel) <= ipbus_in.ipb_wdata;
end if;
ipbus_out.ipb_rdata <= reg(sel);
ack <= ipbus_in.ipb_strobe and not ack;
end if;
end process;
ipbus_out.ipb_ack <= ack;
ipbus_out.ipb_err <= '0';
q_gen: for i in 2**addr_width-1 downto 0 generate
q((i+1)*32-1 downto i*32) <= reg(i);
end generate;
end rtl;
-- Version register, returns a fixed value
--
-- To be replaced by a more coherent versioning mechanism later
--
-- Dave Newbold, August 2011
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ipbus.all;
entity ipbus_ver is
port(
ipbus_in: in ipb_wbus;
ipbus_out: out ipb_rbus
);
end ipbus_ver;
architecture rtl of ipbus_ver is
begin
ipbus_out.ipb_rdata <= X"a618" & X"1008"; -- Lower 16b are ipbus firmware build ID (temporary arrangement).
ipbus_out.ipb_ack <= ipbus_in.ipb_strobe;
ipbus_out.ipb_err <= '0';
end rtl;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
--=============================================================================
--! @file maroc_pkg.vhd
--=============================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.std_logic_1164.ALL;
-------------------------------------------------------------------------------
-- --
-- University of Bristol, High Energy Physics Group.
-- --
------------------------------------------------------------------------------- --
-- unit name: maroc
--
--! @brief User defined types for MAROC readout code.
--
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
--! @date 23\12\2011
--
--! @version v0.1
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! None
--!
--! <b>References:</b>\n
--! referenced by marocShiftReg \n
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! <date> <initials> <log>\n
--! <extended description>
-------------------------------------------------------------------------------
--! @todo <next thing to do> \n
--! <another thing to do> \n
--
---------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package maroc is
constant c_NMAROC : integer := 1; -- -! Number of MAROC chips
constant c_NUMADC : integer := 64; --! number of ADCs in a MAROC
constant c_NUMADCBITS : integer := 12; --! Number of bits for each ADC
constant c_NWORDS : integer := 26; --! number of 32-bit words carrying data to/from MAROC shift register
constant c_BUSWIDTH : integer := 32; --! Width of IPBus bus
constant c_NBITS : integer := 829; -- ! Number of bits to shift out
--! Define a type to pass data to/from MAROC shift register interface.
-- type t_wordarray is array (c_NWORDS-1 downto 0) of std_logic_vector(c_BUSWIDTH-1 downto 0);
type t_wordarray is array (31 downto 0) of std_logic_vector(c_BUSWIDTH-1 downto 0);
type t_timestamp_array is array (0 to c_NMAROC-1) of std_logic_vector(c_BUSWIDTH-1 downto 0) ;
type t_dual_timestamp_array is array (0 to (2*c_NMAROC)-1) of std_logic_vector(c_BUSWIDTH-1 downto 0);
type t_integer_array is array (natural range <>) of integer; -- ! Used to pass clock domain values into fineTimestap
type t_bool_array is array (natural range <>) of boolean; -- ! Used to pass single/dual ISERDES flag to fineTimestamp
type maroc_input_signals is record -- Signals going to MAROC
CK_40M: STD_LOGIC;
HOLD2_2V5: STD_LOGIC;
HOLD1_2V5: STD_LOGIC;
EN_OTAQ_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
CTEST_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
START_ADC_2V5_N: STD_LOGIC;
RST_ADC_2V5_N: STD_LOGIC;
RST_SC_2V5_N: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
D_SC_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
RST_R_2V5_N: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
D_R_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
CK_R_2V5: STD_LOGIC;
CK_SC_2V5: STD_LOGIC;
end record;
type maroc_output_signals is record -- Signals going from MAROC
CK_40M_OUT_2V5: STD_LOGIC;
OR1_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
OR0_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
ADC_DAV_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
OUT_ADC_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
Q_SC_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
Q_R_2V5: STD_LOGIC_VECTOR(c_NMAROC-1 downto 0);
end record;
end maroc;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
files = ["pc049a_top.vhd", "pc049a_top.ucf", "spec_reset_gen.vhd", "ExpansionIO_rtl.vhd"]
modules = { "local" : ["../../../"] }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment