Main Content

hdlcoder.TimingGenerator Class

Namespace: hdlcoder

Base class to implement custom tool and device support for critical path estimation reporting

Since R2024a

Description

The hdlcoder.TimingGenerator class is an abstract base class you can use to implement custom tool and device support for critical path estimation reporting. You can use instances of this class as the input to the genhdltdb function.

Because the hdlcoder.TimingGenerator class is an abstract class, you cannot create an instance of this class directly. You use the handle class to derive other classes, which can be concrete classes whose instances are handle objects.

To define a handle class, derive your class from hdlcoder.TimingGenerator using the syntax in this classdef code.

classdef MyHandleClass < hdlcoder.TimingGenerator
    ...
end

When you create a derived class object from hdlcoder.TimingGenerator, HDL Coder™ generates a comma-separated file called timing_info.txt. The file contains timing details related to the operation undergoing a timing analysis.

The hdlcoder.TimingGenerator class is a handle class.

Class Attributes

Abstract
true
HandleCompatible
true

For information on class attributes, see Class Attributes.

Events

Event NameTriggerEvent DataEvent Attributes
ObjectBeingDestroyedTriggered when the handle object is about to be destroyed, but before calling the delete method. event.EventData

NotifyAccess= private

ListenAccess=public

Examples

collapse all

In this example, you examine an example of an hdlcoder.TimingGenerator subclass designed for Intel® Quartus® hardware and use the information from this class to create a custom subclass of the hdlcoder.timingGenerator class. You should define a synthesizeRTL method that you call to run synthesis and timing analysis and then pass the hdlcoder.TimingGenerator.IntelQuartus class as a name-value argument to the genhdltdb function to generate a timing database. To view the example subclass, at the MATLAB® command line, enter:

edit hdlcoder.timingGenerator.IntelQuartus

Create a custom class called IntelQuartus.

classdef IntelQuartus < hdlcoder.TimingGenerator
%

%   Copyright 2023 The MathWorks, Inc.
    
   

Create a method that generates a TCL script that creates a project and runs synthesis.

methods
function generateSynthesisTclScript(obj)
            %create tcl file to execute
            tfile_name = 'Synthesis.tcl';
            % create timing analysis scripts
            
            project_name = obj.ModelInfo.topSubsystem;
            hdl_files = strjoin(obj.getRTLFileList(), ' ');

            cfile = fopen(tfile_name, 'w');
            fprintf(cfile, [...
                'load_package flow' newline...
                'load_package report' newline...
                'load_package sta' newline...
                newline...
                'project_new ' project_name ' -overwrite' newline...
                'set_global_assignment -name TOP_LEVEL_ENTITY toplevel_Characterization' newline...
                'set_global_assignment -name DEVICE ' obj.TargetInfo.deviceFullName newline...
                'foreach sfile [list ' hdl_files '] {' newline,...
                '   set_global_assignment -name VHDL_FILE $sfile' newline,...
                '}' newline...
                'set_global_assignment -name USE_TIMEQUEST_TIMING_ANALYZER ON' newline...
                'execute_module -tool map' newline...
                newline...
                'set pin_ids [get_names -filter In* -node_type pin]' newline...
                'foreach_in_collection pin_id $pin_ids {' newline...
                '   set pin_name [get_name_info -info full_path $pin_id]' newline...
                     ... puts "$pin_name : $pin_id";
                '   set_instance_assignment -to $pin_name -name VIRTUAL_PIN ON' newline...
                '}' newline...
                newline...
                'set pin_ids [get_names -filter Out* -node_type pin]' newline...
                'foreach_in_collection pin_id $pin_ids {' newline...
                '   set pin_name [get_name_info -info full_path $pin_id]' newline...
                    ... puts "$pin_name : $pin_id";
                '   set_instance_assignment -to $pin_name -name VIRTUAL_PIN ON' newline...
                '}' newline...
                newline...
                'export_assignments' newline,...
                'execute_module -tool map' newline]);
            if strcmp(obj.TargetInfo.toolName, 'Intel Quartus Pro')
                fprintf(cfile, ['execute_module -tool fit -args --plan' newline]);
            end
            fprintf(cfile, 'project_close');
            fclose(cfile);
        end

Create a method that generates a TCL script that performs a timing analysis on all possible input, output, and internal register paths. The method outputs this information to a file called timing_info.txt. Remove:

  • Hold time from input-to-internal paths

  • Setup time from internal-to-output paths

  • Setup and hold times from input-to-output paths

