diff --git a/IntegrationTests/DualFPGA/firmware/hdl/emp_project_decl_f1.vhd b/IntegrationTests/DualFPGA/firmware/hdl/emp_project_decl_f1.vhd index 79f5d17ddb9..a932277dccc 100644 --- a/IntegrationTests/DualFPGA/firmware/hdl/emp_project_decl_f1.vhd +++ b/IntegrationTests/DualFPGA/firmware/hdl/emp_project_decl_f1.vhd @@ -19,7 +19,7 @@ package emp_project_decl is constant CLOCK_AUX_DIV : clock_divisor_array_t := (18, 9, 4); -- Dividers of CLOCK_COMMON_RATIO * 40 MHz -- Readdjust if latency changes for FPGA1 algorithm - constant PAYLOAD_LATENCY : integer := 399; + constant PAYLOAD_LATENCY : integer := 403; -- F1 transmits to F2 on inter-fpga links constant REGION_CONF : region_conf_array_t := ( diff --git a/IntegrationTests/DualFPGA/firmware/hdl/payload_f2.vhd b/IntegrationTests/DualFPGA/firmware/hdl/payload_f2.vhd index 24933c90625..8df1a80767d 100644 --- a/IntegrationTests/DualFPGA/firmware/hdl/payload_f2.vhd +++ b/IntegrationTests/DualFPGA/firmware/hdl/payload_f2.vhd @@ -99,6 +99,7 @@ begin sp2_mem_writer_1 : entity work.sp2_mem_writer port map ( clk => clk_p, + rst => rst, AS_36_link_data => AS_36_link_data, MPAR_73_link_data => MPAR_73_link_data, bx_link_data => bx_link_data, diff --git a/IntegrationTests/DualFPGA/firmware/hdl/sp2_mem_writer.vhd b/IntegrationTests/DualFPGA/firmware/hdl/sp2_mem_writer.vhd index 2d5ad6c44ee..274d4f1de9c 100644 --- a/IntegrationTests/DualFPGA/firmware/hdl/sp2_mem_writer.vhd +++ b/IntegrationTests/DualFPGA/firmware/hdl/sp2_mem_writer.vhd @@ -16,6 +16,7 @@ use work.memUtil_aux_pkg_f2.all; entity sp2_mem_writer is port ( clk : in std_logic; + rst : in std_logic; AS_36_link_data : in t_arr_AS_36_37b; MPAR_73_link_data : in t_arr_MTPAR_73_76b; bx_link_data : in std_logic_vector(2 downto 0); @@ -48,8 +49,6 @@ architecture rtl of sp2_mem_writer is signal sectorprocessor_ctrl : enum_RESET_STATE := S_IDLE; signal sync_counter : unsigned(7 downto 0) := (others => '0'); - signal AS_36_adr : t_arr_AS_36_7b := (others => "0000000"); - signal MPAR_73_adr : t_arr_MTPAR_73_arr4_7b := (others => (others => "0000000")); signal MPAR_73_pge : t_arr_MTPAR_73_2b := (others => "00"); signal bx_prev : std_logic_vector(2 downto 0) := "000"; signal AS_36_wea_int : t_arr_AS_36_1b := (others => '0'); @@ -59,13 +58,10 @@ architecture rtl of sp2_mem_writer is signal PC_start_int : std_logic := '0'; signal AS_36_wea_pipeline0 : t_arr_AS_36_1b := (others => '0'); - signal AS_36_writeaddr_pipeline0 : t_arr_AS_36_ADDR := (others => (others => '0')); signal AS_36_din_pipeline0 : t_arr_AS_36_DATA := (others => (others => '0')); signal MPAR_73_wea_pipeline0 : t_arr_MTPAR_73_1b := (others => '0'); signal MPAR_73_writeaddr_pipeline0 : t_arr_MTPAR_73_ADDR := (others => (others => '0')); signal MPAR_73_din_pipeline0 : t_arr_MTPAR_73_DATA := (others => (others => '0')); - signal PC_bx_in_pipeline0 : std_logic_vector(2 downto 0) := "000"; - signal PC_start_pipeline0 : std_logic := '0'; signal AS_36_wea_pipeline : t_arr_AS_36_1b := (others => '0'); signal AS_36_writeaddr_pipeline : t_arr_AS_36_ADDR := (others => (others => '0')); @@ -79,8 +75,6 @@ architecture rtl of sp2_mem_writer is signal HLS_reset_int : std_logic := '0'; attribute dont_touch : string; - attribute dont_touch of AS_36_writeaddr_pipeline0 : signal is "yes"; - attribute dont_touch of AS_36_writeaddr_pipeline : signal is "yes"; attribute dont_touch of MPAR_73_writeaddr_pipeline0 : signal is "yes"; attribute dont_touch of MPAR_73_writeaddr_pipeline : signal is "yes"; @@ -102,14 +96,6 @@ begin -- architecture rtl else AS_36_wea_int(i) <= '0'; end if; - - if (AS_36_link_valid_prev(i)='0' and AS_36_link_valid(i)='1') then - --beginning of event packet - AS_36_adr(i) <= "0000000"; - elsif (AS_36_wea_int(i) = '1') then - --wrote on previous clock - AS_36_adr(i) <= std_logic_vector(unsigned(AS_36_adr(i))+1); - end if; end loop; --AS_36 loop --Convert streamed MergedParameters data into memory inputs for @@ -127,18 +113,6 @@ begin -- architecture rtl MPAR_73_wea_int(i) <= '0'; end if; - if (MPAR_73_link_valid_prev(i)='0' and MPAR_73_link_valid(i)='1') then - --beginning of event packet - MPAR_73_adr(i)(0) <= "0000000"; - MPAR_73_adr(i)(1) <= "0000000"; - MPAR_73_adr(i)(2) <= "0000000"; - MPAR_73_adr(i)(3) <= "0000000"; - elsif (MPAR_73_wea_int(i) = '1') then - --wrote on previous clock - MPAR_73_adr(i)(to_integer(unsigned(MPAR_73_pge(i)))) - <= std_logic_vector(unsigned(MPAR_73_adr(i)(to_integer( - unsigned(MPAR_73_pge(i)))))+1); - end if; end loop; --MPAR_73 loop --latch BX when input not valid @@ -165,8 +139,8 @@ begin -- architecture rtl else sync_counter <= sync_counter+1; end if; - if (bx_link_valid='1' and bx_link_data /= bx_prev - and to_integer(sync_counter) /= 107) then + if ((bx_link_valid='1' and bx_link_data /= bx_prev + and to_integer(sync_counter) /= 107) or rst = '1') then sync_counter <= (others => '0'); PC_start_int <= '0'; HLS_reset_int <= '1'; @@ -189,37 +163,29 @@ begin -- architecture rtl end process p_writemem; --build full memory addresses based on word, page, and BX - g_as_address : for i in AS_36_writeaddr'range generate - AS_36_writeaddr_pipeline0(i) <= bx_prev & AS_36_adr(i); - end generate g_as_address; - g_mpar_address : for i in MPAR_73_writeaddr'range generate - MPAR_73_writeaddr_pipeline0(i) <= bx_prev & MPAR_73_pge(i) - & MPAR_73_adr(i)(to_integer(unsigned(MPAR_73_pge(i)))); + MPAR_73_writeaddr_pipeline0(i) <= "0000000000" & MPAR_73_pge(i); end generate g_mpar_address; AS_36_wea_pipeline0 <= AS_36_wea_int; MPAR_73_wea_pipeline0 <= MPAR_73_wea_int; AS_36_din_pipeline0 <= AS_36_din_int; MPAR_73_din_pipeline0 <= MPAR_73_din_int; - PC_bx_in_pipeline0 <= std_logic_vector(unsigned(bx_prev)-1); - PC_start_pipeline0 <= PC_start_int; + PC_bx_in_pipeline <= std_logic_vector(unsigned(bx_prev)-1); + PC_start_pipeline <= PC_start_int; HLS_reset <= HLS_reset_int; + AS_36_writeaddr <= AS_36_writeaddr_pipeline; p_pipeline : process (clk) is begin -- process p_pipeline if rising_edge(clk) then -- rising clock edge AS_36_wea_pipeline <= AS_36_wea_pipeline0; - AS_36_writeaddr_pipeline <= AS_36_writeaddr_pipeline0; AS_36_din_pipeline <= AS_36_din_pipeline0; MPAR_73_wea_pipeline <= MPAR_73_wea_pipeline0; MPAR_73_writeaddr_pipeline <= MPAR_73_writeaddr_pipeline0; MPAR_73_din_pipeline <= MPAR_73_din_pipeline0; - PC_bx_in_pipeline <= PC_bx_in_pipeline0; - PC_start_pipeline <= PC_start_pipeline0; AS_36_wea <= AS_36_wea_pipeline; - AS_36_writeaddr <= AS_36_writeaddr_pipeline; AS_36_din <= AS_36_din_pipeline; MPAR_73_wea <= MPAR_73_wea_pipeline; MPAR_73_writeaddr <= MPAR_73_writeaddr_pipeline; diff --git a/IntegrationTests/DualFPGA/firmware/scripts/run_sim.tcl b/IntegrationTests/DualFPGA/firmware/scripts/run_sim.tcl new file mode 100644 index 00000000000..a20ff15a7d0 --- /dev/null +++ b/IntegrationTests/DualFPGA/firmware/scripts/run_sim.tcl @@ -0,0 +1,114 @@ +# The directory where the input files to run are found +set input_dir "../mem" + +# The directory to save the simulation output to +set output_dir "./dataOut" + +# The path to the simulation project +set project_path "../../../../../../proj/vsim_f1/vsim_f1/vsim_f1.xpr" + +# The length of the simulation to run (6us is enough to get through 9 events) +set sim_time 6us + +# The list of input files to run over +set mem_files { + "in_fpga1_0.txt" + "in_fpga1_1.txt" + "in_fpga1_2.txt" + "in_fpga1_3.txt" + "in_fpga1_4.txt" + "in_fpga1_5.txt" + "in_fpga1_6.txt" + "in_fpga1_7.txt" + "in_fpga1_8.txt" + "in_fpga1_9.txt" + "in_fpga1_10.txt" + "in_fpga1_11.txt" +} + +if {[catch {current_project}]} { + if {![file exists $project_path]} { + puts "ERROR: Simulation project file not found. Be sure to create a vsim_f1 project." + exit 1 + } + + puts "Opening project file $project_path" + open_project $project_path + reset_simulation sim_1 + launch_simulation +} else { + puts "Using currently open project." +} + +set proj_name [get_property NAME [current_project]] +set proj_dir [get_property DIRECTORY [current_project]] +set sim_name [get_property NAME [current_fileset -simset]] +set sim_dir [file join $proj_dir "$proj_name.sim" $sim_name "behav" "xsim"] +set temp_backup [file join $sim_dir "temp_input.txt"] + +if {[catch {set input_filename [get_value "/top/sourcefile"]} errMsg]} { + puts "ERROR: Could not infer source input filename." + exit 1 +} else { + set input_filename [string trim $input_filename "\""] + puts "Using source input filename $input_filename" +} + +if {[catch {set output_filename [get_value "/top/sinkfile"]} errMsg]} { + puts "ERROR: Could not infer source output filename." + exit 1 +} else { + set output_filename [string trim $output_filename "\""] + puts "Using source output filename $output_filename" +} + +file delete -force $output_dir +file mkdir $output_dir + +set target_input_path [file join $sim_dir $input_filename] +set source_output_path [file join $sim_dir $output_filename] + +# Save the existing input file since we will be overwriting it +puts "Saving copy of original input file $target_input_path" +file copy -force $target_input_path [file join $sim_dir $temp_backup] + +# try..catch..finally not implemented until tcl 8.6, so we must +# catch any errors to ensure we restore the existing input file +set return_status [catch { + set idx 0 + foreach mem_file $mem_files { + set source_input_path [file join $input_dir $mem_file] + if {![file exists $source_input_path]} { + puts "WARNING: Input file '$mem_file' does not exist. Skipping..." + continue + } + + puts "Copying $source_input_path -> $target_input_path" + file copy -force $source_input_path $target_input_path + + puts "Running simulation for $mem_file" + restart + run $sim_time + puts "Simulation finished for $mem_file" + + if {[file exists $source_output_path]} { + set target_output_path [file join $output_dir "out${idx}.txt"] + file copy -force $source_output_path $target_output_path + puts "Saved output -> $target_output_path" + } else { + puts "WARNING: Output file '$source_output_path' not found after simulation." + } + + incr idx + } +} result options] + +# Restore the existing input file since we overwrote it +puts "Restoring original input file $target_input_path" +file copy -force [file join $sim_dir $temp_backup] $target_input_path +file delete -force [file join $sim_dir $temp_backup] + +# If our code threw an error, we want to report that to the user +if {$return_status != 0} { + return -code $return_status -options $options $result +} diff --git a/IntegrationTests/common/hdl/tf_mem_bin.vhd b/IntegrationTests/common/hdl/tf_mem_bin.vhd index 9ec055dc169..28a98212188 100644 --- a/IntegrationTests/common/hdl/tf_mem_bin.vhd +++ b/IntegrationTests/common/hdl/tf_mem_bin.vhd @@ -355,6 +355,7 @@ begin --report time'image(now)&" tf_mem_bin "&NAME&" sync_nent"; init := '0'; bx := 1; + new_bx := true; slv_clk_cnt := (others => '0'); slv_page_cnt := (0 => '1', others => '0'); validbinmasktmp <= (others => '0');