da4ml 0.5.0__cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. da4ml/__init__.py +4 -0
  2. da4ml/_binary/__init__.py +15 -0
  3. da4ml/_binary/dais_bin.cpython-312-x86_64-linux-gnu.so +0 -0
  4. da4ml/_binary/dais_bin.pyi +5 -0
  5. da4ml/_cli/__init__.py +30 -0
  6. da4ml/_cli/convert.py +194 -0
  7. da4ml/_cli/report.py +295 -0
  8. da4ml/_version.py +32 -0
  9. da4ml/cmvm/__init__.py +4 -0
  10. da4ml/cmvm/api.py +264 -0
  11. da4ml/cmvm/core/__init__.py +221 -0
  12. da4ml/cmvm/core/indexers.py +83 -0
  13. da4ml/cmvm/core/state_opr.py +284 -0
  14. da4ml/cmvm/types.py +739 -0
  15. da4ml/cmvm/util/__init__.py +7 -0
  16. da4ml/cmvm/util/bit_decompose.py +86 -0
  17. da4ml/cmvm/util/mat_decompose.py +121 -0
  18. da4ml/codegen/__init__.py +9 -0
  19. da4ml/codegen/hls/__init__.py +4 -0
  20. da4ml/codegen/hls/hls_codegen.py +196 -0
  21. da4ml/codegen/hls/hls_model.py +255 -0
  22. da4ml/codegen/hls/source/ap_types/ap_binary.h +78 -0
  23. da4ml/codegen/hls/source/ap_types/ap_common.h +376 -0
  24. da4ml/codegen/hls/source/ap_types/ap_decl.h +212 -0
  25. da4ml/codegen/hls/source/ap_types/ap_fixed.h +360 -0
  26. da4ml/codegen/hls/source/ap_types/ap_fixed_base.h +2354 -0
  27. da4ml/codegen/hls/source/ap_types/ap_fixed_ref.h +718 -0
  28. da4ml/codegen/hls/source/ap_types/ap_fixed_special.h +230 -0
  29. da4ml/codegen/hls/source/ap_types/ap_int.h +330 -0
  30. da4ml/codegen/hls/source/ap_types/ap_int_base.h +1885 -0
  31. da4ml/codegen/hls/source/ap_types/ap_int_ref.h +1346 -0
  32. da4ml/codegen/hls/source/ap_types/ap_int_special.h +223 -0
  33. da4ml/codegen/hls/source/ap_types/ap_shift_reg.h +138 -0
  34. da4ml/codegen/hls/source/ap_types/etc/ap_private.h +7199 -0
  35. da4ml/codegen/hls/source/ap_types/hls_math.h +27 -0
  36. da4ml/codegen/hls/source/ap_types/hls_stream.h +263 -0
  37. da4ml/codegen/hls/source/ap_types/utils/x_hls_utils.h +80 -0
  38. da4ml/codegen/hls/source/binder_util.hh +71 -0
  39. da4ml/codegen/hls/source/build_binder.mk +22 -0
  40. da4ml/codegen/hls/source/vitis_bitshift.hh +32 -0
  41. da4ml/codegen/rtl/__init__.py +15 -0
  42. da4ml/codegen/rtl/common_source/binder_util.hh +99 -0
  43. da4ml/codegen/rtl/common_source/build_binder.mk +34 -0
  44. da4ml/codegen/rtl/common_source/build_quartus_prj.tcl +104 -0
  45. da4ml/codegen/rtl/common_source/build_vivado_prj.tcl +111 -0
  46. da4ml/codegen/rtl/common_source/ioutil.hh +124 -0
  47. da4ml/codegen/rtl/common_source/template.sdc +27 -0
  48. da4ml/codegen/rtl/common_source/template.xdc +30 -0
  49. da4ml/codegen/rtl/rtl_model.py +486 -0
  50. da4ml/codegen/rtl/verilog/__init__.py +10 -0
  51. da4ml/codegen/rtl/verilog/comb.py +239 -0
  52. da4ml/codegen/rtl/verilog/io_wrapper.py +113 -0
  53. da4ml/codegen/rtl/verilog/pipeline.py +67 -0
  54. da4ml/codegen/rtl/verilog/source/lookup_table.v +27 -0
  55. da4ml/codegen/rtl/verilog/source/multiplier.v +37 -0
  56. da4ml/codegen/rtl/verilog/source/mux.v +58 -0
  57. da4ml/codegen/rtl/verilog/source/negative.v +31 -0
  58. da4ml/codegen/rtl/verilog/source/shift_adder.v +59 -0
  59. da4ml/codegen/rtl/vhdl/__init__.py +9 -0
  60. da4ml/codegen/rtl/vhdl/comb.py +206 -0
  61. da4ml/codegen/rtl/vhdl/io_wrapper.py +120 -0
  62. da4ml/codegen/rtl/vhdl/pipeline.py +71 -0
  63. da4ml/codegen/rtl/vhdl/source/lookup_table.vhd +52 -0
  64. da4ml/codegen/rtl/vhdl/source/multiplier.vhd +40 -0
  65. da4ml/codegen/rtl/vhdl/source/mux.vhd +102 -0
  66. da4ml/codegen/rtl/vhdl/source/negative.vhd +35 -0
  67. da4ml/codegen/rtl/vhdl/source/shift_adder.vhd +101 -0
  68. da4ml/converter/__init__.py +63 -0
  69. da4ml/converter/hgq2/__init__.py +3 -0
  70. da4ml/converter/hgq2/layers/__init__.py +11 -0
  71. da4ml/converter/hgq2/layers/_base.py +132 -0
  72. da4ml/converter/hgq2/layers/activation.py +81 -0
  73. da4ml/converter/hgq2/layers/attn.py +148 -0
  74. da4ml/converter/hgq2/layers/batchnorm.py +15 -0
  75. da4ml/converter/hgq2/layers/conv.py +149 -0
  76. da4ml/converter/hgq2/layers/dense.py +39 -0
  77. da4ml/converter/hgq2/layers/ops.py +240 -0
  78. da4ml/converter/hgq2/layers/pool.py +107 -0
  79. da4ml/converter/hgq2/layers/table.py +176 -0
  80. da4ml/converter/hgq2/parser.py +161 -0
  81. da4ml/trace/__init__.py +6 -0
  82. da4ml/trace/fixed_variable.py +965 -0
  83. da4ml/trace/fixed_variable_array.py +600 -0
  84. da4ml/trace/ops/__init__.py +13 -0
  85. da4ml/trace/ops/einsum_utils.py +305 -0
  86. da4ml/trace/ops/quantization.py +74 -0
  87. da4ml/trace/ops/reduce_utils.py +105 -0
  88. da4ml/trace/pipeline.py +181 -0
  89. da4ml/trace/tracer.py +186 -0
  90. da4ml/typing/__init__.py +3 -0
  91. da4ml-0.5.0.dist-info/METADATA +85 -0
  92. da4ml-0.5.0.dist-info/RECORD +96 -0
  93. da4ml-0.5.0.dist-info/WHEEL +6 -0
  94. da4ml-0.5.0.dist-info/entry_points.txt +3 -0
  95. da4ml-0.5.0.dist-info/sboms/auditwheel.cdx.json +1 -0
  96. da4ml.libs/libgomp-e985bcbb.so.1.0.0 +0 -0