function obj = generateReportTimingTclScript(obj)
            % perform static timing analysis
            
            % create timing analysis scripts
            cfile = fopen('ReportTimingGroups.tcl', 'w');
            % top level entity name
            project_name = obj.ModelInfo.topSubsystem;
            fprintf(cfile, 'load_package flow\n\n');
            % open project
            fprintf(cfile, ['project_open ' project_name '\n']);
            % open timing_info.txt to store delay data
            fprintf(cfile, ['set tf [open ' obj.CsvFile ' w]\n']);
            tfile = '$tf';
            % create timing netlist
            switch lower(obj.TargetInfo.toolName)
                case 'intel quartus pro'
                    arg = 'post_syn';
                case 'altera quartus ii'
                    arg = 'post_map';
                otherwise
                    error('unknown quartus tool name')
            end
            fprintf(cfile, ['execute_module -tool sta -args --' arg '\n']);
            fprintf(cfile, 'create_timing_netlist -post_map -model slow -zero_ic_delay\n');
            % add clk (period = 100ns) to the design
            %fprintf(cfile, 'create_clock -add clk -name clk_name -period 1\n');
            % update timing netlist (after adding clock)
            %fprintf(cfile, 'update_timing_netlist\n');
            % source the delay method
            % # Input Arguments:
            % # coll1, coll2: collection objects
            % # path_type (one of the following)
            % # Quartus reports setup time on the required path
            % # 1 between internal registers => datapath_delay = clk_q_delay + path_delay + setup_delay
            % # 2 between input and internal registers => datapath_delay = path_delay + setup_delay
            % # 3 between internal and output registers => datapath_delay = path_delay + clk_q_delay
            % # 4 between input and output registers => datapath_delay = path_delay
            % # Return Values:
            % # [list datapath_delay interconnect_delay]
            fprintf(cfile, [...
                'proc get_delay {coll1 coll2 path_type} {' newline...
                ...compute delay only for non-empty collection pairs
                '   if { [get_collection_size $coll1] == 0 || [get_collection_size $coll2] == 0 } {' newline...
                ...if any input collection is empty
                ...return infinite delay in the csv file
        		'      return [list "inf" "inf"]' newline...
                '   }' newline...
                ...retrieve the worst case timing path object
                '   set path [get_timing_paths -from $coll1 -to $coll2]' newline...
                '   puts [report_timing -from $coll1 -to $coll2]' newline...
                '   puts [report_path -summary -from $coll1 -to $coll2]' newline...
                ...if no path is found
                '   if { [get_collection_size $path] == 0 } {' newline...
                ...return infinite delay in the csv file
        		'      return [list "inf" "inf"]' newline...
            	'   }' newline...
                ...extract path information
                '   foreach_in_collection path_var $path {' newline...
                ...nodes on the arrival path
                '      set arrival_nodes [get_path_info -arrival_points $path_var]' newline...
                ...nodes on the required path
                '      set required_nodes [get_path_info -required_points $path_var]' newline...
                ...path delay. report_path return a two-element list. lindex 1 is the path delay
                '      set path_delay [report_path -summary -from $coll1 -to $coll2]' newline...
                '      set path_delay [lindex $path_delay 1]' newline...
                ...interconnect delay and clk to q delay setup delay intialization
                '      set ic_delay 0' newline...
                '      set clk_q_delay 0' newline...
                '      set setup_delay 0' newline...
                '      foreach_in_collection arrival_nodes_var $arrival_nodes {' newline...
                ...retrieve node type. "utco" for input register and "ic" for interconnect element
                '         set type_name [get_point_info -type $arrival_nodes_var]' newline...
                ...search for input register. if matched, clk_q_delay is the incremental delay through the node    
                '         if { [string compare -nocase $type_name "utco"] == 0 } {' newline...
                '            set clk_q_delay [get_point_info -incremental_delay $arrival_nodes_var]' newline...
                '         }' newline...
                ...search for interconnect. if matched, ic_delay is the incremental delay through the node
                '         if { [string compare -nocase $type_name "ic"] == 0 } {' newline...
                '            set inc_ic_delay [get_point_info -incremental_delay $arrival_nodes_var]' newline...
                '            set ic_delay [expr { $ic_delay + $inc_ic_delay }]' newline...
                '         }' newline...
                '      }' newline...
                ...setup delay
                '      foreach_in_collection required_nodes_var $required_nodes {' newline...
                ...retrieve node type. "utsu" for destination register
                '         set type_name [get_point_info -type $required_nodes_var]' newline...
                ...search for destination register. if matched, setup_delay is the incremental delay through the node
                '         if { [string compare -nocase $type_name "utsu"] == 0 } {' newline...
                '            set setup_delay [get_point_info -incremental_delay $required_nodes_var]' newline...
                '         }' newline...
                '      }' newline...
                '   }' newline...
                ...calculations based on path type
                '   if {$path_type == 1} {' newline...
                '      set datapath_delay [expr { $clk_q_delay + $path_delay + $setup_delay }]' newline...
                '   } elseif {$path_type == 2} {' newline...
                '      set datapath_delay [expr { $path_delay + $setup_delay }]' newline...
                '   } elseif {$path_type == 3} {' newline...
                '      set datapath_delay [expr { $path_delay + $clk_q_delay }]' newline...
                '   } else {' newline...
                '      set datapath_delay $path_delay' newline...
                '   }' newline...
                'return [list $datapath_delay $ic_delay]' newline...
                '}' newline]);
            
            % get all registers in the design
            fprintf(cfile, 'set mw_all_registers [get_registers]\n');
            % get all internal registers
            % fprintf(cfile, ['set mw_all_internal_registers [get_registers ' obj.ModelInfo.blockSubsystem '*]\n']);
            fprintf(cfile, ['set mw_internal_registers [get_registers ' obj.ModelInfo.blockSubsystem '*]\n']);
            % get all input registers
            inregs_var = {};
            input_regs = obj.ModelInfo.portRegisters.in.values;   
            for idx = 1:numel(input_regs)
                inregName = input_regs{idx};
                nt = regexp(inregName, '.*_(?<portid>\d+)', 'names');
                portId = str2double(nt.portid);
                
                inregs_var{portId+1} = ['mw_inport_' int2str(portId)]; %#ok<AGROW>
                fprintf(cfile, 'set %s [get_registers %s%s]\n', inregs_var{portId+1}, inregName, obj.RegSuffix);
            end
            % get all output registers
            outregs_var = {};
            output_regs = obj.ModelInfo.portRegisters.out.values;                                      
            for idx = 1:numel(output_regs)
                outregName = output_regs{idx};
                nt = regexp(outregName, '.*_(?<portid>\d+)', 'names');
                portId = str2double(nt.portid);
                
                outregs_var{portId+1} = ['mw_outport_' int2str(portId)]; %#ok<AGROW>
                fprintf(cfile, 'set %s [get_registers %s%s]\n', outregs_var{portId+1}, outregName, obj.RegSuffix);
            end
            % delay between internal registers
            print_path_details('mw_internal_registers', 'mw_internal_registers', '1');
            % delay between input and internal registers
            for idx = 1:numel(inregs_var)
                if isempty(inregs_var{idx})
                    error('Incorrect port names for in script generation');
                end
                print_path_details(inregs_var{idx}, 'mw_internal_registers', '2');
            end
            % delay between output and internal registers
            for idx = 1:numel(outregs_var)
                if isempty(outregs_var{idx})
                    error('Incorrect port names for in script generation');
                end
                print_path_details('mw_internal_registers', outregs_var{idx}, '3');
            end
            % delay between input and output
            for idx = 1:numel(inregs_var)
                for oidx = 1:numel(outregs_var)
                    print_path_details(inregs_var{idx}, outregs_var{oidx}, '4');
                end
            end
            % close script
            fclose(cfile);

            % function to print report_path
            % read get_delay.tcl for help on path_type
            function print_path_details(src_cells, dest_cells, path_type)
                % DelayInfo, mw_xxx, mw_xxx
                fprintf(cfile, 'puts -nonewline %s "DelayInfo, %s, %s"\n', tfile, src_cells, dest_cells);
                fprintf(cfile, 'set delay_data [get_delay $%s $%s %s]\n', src_cells, dest_cells, path_type);
                fprintf(cfile, 'puts %s ", [lindex $delay_data 0]"\n', tfile);
            end
        end

