diff --git a/simulation/UVVMtests/modelsim.ini b/simulation/UVVMtests/modelsim.ini index 766d52c59e8abb7335759eee5f050ff170fd7b1f..784bf6df90da1fc692e229e9d42c28fac8027ac5 100644 --- a/simulation/UVVMtests/modelsim.ini +++ b/simulation/UVVMtests/modelsim.ini @@ -60,29 +60,6 @@ others = $MODEL_TECH/../modelsim.ini ; ; AutoLibMapping = 0 -secureip = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/secureip -unisim = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/unisim -xpm = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/xpm -unimacro = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/unimacro -unifast = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/unifast -unisims_ver = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/unisims_ver -unimacro_ver = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/unimacro_ver -unifast_ver = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/unifast_ver -simprims_ver = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/xilinx_simlib/simprims_ver -uvvm_bitvis_vip_scoreboard = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_scoreboard/sim/bitvis_vip_scoreboard -uvvm_util = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/uvvm_util/sim/uvvm_util -uvvm_vvc_framework = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/uvvm_vvc_framework/sim/uvvm_vvc_framework -bitvis_vip_scoreboard = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_scoreboard/sim/bitvis_vip_scoreboard -bitvis_vip_avalon_mm = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_avalon_mm/sim/bitvis_vip_avalon_mm -bitvis_vip_axilite = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_axilite/sim/bitvis_vip_axilite -bitvis_vip_axistream = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_axistream/sim/bitvis_vip_axistream -bitvis_vip_clock_generator = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_clock_generator/sim/bitvis_vip_clock_generator -bitvis_vip_gpio = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_gpio/sim/bitvis_vip_gpio -bitvis_vip_i2c = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_i2c/sim/bitvis_vip_i2c -bitvis_vip_sbi = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_sbi/sim/bitvis_vip_sbi -bitvis_vip_spi = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_spi/sim/bitvis_vip_spi -bitvis_vip_uart = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_uart/sim/bitvis_vip_uart -bitvis_vip_error_injection = /home/franss/felix/firmware/simulation/UVVMtests/../..//simulation/UVVM/bitvis_vip_error_injection/sim/bitvis_vip_error_injection [DefineOptionset] ; Define optionset entries for the various compilers, vmake, and vsim. ; These option sets can be used with the "-optionset <optionsetname>" syntax. diff --git a/simulation/UVVMtests/tb/FULLModeToHost_tb.vhd b/simulation/UVVMtests/tb/FULLModeToHost_tb.vhd index 67fdc8124089f1038ecbd3779a6092559f967359..6975a4f7c9b1f9ae1d5ef820d13b59eb31dcc029 100644 --- a/simulation/UVVMtests/tb/FULLModeToHost_tb.vhd +++ b/simulation/UVVMtests/tb/FULLModeToHost_tb.vhd @@ -137,6 +137,9 @@ architecture arch of FULLModeToHost_tb is trigger_type => x"0000", data_rdy => '0' ); + signal CRTOHOST_DMA_DESCRIPTOR_WREN : std_logic_vector(0 downto 0); + signal CRTOHOST_DMA_DESCRIPTOR_DESCR : std_logic_vector(2 downto 0); + signal CRTOHOST_DMA_DESCRIPTOR_AXIS_ID : std_logic_vector(10 downto 0); begin LinkAligned <= (others => '0'); @@ -180,6 +183,53 @@ begin register_map_40_control.FE_EMU_CONFIG.WRDATA <= (others => '0'); register_map_40_control.GBT_TOHOST_FANOUT.SEL <= (others => '1'); register_map_control_appreg_clk <= register_map_40_control; + register_map_40_control.CRTOHOST_DMA_DESCRIPTOR_1.WR_EN <= CRTOHOST_DMA_DESCRIPTOR_WREN; + register_map_40_control.CRTOHOST_DMA_DESCRIPTOR_1.DESCR <= CRTOHOST_DMA_DESCRIPTOR_DESCR; + register_map_40_control.CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID <= CRTOHOST_DMA_DESCRIPTOR_AXIS_ID; + associate_epath_id: process + begin + wait until falling_edge(reset); + wait for C_CLK40_PERIOD*10; + CRTOHOST_DMA_DESCRIPTOR_WREN <= "1"; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "00000000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "000"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "00001000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "001"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "00010000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "010"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "00011000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "011"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "00100000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "000"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "00101000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "001"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "00110000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "010"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "00111000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "011"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "01000000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "000"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "01001000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "001"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "01010000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "010"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID <= "01011000000"; + CRTOHOST_DMA_DESCRIPTOR_DESCR <= "011"; + wait for C_CLK40_PERIOD; + CRTOHOST_DMA_DESCRIPTOR_WREN <= "0"; + wait; + end process; g_NogbtEmu: if FIRMWARE_MODE /= FIRMWARE_MODE_GBT generate LinkAligned_FOSEL <= LinkAligned(((GBT_NUM/ENDPOINTS)*(pcie_endpoint+1))-1 downto (GBT_NUM/ENDPOINTS)*pcie_endpoint); diff --git a/sources/CRToHost/CRToHost.vhd b/sources/CRToHost/CRToHost.vhd index 00d98f60eea4e08ae847fa8486aef17e8638c668..82e051eb883fbb25a9aa5688a006a0350b588631 100644 --- a/sources/CRToHost/CRToHost.vhd +++ b/sources/CRToHost/CRToHost.vhd @@ -122,6 +122,7 @@ signal ch_prog_full: std_logic_vector(23 downto 0); signal ch_prog_full_40: std_logic_vector(23 downto 0); signal ch_prog_full_latched: std_logic_vector(23 downto 0); signal toHostFifo_wr_data_count_40: std_logic_vector(11 downto 0); +signal EpathIDs: array_11b(0 to LINK_NUM); begin g_toHostFifo_wr_clk_160: if FIRMWARE_MODE = FIRMWARE_MODE_GBT generate @@ -205,6 +206,7 @@ port map( fmchHighThreshCrossed => register_map_xoff_monitor.XOFF_FM_HIGH_THRESH.CROSS_LATCHED(channel+24), fmchHighThreshCrossedLatch => register_map_xoff_monitor.XOFF_FM_HIGH_THRESH.CROSSED(channel), fmchLowThreshCrossed => register_map_xoff_monitor.XOFF_FM_LOW_THRESH_CROSSED(channel), + AXIS_ID_out => EpathIDs(channel+1), ch_prog_full_out => ch_prog_full(channel) ); @@ -258,6 +260,7 @@ port map( fmchHighThreshCrossed => open, fmchHighThreshCrossedLatch => open, fmchLowThreshCrossed => open, + AXIS_ID_out => EpathIDs(0), ch_prog_full_out => open ); @@ -274,98 +277,78 @@ sync_cr_rst: xpm_cdc_sync_rst src_rst => cr_rst ); ---Split the data from the channels and divide evenly among different Wupper Fifos. -g_divide_over_wupperFifos: for i in 0 to NUMBER_OF_DESCRIPTORS-2 generate - function GBT_NUM_PER_FIFO return integer is - begin - if i = 0 then - return (LINK_NUM/(NUMBER_OF_DESCRIPTORS-1)) + 1; --Include data from AUX channels (TTCToHost/BusyToHost) into the first fifo. - else - return (LINK_NUM/(NUMBER_OF_DESCRIPTORS-1)); - end if; - end function; - function CHANNEL_INDEX return integer is - begin - if i = 0 then - return (LINK_NUM/(NUMBER_OF_DESCRIPTORS-1))*i; - else - return (LINK_NUM/(NUMBER_OF_DESCRIPTORS-1))*i+1; - end if; - - end function; - signal THtransferENA: std_logic; - signal chFifo_hasBlock_array_per_fifo: std_logic_vector(GBT_NUM_PER_FIFO-1 downto 0); - signal chFifo_re_array_per_fifo: std_logic_vector(GBT_NUM_PER_FIFO-1 downto 0); - signal thch_sel, thMUXsel, thMUXsel_s : integer range 0 to GBT_NUM_PER_FIFO-1; - signal thMUXdin_rdy : std_logic := '0'; - signal chFifo_dout_array_per_fifo: slv_array(0 to GBT_NUM_PER_FIFO-1); + +mux_block: block + + signal thch_sel, thMUXsel, thMUXsel_s : integer range 0 to LINK_NUM; + signal thMUXdin_valid : std_logic := '0'; + signal mux_data_out : std_logic_vector(DATA_WIDTH-1 downto 0); + signal mux_data_out_valid : std_logic; + signal descriptor_select: integer range 0 to NUMBER_OF_DESCRIPTORS - 2; + begin - chFifo_dout_array_per_fifo <= chFifo_dout_array(CHANNEL_INDEX to CHANNEL_INDEX+GBT_NUM_PER_FIFO-1); - chFifo_re_array(CHANNEL_INDEX+GBT_NUM_PER_FIFO-1 downto CHANNEL_INDEX) <=chFifo_re_array_per_fifo; - chFifo_hasBlock_array_per_fifo <= chFifo_hasBlock_array(CHANNEL_INDEX+GBT_NUM_PER_FIFO-1 downto CHANNEL_INDEX); + + + + ------------------------------------------------------------ -- writing to the cr OUT FIFO / reading from channel fifos ------------------------------------------------------------ THPCIeM: entity work.CRToHostPCIeManager generic map( - GBT_NUM => GBT_NUM_PER_FIFO, + GBT_NUM => LINK_NUM + 1, DATA_WIDTH => DATA_WIDTH, - BLOCKSIZE => BLOCKSIZE) + BLOCKSIZE => BLOCKSIZE, + NUMBER_OF_DESCRIPTORS_TOHOST => NUMBER_OF_DESCRIPTORS-1) port map( - clk => toHostFifo_wr_clk_s, - rst => cr_rst_sync, -- reset is deasserted after fifo flush! - thch_rdy_array => chFifo_hasBlock_array_per_fifo, -- in, 'block_ready' flags from GBTdms - PCIe_ena => THtransferENA, -- in, '1' when crOUTfifo is ready to accept 1 block (not fifo pfull) - thch_sel => thch_sel, -- out, data mux select - thch_re_array => chFifo_re_array_per_fifo,-- out, enables reading from single fmchannel at a time - thch_re => open -- out, re 1 bit + clk => toHostFifo_wr_clk_s, + clk40 => clk40, + rst => cr_rst_sync, -- reset is deasserted after fifo flush! + thch_hasBlock_array => chFifo_hasBlock_array, -- in, 'block_ready' flags from GBTdms + PCIe_prog_full_array => toHostFifo_prog_full, + thch_sel => thch_sel, -- out, data mux select + thch_re_array => chFifo_re_array,-- out, enables reading from single fmchannel at a time + output_select => descriptor_select, + EpathIDs => EpathIDs, + CRTOHOST_DMA_DESCRIPTOR_WR_EN => register_map_control.CRTOHOST_DMA_DESCRIPTOR_1.WR_EN, + CRTOHOST_DMA_DESCRIPTOR_DESCR => register_map_control.CRTOHOST_DMA_DESCRIPTOR_1.DESCR, + CRTOHOST_DMA_DESCRIPTOR_DESCR_READ => register_map_crtohost_monitor.CRTOHOST_DMA_DESCRIPTOR_2.DESCR_READ, + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID => register_map_control.CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID ); -- - process(toHostFifo_wr_clk_s, cr_rst_sync) -- write to crOUTfifo 2 clk pipeline before data mux, aligned with data + process(toHostFifo_wr_clk_s) -- write to crOUTfifo 2 clk pipeline before data mux, aligned with data begin - if cr_rst_sync = '1' then - thMUXsel_s <= GBT_NUM_PER_FIFO-1; - thMUXsel <= GBT_NUM_PER_FIFO-1; - elsif rising_edge(toHostFifo_wr_clk_s) then + if rising_edge(toHostFifo_wr_clk_s) then thMUXsel_s <= thch_sel; thMUXsel <= thMUXsel_s; end if; end process; - thMUXdin_rdy <= or_reduce(chFifo_dvalid_array(CHANNEL_INDEX+GBT_NUM_PER_FIFO-1 downto CHANNEL_INDEX)); + thMUXdin_valid <= or_reduce(chFifo_dvalid_array(LINK_NUM downto 0)); -- dataMUXn: entity work.MUXn (Behavioral) - generic map(N=>GBT_NUM_PER_FIFO, DATA_WIDTH=>DATA_WIDTH) + generic map(N=>LINK_NUM+1, DATA_WIDTH=>DATA_WIDTH) port map( - clk => toHostFifo_wr_clk_s, - data => chFifo_dout_array_per_fifo, - data_rdy => thMUXdin_rdy, - sel => thMUXsel, - data_out => toHostFifo_din(i), - data_out_rdy => toHostFifo_wr_en(i) + clk => toHostFifo_wr_clk_s, + data => chFifo_dout_array, + data_valid => thMUXdin_valid, + sel => thMUXsel, + data_out => mux_data_out, + data_out_valid => mux_data_out_valid ); - -- - ------------------------------------------------------------ - -- to Host output fifo - ------------------------------------------------------------ - - process(toHostFifo_wr_clk_s, cr_rst_sync) -- - begin - if cr_rst_sync = '1' then - THtransferENA <= '0'; - elsif rising_edge(toHostFifo_wr_clk_s) then - if toHostFifo_prog_full(i) = '1' then -- hardcoded hysteresis on pfull flag: 4060/3830 (out of 4096) - THtransferENA <= '0'; - else -- - THtransferENA <= '1'; - end if; - end if; - end process; + + toHostFifo_din <= (others => mux_data_out); + toHostFifo_wr_en_proc: process(mux_data_out_valid, descriptor_select) + begin + toHostFifo_wr_en <= (others => '0'); + toHostFifo_wr_en(descriptor_select) <= mux_data_out_valid; + end process; + -end generate; +end block; toHostFifo_wr_clk <= toHostFifo_wr_clk_s; toHostFifo_rst <= cr_fifo_flush; diff --git a/sources/CRToHost/CRToHostPCIeManager.vhd b/sources/CRToHost/CRToHostPCIeManager.vhd index 97a2f86574e9d58e28faa1edf9b1c05f512bbb14..66e63682d217bd9e0abd463544baeef55df2de88 100644 --- a/sources/CRToHost/CRToHostPCIeManager.vhd +++ b/sources/CRToHost/CRToHostPCIeManager.vhd @@ -19,159 +19,297 @@ --! See the License for the specific language governing permissions and --! limitations under the License. ----------------------------------------------------------------------------------- ---! Company: EDAQ WIS. ---! Engineer: juna ---! ---! Create Date: 14/09/2016 ---! Module Name: thfmPCIeManager ---! Project Name: FELIX ----------------------------------------------------------------------------------- ---! Use standard library -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use ieee.std_logic_unsigned.all;-- @suppress "Deprecated package" -use work.all; -use work.centralRouter_package.all; -library xpm; -use xpm.vcomponents.all; - ---! reading from Downstream thchs order -entity CRToHostPCIeManager is -Generic ( - GBT_NUM : integer := 1; - DATA_WIDTH: integer; - BLOCKSIZE : integer := 1024 - ); -Port ( - clk : in std_logic; - rst : in std_logic; - thch_rdy_array : in std_logic_vector ((GBT_NUM-1) downto 0); -- complete blocks are ready to be read - PCIe_ena : in std_logic; -- '1' when PCIe is ready to accept data (no data jam) - --- - thch_sel : out integer range 0 to GBT_NUM-1; -- selecting a channel to read from (for writing to crOUTfifo) - thch_re_array : out std_logic_vector ((GBT_NUM-1) downto 0); - thch_re : out std_logic - ); -end CRToHostPCIeManager; - -architecture Behavioral of CRToHostPCIeManager is - -signal FMCHcount : std_logic_vector(5 downto 0) := (others => '0'); -- counts to maximum possible channel number (0 to 31) (double clocks) -constant NUMBER_OF_256_PER_BLOCK : integer := BLOCKSIZE / 32; -signal BLOCKcount : integer range 0 to (NUMBER_OF_256_PER_BLOCK*2)-1:=0; -- std_logic_vector(5 downto 0) := (others => '0'); -- counts 256-bit words in block (0 to 31) - -signal thch_rdy_array_full : std_logic_vector(GBT_NUM-1 downto 0) := (others => '0'); -signal thch_reN_array : std_logic_vector(GBT_NUM-1 downto 0); -signal thch_rdy, block_done, thch_rdy_1clk, thch_rdy_s, re_s, countENA : std_logic; -signal rst_state : std_logic := '1'; -signal thch_sel_int : integer range 0 to GBT_NUM; - -begin - ------------------------------------------------------ --- reset state ------------------------------------------------------ -sync_rst : xpm_cdc_sync_rst - generic map ( - DEST_SYNC_FF => 2, - INIT => 1, - INIT_SYNC_FF => 0, - SIM_ASSERT_CHK => 0 - ) - port map ( - dest_rst => rst_state, - dest_clk => clk, - src_rst => rst - ); - - ------------------------------------------------------ --- FMCH COUNTER 3 bit (31 CHs maximum) ------------------------------------------------------ -FMCH_counter: process(clk, rst_state) -begin - if rst_state = '1' then - FMCHcount <= (others => '0'); - elsif clk'event and clk = '1' then - if countENA = '1' then - if FMCHcount = (std_logic_vector(to_unsigned((GBT_NUM-1), 5)) & '1') then - FMCHcount <= (others => '0'); - else - FMCHcount <= FMCHcount + 1; - end if; - else --(countENA = '0') - -- FMCHcount holds its value on the next clock - end if; - end if; -end process; --- -thch_sel <= to_integer(unsigned(FMCHcount(5 downto 1))); -thch_sel_int <= to_integer(unsigned(FMCHcount(5 downto 1))); --- -thch_rdy_array_full((GBT_NUM-1) downto 0) <= thch_rdy_array; -- GBT_NUM bit --- -thch_rdy <= thch_rdy_array_full(to_integer(unsigned(FMCHcount(5 downto 1)))); - -thch_rdy_s <= thch_rdy and (not FMCHcount(0)) and (not rst_state) and PCIe_ena; -thch_rdy_pulse: entity work.pulse_pdxx_pwxx -generic map( - pd=>0, - pw=>1 -) -port map( - clk => clk, - trigger => thch_rdy_s, - pulseout => thch_rdy_1clk -); - --- -g_256: if DATA_WIDTH = 256 generate -block_done <= '1' when (BLOCKcount = NUMBER_OF_256_PER_BLOCK) else '0'; -- 1KByte = 256 x 32 -end generate; -g_512: if DATA_WIDTH = 512 generate -block_done <= '1' when (BLOCKcount = NUMBER_OF_256_PER_BLOCK/2) else '0'; -- 1KByte = 512 x 16 -end generate; --- -reN: entity work.ReMuxN -generic map( N => GBT_NUM) -port map( - clk => clk, - rst => rst_state, - sel => thch_sel_int, - trigON => thch_rdy_1clk, - trigOFF => block_done, - re => re_s, - reNbit => thch_reN_array - ); --- -countENA <= not re_s; -thch_re <= re_s; -thch_re_array <= thch_reN_array((GBT_NUM-1) downto 0); --- - ------------------------------------------------------ --- BLOCK WORD COUNTER ------------------------------------------------------ -BLOCKcounter : process(rst_state, clk) -begin - if rst_state = '1' then - BLOCKcount <= 1; --(others => '0'); - elsif clk'event and clk = '1' then - if re_s = '1' then - if block_done = '1' then - BLOCKcount <= 1; --(others => '0'); - else - BLOCKcount <= BLOCKcount + 1; - end if; - else - BLOCKcount <= 1; --(others => '0'); - end if; - end if; -end process; --- - - -end Behavioral; - + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all;-- @suppress "Deprecated package" +use work.centralRouter_package.all; +use work.FELIX_package.all; +library xpm; +use xpm.vcomponents.all; + +--! reading from Downstream thchs order +entity CRToHostPCIeManager is +Generic ( + GBT_NUM : integer := 1; + DATA_WIDTH: integer; + BLOCKSIZE : integer := 1024; + NUMBER_OF_DESCRIPTORS_TOHOST : integer:= 1 + ); +Port ( + clk : in std_logic; + clk40 : in std_logic; + rst : in std_logic; + thch_hasBlock_array : in std_logic_vector ((GBT_NUM-1) downto 0); -- complete blocks are ready to be read + PCIe_prog_full_array : in std_logic_vector(NUMBER_OF_DESCRIPTORS_TOHOST-1 downto 0); + --- + thch_sel : out integer range 0 to GBT_NUM-1; -- selecting a channel to read from (for writing to crOUTfifo) + thch_re_array : out std_logic_vector ((GBT_NUM-1) downto 0); + output_select : out integer range 0 to NUMBER_OF_DESCRIPTORS_TOHOST-1; + EpathIDs : in array_11b(0 to GBT_NUM-1); + CRTOHOST_DMA_DESCRIPTOR_WR_EN : in std_logic_vector(0 downto 0); + CRTOHOST_DMA_DESCRIPTOR_DESCR : in std_logic_vector(2 downto 0); + CRTOHOST_DMA_DESCRIPTOR_DESCR_READ : out std_logic_vector(2 downto 0); + CRTOHOST_DMA_DESCRIPTOR_AXIS_ID : in std_logic_vector(10 downto 0) + ); +end CRToHostPCIeManager; + +architecture Behavioral of CRToHostPCIeManager is + +signal FMCHcount : std_logic_vector(5 downto 0) := (others => '0'); -- counts to maximum possible channel number (0 to 31) (double clocks) +constant NUMBER_OF_256_PER_BLOCK : integer := BLOCKSIZE / 32; +signal BLOCKcount : integer range 0 to (NUMBER_OF_256_PER_BLOCK*2)-1:=0; -- std_logic_vector(5 downto 0) := (others => '0'); -- counts 256-bit words in block (0 to 31) + +signal thch_hasBlock_array_full : std_logic_vector(GBT_NUM-1 downto 0) := (others => '0'); +signal thch_reN_array : std_logic_vector(GBT_NUM-1 downto 0); +signal thch_hasBlock, block_done, thch_hasBlock_1clk, thch_hasBlock_s, re_s, countENA : std_logic; +signal rst_state , rst_clk40: std_logic := '1'; +signal thch_sel_int : integer range 0 to GBT_NUM; +signal output_select_s: integer range 0 to NUMBER_OF_DESCRIPTORS_TOHOST-1; +signal EpathID: std_logic_vector(10 downto 0); +signal AssociateEpathIdCNT: integer range 0 to GBT_NUM-1 := 0; +signal AssociateEpathId, AssociateEpathId_p1, AssociateEpathId_p2: integer range 0 to GBT_NUM; +signal EpathIDAssociated : std_logic_vector(GBT_NUM-1 downto 0); +signal AssociatedDMAChannel: array_3b(0 to GBT_NUM-1); +signal doutb: std_logic_vector(2 downto 0); +begin + +----------------------------------------------------- +-- reset state +----------------------------------------------------- +sync_rst : xpm_cdc_sync_rst + generic map ( + DEST_SYNC_FF => 2, + INIT => 1, + INIT_SYNC_FF => 0, + SIM_ASSERT_CHK => 0 + ) + port map ( + dest_rst => rst_state, + dest_clk => clk, + src_rst => rst + ); + +sync_rst40 : xpm_cdc_sync_rst + generic map ( + DEST_SYNC_FF => 2, + INIT => 1, + INIT_SYNC_FF => 0, + SIM_ASSERT_CHK => 0 + ) + port map ( + dest_rst => rst_clk40, + dest_clk => clk40, + src_rst => rst + ); + +----------------------------------------------------- +-- FMCH COUNTER 3 bit (31 CHs maximum) +----------------------------------------------------- +FMCH_counter: process(clk, rst_state) +begin + if rst_state = '1' then + FMCHcount <= (others => '0'); + elsif clk'event and clk = '1' then + if countENA = '1' then + if FMCHcount = (std_logic_vector(to_unsigned((GBT_NUM-1), 5)) & '1') then + FMCHcount <= (others => '0'); + else + FMCHcount <= FMCHcount + 1; + end if; + else --(countENA = '0') + -- FMCHcount holds its value on the next clock + end if; + end if; +end process; +-- +thch_sel <= to_integer(unsigned(FMCHcount(5 downto 1))); +thch_sel_int <= to_integer(unsigned(FMCHcount(5 downto 1))); +-- +thch_hasBlock_array_full((GBT_NUM-1) downto 0) <= thch_hasBlock_array; -- GBT_NUM bit +-- +thch_hasBlock <= thch_hasBlock_array_full(to_integer(unsigned(FMCHcount(5 downto 1)))); + +thch_hasBlock_s <= thch_hasBlock and + (not FMCHcount(0)) and + (not rst_state) and + (not PCIe_prog_full_array(output_select_s)) and + EpathIDAssociated(to_integer(unsigned(FMCHcount(5 downto 1)))); + +output_select <= output_select_s; +thch_rdy_pulse: entity work.pulse_pdxx_pwxx +generic map( + pd=>0, + pw=>1 +) +port map( + clk => clk, + trigger => thch_hasBlock_s, + pulseout => thch_hasBlock_1clk +); + +select_output_proc: process(clk) +begin + if rising_edge(clk) then + if rst_state = '1' then + output_select_s <= 0; + else + if thch_hasBlock_1clk = '1' then + if to_integer(unsigned(AssociatedDMAChannel(to_integer(unsigned(FMCHcount(5 downto 1)))))) < NUMBER_OF_DESCRIPTORS_TOHOST then + output_select_s <= to_integer(unsigned(AssociatedDMAChannel(to_integer(unsigned(FMCHcount(5 downto 1)))))); + else + output_select_s <= 0; + end if; + end if; + end if; + end if; +end process; + +-- +g_256: if DATA_WIDTH = 256 generate +block_done <= '1' when (BLOCKcount = NUMBER_OF_256_PER_BLOCK) else '0'; -- 1KByte = 256 x 32 +end generate; +g_512: if DATA_WIDTH = 512 generate +block_done <= '1' when (BLOCKcount = NUMBER_OF_256_PER_BLOCK/2) else '0'; -- 1KByte = 512 x 16 +end generate; +-- +reN: entity work.ReMuxN +generic map( N => GBT_NUM) +port map( + clk => clk, + rst => rst_state, + sel => thch_sel_int, + trigON => thch_hasBlock_1clk, + trigOFF => block_done, + re => re_s, + reNbit => thch_reN_array + ); +-- +countENA <= not re_s; +thch_re_array <= thch_reN_array((GBT_NUM-1) downto 0); +-- + +----------------------------------------------------- +-- BLOCK WORD COUNTER +----------------------------------------------------- +BLOCKcounter : process(rst_state, clk) +begin + if rst_state = '1' then + BLOCKcount <= 1; --(others => '0'); + elsif clk'event and clk = '1' then + if re_s = '1' then + if block_done = '1' then + BLOCKcount <= 1; --(others => '0'); + else + BLOCKcount <= BLOCKcount + 1; + end if; + else + BLOCKcount <= 1; --(others => '0'); + end if; + end if; +end process; +-- + + +associate_epath_id_proc: process(clk) +begin + + if rising_edge(clk) then + if rst = '1' then + AssociateEpathId <= GBT_NUM; + AssociateEpathId_p1 <= GBT_NUM; + AssociateEpathId_p2 <= GBT_NUM; + AssociateEpathIdCNT <= 0; + EpathIDAssociated <= (others => '0'); + EpathID <= (others => '0'); + else + if AssociateEpathIdCNT < GBT_NUM-1 then + AssociateEpathIdCNT <= AssociateEpathIdCNT + 1; + else + AssociateEpathIdCNT <= 0; + end if; + if thch_hasBlock_array(AssociateEpathIdCNT) = '1' and thch_reN_array(AssociateEpathIdCNT) = '0' then + AssociateEpathId <= AssociateEpathIdCNT; + EpathID <= EpathIDs(AssociateEpathIdCNT); + else + AssociateEpathId <= GBT_NUM; + end if; + AssociateEpathId_p1 <= AssociateEpathId; + AssociateEpathId_p2 <= AssociateEpathId_p1; + if AssociateEpathId_p2 /= GBT_NUM then + AssociatedDMAChannel(AssociateEpathId_p2) <= doutb; + EpathIDAssociated(AssociateEpathId_p2) <= '1'; + end if; + for i in 0 to GBT_NUM-1 loop + if thch_reN_array(i) = '1' then + EpathIDAssociated(i) <= '0'; + end if; + end loop; + end if; + end if; +end process; + +target_fifo_lookup_memory : xpm_memory_tdpram + generic map ( + ADDR_WIDTH_A => 11, + ADDR_WIDTH_B => 11, + AUTO_SLEEP_TIME => 0, + BYTE_WRITE_WIDTH_A => 3, + BYTE_WRITE_WIDTH_B => 3, + CASCADE_HEIGHT => 0, + CLOCKING_MODE => "independent_clock", + ECC_MODE => "no_ecc", + MEMORY_INIT_FILE => "none", + MEMORY_INIT_PARAM => "0", + MEMORY_OPTIMIZATION => "true", + MEMORY_PRIMITIVE => "auto", + MEMORY_SIZE => 2048*3, + MESSAGE_CONTROL => 0, + READ_DATA_WIDTH_A => 3, + READ_DATA_WIDTH_B => 3, + READ_LATENCY_A => 2, + READ_LATENCY_B => 2, + READ_RESET_VALUE_A => "0", + READ_RESET_VALUE_B => "0", + RST_MODE_A => "SYNC", + RST_MODE_B => "SYNC", + SIM_ASSERT_CHK => 0, + USE_EMBEDDED_CONSTRAINT => 0, + USE_MEM_INIT => 0, + WAKEUP_TIME => "disable_sleep", + WRITE_DATA_WIDTH_A => 3, + WRITE_DATA_WIDTH_B => 3, + WRITE_MODE_A => "no_change", + WRITE_MODE_B => "no_change" + ) + port map ( + dbiterra => open, + dbiterrb => open, + douta => CRTOHOST_DMA_DESCRIPTOR_DESCR_READ, + doutb => doutb, + sbiterra => open, + sbiterrb => open, + addra => CRTOHOST_DMA_DESCRIPTOR_AXIS_ID, + addrb => EpathID, + clka => clk40, + clkb => clk, + dina => CRTOHOST_DMA_DESCRIPTOR_DESCR, + dinb => "000", + ena => '1', + enb => '1', + injectdbiterra => '0', + injectdbiterrb => '0', + injectsbiterra => '0', + injectsbiterrb => '0', + regcea => '1', + regceb => '1', + rsta => rst_clk40, + rstb => rst_state, + sleep => '0', + wea => CRTOHOST_DMA_DESCRIPTOR_WR_EN, + web => "0" + ); + +end Behavioral; + diff --git a/sources/CRToHost/CRToHostdm.vhd b/sources/CRToHost/CRToHostdm.vhd index 555500656c913634e45f46df54e69aa635c0ac2a..10fa633a0d08619990b70be701c744ec1cebf199 100644 --- a/sources/CRToHost/CRToHostdm.vhd +++ b/sources/CRToHost/CRToHostdm.vhd @@ -77,6 +77,7 @@ port ( fmchHighThreshCrossed : out std_logic; fmchHighThreshCrossedLatch : out std_logic; fmchLowThreshCrossed : out std_logic; + AXIS_ID_out : out std_logic_vector(10 downto 0); --fmchXoffin : in std_logic; -- in, crOUTfifo is pfull 4060/3830 (out of 4096), stop writing flag -- ch_prog_full_out : out std_logic @@ -295,14 +296,14 @@ begin CASCADE_HEIGHT => 0, RELATED_CLOCKS => 0, --positive integer; 0 or 1 WRITE_DATA_WIDTH => AXIS_WIDTH(LINK_CONFIG), --positive integer - READ_MODE => "std", --string; "std" or "fwft"; + READ_MODE => "fwft", --string; "std" or "fwft"; FIFO_READ_LATENCY => 1, --positive integer; FULL_RESET_VALUE => 1, --positive integer; 0 or 1; USE_ADV_FEATURES => "0406", READ_DATA_WIDTH => DATA_WIDTH, --positive integer CDC_SYNC_STAGES => 2, --positive integer WR_DATA_COUNT_WIDTH => FIFO_WR_COUNT_WIDTH, --positive integer - PROG_FULL_THRESH => FIFO_DEPTH-4, --positive integer + PROG_FULL_THRESH => FIFO_DEPTH-20, --positive integer RD_DATA_COUNT_WIDTH => FIFO_RD_COUNT_WIDTH, --positive integer PROG_EMPTY_THRESH => 5, DOUT_RESET_VALUE => "0", --string @@ -343,9 +344,14 @@ begin begin if rising_edge(toHostFifo_wr_clk) then fmchFifo_dvalid <= fmchFifo_re and not empty; + if fmchFifo_re = '1' then + fmchFifo_dout <= chFIFO_dout_s; --Turn FWFT into STD fifo again. + end if; end if; end process; + AXIS_ID_out <= chFIFO_dout_s(10 downto 0); + end block; sync_TH_L : xpm_cdc_array_single @@ -429,7 +435,7 @@ begin end if; end process; -fmchFifo_dout <= chFIFO_dout_s; + -- fmchFifo_hasBlock <= (not chFIFO_pempty) and (not fmchFifo_flush_toHostFifo_wr_clk); -- chFIFO_pempty is '0' when there is at least one whole block in the fifo diff --git a/sources/CRToHost/MUXn.vhd b/sources/CRToHost/MUXn.vhd index 7cb48c5197b9d75bae830eb09f50705b41644a60..2b940f8009718739da0b4d331dc09c8b665bb6f7 100644 --- a/sources/CRToHost/MUXn.vhd +++ b/sources/CRToHost/MUXn.vhd @@ -16,74 +16,74 @@ --! See the License for the specific language governing permissions and --! limitations under the License. ----------------------------------------------------------------------------------- ---! Company: EDAQ WIS. ---! Engineer: juna ---! ---! Create Date: 14/09/2016 ---! Module Name: MUXn_d256b ---! Project Name: FELIX ----------------------------------------------------------------------------------- ---! Use standard library -library ieee; -use ieee.std_logic_1164.ALL; -use ieee.numeric_std.all; -use work.centralRouter_package.all; -use work.pcie_package.all; - ---! MUX nx1, 256 bit data -entity MUXn is -generic ( - N : integer := 8; - DATA_WIDTH : integer - ); -port ( - clk : in std_logic; - data : in slv_array(0 to (N-1)); - data_rdy : in std_logic; - sel : in integer range 0 to N-1; - data_out : out std_logic_vector(DATA_WIDTH-1 downto 0); - data_out_rdy : out std_logic - ); -end MUXn; - -architecture Behavioral of MUXn is - -signal data_out_rdy_s : std_logic := '0'; - -begin - --------- --------- -process(clk) -begin - if clk'event and clk = '1' then - -- - if sel > (N-1) then - data_out <= (others=>'0'); - else - data_out <= data( sel ); - end if; - -- - end if; -end process; - --------- --------- -process(clk) -- mux output ready, alligned with data -begin - if clk'event and clk = '1' then - data_out_rdy_s <= data_rdy; - end if; -end process; --------- --------- -data_out_rdy <= data_out_rdy_s; - - -end Behavioral; - - - - - +---------------------------------------------------------------------------------- +--! Company: EDAQ WIS. +--! Engineer: juna +--! +--! Create Date: 14/09/2016 +--! Module Name: MUXn_d256b +--! Project Name: FELIX +---------------------------------------------------------------------------------- +--! Use standard library +library ieee; +use ieee.std_logic_1164.ALL; +use ieee.numeric_std.all; +use work.centralRouter_package.all; +use work.pcie_package.all; + +--! MUX nx1, 256 bit data +entity MUXn is +generic ( + N : integer := 8; + DATA_WIDTH : integer + ); +port ( + clk : in std_logic; + data : in slv_array(0 to (N-1)); + data_valid : in std_logic; + sel : in integer range 0 to N-1; + data_out : out std_logic_vector(DATA_WIDTH-1 downto 0); + data_out_valid : out std_logic + ); +end MUXn; + +architecture Behavioral of MUXn is + +signal data_out_valid_s : std_logic := '0'; + +begin + +-------- +-------- +process(clk) +begin + if clk'event and clk = '1' then + -- + if sel > (N-1) then + data_out <= (others=>'0'); + else + data_out <= data( sel ); + end if; + -- + end if; +end process; + +-------- +-------- +process(clk) -- mux output ready, alligned with data +begin + if clk'event and clk = '1' then + data_out_valid_s <= data_valid; + end if; +end process; +-------- +-------- +data_out_valid <= data_out_valid_s; + + +end Behavioral; + + + + + diff --git a/sources/FanoutSelectors/axis_32_fanout_selector.vhd b/sources/FanoutSelectors/axis_32_fanout_selector.vhd index 7697622c76e595900dcf34b17e2f2a4997c13853..b689bef2c6a0e987a00768c22dab1a487baab950 100644 --- a/sources/FanoutSelectors/axis_32_fanout_selector.vhd +++ b/sources/FanoutSelectors/axis_32_fanout_selector.vhd @@ -71,26 +71,19 @@ begin decoding_axis_tready <= fanout_sel_axis_tready; emu_axis_tready <= fanout_sel_axis_tready; - fanout: process(aclk) + fanout: process(fosel_aclk, emu_axis, emu_axis_prog_empty, decoding_axis, decoding_axis_prog_empty) begin - if rising_edge(aclk) then for i in 0 to GBT_NUM-1 loop for j in 0 to STREAMS_TOHOST-1 loop - if fanout_sel_axis_tready(i,j) = '1' then --only update when tready is high, otherwise maintain all axis signals on the same level. if fosel_aclk(i) = '1' then --use emulator data fanout_sel_axis_s(i,j) <= emu_axis(i,j); + fanout_sel_axis_prog_empty(i,j) <= emu_axis_prog_empty(i,j); else --use frontend link data fanout_sel_axis_s(i,j) <= decoding_axis(i,j); + fanout_sel_axis_prog_empty(i,j) <= decoding_axis_prog_empty(i,j); end if; - end if; - if fosel_aclk(i) = '1' then --use emulator data - fanout_sel_axis_prog_empty(i,j) <= emu_axis_prog_empty(i,j); - else --use frontend link data - fanout_sel_axis_prog_empty(i,j) <= decoding_axis_prog_empty(i,j); - end if; end loop; end loop; - end if; end process; tvalid_fanout: process(fanout_sel_axis_s) diff --git a/sources/FullModeDataEmulator/FullModeDataEmulator.vhd b/sources/FullModeDataEmulator/FullModeDataEmulator.vhd index 69dcdc0496f4778caa78005beae48656f11f7786..604e56eb8b56a417312e5e46c04c3e63ccd0ba66 100644 --- a/sources/FullModeDataEmulator/FullModeDataEmulator.vhd +++ b/sources/FullModeDataEmulator/FullModeDataEmulator.vhd @@ -19,394 +19,400 @@ --! See the License for the specific language governing permissions and --! limitations under the License. ----------------------------------------------------------------------------------- ---! Company: EDAQ WIS. ---! Engineer: juna ---! ---! Create Date: 07/09/2016 ---! Module Name: FullModeDataEmulator ---! Project Name: FELIX ----------------------------------------------------------------------------------- ---! Use standard library -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use ieee.numeric_std.all; -use ieee.std_logic_unsigned.all;-- @suppress "Deprecated package" -use work.pcie_package.all; -use work.centralRouter_package.all; -use work.axi_stream_package.all; -library xpm; -use xpm.vcomponents.all; - ---! E-link data emulator -entity FullModeDataEmulator is -generic ( - GBT_NUM: integer := 24; - BLOCKSIZE : integer; - use_blockram: boolean := true - ); -port ( - appreg_clk : in std_logic; - register_map_control : in register_map_control_type; --! configuration settings, 64 bit per EGROUP (7 EGROUPS total) - register_map_control_appreg_clk : in register_map_control_type; --! configuration settings, 64 bit per EGROUP (7 EGROUPS total) - register_map_gbtemu_monitor : out register_map_gbtemu_monitor_type; - -- - clk240 : in std_logic; - aclk : in std_logic; - aresetn : in std_logic; - m_axis : out axis_32_2d_array_type(0 to GBT_NUM-1, 0 to 0); - m_axis_tready : in axis_tready_2d_array_type(0 to GBT_NUM-1, 0 to 0); - m_axis_prog_empty : out axis_tready_2d_array_type(0 to GBT_NUM-1, 0 to 0) - ); -end FullModeDataEmulator; - - -architecture Behavioral of FullModeDataEmulator is - - -signal aresetn_sync, aresetn_sync_appregclk : std_logic; -signal emuram_rdaddr, emuram_wraddr : std_logic_vector(12 downto 0) := (others => '0'); -signal ena,ena_r,out_rdy,out_rdy_r : std_logic := '0'; -signal path_ena, path_ena_40: std_logic_vector(GBT_NUM-1 downto 0); -signal emuram_wrdata,emuram_rddata : std_logic_vector(35 downto 0) := (others=>'0'); -signal wea : std_logic_vector(0 downto 0) := (others=>'0'); - -signal FMdout_s: std_logic_vector(32 downto 0); -signal FMdout_rdy_s: std_logic; - -signal emuram_douta : std_logic_vector(35 downto 0); - -begin - ---------------------------------------------------------------------------------------- --- reset cdc ---------------------------------------------------------------------------------------- --- - - sync_aresetn : xpm_cdc_sync_rst - generic map ( - DEST_SYNC_FF => 2, - INIT => 0, - INIT_SYNC_FF => 0, - SIM_ASSERT_CHK => 0 - ) - port map ( - dest_rst => aresetn_sync, - dest_clk => clk240, - src_rst => aresetn - ); - - sync_aresetn_appregclk : xpm_cdc_sync_rst - generic map ( - DEST_SYNC_FF => 2, - INIT => 0, - INIT_SYNC_FF => 0, - SIM_ASSERT_CHK => 0 - ) - port map ( - dest_rst => aresetn_sync_appregclk, - dest_clk => appreg_clk, - src_rst => aresetn - ); - - --- ---------------------------------------------------------------------------------------- --- loading new contents ---------------------------------------------------------------------------------------- -process(appreg_clk, aresetn_sync) -begin - if aresetn_sync = '0' then - wea(0) <= '0'; - emuram_wrdata <= "0001" & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; - emuram_wraddr <= "0000000000000"; - elsif rising_edge(appreg_clk) then - wea(0) <= register_map_control_appreg_clk.FE_EMU_CONFIG.WE(47); -- (0 to 6 are used for GBT emus) - emuram_wraddr <= register_map_control_appreg_clk.FE_EMU_CONFIG.WRADDR(45 downto 33); -- 10 bit address - emuram_wrdata <= register_map_control_appreg_clk.FE_EMU_CONFIG.WRDATA(32) & - register_map_control_appreg_clk.FE_EMU_CONFIG.WRDATA(32) & - register_map_control_appreg_clk.FE_EMU_CONFIG.WRDATA(32) & - register_map_control_appreg_clk.FE_EMU_CONFIG.WRDATA(32 downto 0); -- 36 bit data - end if; -end process; --- ---------------------------------------------------------------------------------------- --- cdc ---------------------------------------------------------------------------------------- - - sync_ena : xpm_cdc_single - generic map ( - DEST_SYNC_FF => 2, - INIT_SYNC_FF => 0, - SIM_ASSERT_CHK => 0, - SRC_INPUT_REG => 0 - ) - port map ( - dest_out => ena, - dest_clk => clk240, - src_clk => '0', - src_in => to_sl(register_map_control.FE_EMU_ENA.EMU_TOHOST) - ); - sync_path_ena : xpm_cdc_array_single - generic map ( - DEST_SYNC_FF => 2, - INIT_SYNC_FF => 0, - SIM_ASSERT_CHK => 0, - SRC_INPUT_REG => 0, - WIDTH => GBT_NUM - ) - port map ( - dest_out => path_ena, - dest_clk => clk240, - src_clk => '0', - src_in => path_ena_40 - ); - - g_path_ena_40: for i in 0 to GBT_NUM-1 generate - path_ena_40(i) <= register_map_control.DECODING_EGROUP_CTRL(i)(0).EPATH_ENA(0) and to_sl(register_map_control.FE_EMU_ENA.EMU_TOHOST); - end generate; - -ena_reg: process(clk240) -begin - if rising_edge (clk240) then - if aresetn_sync = '0' then - ena_r <= '0'; - out_rdy <= '0'; - out_rdy_r <= '0'; - else - ena_r <= ena; - out_rdy <= ena_r; - out_rdy_r <= out_rdy; - end if; - end if; -end process; --- ---------------------------------------------------------------------------------------- --- reading from enulator ---------------------------------------------------------------------------------------- -address_counter: process(clk240) -begin - if rising_edge (clk240) then - if ena_r = '1' then - emuram_rdaddr <= emuram_rdaddr + 1; - else - emuram_rdaddr <= (others => '0'); -- have to contain a comma - end if; - end if; -end process; --- ---------------------------------------------------------------------------------------- --- emulator ram ---------------------------------------------------------------------------------------- -g_blockram: if use_blockram generate - - emuram_00 : xpm_memory_tdpram - generic map ( -- @suppress "Generic map uses default values. Missing optional actuals: USE_MEM_INIT_MMI, WRITE_PROTECT" - ADDR_WIDTH_A => 13, - ADDR_WIDTH_B => 13, - AUTO_SLEEP_TIME => 0, - BYTE_WRITE_WIDTH_A => 36, - BYTE_WRITE_WIDTH_B => 36, - CASCADE_HEIGHT => 0, - CLOCKING_MODE => "independent_clock", - ECC_MODE => "no_ecc", - MEMORY_INIT_FILE => "../../sources/ip_cores/kintexUltrascale/fmemuram.mem", - MEMORY_INIT_PARAM => "0", - MEMORY_OPTIMIZATION => "true", - MEMORY_PRIMITIVE => "auto", - MEMORY_SIZE => 8192*36, - MESSAGE_CONTROL => 0, - READ_DATA_WIDTH_A => 36, - READ_DATA_WIDTH_B => 36, - READ_LATENCY_A => 2, - READ_LATENCY_B => 2, - READ_RESET_VALUE_A => "0", - READ_RESET_VALUE_B => "0", - RST_MODE_A => "SYNC", - RST_MODE_B => "SYNC", - SIM_ASSERT_CHK => 0, - USE_EMBEDDED_CONSTRAINT => 0, - USE_MEM_INIT => 1, - WAKEUP_TIME => "disable_sleep", - WRITE_DATA_WIDTH_A => 36, - WRITE_DATA_WIDTH_B => 36, - WRITE_MODE_A => "no_change", - WRITE_MODE_B => "no_change" - ) - port map ( - sleep => '0', - clka => appreg_clk, - ena => '1', - wea => wea, - web => "0", - addra => emuram_wraddr, - dinb => (others => '0'), - dina => emuram_wrdata, - douta => emuram_douta, - injectsbiterra => '0', - injectdbiterra => '0', - injectsbiterrb => '0', - injectdbiterrb => '0', - clkb => clk240, - rsta => aresetn_sync_appregclk, - rstb => aresetn_sync, - enb => ena_r, - regcea => '1', - regceb => '1', - addrb => emuram_rdaddr, - doutb => emuram_rddata, - sbiterra => open, - sbiterrb => open, - dbiterra => open, - dbiterrb => open - ); - - register_map_gbtemu_monitor.FE_EMU_READ.DATA <= emuram_douta(32 downto 0); --- -out_sel: process(clk240) -begin - if rising_edge (clk240) then - if out_rdy_r = '1' then - FMdout_s <= emuram_rddata(32 downto 0); - FMdout_rdy_s <= '1'; - else - FMdout_s <= '1' & x"000000" & Kchar_comma; - FMdout_rdy_s <= '1'; - end if; - end if; -end process; -end generate; - ---This version is intended for simulation, because it takes a lot of time to change properties of the blockram model everytime you want to change a parameter ---In therory it could be used on a real device as well, but in that case some constants must be tied to registers. -g_noblockram: if use_blockram = false generate - signal FMdout_p0_s, FMdout_p1_s: std_logic_vector(32 downto 0); - signal crc_start, crc_calc: std_logic; - signal cnt: integer range 0 to 8191; - constant chunkSize: integer := 120; -- in 32b words - constant idleCount: integer := 120; - constant OmitEop: integer := 0;--10; --10: Omit EOP every 10 chunks, 0 for disable - signal OmitEopCnt: integer range 0 to OmitEop; - signal crc_out: std_logic_vector(19 downto 0); -begin - FMdout_rdy_s <= '1'; - - logic_emu: process(clk240) - variable L1ID: std_logic_vector(15 downto 0); - variable clen: std_logic_vector(11 downto 0); - variable datacnt: std_logic_vector(7 downto 0); - begin - if rising_edge(clk240) then - if aresetn_sync = '0' then - FMdout_p0_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; - FMdout_p1_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; - --FMdout_p2_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; - FMdout_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; - cnt <= 0; - L1ID := (others => '0'); - OmitEopCnt <= 0; - else - cnt <= cnt + 1; - if cnt = 0 then --SOP - FMdout_p0_s <= '1' & x"000000" & Kchar_sop; - crc_calc <= '0'; - crc_start <= '0'; - end if; - if cnt = 1 then --First word of header - crc_start <= '1'; - crc_calc <= '1'; - clen := std_logic_vector(to_unsigned(chunkSize*4-8,12)); --excluding 8 byte header - FMdout_p0_s <= '0' & L1ID(15 downto 8) & clen(7 downto 0) & x"0" & clen(11 downto 8) & x"AA"; - end if; - if cnt = 2 then --Second word of header - crc_start <= '0'; - crc_calc <= '1'; - FMdout_p0_s <= '0' & x"10" & x"AA" & x"BB" & L1ID(7 downto 0); - L1ID := L1ID + 1; - datacnt := x"00"; - end if; - if cnt > 2 and cnt < (1+chunkSize) then --data - crc_start <= '0'; - crc_calc <= '1'; - FMdout_p0_s(7 downto 0) <= datacnt; - datacnt := datacnt + 1; - - FMdout_p0_s(15 downto 8) <= datacnt; - datacnt := datacnt + 1; - - FMdout_p0_s(23 downto 16) <= datacnt; - datacnt := datacnt + 1; - - FMdout_p0_s(31 downto 24) <= datacnt; - datacnt := datacnt + 1; - - FMdout_p0_s(32) <= '0'; - end if; - if cnt = (1+chunkSize) then --End of packet - crc_start <= '0'; - crc_calc <= '0'; - FMdout_p0_s <= '1' & x"000000" & Kchar_eop; - if OmitEop /= 0 then - if OmitEopCnt /= OmitEop-1 then -- @suppress "Dead code" - OmitEopCnt <= OmitEopCnt + 1; - else - OmitEopCnt <= 0; - FMdout_p0_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; --send comma instead of EOP. - end if; - end if; - end if; - if cnt > (1+chunkSize) and cnt < (1+chunkSize+idleCount) then - crc_start <= '0'; - crc_calc <= '0'; - FMdout_p0_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; - end if; - if cnt >= (1+chunkSize+idleCount) then - crc_start <= '0'; - crc_calc <= '0'; - FMdout_p0_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; - cnt <= 0; - end if; - FMdout_p1_s <= FMdout_p0_s; - FMdout_s <= FMdout_p1_s; - if(FMdout_p1_s(32) = '1' and FMdout_p1_s(7 downto 0) = Kchar_eop) then - FMdout_s(27 downto 8) <= crc_out; - end if; - - end if; - end if; - end process; - - -- CRC module takes 2 clock cycles to calculate CRC - crc20_0: entity work.CRC - port map( - CRC => crc_out, --in sync with din_r - Calc => crc_calc, - Clk => clk240, - Din => FMdout_p0_s(31 downto 0), - Reset => crc_start); - -end generate; --emulator without blockram. - --- Fifo to cross clock domain to clk250. -g_FIFOS: for i in 0 to GBT_NUM-1 generate -ToAxi0: entity work.FullToAxis - generic map( - BLOCKSIZE => BLOCKSIZE - ) - port map( - clk240 => clk240, - FMdin => FMdout_s, - LinkAligned => FMdout_rdy_s, - aclk => aclk, - aresetn => aresetn_sync, - m_axis => m_axis(i,0), - m_axis_tready => m_axis_tready(i,0), - m_axis_prog_empty => m_axis_prog_empty(i,0), - path_ena => path_ena(i), - super_chunk_factor_link => register_map_control.SUPER_CHUNK_FACTOR_LINK(i) - ); -end generate; - - -end Behavioral; - +---------------------------------------------------------------------------------- +--! Company: EDAQ WIS. +--! Engineer: juna +--! +--! Create Date: 07/09/2016 +--! Module Name: FullModeDataEmulator +--! Project Name: FELIX +---------------------------------------------------------------------------------- +--! Use standard library +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use ieee.numeric_std.all; +use ieee.std_logic_unsigned.all;-- @suppress "Deprecated package" +use work.pcie_package.all; +use work.centralRouter_package.all; +use work.axi_stream_package.all; +library xpm; +use xpm.vcomponents.all; + +--! E-link data emulator +entity FullModeDataEmulator is +generic ( + GBT_NUM: integer := 24; + BLOCKSIZE : integer; + use_blockram: boolean := true + ); +port ( + appreg_clk : in std_logic; + register_map_control : in register_map_control_type; --! configuration settings, 64 bit per EGROUP (7 EGROUPS total) + register_map_control_appreg_clk : in register_map_control_type; --! configuration settings, 64 bit per EGROUP (7 EGROUPS total) + register_map_gbtemu_monitor : out register_map_gbtemu_monitor_type; + -- + clk240 : in std_logic; + aclk : in std_logic; + aresetn : in std_logic; + m_axis : out axis_32_2d_array_type(0 to GBT_NUM-1, 0 to 0); + m_axis_tready : in axis_tready_2d_array_type(0 to GBT_NUM-1, 0 to 0); + m_axis_prog_empty : out axis_tready_2d_array_type(0 to GBT_NUM-1, 0 to 0) + ); +end FullModeDataEmulator; + + +architecture Behavioral of FullModeDataEmulator is + + +signal aresetn_sync, aresetn_sync_appregclk : std_logic; +signal emuram_rdaddr, emuram_wraddr : std_logic_vector(12 downto 0) := (others => '0'); +signal ena,ena_r,out_rdy,out_rdy_r : std_logic := '0'; +signal path_ena, path_ena_40: std_logic_vector(GBT_NUM-1 downto 0); +signal emuram_wrdata,emuram_rddata : std_logic_vector(35 downto 0) := (others=>'0'); +signal wea : std_logic_vector(0 downto 0) := (others=>'0'); + +signal FMdout_s: std_logic_vector(32 downto 0); +signal FMdout_rdy_s: std_logic; + +signal emuram_douta : std_logic_vector(35 downto 0); + +begin + +--------------------------------------------------------------------------------------- +-- reset cdc +--------------------------------------------------------------------------------------- +-- + + sync_aresetn : xpm_cdc_sync_rst + generic map ( + DEST_SYNC_FF => 2, + INIT => 0, + INIT_SYNC_FF => 0, + SIM_ASSERT_CHK => 0 + ) + port map ( + dest_rst => aresetn_sync, + dest_clk => clk240, + src_rst => aresetn + ); + + sync_aresetn_appregclk : xpm_cdc_sync_rst + generic map ( + DEST_SYNC_FF => 2, + INIT => 0, + INIT_SYNC_FF => 0, + SIM_ASSERT_CHK => 0 + ) + port map ( + dest_rst => aresetn_sync_appregclk, + dest_clk => appreg_clk, + src_rst => aresetn + ); + + +-- +--------------------------------------------------------------------------------------- +-- loading new contents +--------------------------------------------------------------------------------------- +process(appreg_clk, aresetn_sync) +begin + if aresetn_sync = '0' then + wea(0) <= '0'; + emuram_wrdata <= "0001" & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; + emuram_wraddr <= "0000000000000"; + elsif rising_edge(appreg_clk) then + wea(0) <= register_map_control_appreg_clk.FE_EMU_CONFIG.WE(47); -- (0 to 6 are used for GBT emus) + emuram_wraddr <= register_map_control_appreg_clk.FE_EMU_CONFIG.WRADDR(45 downto 33); -- 10 bit address + emuram_wrdata <= register_map_control_appreg_clk.FE_EMU_CONFIG.WRDATA(32) & + register_map_control_appreg_clk.FE_EMU_CONFIG.WRDATA(32) & + register_map_control_appreg_clk.FE_EMU_CONFIG.WRDATA(32) & + register_map_control_appreg_clk.FE_EMU_CONFIG.WRDATA(32 downto 0); -- 36 bit data + end if; +end process; +-- +--------------------------------------------------------------------------------------- +-- cdc +--------------------------------------------------------------------------------------- + + sync_ena : xpm_cdc_single + generic map ( + DEST_SYNC_FF => 2, + INIT_SYNC_FF => 0, + SIM_ASSERT_CHK => 0, + SRC_INPUT_REG => 0 + ) + port map ( + dest_out => ena, + dest_clk => clk240, + src_clk => '0', + src_in => to_sl(register_map_control.FE_EMU_ENA.EMU_TOHOST) + ); + sync_path_ena : xpm_cdc_array_single + generic map ( + DEST_SYNC_FF => 2, + INIT_SYNC_FF => 0, + SIM_ASSERT_CHK => 0, + SRC_INPUT_REG => 0, + WIDTH => GBT_NUM + ) + port map ( + dest_out => path_ena, + dest_clk => clk240, + src_clk => '0', + src_in => path_ena_40 + ); + + g_path_ena_40: for i in 0 to GBT_NUM-1 generate + path_ena_40(i) <= register_map_control.DECODING_EGROUP_CTRL(i)(0).EPATH_ENA(0) and to_sl(register_map_control.FE_EMU_ENA.EMU_TOHOST); + end generate; + +ena_reg: process(clk240) +begin + if rising_edge (clk240) then + if aresetn_sync = '0' then + ena_r <= '0'; + out_rdy <= '0'; + out_rdy_r <= '0'; + else + ena_r <= ena; + out_rdy <= ena_r; + out_rdy_r <= out_rdy; + end if; + end if; +end process; +-- +--------------------------------------------------------------------------------------- +-- reading from enulator +--------------------------------------------------------------------------------------- +address_counter: process(clk240) +begin + if rising_edge (clk240) then + if ena_r = '1' then + emuram_rdaddr <= emuram_rdaddr + 1; + else + emuram_rdaddr <= (others => '0'); -- have to contain a comma + end if; + end if; +end process; +-- +--------------------------------------------------------------------------------------- +-- emulator ram +--------------------------------------------------------------------------------------- +g_blockram: if use_blockram generate + signal reset_sync_appregclk : std_logic; + signal reset_sync : std_logic; +begin + + emuram_00 : xpm_memory_tdpram + generic map ( -- @suppress "Generic map uses default values. Missing optional actuals: USE_MEM_INIT_MMI, WRITE_PROTECT" + ADDR_WIDTH_A => 13, + ADDR_WIDTH_B => 13, + AUTO_SLEEP_TIME => 0, + BYTE_WRITE_WIDTH_A => 36, + BYTE_WRITE_WIDTH_B => 36, + CASCADE_HEIGHT => 0, + CLOCKING_MODE => "independent_clock", + ECC_MODE => "no_ecc", + MEMORY_INIT_FILE => "../../sources/ip_cores/kintexUltrascale/fmemuram.mem", + MEMORY_INIT_PARAM => "0", + MEMORY_OPTIMIZATION => "true", + MEMORY_PRIMITIVE => "auto", + MEMORY_SIZE => 8192*36, + MESSAGE_CONTROL => 0, + READ_DATA_WIDTH_A => 36, + READ_DATA_WIDTH_B => 36, + READ_LATENCY_A => 2, + READ_LATENCY_B => 2, + READ_RESET_VALUE_A => "0", + READ_RESET_VALUE_B => "0", + RST_MODE_A => "SYNC", + RST_MODE_B => "SYNC", + SIM_ASSERT_CHK => 0, + USE_EMBEDDED_CONSTRAINT => 0, + USE_MEM_INIT => 1, + WAKEUP_TIME => "disable_sleep", + WRITE_DATA_WIDTH_A => 36, + WRITE_DATA_WIDTH_B => 36, + WRITE_MODE_A => "no_change", + WRITE_MODE_B => "no_change" + ) + port map ( + sleep => '0', + clka => appreg_clk, + ena => '1', + wea => wea, + web => "0", + addra => emuram_wraddr, + dinb => (others => '0'), + dina => emuram_wrdata, + douta => emuram_douta, + injectsbiterra => '0', + injectdbiterra => '0', + injectsbiterrb => '0', + injectdbiterrb => '0', + clkb => clk240, + rsta => reset_sync_appregclk, + rstb => reset_sync, + enb => '1', + regcea => '1', + regceb => '1', + addrb => emuram_rdaddr, + doutb => emuram_rddata, + sbiterra => open, + sbiterrb => open, + dbiterra => open, + dbiterrb => open + ); + + reset_sync_appregclk <= not aresetn_sync_appregclk; + reset_sync <= not aresetn_sync; + + register_map_gbtemu_monitor.FE_EMU_READ.DATA <= emuram_douta(32 downto 0); +-- +out_sel: process(clk240) +begin + if rising_edge (clk240) then + if out_rdy_r = '1' then + FMdout_s <= emuram_rddata(32 downto 0); + FMdout_rdy_s <= '1'; + else + FMdout_s <= '1' & x"000000" & Kchar_comma; + FMdout_rdy_s <= '1'; + end if; + end if; +end process; +end generate; + +--This version is intended for simulation, because it takes a lot of time to change properties of the blockram model everytime you want to change a parameter +--In therory it could be used on a real device as well, but in that case some constants must be tied to registers. +g_noblockram: if use_blockram = false generate + signal FMdout_p0_s, FMdout_p1_s: std_logic_vector(32 downto 0); + signal crc_start, crc_calc: std_logic; + signal cnt: integer range 0 to 8191; + constant chunkSize: integer := 120; -- in 32b words + constant idleCount: integer := 120; + constant OmitEop: integer := 0;--10; --10: Omit EOP every 10 chunks, 0 for disable + signal OmitEopCnt: integer range 0 to OmitEop; + signal crc_out: std_logic_vector(19 downto 0); +begin + FMdout_rdy_s <= '1'; + + logic_emu: process(clk240) + variable L1ID: std_logic_vector(15 downto 0); + variable clen: std_logic_vector(11 downto 0); + variable datacnt: std_logic_vector(7 downto 0); + begin + if rising_edge(clk240) then + if aresetn_sync = '0' then + FMdout_p0_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; + FMdout_p1_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; + --FMdout_p2_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; + FMdout_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; + cnt <= 0; + L1ID := (others => '0'); + OmitEopCnt <= 0; + else + cnt <= cnt + 1; + if cnt = 0 then --SOP + FMdout_p0_s <= '1' & x"000000" & Kchar_sop; + crc_calc <= '0'; + crc_start <= '0'; + end if; + if cnt = 1 then --First word of header + crc_start <= '1'; + crc_calc <= '1'; + clen := std_logic_vector(to_unsigned(chunkSize*4-8,12)); --excluding 8 byte header + FMdout_p0_s <= '0' & L1ID(15 downto 8) & clen(7 downto 0) & x"0" & clen(11 downto 8) & x"AA"; + end if; + if cnt = 2 then --Second word of header + crc_start <= '0'; + crc_calc <= '1'; + FMdout_p0_s <= '0' & x"10" & x"AA" & x"BB" & L1ID(7 downto 0); + L1ID := L1ID + 1; + datacnt := x"00"; + end if; + if cnt > 2 and cnt < (1+chunkSize) then --data + crc_start <= '0'; + crc_calc <= '1'; + FMdout_p0_s(7 downto 0) <= datacnt; + datacnt := datacnt + 1; + + FMdout_p0_s(15 downto 8) <= datacnt; + datacnt := datacnt + 1; + + FMdout_p0_s(23 downto 16) <= datacnt; + datacnt := datacnt + 1; + + FMdout_p0_s(31 downto 24) <= datacnt; + datacnt := datacnt + 1; + + FMdout_p0_s(32) <= '0'; + end if; + if cnt = (1+chunkSize) then --End of packet + crc_start <= '0'; + crc_calc <= '0'; + FMdout_p0_s <= '1' & x"000000" & Kchar_eop; + if OmitEop /= 0 then + if OmitEopCnt /= OmitEop-1 then -- @suppress "Dead code" + OmitEopCnt <= OmitEopCnt + 1; + else + OmitEopCnt <= 0; + FMdout_p0_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; --send comma instead of EOP. + end if; + end if; + end if; + if cnt > (1+chunkSize) and cnt < (1+chunkSize+idleCount) then + crc_start <= '0'; + crc_calc <= '0'; + FMdout_p0_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; + end if; + if cnt >= (1+chunkSize+idleCount) then + crc_start <= '0'; + crc_calc <= '0'; + FMdout_p0_s <= '1' & Kchar_comma & Kchar_comma & Kchar_comma & Kchar_comma; + cnt <= 0; + end if; + FMdout_p1_s <= FMdout_p0_s; + FMdout_s <= FMdout_p1_s; + if(FMdout_p1_s(32) = '1' and FMdout_p1_s(7 downto 0) = Kchar_eop) then + FMdout_s(27 downto 8) <= crc_out; + end if; + + end if; + end if; + end process; + + -- CRC module takes 2 clock cycles to calculate CRC + crc20_0: entity work.CRC + port map( + CRC => crc_out, --in sync with din_r + Calc => crc_calc, + Clk => clk240, + Din => FMdout_p0_s(31 downto 0), + Reset => crc_start); + +end generate; --emulator without blockram. + +-- Fifo to cross clock domain to clk250. +g_FIFOS: for i in 0 to GBT_NUM-1 generate +ToAxi0: entity work.FullToAxis + generic map( + BLOCKSIZE => BLOCKSIZE + ) + port map( + clk240 => clk240, + FMdin => FMdout_s, + LinkAligned => FMdout_rdy_s, + aclk => aclk, + aresetn => aresetn_sync, + m_axis => m_axis(i,0), + m_axis_tready => m_axis_tready(i,0), + m_axis_prog_empty => m_axis_prog_empty(i,0), + path_ena => path_ena(i), + super_chunk_factor_link => register_map_control.SUPER_CHUNK_FACTOR_LINK(i) + ); +end generate; + + +end Behavioral; + diff --git a/sources/ip_cores/kintexUltrascale/ila_endeavour_decoder.xci b/sources/ip_cores/kintexUltrascale/ila_endeavour_decoder.xci old mode 100755 new mode 100644 diff --git a/sources/ip_cores/kintexUltrascale/ila_endeavour_encoder.xci b/sources/ip_cores/kintexUltrascale/ila_endeavour_encoder.xci old mode 100755 new mode 100644 diff --git a/sources/packages/FELIX_package.vhd b/sources/packages/FELIX_package.vhd index e068faab6e74cd071ba40404bb8500d3f351bbea..ce59a1c673855c6c3c2a7e5799615e02a0a29abd 100644 --- a/sources/packages/FELIX_package.vhd +++ b/sources/packages/FELIX_package.vhd @@ -30,10 +30,12 @@ package FELIX_package is type array_36b is array (natural range <>) of std_logic_vector(35 downto 0); type array_32b is array (natural range <>) of std_logic_vector(31 downto 0); type array_34b is array (natural range <>) of std_logic_vector(33 downto 0); + type array_11b is array (natural range <>) of std_logic_vector(10 downto 0); type array_8b is array (natural range <>) of std_logic_vector(7 downto 0); type array_2d_5b is array (natural range <>, natural range <>) of std_logic_vector(4 downto 0); type array_5b is array (natural range <>) of std_logic_vector(4 downto 0); type array_4b is array (natural range <>) of std_logic_vector(3 downto 0); + type array_3b is array (natural range <>) of std_logic_vector(2 downto 0); type array_2b is array (natural range <>) of std_logic_vector(1 downto 0); diff --git a/sources/templates/dma_control.vhd b/sources/templates/dma_control.vhd index fd459cca192b99636a82ae2d9f46d2b76eeb4565..2b13410aeaefc4a6e8b532965d361cf1d2c0b605 100644 --- a/sources/templates/dma_control.vhd +++ b/sources/templates/dma_control.vhd @@ -835,6 +835,8 @@ end process; register_map_control_s.STATUS_LEDS <= REG_STATUS_LEDS_C; -- Board GPIO Leds register_map_control_s.TIMEOUT_CTRL.ENABLE <= REG_TIMEOUT_CTRL_ENABLE_C; -- 1 enables the timout trailer generation for ToHost mode register_map_control_s.TIMEOUT_CTRL.TIMEOUT <= REG_TIMEOUT_CTRL_TIMEOUT_C; -- Number of 40 MHz clock cycles after which a timeout occurs. + register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_1.DESCR <= REG_CRTOHOST_DMA_DESCRIPTOR_1_DESCR_C; -- Target descriptor + register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID <= REG_CRTOHOST_DMA_DESCRIPTOR_2_AXIS_ID_C; -- ID of the AXI stream (E-Path ID) to associate with CRTOHOST_DMA_DESCRIPTOR_1.DESCR if GBT_NUM > 0 then register_map_control_s.BROADCAST_ENABLE(0) <= REG_BROADCAST_ENABLE_00_C; -- Enable path to be included in a broadcast message. end if; @@ -10174,6 +10176,7 @@ end process; ---- ## GENERATED CODE BEGIN #2 ---- ------------------------------------ register_map_control_s.CRTOHOST_FIFO_STATUS.CLEAR <= REG_CRTOHOST_FIFO_STATUS_CLEAR_C; -- Any write to this register clears the latched FULL flags + register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_1.WR_EN <= REG_CRTOHOST_DMA_DESCRIPTOR_1_WR_EN_C; -- Any write to this register assigns the DMA ID to the AXIS_ID set in CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID register_map_control_s.CRFROMHOST_FIFO_STATUS.CLEAR <= REG_CRFROMHOST_FIFO_STATUS_CLEAR_C; -- Any write to this register clears the latched FULL flags register_map_control_s.CRFROMHOST_RESET <= REG_CRFROMHOST_RESET_C; -- Central Router FromHost Controls and Monitors register_map_control_s.TTC_BUSY_CLEAR <= REG_TTC_BUSY_CLEAR_C; -- clears the latching busy bits in TTC_BUSY_ACCEPTED @@ -10408,6 +10411,10 @@ end process; when REG_CRTOHOST_FIFO_STATUS => register_read_data_25_s(64 downto 64) <= register_map_control_s.CRTOHOST_FIFO_STATUS.CLEAR; -- Any write to this register clears the latched FULL flags register_read_data_25_s(47 downto 24) <= register_map_monitor_s.register_map_crtohost_monitor.CRTOHOST_FIFO_STATUS.FULL; -- Every bit represents the full flag of a channel FIFO register_read_data_25_s(23 downto 0) <= register_map_monitor_s.register_map_crtohost_monitor.CRTOHOST_FIFO_STATUS.FULL_LATCHED; -- like FULL but a latched state, clear by writing to this register + when REG_CRTOHOST_DMA_DESCRIPTOR_1 => register_read_data_25_s(64 downto 64) <= register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_1.WR_EN; -- Any write to this register assigns the DMA ID to the AXIS_ID set in CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID + register_read_data_25_s(2 downto 0) <= register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_1.DESCR; -- Target descriptor + when REG_CRTOHOST_DMA_DESCRIPTOR_2 => register_read_data_25_s(13 downto 11) <= register_map_monitor_s.register_map_crtohost_monitor.CRTOHOST_DMA_DESCRIPTOR_2.DESCR_READ; -- Read back the value of the descriptor assigned to AXIS_ID + register_read_data_25_s(10 downto 0) <= register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID; -- ID of the AXI stream (E-Path ID) to associate with CRTOHOST_DMA_DESCRIPTOR_1.DESCR when REG_CRFROMHOST_FIFO_STATUS => register_read_data_25_s(64 downto 64) <= register_map_control_s.CRFROMHOST_FIFO_STATUS.CLEAR; -- Any write to this register clears the latched FULL flags register_read_data_25_s(47 downto 24) <= register_map_monitor_s.register_map_crfromhost_monitor.CRFROMHOST_FIFO_STATUS.FULL; -- Every bit represents the full flag of a channel FIFO register_read_data_25_s(23 downto 0) <= register_map_monitor_s.register_map_crfromhost_monitor.CRFROMHOST_FIFO_STATUS.FULL_LATCHED; -- like FULL but a latched state, clear by writing to this register @@ -18210,6 +18217,9 @@ end process; when REG_TIMEOUT_CTRL => register_map_control_s.TIMEOUT_CTRL.ENABLE <= register_write_data_25_v(32 downto 32); -- 1 enables the timout trailer generation for ToHost mode register_map_control_s.TIMEOUT_CTRL.TIMEOUT <= register_write_data_25_v(31 downto 0); -- Number of 40 MHz clock cycles after which a timeout occurs. when REG_CRTOHOST_FIFO_STATUS => register_map_control_s.CRTOHOST_FIFO_STATUS.CLEAR <= "1"; -- Any write to this register clears the latched FULL flags + when REG_CRTOHOST_DMA_DESCRIPTOR_1 => register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_1.WR_EN <= "1"; -- Any write to this register assigns the DMA ID to the AXIS_ID set in CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID + register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_1.DESCR <= register_write_data_25_v(2 downto 0); -- Target descriptor + when REG_CRTOHOST_DMA_DESCRIPTOR_2 => register_map_control_s.CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID <= register_write_data_25_v(10 downto 0); -- ID of the AXI stream (E-Path ID) to associate with CRTOHOST_DMA_DESCRIPTOR_1.DESCR when REG_CRFROMHOST_FIFO_STATUS => register_map_control_s.CRFROMHOST_FIFO_STATUS.CLEAR <= "1"; -- Any write to this register clears the latched FULL flags when REG_BROADCAST_ENABLE_00 => if GBT_NUM > 0 then diff --git a/sources/templates/pcie_package.vhd b/sources/templates/pcie_package.vhd index 6322844a1e606768616c1e36cd07d67d250b3e19..6b0da86e4d11c11c6f21311fe5ca80a1d8c21964 100644 --- a/sources/templates/pcie_package.vhd +++ b/sources/templates/pcie_package.vhd @@ -295,6 +295,8 @@ package pcie_package is constant REG_TIMEOUT_CTRL : std_logic_vector(19 downto 0) := x"00800"; constant REG_MAX_TIMEOUT : std_logic_vector(19 downto 0) := x"00810"; constant REG_CRTOHOST_FIFO_STATUS : std_logic_vector(19 downto 0) := x"00820"; + constant REG_CRTOHOST_DMA_DESCRIPTOR_1 : std_logic_vector(19 downto 0) := x"00830"; + constant REG_CRTOHOST_DMA_DESCRIPTOR_2 : std_logic_vector(19 downto 0) := x"00840"; --** CRFromHostControlsAndMonitors constant REG_CRFROMHOST_FIFO_STATUS : std_logic_vector(19 downto 0) := x"01000"; @@ -1436,6 +1438,15 @@ package pcie_package is CLEAR : std_logic_vector(64 downto 64); -- Any write to this register clears the latched FULL flags end record; + type bitfield_crtohost_dma_descriptor_1_t_type is record + WR_EN : std_logic_vector(64 downto 64); -- Any write to this register assigns the DMA ID to the AXIS_ID set in CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID + DESCR : std_logic_vector(2 downto 0); -- Target descriptor + end record; + + type bitfield_crtohost_dma_descriptor_2_w_type is record + AXIS_ID : std_logic_vector(10 downto 0); -- ID of the AXI stream (E-Path ID) to associate with CRTOHOST_DMA_DESCRIPTOR_1.DESCR + end record; + type bitfield_crfromhost_fifo_status_t_type is record CLEAR : std_logic_vector(64 downto 64); -- Any write to this register clears the latched FULL flags end record; @@ -1932,6 +1943,8 @@ package pcie_package is STATUS_LEDS : std_logic_vector(7 downto 0); -- Board GPIO Leds TIMEOUT_CTRL : bitfield_timeout_ctrl_w_type; -- Central Router ToHost Controls and Monitors CRTOHOST_FIFO_STATUS : bitfield_crtohost_fifo_status_t_type; -- Central Router ToHost Controls and Monitors + CRTOHOST_DMA_DESCRIPTOR_1 : bitfield_crtohost_dma_descriptor_1_t_type; -- Central Router ToHost Controls and Monitors + CRTOHOST_DMA_DESCRIPTOR_2 : bitfield_crtohost_dma_descriptor_2_w_type; -- Central Router ToHost Controls and Monitors CRFROMHOST_FIFO_STATUS : bitfield_crfromhost_fifo_status_t_type; -- Central Router FromHost Controls and Monitors BROADCAST_ENABLE : bitfield_broadcast_enable_w_array_type; -- Enable path to be included in a broadcast message. CRFROMHOST_RESET : std_logic_vector(64 downto 64); -- Central Router FromHost Controls and Monitors @@ -2110,6 +2123,9 @@ package pcie_package is constant REG_TIMEOUT_CTRL_ENABLE_C : std_logic_vector(32 downto 32) := "1"; -- 1 enables the timout trailer generation for ToHost mode constant REG_TIMEOUT_CTRL_TIMEOUT_C : std_logic_vector(31 downto 0) := x"ffffffff"; -- Number of 40 MHz clock cycles after which a timeout occurs. constant REG_CRTOHOST_FIFO_STATUS_CLEAR_C : std_logic_vector(64 downto 64) := "0"; -- Any write to this register clears the latched FULL flags + constant REG_CRTOHOST_DMA_DESCRIPTOR_1_WR_EN_C : std_logic_vector(64 downto 64) := "0"; -- Any write to this register assigns the DMA ID to the AXIS_ID set in CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID + constant REG_CRTOHOST_DMA_DESCRIPTOR_1_DESCR_C : std_logic_vector(2 downto 0) := "000"; -- Target descriptor + constant REG_CRTOHOST_DMA_DESCRIPTOR_2_AXIS_ID_C : std_logic_vector(10 downto 0) := "00000000000"; -- ID of the AXI stream (E-Path ID) to associate with CRTOHOST_DMA_DESCRIPTOR_1.DESCR constant REG_CRFROMHOST_FIFO_STATUS_CLEAR_C : std_logic_vector(64 downto 64) := "0"; -- Any write to this register clears the latched FULL flags constant REG_BROADCAST_ENABLE_00_C : std_logic_vector(41 downto 0) := "000000000000000000000000000000000000000000"; -- Enable path to be included in a broadcast message. constant REG_BROADCAST_ENABLE_01_C : std_logic_vector(41 downto 0) := "000000000000000000000000000000000000000000"; -- Enable path to be included in a broadcast message. @@ -6580,11 +6596,15 @@ end record; FULL : std_logic_vector(47 downto 24); -- Every bit represents the full flag of a channel FIFO FULL_LATCHED : std_logic_vector(23 downto 0); -- like FULL but a latched state, clear by writing to this register end record; + type bitfield_crtohost_dma_descriptor_2_r_type is record + DESCR_READ : std_logic_vector(13 downto 11); -- Read back the value of the descriptor assigned to AXIS_ID + end record; -- CRToHostControlsAndMonitors type register_map_crtohost_monitor_type is record MAX_TIMEOUT : std_logic_vector(31 downto 0); -- Maximum allowed timeout value CRTOHOST_FIFO_STATUS : bitfield_crtohost_fifo_status_r_type; + CRTOHOST_DMA_DESCRIPTOR_2 : bitfield_crtohost_dma_descriptor_2_r_type; end record; -- -- CRFromHostControlsAndMonitors @@ -7038,7 +7058,8 @@ end record; constant register_map_crtohost_monitor_c : register_map_crtohost_monitor_type := ( MAX_TIMEOUT => (others => '0'), - CRTOHOST_FIFO_STATUS => (others => (others => '0')) + CRTOHOST_FIFO_STATUS => (others => (others => '0')), + CRTOHOST_DMA_DESCRIPTOR_2 => (others => (others => '0')) ); constant register_map_crfromhost_monitor_c : register_map_crfromhost_monitor_type := ( diff --git a/sources/templates/registers-5.0.html b/sources/templates/registers-5.0.html index 31598b2d93d88201d4411f345cd710c33eaa6df6..c9a0c50681628da5be3da9f4b6b59b89f6f8704c 100644 --- a/sources/templates/registers-5.0.html +++ b/sources/templates/registers-5.0.html @@ -858,6 +858,36 @@ th { <td class="type">R</td> <td class="desc">like FULL but a latched state, clear by writing to this register</td> </tr> + <tr> + <td rowspan="2">0x0830</td> + <td rowspan="2">0,1</td> + <td rowspan="2">CRTOHOST_DMA_DESCRIPTOR_1</td> + <td class="name">WR_EN</td> + <td class="range">any</td> + <td class="type">T</td> + <td class="desc">Any write to this register assigns the DMA ID to the AXIS_ID set in CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID</td> + </tr> + <tr> + <td class="name">DESCR</td> + <td class="range">2..0</td> + <td class="type">W</td> + <td class="desc">Target descriptor</td> + </tr> + <tr> + <td rowspan="2">0x0840</td> + <td rowspan="2">0,1</td> + <td rowspan="2">CRTOHOST_DMA_DESCRIPTOR_2</td> + <td class="name">DESCR_READ</td> + <td class="range">13..11</td> + <td class="type">R</td> + <td class="desc">Read back the value of the descriptor assigned to AXIS_ID</td> + </tr> + <tr> + <td class="name">AXIS_ID</td> + <td class="range">10..0</td> + <td class="type">W</td> + <td class="desc">ID of the AXI stream (E-Path ID) to associate with CRTOHOST_DMA_DESCRIPTOR_1.DESCR</td> + </tr> <tr> <td colspan="7" class="group">CR From Host Controls And Monitors</td> </tr> diff --git a/sources/templates/registers-5.0.yaml b/sources/templates/registers-5.0.yaml index 4ffb58235764ae705ecd5a6656e86a03ce9744b9..23f8994518640dedb4e74c2c970fd397249b9ff9 100644 --- a/sources/templates/registers-5.0.yaml +++ b/sources/templates/registers-5.0.yaml @@ -610,7 +610,28 @@ CRToHostControlsAndMonitors: type: R name: FULL_LATCHED desc: like FULL but a latched state, clear by writing to this register - + - name: CRTOHOST_DMA_DESCRIPTOR_1 + type: W + bitfield: + - range: any + name: WR_EN + type: T + value: 1 + desc: Any write to this register assigns the DMA ID to the AXIS_ID set in CRTOHOST_DMA_DESCRIPTOR_2.AXIS_ID + - range: 2..0 + name: DESCR + desc: Target descriptor + - name: CRTOHOST_DMA_DESCRIPTOR_2 + type: W + bitfield: + - range: 13..11 + name: DESCR_READ + type: R + desc: Read back the value of the descriptor assigned to AXIS_ID + - range: 10..0 + name: AXIS_ID + desc: ID of the AXI stream (E-Path ID) to associate with CRTOHOST_DMA_DESCRIPTOR_1.DESCR + type: W CRFromHostControlsAndMonitors: group: CRFHC