da4ml 0.5.1.post1__cp311-cp311-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.
- da4ml/__init__.py +4 -0
- da4ml/_binary/__init__.py +15 -0
- da4ml/_binary/dais_bin.cpython-311-x86_64-linux-gnu.so +0 -0
- da4ml/_binary/dais_bin.pyi +5 -0
- da4ml/_cli/__init__.py +30 -0
- da4ml/_cli/convert.py +204 -0
- da4ml/_cli/report.py +295 -0
- da4ml/_version.py +32 -0
- da4ml/cmvm/__init__.py +4 -0
- da4ml/cmvm/api.py +264 -0
- da4ml/cmvm/core/__init__.py +221 -0
- da4ml/cmvm/core/indexers.py +83 -0
- da4ml/cmvm/core/state_opr.py +284 -0
- da4ml/cmvm/types.py +739 -0
- da4ml/cmvm/util/__init__.py +7 -0
- da4ml/cmvm/util/bit_decompose.py +86 -0
- da4ml/cmvm/util/mat_decompose.py +121 -0
- da4ml/codegen/__init__.py +9 -0
- da4ml/codegen/hls/__init__.py +4 -0
- da4ml/codegen/hls/hls_codegen.py +196 -0
- da4ml/codegen/hls/hls_model.py +255 -0
- da4ml/codegen/hls/source/ap_types/ap_binary.h +78 -0
- da4ml/codegen/hls/source/ap_types/ap_common.h +376 -0
- da4ml/codegen/hls/source/ap_types/ap_decl.h +212 -0
- da4ml/codegen/hls/source/ap_types/ap_fixed.h +360 -0
- da4ml/codegen/hls/source/ap_types/ap_fixed_base.h +2354 -0
- da4ml/codegen/hls/source/ap_types/ap_fixed_ref.h +718 -0
- da4ml/codegen/hls/source/ap_types/ap_fixed_special.h +230 -0
- da4ml/codegen/hls/source/ap_types/ap_int.h +330 -0
- da4ml/codegen/hls/source/ap_types/ap_int_base.h +1885 -0
- da4ml/codegen/hls/source/ap_types/ap_int_ref.h +1346 -0
- da4ml/codegen/hls/source/ap_types/ap_int_special.h +223 -0
- da4ml/codegen/hls/source/ap_types/ap_shift_reg.h +138 -0
- da4ml/codegen/hls/source/ap_types/etc/ap_private.h +7199 -0
- da4ml/codegen/hls/source/ap_types/hls_math.h +27 -0
- da4ml/codegen/hls/source/ap_types/hls_stream.h +263 -0
- da4ml/codegen/hls/source/ap_types/utils/x_hls_utils.h +80 -0
- da4ml/codegen/hls/source/binder_util.hh +71 -0
- da4ml/codegen/hls/source/build_binder.mk +22 -0
- da4ml/codegen/hls/source/vitis_bitshift.hh +32 -0
- da4ml/codegen/rtl/__init__.py +15 -0
- da4ml/codegen/rtl/common_source/binder_util.hh +99 -0
- da4ml/codegen/rtl/common_source/build_binder.mk +34 -0
- da4ml/codegen/rtl/common_source/build_quartus_prj.tcl +104 -0
- da4ml/codegen/rtl/common_source/build_vivado_prj.tcl +111 -0
- da4ml/codegen/rtl/common_source/ioutil.hh +124 -0
- da4ml/codegen/rtl/common_source/template.sdc +27 -0
- da4ml/codegen/rtl/common_source/template.xdc +30 -0
- da4ml/codegen/rtl/rtl_model.py +486 -0
- da4ml/codegen/rtl/verilog/__init__.py +10 -0
- da4ml/codegen/rtl/verilog/comb.py +239 -0
- da4ml/codegen/rtl/verilog/io_wrapper.py +113 -0
- da4ml/codegen/rtl/verilog/pipeline.py +67 -0
- da4ml/codegen/rtl/verilog/source/lookup_table.v +27 -0
- da4ml/codegen/rtl/verilog/source/multiplier.v +37 -0
- da4ml/codegen/rtl/verilog/source/mux.v +58 -0
- da4ml/codegen/rtl/verilog/source/negative.v +31 -0
- da4ml/codegen/rtl/verilog/source/shift_adder.v +59 -0
- da4ml/codegen/rtl/vhdl/__init__.py +9 -0
- da4ml/codegen/rtl/vhdl/comb.py +206 -0
- da4ml/codegen/rtl/vhdl/io_wrapper.py +120 -0
- da4ml/codegen/rtl/vhdl/pipeline.py +71 -0
- da4ml/codegen/rtl/vhdl/source/lookup_table.vhd +52 -0
- da4ml/codegen/rtl/vhdl/source/multiplier.vhd +40 -0
- da4ml/codegen/rtl/vhdl/source/mux.vhd +102 -0
- da4ml/codegen/rtl/vhdl/source/negative.vhd +35 -0
- da4ml/codegen/rtl/vhdl/source/shift_adder.vhd +101 -0
- da4ml/converter/__init__.py +63 -0
- da4ml/converter/hgq2/__init__.py +3 -0
- da4ml/converter/hgq2/layers/__init__.py +11 -0
- da4ml/converter/hgq2/layers/_base.py +132 -0
- da4ml/converter/hgq2/layers/activation.py +81 -0
- da4ml/converter/hgq2/layers/attn.py +148 -0
- da4ml/converter/hgq2/layers/batchnorm.py +15 -0
- da4ml/converter/hgq2/layers/conv.py +149 -0
- da4ml/converter/hgq2/layers/dense.py +39 -0
- da4ml/converter/hgq2/layers/ops.py +246 -0
- da4ml/converter/hgq2/layers/pool.py +107 -0
- da4ml/converter/hgq2/layers/table.py +176 -0
- da4ml/converter/hgq2/parser.py +161 -0
- da4ml/trace/__init__.py +6 -0
- da4ml/trace/fixed_variable.py +965 -0
- da4ml/trace/fixed_variable_array.py +600 -0
- da4ml/trace/ops/__init__.py +13 -0
- da4ml/trace/ops/einsum_utils.py +305 -0
- da4ml/trace/ops/quantization.py +74 -0
- da4ml/trace/ops/reduce_utils.py +105 -0
- da4ml/trace/pipeline.py +181 -0
- da4ml/trace/tracer.py +186 -0
- da4ml/typing/__init__.py +3 -0
- da4ml-0.5.1.post1.dist-info/METADATA +85 -0
- da4ml-0.5.1.post1.dist-info/RECORD +96 -0
- da4ml-0.5.1.post1.dist-info/WHEEL +6 -0
- da4ml-0.5.1.post1.dist-info/entry_points.txt +3 -0
- da4ml-0.5.1.post1.dist-info/sboms/auditwheel.cdx.json +1 -0
- 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]
|