Create a synthesizeRTL method that calls the project creation, synthesis, and timing analysis TCL scripts.

function [status, logTxt] = synthesizeRTL(obj)
            % perform RTL synthesis

            obj.generateSynthesisTclScript();
            obj.generateReportTimingTclScript();
            
            % execute quartus_map
            scriptName = fullfile(pwd, 'Synthesis.tcl');
            cmdString = ['quartus_sta -t ' scriptName];
            [status, logTxt] = system(cmdString);

            if status
                % synthesis errored out
                return;
            end
            % reopen project and perform timing analysis
            scriptName = fullfile(pwd, 'ReportTimingGroups.tcl');
            cmdString = ['quartus_sta -t' scriptName] ;
            [status, logTxt] = system(cmdString);
        end
        
    end
end

Generate a timing database by using the genhdltdb function and passing the IntelQuartus class as a name-value argument to the function.

tg = IntelQuartus;
genhdltdb("SynthesisDeviceConfiguration",{"Arria10","10AS066N3F40E2SG"},...
"TimingDatabaseDirectory","C:Work\Database",...
"NativeFloatingPoint","off",...
"TimingGenerator",tg);

In this example, you examine an example of an hdlcoder.TimingGenerator subclass designed for Xilinx® Vivado® hardware and use the information from this class to create a custom subclass of the hdlcoder.timingGenerator class. You should define a synthesizeRTL method that you call to run synthesis and timing analysis. Pass the hdlcoder.TimingGenerator.XilinxVivado class as a name-value argument to the genhdltdb function to generate a timing database. To view the shipping custom class, at the MATLAB Command Line, enter:

