
%

%   Copyright 2015-2024 The MathWorks, Inc.

classdef (Abstract) Plugin_Tcl_Vivado < handle
    % Vivado Tcl generation functions

    %% all functions are required to be implemented in plugin folder
    methods (Abstract, Static)

        getTclIPPackageInit(fid, ipPackageProjName, fpgaPartStr)
        getTclSetIPProperty(fid, ipcoreName, ipcoreVersion, ipcoreTimestamp)
        getTclPackageIPFromProject(fid)

        getTclAddFileToProject(fid, srcFileRelPath, libName)
        getTclAddIPGroup(fid, groupName)
        getTclAddFileToIPGroup(fid, srcFileIPPath, groupName, fileTypeName, libName)
        getTclAddFilesToIP(fid, srcFileIPPath, libName, isVHDL)

        getTclRemoveInterface(fid)
        getTclInterfaceDefinition(fid, interfaceName, abstractionVLNV, busVLNV)
        getTclInterfaceMode(fid, interfaceName, channelDirType)
        getTclParameter(fid, interfaceName, parameterName, parameterValue)
        getTclPortMap(fid, interfaceName, xilinxPortID, interfacePortID)
        getTclMemoryMap(fid, interfaceName, addrRange)

        getTclAddIPReport(fid, reportHTMLFileRelPath, docFolder)
        getTclAddSWDriver(fid, headerFileRelPath)
        getTclIPCacheOOC(fid, bdName);
        getTclEnableUserIPCache(fid);
        getTclSetGlobalSynth(fid,bdName);

        generateProductGuidePDF(ipCoreName, docFolder, reportFileName);

        generateTclDownloadBitstreamJTAG(bitstreamPath, toolPath, chainPosition);
    end

    %-------------------READ BEFORE MODIFYING BELOW------------------------
    % To change these methods in future releases, first move the method you
    % wish to move into the version specific child classes and then modify
    % this method in the current version only. This will help maintain
    % backward compatibility with previous Quartus/Qsys tools that are no
    % longer tested in BaT
    %----------------------------------------------------------------------
    methods( Static )
        function copyIPcacheFolderFromZipFile(hVTool, hRD)
            % copy pre-generated IP cache to target project path
            % for vivado 2016.4 or earlier, the IP cache files are
            % directly copied to folder ipcache
            % for vivado 2017.2, the IP cache files are also copied to
            % folder ipcache, but the zip file should contain the folder
            % name with version number, for example, 2017.2/
            if ~isempty(hRD.IPCacheZipFile)         % Empty dir
                filePath = hRD.getFilePathFromRD(hRD.IPCacheZipFile);
                if ~exist(filePath,'file')             % ipcache.zip not found
                    downstream.tool.createDir(fullfile(hVTool.getProjectFolder, 'ipcache'));
                else
                    hVTool.unzipFileFromRD(hRD.IPCacheZipFile,'ipcache',hRD);
                end
            end
        end
        
        function copyIPcacheFolderFromFunction(hVTool, hRD)
            % copy pre-generated IP cache files to target project path
            ipCacheFunction = hRD.IPCacheFunction;
            if ~isempty(ipCacheFunction)
                if nargout(ipCacheFunction) == 1
                    % IP cache file directory not specified
                    % IP cache file is same as IP list function
                    ipCacheFile = feval(ipCacheFunction);
                    ipCacheFilePath = which(ipCacheFunction);
                    [ipCacheDir,~,~] = fileparts(ipCacheFilePath);

                elseif nargout(ipCacheFunction) == 2
                    % IP cache file root directory specified by IP cache function
                    [ipCacheFile, ipCacheDir] = feval(ipCacheFunction);
                else
                    error(message('hdlcommon:plugin:InvalidOutputIPCacheFunction', ...
                        ipCacheFunction));
                end
                sourcePath = fullfile(ipCacheDir,ipCacheFile);
                if ~exist(sourcePath,'file') % ipcache.zip not found
                    downstream.tool.createDir(fullfile(hVTool.getProjectFolder, 'ipcache'));
                else
                    hVTool.unzipIPcaheFile(sourcePath,'ipcache');
                end
            end
        end

        function getTclClockResetConnection(fid,clk,rst)
            fprintf(fid, 'connect_bd_net -net [get_bd_nets -of_objects [get_bd_pins %s]] [get_bd_pins $HDLCODERIPINST/IPCORE_CLK] [get_bd_pins %s]\n', clk, clk);
            fprintf(fid, 'connect_bd_net -net [get_bd_nets -of_objects [get_bd_pins %s]] [get_bd_pins $HDLCODERIPINST/IPCORE_RESETN] [get_bd_pins %s]\n', rst,rst);
        end

        function getTclSetClockFreq(fid,clkNum,freq,inst)
            fprintf(fid, '# Update output frequency on clock wizard based on target frequency\n');
            fprintf(fid, 'set_property -dict [list CONFIG.CLKOUT%d_REQUESTED_OUT_FREQ {%0.3f}] [get_bd_cells %s]\n', clkNum, freq, inst);
        end

        function getTclSetClockFreqVersal(fid,clkNum,freq,inst)
            % Note: The Versal clock wizard is different from other clock
            % wizards. It does not let you set the frequency of an
            % individual output clock. Instead, you need to specify the
            % complete list of output clock frequencies (7 total) if you
            % want to make a change to any of them. See "Appendix A:
            % Migrating" in Versal Clocking Wizard IP guide (found here:
            % https://www.xilinx.com/content/dam/xilinx/support/documentation/ip_documentation/clk_wizard/v1_0/pg321-clocking-wizard.pdf)
            fprintf(fid, '# Update output frequency on clocking wizard based on target frequency\n');

            % Get output clock frequencies. This returns a comma-separated
            % list of ALL the output clock frequencies (7 total)
            fprintf(fid, 'set clk_freq_list_str [get_property CONFIG.CLKOUT_REQUESTED_OUT_FREQUENCY [get_bd_cells %s]]\n', inst);

            % Since the previous command returns a comma-separated string
            % we need to split it into a list to use list-based Tcl
            % commands
            fprintf(fid, 'set clk_freq_list [split $clk_freq_list_str ","]\n');

            % Update the frequency of the output clock in clk_freq_list
            % given by clkNum. Then rejoin the list with ","
            fprintf(fid, 'set clk_freq_list_updated [join [lreplace $clk_freq_list %d %d %0.3f] ","]\n', clkNum-1, clkNum-1, freq);

            % Set the output clock frequency on the clock wizard IP (for
            % all the clocks in the list)
            fprintf(fid, 'set_property -dict [list CONFIG.CLKOUT_REQUESTED_OUT_FREQUENCY $clk_freq_list_updated] [get_bd_cells %s]\n', inst);
        end

        function getTclClockResetAXIConnection(fid,interface,clk,rst)
            % connect AXI clock/reset to IPCORE
            fprintf(fid, 'connect_bd_net -net [get_bd_nets -of_objects [get_bd_pins %s]] [get_bd_pins $HDLCODERIPINST/%s_ACLK] [get_bd_pins %s]\n', clk, interface, clk);
            fprintf(fid, 'connect_bd_net -net [get_bd_nets -of_objects [get_bd_pins %s]] [get_bd_pins $HDLCODERIPINST/%s_ARESETN] [get_bd_pins %s]\n', rst, interface, rst);
        end

        function getTclAddConstraintFilesToIP(fid, srcFileIPPath, libName, ~)
            % add multicycle path constraint to IP Tcl
            hdlTypeName = 'xdcFile';
            hdlSynGroupName = 'xilinx_anylanguagesynthesis';

            thisClassName = mfilename('class');
            % add XDC file to IP synthesis file group
            downstream.tool.runInClass(thisClassName, 'getTclAddXDCToIPGroup', ...
                fid, srcFileIPPath, hdlSynGroupName, hdlTypeName, libName);
        end

        function getTclAddXDCToIPGroup(fid, srcFileIPPath, groupName, fileTypeName, libName)
            % add file to IP file group
            if nargin < 5
                libName = '';
            end

            fprintf(fid, 'ipx::add_file {%s} [ipx::get_file_groups %s -of_objects [ipx::current_core]]\n', ...
                srcFileIPPath, groupName);
            fprintf(fid, 'set_property type {{%s}} [ipx::get_files {%s} -of_objects [ipx::get_file_groups %s -of_objects [ipx::current_core]]]\n', ...
                fileTypeName, srcFileIPPath, groupName);
            if ~isempty(libName)
                fprintf(fid, 'set_property library_name {%s} [ipx::get_files {%s} -of_objects [ipx::get_file_groups %s -of_objects [ipx::current_core]]]\n', ...
                    libName, srcFileIPPath, groupName);
            end
        end

        function getTclSetIPKernelProperty(fid, ctrlProtocol)
            % fprintf(fid, 'set_property ipi_drc {ignore_freq_hz false} [ipx::current_core]\n');
            fprintf(fid, 'set_property sdx_kernel true [ipx::current_core]\n');
            fprintf(fid, 'set_property sdx_kernel_type rtl [ipx::current_core]\n');
            fprintf(fid, 'set_property vitis_drc {ctrl_protocol %s} [ipx::current_core]\n', ctrlProtocol);
            fprintf(fid, 'set_property ipi_drc {ignore_freq_hz true} [ipx::current_core]\n');
        end
        
        function getTclPackageIP(fid)
            % finishing up IP core package
            fprintf(fid, '\n# Package IP\n');
            fprintf(fid, 'ipx::create_xgui_files [ipx::current_core]\n');
            fprintf(fid, 'ipx::check_integrity -quiet [ipx::current_core]\n');
            fprintf(fid, 'ipx::save_core [ipx::current_core]\n');
        end

        function getTclArchiveIP(fid, packageZipFileRelPath)
            % create IP zip file
            fprintf(fid, 'ipx::archive_core {%s} [ipx::current_core]\n', ...
                packageZipFileRelPath);
        end

        function getTclPackageXO(fid, xoFileRelPath, kernelName, ipFolderRelPath, ctrlProtocol)
            % Package IP as XO file
            fprintf(fid, '\n# Package XO\n');
            fprintf(fid, 'ipx::check_integrity -kernel -quiet [ipx::current_core]\n');
            fprintf(fid, 'package_xo -force -xo_path %s -kernel_name %s -ip_directory %s -ctrl_protocol %s\n', ...
                xoFileRelPath, kernelName, ipFolderRelPath, ctrlProtocol);
        end

        function getTclProjectClose(fid)
            fprintf(fid, 'close_project\n');
            fprintf(fid, 'exit\n');
        end

        %% JTAG AXI Master Tcl connections
        function getTclInterfaceConnectionWithJTAGAXIMaster (fid,clk,rst,interface,target,isAXI4InterfaceInUse,targetFreq,isversal)
            % instantiate the axi manager
            % instantiate axi interconnect
            % define the axi interconnect clk and rst interface coresponding to axim
            if(isversal)
                fprintf(fid, 'create_bd_cell -type ip -vlnv mathworks.com:user:hdlverifier_axi_manager_versal:*.* hdlverifier_axi_mngr\n\n');
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:smartconnect:1.0 axi_interconnect\n');

                % for smart connect having single clock and rst interface
                interconnect_clk_intr_axim = 'axi_interconnect/aclk';
                interconnect_rst_intr_axim = 'axi_interconnect/aresetn';
            else
                fprintf(fid, 'create_bd_cell -type ip -vlnv mathworks.com:ip:hdlverifier_axi_manager:*.* hdlverifier_axi_mngr\n');
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:*.* axi_interconnect\n');

                % interconnect clock and rst interface for axim
                interconnect_clk_intr_axim = 'axi_interconnect/S00_ACLK';
                interconnect_rst_intr_axim = 'axi_interconnect/S00_ARESETN';
            end
            % configure axi interconnect
            if isAXI4InterfaceInUse
                fprintf(fid, 'set_property -dict [list CONFIG.NUM_SI {1} CONFIG.NUM_MI {1}] [get_bd_cells axi_interconnect]\n');
            else
                fprintf(fid, 'set_property -dict [list CONFIG.NUM_SI {2} CONFIG.NUM_MI {1}] [get_bd_cells axi_interconnect]\n');
            end

            % Clock and reset connections of hdl verifier and Interconnect
            % IPs to the reference design IPcore clock and IP core reset
            % To avoid negative slack at JTAG AXI Master, A 50 MHz clock
            % and reset will get as input to the HDL Verifier MATLAB
            % AXI Master
            % Set Target Frequency step in WFAGUI
            % Insetion of new clock wizard(50 MHz output clock) and
            % Processor system reset and
            if targetFreq > 100
                if isversal
                    fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wizard:*.0 clk_wiz\n');
                    fprintf(fid, 'set_property -dict [list CONFIG.USE_LOCKED {true} CONFIG.USE_RESET {true} CONFIG.CLKOUT_USED {true} CONFIG.CLKOUT_PORT {clk_out1} CONFIG.CLKOUT_REQUESTED_OUT_FREQUENCY {50} CONFIG.CLKOUT_REQUESTED_PHASE {0.000} CONFIG.CLKOUT_REQUESTED_DUTY_CYCLE {50.000} CONFIG.CLKOUT_DRIVES {BUFG} CONFIG.CLKOUT1_DIVIDE {60.000000}] [get_bd_cells clk_wiz]\n');
                    interconnect_clk_less100 = clk;
                    interconnect_rst_less100   = rst;
                else
                    fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:*.0 clk_wiz\n');
                    fprintf(fid, 'set_property -dict [list CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {50.000} CONFIG.RESET_TYPE {ACTIVE_LOW} CONFIG.MMCM_DIVCLK_DIVIDE {1} CONFIG.MMCM_CLKOUT0_DIVIDE_F {20.000} CONFIG.RESET_PORT {resetn} CONFIG.CLKOUT1_JITTER {151.636}] [get_bd_cells clk_wiz]\n');
                    interconnect_clk_less100 = 'clk_wiz/clk_out1';
                    interconnect_rst_less100   = 'proc_sys_reset/peripheral_aresetn';
                end
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:*.0 proc_sys_reset\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins clk_wiz/clk_in1]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins clk_wiz/resetn]\n', rst);
                fprintf(fid, 'connect_bd_net [get_bd_pins clk_wiz/clk_out1] [get_bd_pins proc_sys_reset/slowest_sync_clk]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins clk_wiz/locked] [get_bd_pins proc_sys_reset/dcm_locked]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins proc_sys_reset/ext_reset_in]\n', rst);
                % Connect the newly generated 50 MHz clock and reset
                % connections to the JTAG AXI Master
                fprintf(fid, 'connect_bd_net [get_bd_pins clk_wiz/clk_out1] [get_bd_pins hdlverifier_axi_mngr/aclk]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins proc_sys_reset/peripheral_aresetn] [get_bd_pins hdlverifier_axi_mngr/aresetn]\n');

                % Connect the Corresponding JTAG AXI Master clock and reset
                % connections to the AXI interconnect
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins %s]\n',interconnect_clk_less100,interconnect_clk_intr_axim);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins %s]\n',interconnect_rst_less100,interconnect_rst_intr_axim);
            else
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/aclk]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/aresetn]\n', rst);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins %s]\n', clk,interconnect_clk_intr_axim);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins %s]\n', rst,interconnect_rst_intr_axim);
            end

            % Connect Slave0 interface of AXI Interconnect to hdl verifier IP
            fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/axi4m] [get_bd_intf_pins axi_interconnect/S00_AXI]\n');

            % Remove AXI interconnects S01 pin connections for the reference designs which has no AXI4 Slave interface in it,
            % Aslo only when the reference design parameter 'Insert JTAG AXI Master' is turned 'on'.
            if ~isAXI4InterfaceInUse
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins %s] [get_bd_intf_pins axi_interconnect/S01_AXI]\n', target);
            end

            % Master interface of AXI Interconnect with HDLCoder DUT IP
            fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins $HDLCODERIPINST/%s] [get_bd_intf_pins axi_interconnect/M00_AXI]\n', interface);

            if ~isversal
                % interconnect clock and reset connections
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/ACLK]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/ARESETN]\n', rst);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/M00_ACLK]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/M00_ARESETN]\n', rst);
                if ~isAXI4InterfaceInUse
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S01_ACLK]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S01_ARESETN]\n', rst);
                end
            end
        end


        %% get instace name of Versal
        function getTCLversalCIPSinstance(fid)
            fprintf(fid,'# get instance name of : versal_cips_0\n');
            fprintf(fid,'set bd_cells [get_bd_cell *]\n');
            fprintf(fid,'for { set a 0}  {$a <= [llength $bd_cells]} {incr a} {\n');
            fprintf(fid,'set bd_cell_vlnv [get_property VLNV [lindex $bd_cells $a] -quiet]\n');
            fprintf(fid,'if { [string match "*xilinx.com:ip:versal_cips:*.*" $bd_cell_vlnv] } {\n');
            fprintf(fid,'break\n');
            fprintf(fid,'}\n');
            fprintf(fid,'}\n');
            fprintf(fid,'if {$a <= [llength $bd_cells]} {\n');
            fprintf(fid,'set versal_cips_0 [lindex $bd_cells $a]\n');
            fprintf(fid,'} else {\n');
            fprintf(fid,'error "Error: Unable to find CIPS IP in reference design. To use AXI Manager and FPGA Data Capture, insert Xilinx Versal platform CIPS IP in your reference design."\n');
            fprintf(fid,'}\n');
        end

        function getTCLconfigVersalCIPSforAXIM(fid)
            % Configure CIPS to enable USER3 interface
            % connect CIPS BSCAN interface to AXIM
            fprintf(fid,'set_property -dict [list CONFIG.PS_PMC_CONFIG {PS_USE_BSCAN_USER3 1} CONFIG.PS_PMC_CONFIG_APPLIED {1}] [get_bd_cells $versal_cips_0]\n');
            fprintf(fid, 'if {[catch {connect_bd_intf_net [get_bd_intf_pins $versal_cips_0/BSCAN_USER3] [get_bd_intf_pins hdlverifier_axi_mngr/bscan]} errmsg]} {\n');
            fprintf(fid, 'error "Error : Unable to add AXI Manager IP to your reference design because BSCAN_USER3 interface of Xilinx Versal platform CIPS IP is not available."\n');
            fprintf(fid, '}\n');
        end

        %% Ethernet AXI Master Tcl connections
        function getTclInterfaceConnectionWithEthernetAXIMaster(fid,clk,rst,interface,target,isAXI4InterfaceInUse, targetFreq,hBoard)
            % Add hdl verifier IPs and AXI Interconnect to the blok design
            % and configure AXI Interconnect to two Slave interfaces
            % (Master1: hdlverifier IP, Master2: Zynq processing system IP)
            % and one Master interface

            % Check for ethernet Interface type
            if strcmp(hBoard.InterfaceType, 'GMII')
                fprintf(fid, 'create_bd_cell -type ip -vlnv mathworks.com:ip:udp_axi_manager:*.* hdlverifier_axi_mngr\n');
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:*.* axi_interconnect\n');

                if isAXI4InterfaceInUse
                    fprintf(fid, 'set_property -dict [list CONFIG.NUM_SI {1} CONFIG.NUM_MI {1}] [get_bd_cells axi_interconnect]\n');
                else
                    fprintf(fid, 'set_property -dict [list CONFIG.NUM_SI {2} CONFIG.NUM_MI {1}] [get_bd_cells axi_interconnect]\n');
                end
                % Clock and reset connections of hdl verifier and Interconnect
                % IPs to the reference design IPcore clock and IP core reset
                % To avoid negative slack at Ethernet AXI Master , A 50 MHz
                % clock output is enabled

                if targetFreq > 100
                    % Connect the newly generated 50 MHz clock and reset
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins hdlverifier_axi_mngr/aclk]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins hdlverifier_axi_mngr/axis_aclk]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins hdlverifier_axi_mngr/aresetn]\n');
                    % Connect the Corresponding Ethernet AXI Master clock and reset
                    % connections to the AXI interconnect
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins axi_interconnect/S00_ACLK]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins axi_interconnect/S00_ARESETN]\n');
                    % Connect clock and reset connections to the AXIS of
                    % Ethernet MAC Hub
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins hdlverifier_axi_mngr/axis_aresetn]\n');
                else
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/aclk]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/aresetn]\n', rst);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S00_ACLK]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S00_ARESETN]\n', rst);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/axis_aclk]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/axis_aresetn]\n', rst);
                end

                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/ACLK]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/ARESETN]\n', rst);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/M00_ACLK]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/M00_ARESETN]\n', rst);

                % Connect Slave0 interface of AXI Interconnect to hdl verifier IP
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/axi4m] [get_bd_intf_pins axi_interconnect/S00_AXI]\n');

                % Remove AXI interconnects S01 pin connections for the reference designs which has no AXI4 Slave interface in it,
                % Also only when the reference design parameter 'Insert AXI Master' is turned 'on'.
                if ~isAXI4InterfaceInUse
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S01_ACLK]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S01_ARESETN]\n', rst);
                end

                % Master interface of AXI Interconnect with HDLCoder DUT IP
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins $HDLCODERIPINST/%s] [get_bd_intf_pins axi_interconnect/M00_AXI]\n', interface);


                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/s_axis] [get_bd_intf_pins ethernet_mac_hub_gmii/m0_axis]\n');
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/m_axis] [get_bd_intf_pins ethernet_mac_hub_gmii/s0_axis]\n');

            elseif (strcmp(hBoard.InterfaceType, 'MII'))
                fprintf(fid, 'create_bd_cell -type ip -vlnv mathworks.com:ip:udp_axi_manager:*.* hdlverifier_axi_mngr\n');
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:*.* axi_interconnect\n');

                if isAXI4InterfaceInUse
                    fprintf(fid, 'set_property -dict [list CONFIG.NUM_SI {1} CONFIG.NUM_MI {1}] [get_bd_cells axi_interconnect]\n');
                else
                    fprintf(fid, 'set_property -dict [list CONFIG.NUM_SI {2} CONFIG.NUM_MI {1}] [get_bd_cells axi_interconnect]\n');
                end

                % Clock and reset connections of hdl verifier and Interconnect
                % IPs to the reference design IPcore clock and IP core reset
                % To avoid negative slack at JTAG AXI Master, A 50 MHz clock
                % and reset will get as input to the HDL Verifier MATLAB
                % AXI Master
                % Set Target Frequency step in WFAGUI
                % Insetion of new clock wizard(50 MHz output clock) and
                % Processor system reset and
                if targetFreq > 100
                    % Connect the newly generated 50 MHz clock and reset
                    % connections to the UDP MATLAB as AXI Master
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out1] [get_bd_pins hdlverifier_axi_mngr/aclk]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out1] [get_bd_pins hdlverifier_axi_mngr/axis_aclk]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins hdlverifier_axi_mngr/aresetn]\n');
                    % Connect the Corresponding Ethernet AXI Master clock and reset
                    % connections to the AXI interconnect
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out1] [get_bd_pins axi_interconnect/S00_ACLK]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins axi_interconnect/S00_ARESETN]\n');
                    % Connect clock and reset connections to the AXIS of
                    % Ethernet MAC Hub
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins hdlverifier_axi_mngr/axis_aresetn]\n');
                else
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/aclk]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/aresetn]\n', rst);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S00_ACLK]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S00_ARESETN]\n', rst);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/axis_aclk]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins hdlverifier_axi_mngr/axis_aresetn]\n', rst);
                end

                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/ACLK]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/ARESETN]\n', rst);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/M00_ACLK]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/M00_ARESETN]\n', rst);

                % Connect Slave0 interface of AXI Interconnect to hdl verifier IP
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/axi4m] [get_bd_intf_pins axi_interconnect/S00_AXI]\n');

                % Remove AXI interconnects S01 pin connections for the reference designs which has no AXI4 Slave interface in it,
                % Also only when the reference design parameter 'Insert AXI Master' is turned 'on'.
                if ~isAXI4InterfaceInUse
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S01_ACLK]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S01_ARESETN]\n', rst);
                end

                % Master interface of AXI Interconnect with HDLCoder DUT IP
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins $HDLCODERIPINST/%s] [get_bd_intf_pins axi_interconnect/M00_AXI]\n', interface);

                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/s_axis] [get_bd_intf_pins ethernet_mac_hub_mii/m0_axis]\n');
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/m_axis] [get_bd_intf_pins ethernet_mac_hub_mii/s0_axis]\n');

            elseif(strcmp(hBoard.InterfaceType, 'SGMII'))
                fprintf(fid, 'create_bd_cell -type ip -vlnv mathworks.com:ip:udp_axi_manager:*.* hdlverifier_axi_mngr\n');
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:*.* axi_interconnect\n');
                if isAXI4InterfaceInUse
                    fprintf(fid, 'set_property -dict [list CONFIG.NUM_SI {1} CONFIG.NUM_MI {1}] [get_bd_cells axi_interconnect]\n');
                else
                    fprintf(fid, 'set_property -dict [list CONFIG.NUM_SI {2} CONFIG.NUM_MI {1}] [get_bd_cells axi_interconnect]\n');
                end
                % in SGMII the axis clock of Ethernet MAC limited to 50 MHz
                % so unlike GMII and MII , in SGMII the 50 MHz clock
                % generated for any target freq and connected to axis clock
                % of Ethernet MAC and UDP AM.
                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins hdlverifier_axi_mngr/aclk]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins hdlverifier_axi_mngr/axis_aclk]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins hdlverifier_axi_mngr/aresetn]\n');
                % Connect the Corresponding Ethernet AXI Master clock and reset
                % connections to the AXI interconnect
                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins axi_interconnect/S00_ACLK]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins axi_interconnect/S00_ARESETN]\n');

                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_rest/peripheral_aresetn] [get_bd_pins hdlverifier_axi_mngr/axis_aresetn]\n');

                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/ACLK]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/ARESETN]\n', rst);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/M00_ACLK]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/M00_ARESETN]\n', rst);

                % Connect Slave0 interface of AXI Interconnect to hdl verifier IP
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/axi4m] [get_bd_intf_pins axi_interconnect/S00_AXI]\n');

                % Remove AXI interconnects S01 pin connections for the reference designs which has no AXI4 Slave interface in it,
                % Also only when the reference design parameter 'Insert AXI Master' is turned 'on'.
                if ~isAXI4InterfaceInUse
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S01_ACLK]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins axi_interconnect/S01_ARESETN]\n', rst);
                end

                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins ethernet_mac_hub_gmii/m0_axis] [get_bd_intf_pins hdlverifier_axi_mngr/s_axis]\n');
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins hdlverifier_axi_mngr/m_axis] [get_bd_intf_pins ethernet_mac_hub_gmii/s0_axis]\n');
                % Master interface of AXI Interconnect with HDLCoder DUT IP
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins $HDLCODERIPINST/%s] [get_bd_intf_pins axi_interconnect/M00_AXI]\n', interface);

            else
                ;
            end
        end

        %% Ethernet FDC Tcl connections
        function getTclInterfaceConnectionWithEthernetFDC(fid,clk,rst,isInsertEthernetFDC,isInsertEthernetAXI,targetFreq,hBoard)
            if(isInsertEthernetAXI && isInsertEthernetFDC)
                numChannel = 2;
            else
                numChannel = 1;
            end

            if strcmp(hBoard.InterfaceType, 'GMII')
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins $HDLCODERIPINST/S_AXIS_FDC] [get_bd_intf_pins ethernet_mac_hub_gmii/m%s_axis]\n',num2str(numChannel-1));
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins $HDLCODERIPINST/M_AXIS_FDC]  [get_bd_intf_pins ethernet_mac_hub_gmii/s%s_axis]\n',num2str(numChannel-1));
            elseif strcmp(hBoard.InterfaceType, 'MII')
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins ethernet_mac_hub_mii/m%s_axis] [get_bd_intf_pins $HDLCODERIPINST/S_AXIS_FDC] \n',num2str(numChannel-1));
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins ethernet_mac_hub_mii/s%s_axis] [get_bd_intf_pins $HDLCODERIPINST/M_AXIS_FDC] \n',num2str(numChannel-1));
            elseif strcmp(hBoard.InterfaceType, 'SGMII')
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins ethernet_mac_hub_gmii/m%s_axis] [get_bd_intf_pins $HDLCODERIPINST/S_AXIS_FDC] \n',num2str(numChannel-1));
                fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins ethernet_mac_hub_gmii/s%s_axis] [get_bd_intf_pins $HDLCODERIPINST/M_AXIS_FDC] \n',num2str(numChannel-1));
            end
        end

        function getTclInstantiateEtherMac(fid,clk,rst,numChannel,targetFreq,isInsertEthernetAXI,hBoard,hRD,prjFolder)

            % Add Ethernet Mac to the block design
            % add a clock widget , for Ethernet mac
            if strcmp(hBoard.InterfaceType, 'GMII')
                fprintf(fid, 'create_bd_cell -type ip -vlnv mathworks.com:ip:ethernet_mac_hub_gmii:*.* ethernet_mac_hub_gmii\n');
                fprintf(fid, 'set_property -dict [list CONFIG.NUM_AXIS_CHANNELS {%d}] [get_bd_cells ethernet_mac_hub_gmii]\n',numChannel);
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:*.* xlconstant\n');

                % Create a clock and reset as required by Ethernet MAC Hub A 50MHz clock
                % is created but disabled here will be enabled if required later
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:*.0 ether_mac_clk\n');
                fprintf(fid, 'set_property -dict [list CONFIG.CLKOUT2_USED {false} CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {125} CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {50} CONFIG.RESET_TYPE {ACTIVE_LOW}] [get_bd_cells ether_mac_clk]\n');
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:*.0 ether_mac_rest\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_clk/clk_in1]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_clk/resetn]\n', rst);
                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/locked] [get_bd_pins ether_mac_rest/dcm_locked]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_rest/ext_reset_in]\n', rst);

                % Clock and reset connections of hdl verifier and Interconnect
                % IPs to the reference design IPcore clock and IP core reset
                % To avoid negative slack at Ethernet AXI Master , A 50 MHz
                % clock output is enabled

                if (targetFreq > 100 && isInsertEthernetAXI)
                    fprintf(fid, 'set_property -dict [list CONFIG.CLKOUT2_USED {true}] [get_bd_cells ether_mac_clk]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins ether_mac_rest/slowest_sync_clk]\n');

                    % Connect clock and reset connections to the AXIS of
                    % Ethernet MAC Hub
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins ethernet_mac_hub_gmii/axis_aclk]\n');
                else
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ethernet_mac_hub_gmii/axis_aclk]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_rest/slowest_sync_clk]\n', clk);
                end


                % Connect Ethernet MAC Hub reset
                fprintf(fid, 'lassign [split $EthernetIPAddress .] ipa1 ipa2 ipa3 ipa4\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR1 $ipa1] [get_bd_cells ethernet_mac_hub_gmii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR2 $ipa2] [get_bd_cells ethernet_mac_hub_gmii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR3 $ipa3] [get_bd_cells ethernet_mac_hub_gmii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR4 $ipa4] [get_bd_cells ethernet_mac_hub_gmii]\n');
                fprintf(fid, 'set_property -dict [ list CONFIG.POLARITY {ACTIVE_HIGH} ] [get_bd_pins /ethernet_mac_hub_gmii/ref_reset]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins ethernet_mac_hub_gmii/ref_reset] [get_bd_pins ether_mac_rest/peripheral_reset]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out1] [get_bd_pins ethernet_mac_hub_gmii/ref_clk]\n');
                fprintf(fid, 'connect_bd_net -net xlconstant_dout [get_bd_pins ethernet_mac_hub_gmii/rxclk_en] [get_bd_pins ethernet_mac_hub_gmii/txclk_en] [get_bd_pins xlconstant/dout]\n');
                fprintf(fid, 'create_bd_port -dir O phy_mdc\n');
                fprintf(fid, 'create_bd_port -dir IO phy_mdio\n');
                fprintf(fid, 'create_bd_port -dir O phy_reset_n\n');
                fprintf(fid, 'connect_bd_net [get_bd_ports phy_reset_n] [get_bd_pins ether_mac_rest/peripheral_aresetn]\n');
                fprintf(fid, ['make_bd_pins_external  [get_bd_pins ethernet_mac_hub_gmii/phy_gtxclk] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_rxclk] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_txen] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_rxdv] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_rxer] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_rxd] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_txd] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_col] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_crs] ' ...
                    '[get_bd_pins ethernet_mac_hub_gmii/phy_txer]\n']);
                fprintf(fid, 'set_property name phy_gtxclk [get_bd_ports phy_gtxclk_0]\n');
                fprintf(fid, 'set_property name phy_rxclk [get_bd_ports phy_rxclk_0]\n');
                fprintf(fid, 'set_property name phy_txen [get_bd_ports phy_txen_0]\n');
                fprintf(fid, 'set_property name phy_rxdv [get_bd_ports phy_rxdv_0]\n');
                fprintf(fid, 'set_property name phy_rxer [get_bd_ports phy_rxer_0]\n');
                fprintf(fid, 'set_property name phy_rxd [get_bd_ports phy_rxd_0]\n');
                fprintf(fid, 'set_property name phy_txd [get_bd_ports phy_txd_0]\n');
                fprintf(fid, 'set_property name phy_col [get_bd_ports phy_col_0]\n');
                fprintf(fid, 'set_property name phy_crs [get_bd_ports phy_crs_0]\n');
                fprintf(fid, 'set_property name phy_txer [get_bd_ports phy_txer_0]\n');
                fprintf(fid, 'connect_bd_net [get_bd_ports phy_mdc] [get_bd_pins xlconstant/dout]\n');

                % update Ethernet Port Address
                for ii = 1:8
                    fprintf(fid, 'set_property -dict [list CONFIG.UDP_DSTPORT_FORCH%d {%d}] [get_bd_cells ethernet_mac_hub_gmii]\n',ii,hRD.EthernetPortAddr(ii));
                end

            elseif (strcmp(hBoard.InterfaceType, 'MII'))
                fprintf(fid, 'create_bd_cell -type ip -vlnv mathworks.com:user:ethernet_mac_hub_mii:*.* ethernet_mac_hub_mii\n');
                fprintf(fid, 'set_property -dict [list CONFIG.NUM_AXIS_CHANNELS {%d}] [get_bd_cells ethernet_mac_hub_mii]\n',numChannel);

                if (targetFreq > 100 && isInsertEthernetAXI)
                    fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:*.0 ether_mac_clk\n');
                    fprintf(fid, 'set_property -dict [list CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {50.000} CONFIG.RESET_TYPE {ACTIVE_LOW} CONFIG.MMCM_DIVCLK_DIVIDE {1} CONFIG.MMCM_CLKOUT0_DIVIDE_F {20.000} CONFIG.RESET_PORT {resetn} CONFIG.CLKOUT1_JITTER {151.636}] [get_bd_cells ether_mac_clk]\n');
                    fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:*.0 ether_mac_rest\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_clk/clk_in1]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_clk/resetn]\n', rst);
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out1] [get_bd_pins ether_mac_rest/slowest_sync_clk]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/locked] [get_bd_pins ether_mac_rest/dcm_locked]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_rest/ext_reset_in]\n', rst);
                    % Connect clock and reset connections to the AXIS of
                    % Ethernet MAC Hub
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out1] [get_bd_pins ethernet_mac_hub_mii/axis_aclk]\n');
                else
                    fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:*.0 ether_mac_rest\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ethernet_mac_hub_mii/axis_aclk]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_rest/slowest_sync_clk]\n', clk);
                    fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_rest/ext_reset_in]\n', rst);
                end
                % Set IP Address
                fprintf(fid, 'lassign [split $EthernetIPAddress .] ipa1 ipa2 ipa3 ipa4\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR1 $ipa1] [get_bd_cells ethernet_mac_hub_mii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR2 $ipa2] [get_bd_cells ethernet_mac_hub_mii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR3 $ipa3] [get_bd_cells ethernet_mac_hub_mii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR4 $ipa4] [get_bd_cells ethernet_mac_hub_mii]\n');
                % Connect Ethernet MAC Hub reset
                fprintf(fid, 'set_property -dict [ list CONFIG.POLARITY {ACTIVE_HIGH} ] [get_bd_pins /ethernet_mac_hub_mii/reset]\n');

                % Connect Ethernet MAC Hub signals to PHY
                fprintf(fid, 'connect_bd_net [get_bd_pins ethernet_mac_hub_mii/reset] [get_bd_pins ether_mac_rest/peripheral_reset]\n');
                fprintf(fid, ['make_bd_pins_external  [get_bd_pins ethernet_mac_hub_mii/mii_txen]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_txer]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_txclk]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/phy_mdc]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/phy_mdio]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/phy_reset_n]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_col]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_rxd]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_crs]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_rxclk]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_txd]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_rxdv]' ...
                    ' [get_bd_pins ethernet_mac_hub_mii/mii_rxer]\n']);

                fprintf(fid, 'set_property name phy_txen   [get_bd_ports mii_txen_0]\n');
                fprintf(fid, 'set_property name phy_txer  [get_bd_ports mii_txer_0]\n');
                fprintf(fid, 'set_property name phy_txclk [get_bd_ports mii_txclk_0]\n');
                fprintf(fid, 'set_property name phy_mdc   [get_bd_ports phy_mdc_0]\n');
                fprintf(fid, 'set_property name phy_mdio  [get_bd_ports phy_mdio_0]\n');
                fprintf(fid, 'set_property name phy_reset_n [get_bd_ports phy_reset_n_0]\n');
                fprintf(fid, 'set_property name phy_col   [get_bd_ports mii_col_0]\n');
                fprintf(fid, 'set_property name phy_rxd   [get_bd_ports mii_rxd_0]\n');
                fprintf(fid, 'set_property name phy_crs   [get_bd_ports mii_crs_0]\n');
                fprintf(fid, 'set_property name phy_rxclk [get_bd_ports mii_rxclk_0]\n');
                fprintf(fid, 'set_property name phy_txd   [get_bd_ports mii_txd_0]\n');
                fprintf(fid, 'set_property name phy_rxdv  [get_bd_ports mii_rxdv_0]\n');
                fprintf(fid, 'set_property name phy_rxer  [get_bd_ports mii_rxer_0]\n');

                % update Ethernet Port Address
                for ii = 1:8
                    fprintf(fid, 'set_property -dict [list CONFIG.UDP_DSTPORT_FORCH%d {%d}] [get_bd_cells ethernet_mac_hub_mii]\n',ii,hRD.EthernetPortAddr(ii));
                end

            elseif(strcmp(hBoard.InterfaceType, 'SGMII'))
                fprintf(fid, 'create_bd_cell -type ip -vlnv mathworks.com:ip:ethernet_mac_hub_gmii:*.* ethernet_mac_hub_gmii\n');
                fprintf(fid, 'set_property -dict [list CONFIG.NUM_AXIS_CHANNELS {%d}] [get_bd_cells ethernet_mac_hub_gmii]\n',numChannel);
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:gig_ethernet_pcs_pma:*.* gig_ethernet_pcs_pma\n');
                fprintf(fid, 'set_property -dict [ list CONFIG.Management_Interface {false} CONFIG.Standard {SGMII} CONFIG.SupportLevel {Include_Shared_Logic_in_Core}] [get_bd_cells gig_ethernet_pcs_pma]\n');

                % Create a clock and reset as required by Ethernet MAC Hub A 50MHz clock
                % is created but disabled here will be enabled if required later
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz:*.0 ether_mac_clk\n');
                fprintf(fid, 'set_property -dict [list CONFIG.CLKOUT2_USED {false} CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {200} CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {50} CONFIG.RESET_TYPE {ACTIVE_LOW}] [get_bd_cells ether_mac_clk]\n');
                fprintf(fid, 'create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:*.0 ether_mac_rest\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_clk/clk_in1]\n', clk);
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_clk/resetn]\n', rst);
                fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/locked] [get_bd_pins ether_mac_rest/dcm_locked]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins %s] [get_bd_pins ether_mac_rest/ext_reset_in]\n', rst);

                % Clock and reset connections of hdl verifier and Interconnect
                % IPs to the reference design IPcore clock and IP core reset
                % To avoid negative slack at Ethernet AXI Master , A 50 MHz
                % clock output is enabled

                if (isInsertEthernetAXI)
                    fprintf(fid, 'set_property -dict [list CONFIG.CLKOUT2_USED {true} CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {50}] [get_bd_cells ether_mac_clk]\n');
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins ether_mac_rest/slowest_sync_clk]\n');

                    % Connect clock and reset connections to the AXIS of
                    % Ethernet MAC Hub
                    fprintf(fid, 'connect_bd_net [get_bd_pins ether_mac_clk/clk_out2] [get_bd_pins ethernet_mac_hub_gmii/axis_aclk]\n');
                end

                % Create ports
                fprintf(fid, 'set ETH_GTREFCLK_N [ create_bd_port -dir I -type clk -freq_hz 125000000 ETH_GTREFCLK_N ]\n');
                fprintf(fid, 'set ETH_GTREFCLK_P [ create_bd_port -dir I -type clk -freq_hz 125000000 ETH_GTREFCLK_P ]\n');
                fprintf(fid, 'set ETH_MDC [ create_bd_port -dir O ETH_MDC ]\n');
                fprintf(fid, 'set ETH_MDIO [ create_bd_port -dir IO ETH_MDIO ]\n');
                fprintf(fid, 'set ETH_RESET_n [ create_bd_port -dir O ETH_RESET_n ]\n');
                fprintf(fid, 'set ETH_RXN [ create_bd_port -dir I ETH_RXN ]\n');
                fprintf(fid, 'set ETH_RXP [ create_bd_port -dir I ETH_RXP ]\n');
                fprintf(fid, 'set ETH_TXN [ create_bd_port -dir O ETH_TXN ]\n');
                fprintf(fid, 'set ETH_TXP [ create_bd_port -dir O ETH_TXP ]\n');

                %create instance of constants and set their properties
                fprintf(fid, 'set xlconstant_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0 ]\n');
                fprintf(fid, 'set_property -dict [ list CONFIG.CONST_VAL {0} CONFIG.CONST_WIDTH {1} ] $xlconstant_0\n');

                fprintf(fid, 'set xlconstant_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_1 ]\n');
                fprintf(fid, 'set_property -dict [ list CONFIG.CONST_VAL {33} CONFIG.CONST_WIDTH {16} ] $xlconstant_1\n');

                fprintf(fid, 'set xlconstant_2 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_2 ]\n');
                fprintf(fid, 'set_property -dict [ list CONFIG.CONST_VAL {16} CONFIG.CONST_WIDTH {5} ] $xlconstant_2\n');

                fprintf(fid, 'set xlconstant_3 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_3 ]\n');
                fprintf(fid, 'set_property -dict [ list CONFIG.CONST_VAL {1} CONFIG.CONST_WIDTH {1} ] $xlconstant_3\n');

                % Create connection between Ethernet MAC Hub and Xilinx
                % Set IP Address
                fprintf(fid, 'lassign [split $EthernetIPAddress .] ipa1 ipa2 ipa3 ipa4\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR1 $ipa1] [get_bd_cells ethernet_mac_hub_gmii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR2 $ipa2] [get_bd_cells ethernet_mac_hub_gmii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR3 $ipa3] [get_bd_cells ethernet_mac_hub_gmii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.IPADDR4 $ipa4] [get_bd_cells ethernet_mac_hub_gmii]\n');
                fprintf(fid, 'set_property -dict [list CONFIG.NUM_AXIS_CHANNELS {%d}] [get_bd_cells ethernet_mac_hub_gmii]\n',hBoard.NumChannels);

                % SGMII converter IP
                fprintf(fid, 'connect_bd_net -net ETH_GTREFCLK_N [get_bd_ports ETH_GTREFCLK_N] [get_bd_pins gig_ethernet_pcs_pma/gtrefclk_n]\n');
                fprintf(fid, 'connect_bd_net -net ETH_GTREFCLK_P [get_bd_ports ETH_GTREFCLK_P] [get_bd_pins gig_ethernet_pcs_pma/gtrefclk_p]\n');
                fprintf(fid, 'connect_bd_net -net ETH_RXN [get_bd_ports ETH_RXN] [get_bd_pins gig_ethernet_pcs_pma/rxn]\n');
                fprintf(fid, 'connect_bd_net -net ETH_RXP [get_bd_ports ETH_RXP] [get_bd_pins gig_ethernet_pcs_pma/rxp]\n');
                fprintf(fid, 'connect_bd_net -net ether_mac_clk_clk_out1 [get_bd_pins ether_mac_clk/clk_out1] [get_bd_pins gig_ethernet_pcs_pma/independent_clock_bufg]\n');
                fprintf(fid, 'connect_bd_net -net ethernet_mac_hub_gmii_0_phy_txd [get_bd_pins ethernet_mac_hub_gmii/phy_txd] [get_bd_pins gig_ethernet_pcs_pma/gmii_txd]\n');
                fprintf(fid, 'connect_bd_net -net ethernet_mac_hub_gmii_0_phy_txen [get_bd_pins ethernet_mac_hub_gmii/phy_txen] [get_bd_pins gig_ethernet_pcs_pma/gmii_tx_en]\n');
                fprintf(fid, 'connect_bd_net -net ethernet_mac_hub_gmii_0_phy_txer [get_bd_pins ethernet_mac_hub_gmii/phy_txer] [get_bd_pins gig_ethernet_pcs_pma/gmii_tx_er]\n');
                fprintf(fid, 'connect_bd_net -net gig_ethernet_pcs_pma_gmii_rx_dv [get_bd_pins ethernet_mac_hub_gmii/phy_rxdv] [get_bd_pins gig_ethernet_pcs_pma/gmii_rx_dv]\n');
                fprintf(fid, 'connect_bd_net -net gig_ethernet_pcs_pma_gmii_rx_er [get_bd_pins ethernet_mac_hub_gmii/phy_rxer] [get_bd_pins gig_ethernet_pcs_pma/gmii_rx_er]\n');
                fprintf(fid, 'connect_bd_net -net gig_ethernet_pcs_pma_gmii_rxd [get_bd_pins ethernet_mac_hub_gmii/phy_rxd] [get_bd_pins gig_ethernet_pcs_pma/gmii_rxd]\n');
                fprintf(fid, 'connect_bd_net -net gig_ethernet_pcs_pma_txn [get_bd_ports ETH_TXN] [get_bd_pins gig_ethernet_pcs_pma/txn]\n');
                fprintf(fid, 'connect_bd_net -net gig_ethernet_pcs_pma_txp [get_bd_ports ETH_TXP] [get_bd_pins gig_ethernet_pcs_pma/txp]\n');
                fprintf(fid, 'connect_bd_net -net gig_ethernet_pcs_pma_userclk2_out [get_bd_pins ethernet_mac_hub_gmii/phy_rxclk] [get_bd_pins ethernet_mac_hub_gmii/ref_clk] [get_bd_pins gig_ethernet_pcs_pma/userclk2_out]\n');
                fprintf(fid, 'connect_bd_net -net ether_mac_rest_0_peripheral_aresetn [get_bd_ports ETH_RESET_n] [get_bd_pins ether_mac_clk/reset] [get_bd_pins ether_mac_rest_0/peripheral_aresetn]\n');
                fprintf(fid, 'connect_bd_net -net xlconstant_0_dout [get_bd_pins ethernet_mac_hub_gmii/ref_reset] [get_bd_pins gig_ethernet_pcs_pma/an_restart_config] [get_bd_pins gig_ethernet_pcs_pma/reset] [get_bd_pins gig_ethernet_pcs_pma/speed_is_100] [get_bd_pins gig_ethernet_pcs_pma/speed_is_10_100] [get_bd_pins xlconstant_0/dout]\n');
                fprintf(fid, 'connect_bd_net -net xlconstant_1_dout [get_bd_pins gig_ethernet_pcs_pma/an_adv_config_vector] [get_bd_pins xlconstant_1/dout]\n');
                fprintf(fid, 'connect_bd_net -net xlconstant_2_dout [get_bd_pins gig_ethernet_pcs_pma/configuration_vector] [get_bd_pins xlconstant_2/dout]\n');
                fprintf(fid, 'connect_bd_net -net xlconstant_3_dout [get_bd_pins ethernet_mac_hub_gmii/rxclk_en] [get_bd_pins ethernet_mac_hub_gmii/txclk_en] [get_bd_pins gig_ethernet_pcs_pma/signal_detect] [get_bd_pins xlconstant_3/dout]\n');

                fprintf(fid, 'connect_bd_net [get_bd_pins xlconstant_0/dout] [get_bd_pins ethernet_mac_hub_gmii/phy_col]\n');
                fprintf(fid, 'connect_bd_net [get_bd_pins xlconstant_0/dout] [get_bd_pins ethernet_mac_hub_gmii/phy_crs]\n');
                fprintf(fid, 'connect_bd_net [get_bd_ports ETH_MDC] [get_bd_pins xlconstant_3/dout]\n');
                fprintf(fid, 'connect_bd_net [get_bd_ports ETH_RESET_n] [get_bd_pins xlconstant_3/dout]\n');

                % update Ethernet Port Address
                for ii = 1:8
                    fprintf(fid, 'set_property -dict [list CONFIG.UDP_DSTPORT_FORCH%d {%d}] [get_bd_cells ethernet_mac_hub_gmii]\n',ii,hRD.EthernetPortAddr(ii));
                end
            else
                ;
            end
            % create constraint file for ethernet mac hub
            if contains(hBoard.InterfaceType, {'GMII','SGMII'})
                fidEtherMac = fopen(fullfile(prjFolder,'vivado_ip_prj','EthernetMac_constraints.xdc'),'w');
                switch hBoard.InterfaceType
                    case 'GMII'
                        if targetFreq > 100
                            fprintf(fidEtherMac, 'set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins */ether_mac_clk/inst/*/CLKOUT0]] -group [get_clocks -of_objects [get_pins */ether_mac_clk/inst/*/CLKOUT1]]\n');
                        else
                            fprintf(fidEtherMac, 'set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins */ether_mac_clk/inst/*/CLKOUT0]] -group [get_clocks -of_objects [get_pins */system_0/clk_wiz_0/inst/*/CLKOUT0]]\n');
                        end
                    otherwise
                        fprintf(fidEtherMac, 'set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins */gig_ethernet_pcs_pma/*/*/*/CLKOUT0]] -group [get_clocks -of_objects [get_pins */ether_mac_clk/*/*/CLKOUT1]]\n');
                        % 						else
                        % 							fprintf(fidEtherMac, 'set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins */gig_ethernet_pcs_pma/*/*/*/CLKOUT0]] -group [get_clocks -of_objects [get_pins */system_0/clk_wiz_0/*/*/CLKOUT0]]\n');
                        % 						end
                end
                fclose(fidEtherMac);
                fprintf(fid,'add_files -fileset constrs_1 -norecurse EthernetMac_constraints.xdc\n');
            end
        end

        function getTclConnectFDCCIPS(fid)
            % Configures CIPS to connects with FPGA Data Capture interface
            fprintf(fid,'set_property -dict [list CONFIG.PS_PMC_CONFIG {PS_USE_BSCAN_USER2 1 } CONFIG.PS_PMC_CONFIG_APPLIED {1}] [get_bd_cells $versal_cips_0]\n');
            fprintf(fid, 'if {[catch {connect_bd_intf_net [get_bd_intf_pins $versal_cips_0/BSCAN_USER2] [get_bd_intf_pins $HDLCODERIPINST/S_BSCAN_FDC]} errmsg]} {\n');
            fprintf(fid, 'error "Error : Unable to add FPGA Data Capture to your reference design because BSCAN_USER2 interface of Xilinx Versal platform CIPS IP is not available."\n');
            fprintf(fid, '}\n');
        end

        function getTclInterfaceConnection(fid,interface,target)
            % connect interface to IPCORE
            fprintf(fid, 'connect_bd_intf_net [get_bd_intf_pins $HDLCODERIPINST/%s] [get_bd_intf_pins %s]\n', interface, target);
        end

        function getTclSetTopLevelEntity(fid, topLevelEntityName)
            % set top level HDL file
            fprintf(fid, 'set_property top %s [get_filesets sources_1]\n', topLevelEntityName);
            fprintf(fid, 'set_property top %s [get_filesets sim_1]\n', topLevelEntityName);

            fprintf(fid, 'update_compile_order -fileset sources_1\n');
            fprintf(fid, 'update_compile_order -fileset sim_1\n');
        end

        function getTclCreateAddrSeg(fid, range, offset, addrSpace, slaveSeg, name)
            fprintf(fid,['create_bd_addr_seg -range 0x%X -offset 0x%X '...
                '[get_bd_addr_spaces %s] '...
                '[get_bd_addr_segs %s] SEG_%s\n'],...
                range, offset, addrSpace, slaveSeg, name);
        end

        function getTclCreateAddrSpace(fid, interfaceName, addrWidth, dataWidth)
            % set AXI4 address space in ip core packaging step
            fprintf(fid,'ipx::add_address_space %s [ipx::current_core]\n',interfaceName);
            fprintf(fid,'set_property master_address_space_ref %s [ipx::get_bus_interfaces %s -of_objects [ipx::current_core]]\n',interfaceName,interfaceName);
            fprintf(fid,'set_property range %d [ipx::get_address_spaces %s -of_objects [ipx::current_core]]\n',2^addrWidth,interfaceName);
            fprintf(fid,'set_property width %d [ipx::get_address_spaces %s -of_objects [ipx::current_core]]\n',dataWidth,interfaceName);
        end

        function getTclCreateClockConstraint(fid, clkName,clkFreq)
            % generate a clock constraint
            period = (1/clkFreq)*1000;  %period is in ns, clkFreq in MHz
            fprintf(fid, 'create_clock -name MWCLK  -period %0.3f [get_ports %s]\n',period,clkName );

        end

        function getTclSysGenAddCoeFile(fid, coeFilePath)
            fprintf(fid, 'ipx::add_file {%s} [ipx::get_file_groups xilinx_anylanguagesynthesis -of_objects [ipx::current_core]]\n', coeFilePath);
            fprintf(fid, 'ipx::add_file {%s} [ipx::get_file_groups xilinx_anylanguagebehavioralsimulation -of_objects [ipx::current_core]]\n', coeFilePath);
        end

        function getTclSysGenIPPackage(fid, sysGenTclFileList)
            % generate SysGen related files and attach them to IP file list
            fprintf(fid, '\n# Generate System Generator related files\n');
            for ii = 1:length(sysGenTclFileList)
                aSysGenTclFile = sysGenTclFileList{ii};
                fprintf(fid, 'source "../../../../%s"\n', downstream.tool.filterBackSlash(aSysGenTclFile));
            end
            fprintf(fid, 'update_compile_order -fileset sources_1\n');

            fprintf(fid, '\n# Copy System Generator XCI files and add them to IP\n');
            fprintf(fid, 'set root_ip_dir "../ip"\n');
            fprintf(fid, 'if {![file isdirectory $root_ip_dir]} {\n');
            fprintf(fid, '    file mkdir $root_ip_dir\n');
            fprintf(fid, '}\n');
            fprintf(fid, 'set ip_xci_dir "ip"\n');
            fprintf(fid, 'set ip_source_dir "prj_ip.srcs/sources_1/ip/"\n');
            fprintf(fid, 'set ip_dir_list [glob -nocomplain -types {d r} -directory ${ip_source_dir} *]\n');
            fprintf(fid, 'foreach src_ip_dir $ip_dir_list {\n');
            fprintf(fid, '    set ipfiles [glob -nocomplain -type {f r} -directory ${src_ip_dir} *]\n');
            fprintf(fid, '    foreach ipfile $ipfiles {\n');
            fprintf(fid, '        if {[string match -nocase "*.xci" $ipfile]} {\n');
            fprintf(fid, '            set dest_ip_dir "$root_ip_dir/[file tail $src_ip_dir]"\n');
            fprintf(fid, '            set ip_xci_src_dir "$ip_xci_dir/[file tail $src_ip_dir]"\n');
            fprintf(fid, '            file mkdir $dest_ip_dir\n');
            fprintf(fid, '            puts "Copying ip file: $ipfile to IP directory: $dest_ip_dir "\n');
            fprintf(fid, '            file copy -force "$ipfile" "$dest_ip_dir"\n');
            fprintf(fid, '            set ip_xci_src_file_path "${ip_xci_src_dir}/[file tail $ipfile]"\n');
            fprintf(fid, '            ipx::add_file ${ip_xci_src_file_path} [ipx::get_file_groups xilinx_anylanguagesynthesis -of_objects [ipx::current_core]]\n');
            fprintf(fid, '            ipx::add_file ${ip_xci_src_file_path} [ipx::get_file_groups xilinx_anylanguagebehavioralsimulation -of_objects [ipx::current_core]]\n');
            fprintf(fid, '        }\n');
            fprintf(fid, '    }\n');
            fprintf(fid, '}\n');

        end
        function getTclVivadoMakeWrapper(fid, BlockDesignName, hdlExt)
            % generate Tcl to generate top level wrapper in Vivado

            fprintf(fid, 'make_wrapper -files $BDFILEPATH -top\n');
            fprintf(fid, 'regsub -all "%s.%s" [get_files %s.%s] "%s_wrapper.%s" TOPFILEPATH\n', ...
                BlockDesignName, hdlExt, ...
                BlockDesignName, hdlExt, ...
                BlockDesignName, hdlExt);
            fprintf(fid, 'add_files -norecurse $TOPFILEPATH\n');
        end

        function getTclBuildStreamWithTimingCheck(fid,bitstreamfolderPath,bitStreamFilename,timingFailurePostfix,bitStreamFileExt, reportErrorOnTiming, runExt, SlackTolerance)
            fprintf(fid, 'open_run impl_1\n');
            fprintf(fid, 'set slackvalue [get_property SLACK [get_timing_paths]]\n');
            if SlackTolerance == 0
                fprintf(fid, 'if [expr [get_property SLACK [get_timing_paths]] < 0] { \n');
            else
                fprintf(fid, 'if [expr [get_property SLACK [get_timing_paths]] < -%4.4f] { \n', SlackTolerance);
            end
            % When run build externally and ref design parameter is set to error
            % then rename the bitstream to _timingfailure
            if runExt && reportErrorOnTiming % Run build externally
                fprintf(fid, '   cd %s\n',bitstreamfolderPath);
                fprintf(fid, '   file rename %s.%s %s%s.%s\n',bitStreamFilename,bitStreamFileExt,bitStreamFilename,timingFailurePostfix,bitStreamFileExt);
                % When run build internally, make a copy of the bitstream
                % After the run build, delete one of the bitstream in EmbeddedToolDriver
                % class based on the ref design parameter
            elseif ~runExt % Run build internally
                fprintf(fid, '   cd %s\n',bitstreamfolderPath);
                fprintf(fid, '   file copy %s.%s %s%s.%s\n',bitStreamFilename,bitStreamFileExt,bitStreamFilename,timingFailurePostfix,bitStreamFileExt);
            end
            fprintf(fid, '   puts " \n The worst slack is: $slackvalue ns "\n');
            if reportErrorOnTiming
                fprintf(fid, '   return -code error [format " ERROR- Timing constraints NOT met! \n "] \n');
            else
                fprintf(fid, '   puts " Timing constraints NOT met! "\n');
            end
            fprintf(fid, '} \n' );
        end

        function getValidateBd(fid)
            % Generate Tcl to validate block design in Vivado
            fprintf(fid, 'validate_bd_design\n');
        end
    end

end

% LocalWords:  HDLCODERIPINST IPCORE RESETN CLKOUT intf ACLK ARESETN filesets
% LocalWords:  fileset MWCLK AXI seg segs isdirectory prj nocomplain ipfiles
% LocalWords:  ipfile nocase dest ipx anylanguagesynthesis BDFILEPATH regsub
% LocalWords:  anylanguagebehavioralsimulation TOPFILEPATH norecurse Qsys
% LocalWords:  vivado ipcache