@@ -0,0 +1,104 @@
1
+ set project_name "$::env(PROJECT_NAME)"
2
+ set device "$::env(DEVICE)"
3
+ set source_type "$::env(SOURCE_TYPE)"
4
+
5
+ set top_module "${project_name}"
6
+ set output_dir "./output_${project_name}"
7
+
8
+ file mkdir $output_dir
9
+ file mkdir "${output_dir}/reports"
10
+
11
+ project_new "${project_name}" -overwrite -revision "${project_name}"
12
+
13
+ set_global_assignment -name FAMILY [lindex [split "${device}" "-"] 0]
14
+ set_global_assignment -name DEVICE "${device}"
15
+
16
+ if { "${source_type}" != "vhdl" && "${source_type}" != "verilog" } {
17
+ puts "Error: SOURCE_TYPE must be either 'vhdl' or 'verilog'."
18
+ exit 1
19
+ }
20
+
21
+ # Add source files based on type
22
+ if { "${source_type}" == "vhdl" } {
23
+ set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
24
+
25
+ foreach file [glob -nocomplain "src/static/*.vhd"] {
26
+ set_global_assignment -name VHDL_FILE "${file}"
27
+ }
28
+
29
+ set_global_assignment -name VHDL_FILE "src/${project_name}.vhd"
30
+ foreach file [glob -nocomplain "src/${project_name}_stage*.vhd"] {
31
+ set_global_assignment -name VHDL_FILE "${file}"
32
+ }
33
+ } else {
34
+ foreach file [glob -nocomplain "src/static/*.v"] {
35
+ set_global_assignment -name VERILOG_FILE "${file}"
36
+ }
37
+
38
+ set_global_assignment -name VERILOG_FILE "src/${project_name}.v"
39
+ foreach file [glob -nocomplain "src/${project_name}_stage*.v"] {
40
+ set_global_assignment -name VERILOG_FILE "${file}"
41
+ }
42
+ }
43
+
44
+ set mems [glob -nocomplain "src/memfiles/*.mem"]
45
+
46
+ # VHDL only uses relative path to working dir apparently...
47
+ if { "${source_type}" == "vhdl" } {
48
+ foreach f $mems {
49
+ file copy -force $f [file tail $f]
50
+ }
51
+ set mems [glob -nocomplain "*.mem"]
52
+ }
53
+
54
+ foreach f $mems {
55
+ set_global_assignment -name MIF_FILE "${f}"
56
+ }
57
+
58
+ # Add SDC constraint file if it exists
59
+ if { [file exists "src/${project_name}.sdc"] } {
60
+ set_global_assignment -name SDC_FILE "${project_name}.sdc"
61
+ }
62
+
63
+ # Set top-level entity
64
+ set_global_assignment -name TOP_LEVEL_ENTITY "${top_module}"
65
+
66
+ # OOC
67
+ load_package flow
68
+
69
+ proc make_all_pins_virtual {} {
70
+ execute_module -tool map
71
+
72
+ set name_ids [get_names -filter * -node_type pin]
73
+
74
+ foreach_in_collection name_id $name_ids {
75
+ set pin_name [get_name_info -info full_path $name_id]
76
+ post_message "Making VIRTUAL_PIN assignment to $pin_name"
77
+ set_instance_assignment -to $pin_name -name VIRTUAL_PIN ON
78
+ }
79
+ export_assignments
80
+ }
81
+
82
+ make_all_pins_virtual
83
+
84
+ # Config
85
+ set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
86
+ set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED
87
+ set_global_assignment -name AUTO_RESOURCE_SHARING ON
88
+ set_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ON
89
+ set_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION ON
90
+ set_global_assignment -name ALLOW_REGISTER_RETIMING ON
91
+
92
+ set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
93
+ set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON
94
+
95
+ set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
96
+
97
+ set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
98
+ set_global_assignment -name SYNTHESIS_EFFORT AUTO
99
+ set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON
100
+
101
+ # Run!!!
102
+ execute_flow -compile
103
+
104
+ project_close
@@ -0,0 +1,111 @@
1
+ set project_name "$::env(PROJECT_NAME)"
2
+ set device "$::env(DEVICE)"
3
+ set source_type "$::env(SOURCE_TYPE)"
4
+
5
+ set top_module "${project_name}"
6
+ set output_dir "./output_${project_name}"
7
+
8
+ create_project $project_name "${output_dir}/$project_name" -force -part $device
9
+
10
+ set_property DEFAULT_LIB work [current_project]
11
+
12
+ if { $source_type != "vhdl" && $source_type != "verilog" } {
13
+ puts "Error: SOURCE_TYPE must be either 'vhdl' or 'verilog'."
14
+ exit 1
15
+ }
16
+
17
+ if { $source_type == "vhdl" } {
18
+ set_property TARGET_LANGUAGE VHDL [current_project]
19
+
20
+ set statis_files [glob -nocomplain "src/static/*.vhd"]
21
+ set top_file "src/${project_name}.vhd"
22
+ set stage_files [glob -nocomplain "src/${project_name}_stage*.vhd"]
23
+
24
+ read_vhdl -vhdl2008 $top_file $statis_files $stage_files
25
+
26
+ } else {
27
+ set_property TARGET_LANGUAGE Verilog [current_project]
28
+
29
+ set statis_files [glob -nocomplain "src/static/*.v"]
30
+ set top_file "src/${project_name}.v"
31
+ set stage_files [glob -nocomplain "src/${project_name}_stage*.v"]
32
+
33
+ read_verilog $top_file $statis_files $stage_files
34
+
35
+ }
36
+
37
+
38
+ set mems [glob -nocomplain "src/memfiles/*.mem"]
39
+
40
+ # VHDL only uses relative path to working dir apparently...
41
+ if { $source_type == "vhdl" } {
42
+ foreach f $mems {
43
+ file copy -force $f [file tail $f]
44
+ }
45
+ set mems [glob -nocomplain "*.mem"]
46
+ }
47
+
48
+ add_files -fileset [current_fileset] $mems
49
+
50
+ foreach f $mems {
51
+ set_property used_in_synthesis true [get_files $f]
52
+ }
53
+
54
+ # Add XDC constraint if it exists
55
+ if { [file exists "src/${project_name}.xdc"] } {
56
+ read_xdc "src/${project_name}.xdc" -mode out_of_context
57
+ }
58
+
59
+ set_property top $top_module [current_fileset]
60
+
61
+ file mkdir $output_dir
62
+ file mkdir "${output_dir}/reports"
63
+
64
+ # synth
65
+ synth_design -top $top_module -mode out_of_context -global_retiming on \
66
+ -flatten_hierarchy full -resource_sharing auto -directive AreaOptimized_High
67
+
68
+ write_checkpoint -force "${output_dir}/${project_name}_post_synth.dcp"
69
+
70
+ report_timing_summary -file "${output_dir}/reports/${project_name}_post_synth_timing.rpt"
71
+ report_power -file "${output_dir}/reports/${project_name}_post_synth_power.rpt"
72
+ report_utilization -file "${output_dir}/reports/${project_name}_post_synth_util.rpt"
73
+
74
+ # opt_design -directive ExploreSequentialArea
75
+ opt_design -directive ExploreWithRemap
76
+
77
+ report_design_analysis -congestion -file "${output_dir}/reports/${project_name}_post_opt_congestion.rpt"
78
+
79
+ # place
80
+ place_design -directive SSI_HighUtilSLRs -fanout_opt
81
+ report_design_analysis -congestion -file "${output_dir}/reports/${project_name}_post_place_congestion_initial.rpt"
82
+
83
+ phys_opt_design -directive AggressiveExplore
84
+ write_checkpoint -force "${output_dir}/${project_name}_post_place.dcp"
85
+ file delete -force "${output_dir}/${project_name}_post_synth.dcp"
86
+
87
+ report_design_analysis -congestion -file "${output_dir}/reports/${project_name}_post_place_congestion_final.rpt"
88
+
89
+ report_timing_summary -file "${output_dir}/reports/${project_name}_post_place_timing.rpt"
90
+ report_utilization -hierarchical -file "${output_dir}/reports/${project_name}_post_place_util.rpt"
91
+
92
+ # route
93
+ route_design -directive NoTimingRelaxation
94
+ write_checkpoint -force "${output_dir}/${project_name}_post_route.dcp"
95
+ file delete -force "${output_dir}/${project_name}_post_place.dcp"
96
+
97
+
98
+ report_timing_summary -file "${output_dir}/reports/${project_name}_post_route_timing.rpt"
99
+ report_timing -sort_by group -max_paths 100 -path_type summary -file "${output_dir}/reports/${project_name}_post_route_timing_paths.rpt"
100
+ report_clock_utilization -file "${output_dir}/reports/${project_name}_post_route_clock_util.rpt"
101
+ report_utilization -file "${output_dir}/reports/${project_name}_post_route_util.rpt"
102
+ report_power -file "${output_dir}/reports/${project_name}_post_route_power.rpt"
103
+ report_drc -file "${output_dir}/reports/${project_name}_post_route_drc.rpt"
104
+
105
+ report_utilization -format xml -hierarchical -file "${output_dir}/reports/${project_name}_post_route_util.xml"
106
+ report_power -xpe "${output_dir}/reports/${project_name}_post_route_power.xml"
107
+
108
+ # Generate Verilog netlist for simulation
109
+ # write_verilog -force "${output_dir}/${project_name}_impl_netlist.v" -mode timesim -sdf_anno true
110
+
111
+ puts "Implementation complete. Results saved in ${output_dir}"
@@ -0,0 +1,124 @@
1
+ #include "verilated.h"
2
+ #include <cassert>
3
+ #include <cstdint>
4
+ #include <vector>
5
+ template <size_t bw, size_t N_in> std::vector<int32_t> bitpack(const int32_t *values) {
6
+ static_assert(bw > 0 && bw <= 32, "Bit width must be between 1 and 32");
7
+
8
+ constexpr size_t total_bits = N_in * bw;
9
+ constexpr size_t result_size = (total_bits + 31) / 32;
10
+ std::vector<int32_t> result(result_size, 0);
11
+
12
+ constexpr uint32_t mask = (bw == 32) ? 0xFFFFFFFF : ((1U << bw) - 1);
13
+
14
+ size_t bit_pos = 0;
15
+ for (size_t i = 0; i < N_in; i++) {
16
+ int32_t val = values[i];
17
+ uint32_t bits = val & mask;
18
+
19
+ size_t result_idx = bit_pos / 32;
20
+ size_t offset = bit_pos % 32;
21
+
22
+ // base case
23
+ result[result_idx] |= (bits << offset);
24
+
25
+ // cross boundary case
26
+ if (offset + bw > 32 && result_idx + 1 < result.size()) {
27
+ result[result_idx + 1] |= (bits >> (32 - offset));
28
+ }
29
+
30
+ bit_pos += bw;
31
+ }
32
+
33
+ return result;
34
+ }
35
+
36
+ template <size_t bw, size_t N_out>
37
+ std::vector<int32_t> bitunpack(const std::vector<int32_t> &packed) {
38
+ static_assert(bw > 0 && bw <= 32, "Bit width must be between 1 and 32");
39
+
40
+ constexpr size_t total_bits = N_out * bw;
41
+ constexpr size_t packed_size = (total_bits + 31) / 32;
42
+ assert(packed.size() == packed_size);
43
+
44
+ std::vector<int32_t> result(N_out, 0);
45
+
46
+ for (size_t i = 0; i < N_out; i++) {
47
+ size_t bit_pos = i * bw;
48
+ size_t packed_idx = bit_pos / 32;
49
+ size_t offset = bit_pos % 32;
50
+
51
+ // base case
52
+ size_t bw_v0 = std::min(bw, 32 - offset);
53
+ uint32_t mask = bw_v0 == 32 ? 0xFFFFFFFF : ((1U << bw_v0) - 1);
54
+ int32_t value = (packed[packed_idx] >> offset) & mask;
55
+
56
+ // cross boundary
57
+ if (offset + bw > 32) {
58
+ assert(packed_idx + 1 < packed.size());
59
+ size_t bw_v1 = offset + bw - 32;
60
+ uint32_t mask_v1 = ((1U << bw_v1) - 1);
61
+ uint32_t additional_bits = packed[packed_idx + 1] & mask_v1;
62
+ value |= (additional_bits << bw_v0);
63
+ }
64
+
65
+ result[i] = value;
66
+ }
67
+
68
+ return result;
69
+ }
70
+
71
+ template <size_t bits_in, typename inp_buf_t>
72
+ std::enable_if_t<std::is_integral_v<inp_buf_t>, void>
73
+ _write_input(inp_buf_t &inp_buf, const std::vector<int32_t> &input) {
74
+ assert(input.size() == (bits_in + 31) / 32);
75
+ inp_buf = input[0] & 0xFFFFFFFF;
76
+ if (bits_in > 32) {
77
+ inp_buf |= static_cast<int64_t>(input[1]) << 32;
78
+ }
79
+ }
80
+
81
+ template <size_t bits_in, size_t N_in>
82
+ void _write_input(VlWide<N_in> &inp_buf, const std::vector<int32_t> &input) {
83
+ assert(input.size() == (bits_in + 31) / 32);
84
+ for (size_t i = 0; i < input.size(); ++i) {
85
+ inp_buf[i] = input[i];
86
+ }
87
+ }
88
+
89
+ template <size_t bits_out, typename out_buf_t>
90
+ std::enable_if_t<std::is_integral_v<out_buf_t>, std::vector<int32_t>>
91
+ _read_output(out_buf_t &out_buf) {
92
+ std::vector<int32_t> output((bits_out + 31) / 32);
93
+ output[0] = out_buf & 0xFFFFFFFF;
94
+ if (bits_out > 32) {
95
+ output[1] = (out_buf >> 32) & 0xFFFFFFFF;
96
+ }
97
+ return output;
98
+ }
99
+
100
+ template <size_t bits_out, size_t N_out>
101
+ std::vector<int32_t> _read_output(VlWide<N_out> out_buf) {
102
+ std::vector<int32_t> output((bits_out + 31) / 32);
103
+ for (size_t i = 0; i < output.size(); ++i) {
104
+ output[i] = out_buf[i] & 0xFFFFFFFF;
105
+ }
106
+ return output;
107
+ }
108
+
109
+ template <size_t N, size_t max_bw, typename inp_buf_t>
110
+ void write_input(inp_buf_t &inp_buf, const int32_t *c_inp) {
111
+ constexpr size_t bits_in = N * max_bw;
112
+ std::vector<int32_t> input = bitpack<max_bw, N>(c_inp);
113
+ _write_input<bits_in>(inp_buf, input);
114
+ }
115
+
116
+ template <size_t N, size_t max_bw, typename out_buf_t>
117
+ void read_output(out_buf_t out_buf, int32_t *c_out) {
118
+ constexpr size_t bits_out = N * max_bw;
119
+ std::vector<int32_t> packed = _read_output<bits_out>(out_buf);
120
+ std::vector<int32_t> unpacked = bitunpack<max_bw, N>(packed);
121
+ for (size_t i = 0; i < N; ++i) {
122
+ c_out[i] = unpacked[i];
123
+ }
124
+ }
@@ -0,0 +1,27 @@
1
+ set clock_period $::env(CLOCK_PERIOD)
2
+
3
+ # Clock uncertainty as percentage of clock period
4
+ set uncertainty_setup_r $::env(UNCERTAINITY_SETUP)
5
+ set uncertainty_hold_r $::env(UNCERTAINITY_HOLD)
6
+ set delay_max_r $::env(DELAY_MAX)
7
+ set delay_min_r $::env(DELAY_MIN)
8
+
9
+ # Calculate actual uncertainty values
10
+ set uncertainty_setup [expr {$clock_period * $uncertainty_setup_r}]
11
+ set uncertainty_hold [expr {$clock_period * $uncertainty_hold_r}]
12
+ set delay_max [expr {$clock_period * $delay_max_r}]
13
+ set delay_min [expr {$clock_period * $delay_min_r}]
14
+
15
+ # Create clock with variable period
16
+ create_clock -period $clock_period -name sys_clk [get_ports {clk}]
17
+
18
+ # Input/Output constraints
19
+ set_input_delay -clock sys_clk -max $delay_max [get_ports {model_inp[*]}]
20
+ set_input_delay -clock sys_clk -min $delay_min [get_ports {model_inp[*]}]
21
+
22
+ set_output_delay -clock sys_clk -max $delay_max [get_ports {model_out[*]}]
23
+ set_output_delay -clock sys_clk -min $delay_min [get_ports {model_out[*]}]
24
+
25
+ # Apply calculated uncertainty values
26
+ set_clock_uncertainty -setup -to [get_clocks sys_clk] $uncertainty_setup
27
+ set_clock_uncertainty -hold -to [get_clocks sys_clk] $uncertainty_hold
@@ -0,0 +1,30 @@
1
+ set clock_period $::env(CLOCK_PERIOD)
2
+
3
+ # Clock uncertainty as percentage of clock period
4
+ set uncertainty_setup_r $::env(UNCERTAINITY_SETUP)
5
+ set uncertainty_hold_r $::env(UNCERTAINITY_HOLD)
6
+ set delay_max_r $::env(DELAY_MAX)
7
+ set delay_min_r $::env(DELAY_MIN)
8
+
9
+ # Calculate actual uncertainty values
10
+ set uncertainty_setup [expr {$clock_period * $uncertainty_setup_r}]
11
+ set uncertainty_hold [expr {$clock_period * $uncertainty_hold_r}]
12
+ set delay_max [expr {$clock_period * $delay_max_r}]
13
+ set delay_min [expr {$clock_period * $delay_min_r}]
14
+
15
+ # Create clock with variable period
16
+ create_clock -period $clock_period -name sys_clk [get_ports {clk}]
17
+
18
+ # Input/Output constraints
19
+ set_input_delay -clock sys_clk -max $delay_max [get_ports {model_inp[*]}]
20
+ set_input_delay -clock sys_clk -min $delay_min [get_ports {model_inp[*]}]
21
+
22
+ set_output_delay -clock sys_clk -max $delay_max [get_ports {model_out[*]}]
23
+ set_output_delay -clock sys_clk -min $delay_min [get_ports {model_out[*]}]
24
+
25
+ # Apply calculated uncertainty values
26
+ set_clock_uncertainty -setup $uncertainty_setup [get_clocks sys_clk]
27
+ set_clock_uncertainty -hold $uncertainty_hold [get_clocks sys_clk]
28
+
29
+ # Mark lut_rom to be implemented as distributed ROM (*rom_style = "distributed" *)
30
+ set_property rom_style "distributed" [get_cells lut_rom]