edit hdlcoder.timingGenerator.XilinxVivado

Create a custom class called XilinxVivado.

classdef XilinxVivado < hdlcoder.TimingGenerator
%

%   Copyright 2023 The MathWorks, Inc.
    
   

Create a method that generates a TCL script that creates a project and runs synthesis.

methods
function generateSynthesisTclScript(obj)
            cfile = fopen('Synthesis.tcl', 'w');
            fprintf(cfile, ['set mypart ' obj.TargetInfo.deviceFullName '\n']);
            fprintf(cfile, ['set myTopLevelEntry ' obj.ModelInfo.topSubsystem '\n']);
            hdl_files = strjoin(obj.getRTLFileList(), ' ');
            fprintf(cfile, [...
                'set hdl_files [list ' hdl_files ']' newline...
                'foreach filename $hdl_files {' newline...
                '    read_vhdl  $filename' newline...
                '    puts "Reading file $filename."' newline...
                '}' newline...
                'set temp [open ' obj.ReportFile ' w ]' newline...
                'close $temp' newline...
                'synth_design -top $myTopLevelEntry -part $mypart' newline...
                'set myclk_ports [list [get_ports clk] ]' newline...
                'if { [ llength $myclk_ports ] > 0 } {' newline...
                '   create_clock -name named_clock [get_ports clk] -period 100' newline...
                '}']);
            fclose(cfile);
        end

Create a method that generates a TCL script that performs a timing analysis on all possible input, output, and internal register paths. The method outputs this information to a file called timing_info.txt. Remove:

  • Hold time from input-to-internal paths

  • Setup time from internal-to-output paths

  • Setup and hold times from input-to-output paths

function generateReportTimingTclScript(obj)
            
            rfile = fopen('ReportTimingGroups.tcl', 'w');
            tfile = '$tf' ;
            csvfile = obj.CsvFile;
            reportfile = obj.ReportFile;

            fprintf(rfile, 'source library.tcl\n');
            fprintf(rfile, ['set tf [open ' csvfile ' w]\n']);
            fprintf(rfile, 'set mw_all_registers [get_cells  -filter { IS_SEQUENTIAL && IS_PRIMITIVE }] \n');
            
            intRegsCmd = [ '[ get_cells -hierarchical -regexp { .*' obj.ModelInfo.blockSubsystem '/.* } -filter { IS_SEQUENTIAL && IS_PRIMITIVE } ]'];
            
            fprintf(rfile, 'set mw_internal_registers %s \n', intRegsCmd);
            
            input_regs = obj.ModelInfo.portRegisters.in.values;
            inregs_var = cell(1,numel(input_regs));
            for idx = 1:numel(input_regs)
                inregName = input_regs{idx};
                nt = regexp(inregName, '.*_(?<portid>\d+)_RED$', 'names') ;
                portId = str2double(nt.portid) ;
                
                inregs_var{portId+1} = ['mw_inport_' int2str(portId) ] ;
                fprintf(rfile, 'set %s [list ]\n', inregs_var{portId+1});
                fprintf(rfile, 'set %s [concat $%s [get_cells %s%s] ] \n', inregs_var{portId+1}, inregs_var{portId+1}, inregName, obj.RegSuffix);
            end
            
            output_regs = obj.ModelInfo.portRegisters.out.values ;
            outregs_var = cell(1,numel(output_regs));
            for idx = 1:numel(output_regs)
                outregName = output_regs{idx};
                nt = regexp(outregName, '.*_(?<portid>\d+)_RED$', 'names') ;
                portId = str2double(nt.portid) ;
                
                outregs_var{portId+1} = ['mw_outport_' int2str(portId) ] ;
                fprintf(rfile, 'set %s [list ]\n', outregs_var{portId+1});
                fprintf(rfile, 'set %s [concat $%s [get_cells %s%s]] \n', outregs_var{portId+1}, outregs_var{portId+1}, outregName, obj.RegSuffix);
            end
            print_path_details('mw_internal_registers', 'mw_internal_registers');
            
            for idx = 1 : numel(inregs_var)
                if isempty(inregs_var{idx})
                    error('Incorrect port names for in script generation');
                end
                print_path_details(inregs_var{idx}, 'mw_internal_registers');
            end
            
            for idx = 1 : numel(outregs_var)
                if isempty(outregs_var{idx})
                    error(' Incorrect port names for in script generation');
                end
                print_path_details('mw_internal_registers', outregs_var{idx});
            end
            
            for iidx = 1:numel(inregs_var)
                for oidx = 1:numel(outregs_var)
                    print_path_details(inregs_var{iidx}, outregs_var{oidx});
                end
            end
            
            fprintf(rfile, 'close $tf\n');
            fclose(rfile);

            cfile = fopen('library.tcl', 'w');
            fprintf(cfile, [...
                'proc remove_list {il y} {' newline...
                '  set x [lsort $il ]' newline...
                '  set y [lsort $y ]' newline...
                '  foreach e $y {' newline...
                '    set idx [lsearch -exact  $x $e]' newline...
                '    set len [llength $x]' newline...
                ...puts "index : $idx and length $len"
                '    if { $idx < $len } {' newline...
                '      if { $idx != -1 } {' newline...
                '        set x [lreplace $x $idx $idx]' newline...
                '      }' newline...
                '    }' newline...
                '  }' newline...
                '  set rval $x' newline...
                ...set len [llength $x]
                ...puts "return list size $len"
                '  return $rval' newline...
                '}' newline...
                newline...
                'proc handle_path { tpath fname  } {' newline...
                '    if { [llength $tpath] == 0 } {' newline...
                '        puts  $fname ", inf"' newline...
                '    } else {' newline...
                '        set tpath_t  [lindex $tpath 0 ]' newline...
                '        set delay_t [get_property DATAPATH_DELAY $tpath_t]' newline...
                '        puts  $fname ", $delay_t"' newline...
                '    }' newline...
                '}']);
            fclose(cfile);

            function print_path_details(src_cells, dest_cells)
                %fprintf(sfile, 'puts "************ Begin Delay Section *************** >> mathworks_report_timing_groups.log "\n');
                fprintf(rfile, 'puts -nonewline %s "DelayInfo, %s, %s"\n', tfile, src_cells, dest_cells);
                fprintf(rfile, 'set mw_path [list ]\n');
                fprintf(rfile, 'if { [llength $%s] > 0 && [llength $%s] > 0 } { \n ', src_cells, dest_cells);
                fprintf(rfile, '     set mw_path [get_timing_paths -delay_type max -from $%s -to $%s -nworst 1 -max_paths 1]\n', src_cells, dest_cells);
                fprintf(rfile, '     report_timing -from $%s -to $%s >> %s \n', src_cells, dest_cells, reportfile);
                fprintf(rfile, '}\n');
                fprintf(rfile, 'handle_path $mw_path %s\n', tfile);
                %fprintf(sfile, 'puts "************ End Delay Section ***************" >> mathworks_report_timing_groups.log \n');
            end
        end

Create a synthesizeRTL method that calls the project creation, synthesis, and timing analysis TCL scripts.

function [status, logTxt] = synthesizeRTL(obj)
            obj.generateSynthesisTclScript();
            obj.generateReportTimingTclScript();

            runTclFile = 'run.tcl';
            cfile = fopen(runTclFile, 'w');
            fprintf(cfile, 'source Synthesis.tcl\n');
            fprintf(cfile, 'source ReportTimingGroups.tcl\n');
            fclose(cfile);

            scriptName = fullfile(pwd, runTclFile);
            cmdString = ['vivado -mode batch -source ' scriptName] ;
            [status, logTxt] = system(cmdString);
        end

Create a postProcessTimingInfo method to further process the timing information reported by the synthesis tool.

function timingInfo = postProcessTimingInfo(obj, timingInfo)
            %correct the delay numbers by removing setup and
            %clock-q delays
            for i=1:numel(timingInfo)
                pt = timingInfo(i);

                if pt.ports(1) ~= characterization.STA.Characterization.RegisterPort
                    regName = [ obj.ModelInfo.portRegisters.in( pt.ports(1) + 1) ...
                        obj.RegSuffix ] ;
                    regName = regexprep(regName, '\*','');

                    d = obj.getCQTime(regName);

                    if ( d > 0 )
                        pt.delay = pt.delay - d ;
                        assert(pt.delay >= 0,'Negative delay');
                    end
                elseif pt.ports(2) ~= characterization.STA.Characterization.RegisterPort
                    regName = [ obj.ModelInfo.portRegisters.out( pt.ports(2) + 1) ...
                        obj.RegSuffix ] ;
                    regName = regexprep(regName, '\*','');

                    d = obj.getSetupTime(regName);

                    if ( d > 0 )
                        pt.delay = pt.delay - d ;
                        assert(pt.delay >= 0, 'Negative delay');
                    end
                end
                timingInfo(i) = pt ;
            end
        end

Create methods to extract timing information from a report file. The getSetupTime function retrieves setup time information from the report file and the getCQTime function retrieves the clock-to-Q time information from the report file.

function delay = getSetupTime(obj, regName)
            delay = -1 ;
            entryRegExp = '^\s*(?<name>[^\s]+)\s+\((?<desc>[^\)]+)?\)?\s+(?<delay>[\d\.]+)\s+(?<cdelay>[\d\.]+)\s+([rf])?\s+(?<compname>[^\s]+)$';
            fid = fopen(obj.ReportFile, 'r');

            cline = fgets(fid);

            while ischar(cline)
                cline = strtrim(cline);
                matched = regexp(cline, entryRegExp, 'match');
                if isempty(matched)
                    % continue to next line
                    cline = fgets(fid);
                    continue
                end

                dEntry = regexp(cline, entryRegExp, 'names');
                matched = regexp(dEntry.compname, [ '^\s*([^\/\s]*)' regName '([^\s\/]*)$'], 'match');
                % peak to next line
                cline = fgets(fid);
                if isempty(matched) || ~ischar(cline) || ...
                        isempty(regexp(strtrim(cline), '^([\s-]+)$', 'match'))
                    % continue to next line
                    continue;
                end

                delay = str2double(dEntry.delay);
                break;
            end
            fclose(fid);
        end


        function delay = getCQTime(obj, regName)
            delay = -1 ;
            entryRegExp = '^\s*(?<name>[^\s]+)\s+\((?<desc>[^\)]+)?\)?\s+(?<delay>[\d\.]+)\s+(?<cdelay>[\d\.]+)\s+([rf])?\s+(?<compname>[^\s]+)$';
            fid = fopen(obj.ReportFile, 'r');

            cline = fgets(fid);

            while ischar(cline)
                cline = strtrim(cline);
                matched = regexp(cline, entryRegExp, 'match');
                if isempty(matched)
                    % continue to next line
                    cline = fgets(fid);
                    continue;
                end

                dEntry = regexp(cline, entryRegExp, 'names');
                matched = regexp(dEntry.compname, [ '^\s*([^\/\s]*)' regName '([^\s\/]*)/Q$'], 'match');
                if isempty(matched)
                    % continue to next line
                    cline = fgets(fid);
                    continue;
                end

                delay = str2double(dEntry.delay);
                break;
            end
            fclose(fid);
        end

    end
end

Generate a timing database by using the genhdltdb function and passing the XilinxVivado class as a name-value argument to the function.

tg = XilinxVivado;
genhdltdb("SynthesisDeviceConfiguration",{"Zynq","xc7z020","clg484","-1"}, ...
    "TimingDatabaseDirectory","C:\Work\database\", ...
    "NativeFloatingPoint","off", ...
    "TimingGenerator",tg);

More About

expand all

Version History

Introduced in R2024a