URL
https://opencores.org/ocsvn/radiohdl/radiohdl/trunk
Subversion Repositories radiohdl
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 3 to Rev 4
- ↔ Reverse comparison
Rev 3 → Rev 4
/radiohdl/trunk/config/hdl_buildset_rsp.cfg
0,0 → 1,24
# TODO: Does RadioHDL still works for RSP?? |
buildset_name = rsp |
technology_names = ip_virtex4 |
family_names = virtex4 |
block_design_names = sopc |
|
synth_tool_name = ise |
synth_tool_version = 11.1 |
sim_tool_name = modelsim |
sim_tool_version = 6.6c |
ip_tool_name = coregen |
|
project_dir_depth_sim = 4 |
project_dir_depth_synth = 0 |
|
lib_root_dirs = $RSP |
|
[quartus] |
quartus_dir = ${ALTERA_DIR}/<synth_tool_version> |
|
[modelsim] |
modelsim_dir = ${MENTOR_DIR}/<sim_tool_version>/modeltech |
modelsim_platform = linux_x86_64 |
modelsim_search_libraries = |
/radiohdl/trunk/config/hdl_buildset_unb1.cfg
0,0 → 1,23
# Uniboard 1 configuration |
buildset_name = unb1 |
technology_names = ip_stratixiv |
family_names = stratixiv |
block_design_names = sopc |
|
synth_tool_name = quartus |
synth_tool_version = 11.1 |
sim_tool_name = modelsim |
sim_tool_version = 6.6c |
|
lib_root_dirs = ${RADIOHDL_WORK}/libraries ${RADIOHDL_WORK}/applications ${RADIOHDL_WORK}/boards |
|
[quartus] |
quartus_dir = ${ALTERA_DIR}/<synth_tool_version> |
|
[modelsim] |
modelsim_dir = ${MENTOR_DIR}/<sim_tool_version>/modeltech |
modelsim_platform = linux_x86_64 |
modelsim_search_libraries = |
# stratixiv only |
altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver stratixiv_ver stratixiv_hssi_ver stratixiv_pcie_hip_ver |
altera lpm sgate altera_mf altera_lnsim stratixiv stratixiv_hssi stratixiv_pcie_hip |
/radiohdl/trunk/config/hdl_buildset_unb2.cfg
0,0 → 1,27
# Uniboard 2 configuration |
buildset_name = unb2 |
technology_names = ip_arria10 |
family_names = arria10 stratixiv |
block_design_names = sopc |
|
synth_tool_name = quartus |
synth_tool_version = 15.0 |
sim_tool_name = modelsim |
sim_tool_version = 10.4 |
|
lib_root_dirs = ${RADIOHDL_WORK}/libraries ${RADIOHDL_WORK}/applications ${RADIOHDL_WORK}/boards |
|
[quartus] |
quartus_dir = ${ALTERA_DIR}/<synth_tool_version> |
|
[modelsim] |
modelsim_dir = ${MENTOR_DIR}/<sim_tool_version>/questasim |
modelsim_platform = linux_x86_64 |
model_tech_altera_lib = ${MODELSIM_ALTERA_LIBS_DIR}/<synth_tool_version> |
modelsim_search_libraries = |
# arria10 only |
altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver twentynm_ver twentynm_hssi_ver twentynm_hip_ver |
altera lpm sgate altera_mf altera_lnsim twentynm twentynm_hssi twentynm_hip |
# both stratixiv and arria10 |
#altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver stratixiv_ver stratixiv_hssi_ver stratixiv_pcie_hip_ver twentynm_ver twentynm_hssi_ver twentynm_hip_ver |
#altera lpm sgate altera_mf altera_lnsim stratixiv stratixiv_hssi stratixiv_pcie_hip twentynm twentynm_hssi twentynm_hip |
/radiohdl/trunk/config/hdl_buildset_unb2a.cfg
0,0 → 1,26
# Uniboard 2a configuration |
buildset_name = unb2a |
technology_names = ip_arria10_e3sge3 |
family_names = arria10 |
block_design_names = sopc |
|
synth_tool_name = quartus |
synth_tool_version = 16.0 |
sim_tool_name = modelsim |
sim_tool_version = 10.4 |
|
lib_root_dirs = ${RADIOHDL_WORK}/libraries ${RADIOHDL_WORK}/applications ${RADIOHDL_WORK}/boards |
|
[quartus] |
quartus_dir = ${ALTERA_DIR}/<synth_tool_version> |
|
[modelsim] |
modelsim_dir = ${MENTOR_DIR}/<sim_tool_version>/questasim |
modelsim_platform = linux_x86_64 |
modelsim_search_libraries = |
# arria10 only |
altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver twentynm_ver twentynm_hssi_ver twentynm_hip_ver |
altera lpm sgate altera_mf altera_lnsim twentynm twentynm_hssi twentynm_hip |
# both stratixiv and arria10 |
#altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver stratixiv_ver stratixiv_hssi_ver stratixiv_pcie_hip_ver twentynm_ver twentynm_hssi_ver twentynm_hip_ver |
#altera lpm sgate altera_mf altera_lnsim stratixiv stratixiv_hssi stratixiv_pcie_hip twentynm twentynm_hssi twentynm_hip |
/radiohdl/trunk/config/hdl_buildset_unb2b.cfg
0,0 → 1,26
# Uniboard 2b configuration |
buildset_name = unb2b |
technology_names = ip_arria10_e1sg |
family_names = arria10 |
block_design_names = qsys |
|
synth_tool_name = quartus |
synth_tool_version = 18.0 |
sim_tool_name = modelsim |
sim_tool_version = 10.4 |
|
lib_root_dirs = ${RADIOHDL_WORK}/libraries ${RADIOHDL_WORK}/applications ${RADIOHDL_WORK}/boards |
|
[quartus] |
quartus_dir = ${ALTERA_DIR}/<synth_tool_version> |
|
[modelsim] |
modelsim_dir = ${MENTOR_DIR}/<sim_tool_version>/questasim |
modelsim_platform = linux_x86_64 |
modelsim_search_libraries = |
# arria10 only |
altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver twentynm_ver twentynm_hssi_ver twentynm_hip_ver |
altera lpm sgate altera_mf altera_lnsim twentynm twentynm_hssi twentynm_hip |
# both stratixiv and arria10 |
#altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver stratixiv_ver stratixiv_hssi_ver stratixiv_pcie_hip_ver twentynm_ver twentynm_hssi_ver twentynm_hip_ver |
#altera lpm sgate altera_mf altera_lnsim stratixiv stratixiv_hssi stratixiv_pcie_hip twentynm twentynm_hssi twentynm_hip |
/radiohdl/trunk/config/hdl_buildset_unb2c.cfg
0,0 → 1,26
# Uniboard 2c configuration |
buildset_name = unb2c |
technology_names = ip_arria10_e1sg |
family_names = arria10 |
block_design_names = qsys |
|
synth_tool_name = quartus |
synth_tool_version = 18.0 |
sim_tool_name = modelsim |
sim_tool_version = 10.4 |
|
lib_root_dirs = ${RADIOHDL_WORK}/libraries ${RADIOHDL_WORK}/applications ${RADIOHDL_WORK}/boards |
|
[quartus] |
quartus_dir = ${ALTERA_DIR}/<synth_tool_version> |
|
[modelsim] |
modelsim_dir = ${MENTOR_DIR}/<sim_tool_version>/questasim |
modelsim_platform = linux_x86_64 |
modelsim_search_libraries = |
# arria10 only |
altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver twentynm_ver twentynm_hssi_ver twentynm_hip_ver |
altera lpm sgate altera_mf altera_lnsim twentynm twentynm_hssi twentynm_hip |
# both stratixiv and arria10 |
#altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver stratixiv_ver stratixiv_hssi_ver stratixiv_pcie_hip_ver twentynm_ver twentynm_hssi_ver twentynm_hip_ver |
#altera lpm sgate altera_mf altera_lnsim stratixiv stratixiv_hssi stratixiv_pcie_hip twentynm twentynm_hssi twentynm_hip |
/radiohdl/trunk/config/hdl_tool_modelsim.cfg
0,0 → 1,2
# configuration file for defining the model installation on this system |
model_tech_altera_lib = ${MODELSIM_ALTERA_LIBS_DIR}/${SYNTH_TOOL_VERSION} |
/radiohdl/trunk/config/hdl_tool_quartus.cfg
0,0 → 1,35
# configuration file for defining the quartus installation on this system |
quartus_rootdir = ${QUARTUS_DIR}/quartus |
quartus_rootdir_override = ${QUARTUS_DIR}/quartus |
niosdir = ${QUARTUS_DIR}/nios2eds |
|
# extension to the PATH variable |
quartus_paths = |
<quartus_rootdir>/bin |
<niosdir>/bin |
<niosdir>/bin/gnu/H-i686-pc-linux-gnu/bin |
<niosdir>/bin/gnu/H-x86_64-pc-linux-gnu/bin |
<niosdir>/sdk2/bin |
|
[sopc] |
sopc_paths = |
<quartus_rootdir>/sopc_builder/bin |
sopc_environment_variables = |
sopc_kit_nios2 <niosdir> |
|
[qsys] |
qsys_paths = |
<quartus_rootdir>/../qsys/bin |
|
[ip generation] |
ip_tools = qmegawiz qsys-generate quartus_sh |
qmegawiz_default_options = -silent |
qsys-generate_default_options = --synthesis=VHDL --simulation=VHDL --allow-mixed-language-simulation --block-symbol-file |
quartus_sh_default_options = |
|
[user settings] |
user_paths = |
user_environment_variables = |
altera_hw_tcl_keep_temp_files 1 |
|
#unb_compile_stamps 1 |
/radiohdl/trunk/core/test/cdf_dir/correct_files/dangling_test.txt
0,0 → 1,6
# Testfile for testing sections the CommonDictFile class |
# |
# First some keys with different spacing (spaces and tabs) |
this is a lost value which causes an exception |
|
global_key_1 = global_1 |
/radiohdl/trunk/core/test/cdf_dir/correct_files/key_value_test.txt
0,0 → 1,43
# Testfile for testing the CommonDictFile class |
# |
# First some keys with different spacing (spaces and tabs) |
|
space_key_0= |
space_key_1=value_1 |
space_key_2 =value_2 |
space_key_3= value_3 |
space_key_4 = value_4 |
space_key_5 = value_5 |
space_key_6 = value_6 |
space_key_7 = value_7 |
|
# Test keys with multiple values |
multi_key_1 = value10 value11 value12 |
multi_key_2 = value20, value21, value22 |
multi_key_3 = value30 |
value31 |
value32 |
value33 |
multi_key_4 = value40 = value41 = |
value42 |
|
# Difference between empty keys and multiline keys |
tricky_key_1 = |
tricky_key_2 = |
tricky_value_2 |
tricky_key_3 = |
|
["my_section"] |
section_key_1 = |
section_value_10 |
|
section_value_11 |
= # equal sign without a key is added as value |
value which is also part of section_key_1 |
|
warning_key_1 = Be aware that multiline values can be tricky: |
|
this also belongs |
to previous |
key 'warning_key_1' |
but_this = a new key-value pair |
/radiohdl/trunk/core/test/cdf_dir/correct_files/section_test.txt
0,0 → 1,18
# Testfile for testing sections the CommonDictFile class |
# |
# First some keys with different spacing (spaces and tabs) |
|
global_key_1 = global_1 |
global_key_2 = [ "aap", "noot", "mies" ] # this is seen as a section header instead of a value!!! |
|
just_some_key_1 = global value1 which is lost without a warning |
just_some_key_2 = global value2 which is lost without a warning |
|
[section_1] |
just_some_key_1 = section1 value1 which is lost without a warning |
just_some_key_2 = section1 value2 which is lost without a warning |
|
[section_2] |
just_some_key_1 = section2 value1 |
just_some_key_2 = section2 value2 |
|
/radiohdl/trunk/core/test/cdf_dir/empty_file/comment_only_dict.txt
0,0 → 1,4
# This file only |
# contains comments |
# and no |
# key = value lines |
/radiohdl/trunk/core/test/cdf_dir/empty_file/empty_dict.txt
--- radiohdl/trunk/core/test/cdf_dir/hdlbuildset_files/hdl_buildset_rsp.cfg (nonexistent)
+++ radiohdl/trunk/core/test/cdf_dir/hdlbuildset_files/hdl_buildset_rsp.cfg (revision 4)
@@ -0,0 +1,22 @@
+# TODO: Does RadioHDL still works for RSP??
+buildset_name = rsp
+technology_names = ip_virtex4
+family_names = virtex4
+block_design_names = sopc
+
+sim_tool_name = modelsim
+sim_tool_version = 6.6c
+synth_tool_name = ise
+synth_tool_version = 11.1
+ip_tool_name = coregen
+
+project_dir_depth_sim = 4
+project_dir_depth_synth = 0
+
+lib_root_dir = $RSP
+build_dir = $RADIOHDL_BUILD_DIR
+quartus_dir = /home/software/Altera/
+model_tech_altera_lib = /home/software/modelsim_altera_libs/
+model_tech_dir = /home/software/Mentor//modeltech
+vsim_dir = /linux_x86_64
+modelsim_search_libraries =
/radiohdl/trunk/core/test/cdf_dir/hdlbuildset_files/hdl_buildset_unb1.cfg
0,0 → 1,21
# Uniboardd 1 configuration |
buildset_name = unb1 |
technology_names = ip_stratixiv |
family_names = stratixiv |
block_design_names = sopc |
|
sim_tool_name = modelsim |
sim_tool_version = 6.6c |
synth_tool_name = quartus |
synth_tool_version = 11.1sp2 |
|
lib_root_dirs = ${RADIOHDL_WORK}/libraries ${RADIOHDL_WORK}/applications ${RADIOHDL_WORK}/boards |
build_dir = $RADIOHDL_BUILD_DIR |
quartus_dir = /home/software/Altera/<synth_tool_version> |
model_tech_altera_lib = /home/software/modelsim_altera_libs/<synth_tool_version> |
model_tech_dir = /home/software/Mentor/<sim_tool_version>/modeltech |
vsim_dir = <model_tech_dir>/linux_x86_64 |
modelsim_search_libraries = |
# stratixiv only |
altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver stratixiv_ver stratixiv_hssi_ver stratixiv_pcie_hip_ver |
altera lpm sgate altera_mf altera_lnsim stratixiv stratixiv_hssi stratixiv_pcie_hip |
/radiohdl/trunk/core/test/cdf_dir/hdlbuildset_files/hdl_buildset_wrong.cfg
0,0 → 1,21
# Uniboardd 1 configuration |
buildset_name = unb1 |
#technology_names = ip_stratixiv |
family_names = stratixiv |
block_design_names = sopc |
|
sim_tool_name = modelsim |
sim_tool_version = 6.6c |
synth_tool_name = quartus |
synth_tool_version = 11.1sp2 |
|
lib_root_dir = $HDL |
build_dir = $RADIOHDL_BUILD_DIR |
quartus_dir = /home/software/Altera/<synth_tool_version> |
model_tech_altera_lib = /home/software/modelsim_altera_libs/<synth_tool_version> |
model_tech_dir = /home/software/Mentor/<sim_tool_version>/modeltech |
vsim_dir = <model_tech_dir>/linux_x86_64 |
modelsim_search_libraries = |
# stratixiv only |
altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver stratixiv_ver stratixiv_hssi_ver stratixiv_pcie_hip_ver |
altera lpm sgate altera_mf altera_lnsim stratixiv stratixiv_hssi stratixiv_pcie_hip |
/radiohdl/trunk/core/test/cdf_dir/hdllib_files/hdllib_wrong.cfg
0,0 → 1,24
hdl_lib_name = technology |
hdl_library_clause_name = technology_lib |
#hdl_lib_uses_synth = |
hdl_lib_uses_sim = |
hdl_lib_technology = |
|
synth_files = |
technology_pkg.vhd |
$RADIOHDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd |
test_bench_files = |
|
regression_test_vhdl = |
# no self checking tb available yet |
|
|
[modelsim_project_file] |
modelsim_copy_files = |
technology_select_pkg_<buildset_name>.vhd $RADIOHDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd |
|
|
|
[quartus_project_file] |
quartus_copy_files = |
technology_select_pkg_<buildset_name>.vhd $RADIOHDL_BUILD_DIR/<buildset_name>/quartus/technology/technology_select_pkg.vhd |
/radiohdl/trunk/core/test/cdf_dir/hdllib_files/test_hdllib.cfg
0,0 → 1,24
hdl_lib_name = technology |
hdl_library_clause_name = technology_lib |
hdl_lib_uses_synth = |
hdl_lib_uses_sim = |
hdl_lib_technology = |
|
synth_files = |
technology_pkg.vhd |
$RADIOHDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd |
test_bench_files = |
|
regression_test_vhdl = |
# no self checking tb available yet |
|
|
[modelsim_project_file] |
modelsim_copy_files = |
technology_select_pkg_<buildset_name>.vhd $RADIOHDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd |
|
|
|
[quartus_project_file] |
quartus_copy_files = |
technology_select_pkg_<buildset_name>.vhd $RADIOHDL_BUILD_DIR/<buildset_name>/quartus/technology/technology_select_pkg.vhd |
/radiohdl/trunk/core/test/cdf_dir/hdltool_files/hdl_tool_quartus.cfg
0,0 → 1,27
# configuration file for defining the quartus installation on this system |
quartus_rootdir = ${QUARTUS_DIR}/quartus |
quartus_rootdir_override = ${QUARTUS_DIR}/quartus |
niosdir = ${QUARTUS_DIR}/nios2eds |
|
# extension to the PATH variable |
quartus_paths = |
<quartus_rootdir>/bin |
<niosdir>/bin |
<niosdir>/bin/gnu/H-i686-pc-linux-gnu/bin |
<niosdir>/bin/gnu/H-x86_64-pc-linux-gnu/bin |
<niosdir>/sdk2/bin |
|
[sopc] |
sopc_paths = |
<quartus_rootdir>/sopc_builder/bin |
sopc_environment_variables = |
sopc_kit_nios2 <niosdir> |
|
[qsys] |
qsys_paths = |
<quartus_rootdir>/../qsys/bin |
|
[user settings] |
user_environment_variables = |
altera_hw_tcl_keep_temp_files 1 |
|
/radiohdl/trunk/core/test/cdf_dir/referenced_files/reference_test.txt
0,0 → 1,34
# Testfile for testing the CommonDictFile class |
# |
non_ref_key_1 = some_value |
non_ref_key_2 = some_other_value |
|
early_ref_key1 = before <ref_key_2> is defined |
|
ref_key_1 = single_reference |
ref_key_2 = multiple words in the value |
|
simple_ref_1 = a value with <ref_key_1> |
double_ref_1 = a value with twice <ref_key_1><ref_key_1> |
triple_key_1 = its here <ref_key_1> and here <ref_key_1> and here <ref_key_1>!!! |
triple_key_2 = its here <ref_key_2> and here <ref_key_1>!!! |
|
ref_only_key_1 = <ref_key_1> |
|
wrong_ref_1 = what will double brackets <<ref_key_2>> do? # will not be replaced |
|
# this will give all nested_key_x the value 'some_value' |
nested_key_1 = some_value |
nested_key_2 = <nested_key_1> |
nested_key_3 = <nested_key_2> |
|
reverse_nested_key_1 = <reverse_nested_key_2> # becomes <reverse_nested_key_3> after substitution!!! |
reverse_nested_key_2 = <reverse_nested_key_3> |
reverse_nested_key_3 = some_value |
|
mutual_key_1 = <mutual_key_2> # becomes <<mutual_key_1> after substitution |
mutual_key_2 = <mutual_key_1> # remains the same |
|
loop_key_1 = <loop_key_1> # remains the same |
|
undefined_key_1 = reference to <non existing key> |
/radiohdl/trunk/core/test/cdf_dir/tree/cfgfile/a/dict.txt
0,0 → 1,3
# Testfile for testing the CommonDictFile class |
# |
key_1 = top_dir/a |
/radiohdl/trunk/core/test/cdf_dir/tree/cfgfile/b/0/dict.txt
0,0 → 1,3
# Testfile for testing the CommonDictFile class |
# |
key_1 = top_dir/b/0 |
/radiohdl/trunk/core/test/cdf_dir/tree/cfgfile/b/1/dict.txt
0,0 → 1,3
# Testfile for testing the CommonDictFile class |
# |
key_1 = top_dir/b/1 |
/radiohdl/trunk/core/test/cdf_dir/tree/cfgfile/b/2/dict.txt
0,0 → 1,3
# Testfile for testing the CommonDictFile class |
# |
key_1 = top_dir/b/2 |
/radiohdl/trunk/core/test/cdf_dir/tree/cfgfile/b/dict.txt
0,0 → 1,3
# Testfile for testing the CommonDictFile class |
# |
key_1 = top_dir/b |
/radiohdl/trunk/core/test/cdf_dir/tree/cfgfile/c/dict.txt
0,0 → 1,3
# Testfile for testing the CommonDictFile class |
# |
key_1 = top_dir/c |
/radiohdl/trunk/core/test/cdf_dir/tree/cfgfile/dict.txt
0,0 → 1,3
# Testfile for testing the CommonDictFile class |
# |
key_1 = top_dir |
/radiohdl/trunk/core/test/cdf_dir/tree/hdlbuildset/hdl_buildset_rsp.cfg
0,0 → 1,22
# TODO: Does RadioHDL still works for RSP?? |
buildset_name = rsp |
technology_names = ip_virtex4 |
family_names = virtex4 |
block_design_names = sopc |
|
sim_tool_name = modelsim |
sim_tool_version = 6.6c |
synth_tool_name = ise |
synth_tool_version = 11.1 |
ip_tool_name = coregen |
|
project_dir_depth_sim = 4 |
project_dir_depth_synth = 0 |
|
lib_root_dir = $RSP |
build_dir = $RADIOHDL_BUILD_DIR |
quartus_dir = /home/software/Altera/<synth_tool_version> |
model_tech_altera_lib = /home/software/modelsim_altera_libs/<synth_tool_version> |
model_tech_dir = /home/software/Mentor/<sim_tool_version>/modeltech |
vsim_dir = <model_tech_dir>/linux_x86_64 |
modelsim_search_libraries = |
/radiohdl/trunk/core/test/cdf_dir/tree/hdlbuildset/hdl_buildset_unb1.cfg
0,0 → 1,21
# Uniboardd 1 configuration |
buildset_name = unb1 |
technology_names = ip_stratixiv |
family_names = stratixiv |
block_design_names = sopc |
|
sim_tool_name = modelsim |
sim_tool_version = 6.6c |
synth_tool_name = quartus |
synth_tool_version = 11.1sp2 |
|
lib_root_dir = $HDL |
build_dir = $RADIOHDL_BUILD_DIR |
quartus_dir = /home/software/Altera/<synth_tool_version> |
model_tech_altera_lib = /home/software/modelsim_altera_libs/<synth_tool_version> |
model_tech_dir = /home/software/Mentor/<sim_tool_version>/modeltech |
vsim_dir = <model_tech_dir>/linux_x86_64 |
modelsim_search_libraries = |
# stratixiv only |
altera_ver lpm_ver sgate_ver altera_mf_ver altera_lnsim_ver stratixiv_ver stratixiv_hssi_ver stratixiv_pcie_hip_ver |
altera lpm sgate altera_mf altera_lnsim stratixiv stratixiv_hssi stratixiv_pcie_hip |
/radiohdl/trunk/core/test/cdf_dir/tree/hdllib/technology/test_hdllib.cfg
0,0 → 1,24
hdl_lib_name = technology |
hdl_library_clause_name = technology_lib |
hdl_lib_uses_synth = |
hdl_lib_uses_sim = |
hdl_lib_technology = |
|
synth_files = |
technology_pkg.vhd |
$RADIOHDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd |
test_bench_files = |
|
regression_test_vhdl = |
# no self checking tb available yet |
|
|
[modelsim_project_file] |
modelsim_copy_files = |
technology_select_pkg_<buildset_name>.vhd $RADIOHDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd |
|
|
|
[quartus_project_file] |
quartus_copy_files = |
technology_select_pkg_<buildset_name>.vhd $RADIOHDL_BUILD_DIR/<buildset_name>/quartus/technology/technology_select_pkg.vhd |
/radiohdl/trunk/core/test/cdf_dir/tree/hdllib/util/test_hdllib.cfg
0,0 → 1,22
hdl_lib_name = util |
hdl_library_clause_name = util_lib |
hdl_lib_uses_synth = mm common common_mult technology |
hdl_lib_uses_sim = |
hdl_lib_technology = |
|
synth_files = |
src/vhdl/util_logic.vhd |
src/vhdl/util_heater_pkg.vhd |
src/vhdl/util_heater.vhd |
|
test_bench_files = |
tb/vhdl/tb_util_heater.vhd |
|
regression_test_vhdl = |
# no self checking tb available yet |
|
[modelsim_project_file] |
|
|
[quartus_project_file] |
|
/radiohdl/trunk/core/test/cdf_dir/tree/hdltool/hdl_tool_altera.cfg
0,0 → 1,23
# configuration file for defining the altera installation on this system |
altera_rootdir = ${ALTERA_DIR}/altera |
altera_rootdir_override = ${ALTERA_DIR}/altera |
niosdir = ${ALTERA_DIR}/nios2eds |
|
# extension to the PATH variable |
altera_paths = |
<altera_rootdir>/bin |
<niosdir>/bin |
<niosdir>/bin/gnu/H-i686-pc-linux-gnu/bin |
<niosdir>/bin/gnu/H-x86_64-pc-linux-gnu/bin |
<niosdir>/sdk2/bin |
|
[sopc] |
sopc_paths = |
sopc_environment_variables = |
|
[qsys] |
qsys_paths = |
|
[user settings] |
user_environment_variables = |
|
/radiohdl/trunk/core/test/cdf_dir/tree/hdltool/hdl_tool_quartus.cfg
0,0 → 1,27
# configuration file for defining the quartus installation on this system |
quartus_rootdir = ${QUARTUS_DIR}/quartus |
quartus_rootdir_override = ${QUARTUS_DIR}/quartus |
niosdir = ${QUARTUS_DIR}/nios2eds |
|
# extension to the PATH variable |
quartus_paths = |
<quartus_rootdir>/bin |
<niosdir>/bin |
<niosdir>/bin/gnu/H-i686-pc-linux-gnu/bin |
<niosdir>/bin/gnu/H-x86_64-pc-linux-gnu/bin |
<niosdir>/sdk2/bin |
|
[sopc] |
sopc_paths = |
<quartus_rootdir>/sopc_builder/bin |
sopc_environment_variables = |
sopc_kit_nios2 <niosdir> |
|
[qsys] |
qsys_paths = |
<quartus_rootdir>/../qsys/bin |
|
[user settings] |
user_environment_variables = |
altera_hw_tcl_keep_temp_files 1 |
|
/radiohdl/trunk/core/test/cdf_dir/wrong_files/dangling_test.txt
0,0 → 1,6
# Testfile for testing sections the CommonDictFile class |
# |
# First some keys with different spacing (spaces and tabs) |
this is a lost value which causes an exception |
|
global_key_1 = global_1 |
/radiohdl/trunk/core/test/cdf_dir/wrong_files/wrong_key_test.txt
0,0 → 1,6
# Testfile for testing the CommonDictFile class |
# |
# First some keys with different spacing (spaces and tabs) |
|
key with spaces = should result in an exception |
|
/radiohdl/trunk/core/test/t_hdl_configfile.py
0,0 → 1,147
import unittest |
from configfile import * |
from hdl_configfile import * |
|
|
class Test_construction(unittest.TestCase): |
"Class to the various ways of construction" |
|
def test_wrong_filename(self): |
"Test constructor with non-existing file" |
self.assertRaises(ConfigFileException, ConfigFile, "/Is/Not/A/Valid/Directory") |
|
def test_empty_dictfile(self): |
"Test constructor with empty config file" |
cfg = ConfigFile("./cdf_dir/empty_file/empty_dict.txt") |
self.assertEqual(len(cfg.content), 0) |
|
def test_comment_only_dictfile(self): |
"Test constructor with comment-only config files" |
cfg = ConfigFile("./cdf_dir/empty_file/comment_only_dict.txt") |
self.assertEqual(len(cfg.content), 0) |
|
|
class Test_key_value_spacing(unittest.TestCase): |
"Class to the various kind of spacing between the keys and the values" |
|
def test_key_value_spacing(self): |
cfg = ConfigFile("./cdf_dir/correct_files/key_value_test.txt") |
self.assertEqual(cfg.space_key_1, "value_1") |
self.assertEqual(cfg.space_key_2, "value_2") |
self.assertEqual(cfg.space_key_3, "value_3") |
self.assertEqual(cfg.space_key_4, "value_4") |
self.assertEqual(cfg.space_key_5, "value_5") |
self.assertEqual(cfg.space_key_6, "value_6") |
self.assertEqual(cfg.space_key_7, "value_7") |
self.assertEqual(cfg.multi_key_1, "value10 value11 value12") |
self.assertEqual(cfg.multi_key_2, "value20, value21, value22") |
self.assertEqual(cfg.multi_key_3, "value30 value31 value32 value33") |
self.assertEqual(cfg.multi_key_4, "value40 = value41 = value42") |
self.assertEqual(cfg.tricky_key_1, "") |
self.assertEqual(cfg.tricky_key_2, "tricky_value_2") |
self.assertEqual(cfg.tricky_key_3, "") |
self.assertEqual(cfg.section_headers, ['"my_section"']) |
self.assertEqual(cfg.warning_key_1, "Be aware that multiline values can be tricky: this also belongs to previous key 'warning_key_1'") |
# also test attribute access versus item access |
self.assertEqual(cfg.multi_key_2, cfg['multi_key_2']) |
print(cfg.content) |
|
def test_sections(self): |
cfg = ConfigFile("./cdf_dir/correct_files/section_test.txt") |
self.assertEqual(cfg.global_key_1, "global_1"), |
self.assertEqual(cfg.global_key_2, '[ "aap", "noot", "mies" ]'), |
self.assertEqual(cfg.just_some_key_1, "section2 value1"), |
self.assertEqual(cfg.just_some_key_2, "section2 value2"), |
self.assertEqual(cfg.section_headers, ['section_1', 'section_2']) |
|
def test_dangling_value(self): |
"Test if a value without a key is detected" |
self.assertRaises(ConfigFileException, ConfigFile, "./cdf_dir/wrong_files/dangling_test.txt") |
|
def test_keys_with_spaces(self): |
"Test if a key that contains spaces is detected" |
self.assertRaises(ConfigFileException, ConfigFile, "./cdf_dir/wrong_files/wrong_key_test.txt") |
|
|
class Test_reference_key_substitution(unittest.TestCase): |
"Class to the the substitution of referenced keys." |
|
def test_read_the_file(self): |
cfg = ConfigFile("./cdf_dir/referenced_files/reference_test.txt") |
self.assertEqual(cfg.early_ref_key1, "before <ref_key_2> is defined") |
self.assertEqual(cfg.simple_ref_1, "a value with <ref_key_1>") |
self.assertEqual(cfg.double_ref_1, "a value with twice <ref_key_1><ref_key_1>") |
self.assertEqual(cfg.triple_key_1, "its here <ref_key_1> and here <ref_key_1> and here <ref_key_1>!!!") |
self.assertEqual(cfg.triple_key_2, "its here <ref_key_2> and here <ref_key_1>!!!") |
self.assertEqual(cfg.ref_only_key_1, "<ref_key_1>") |
self.assertEqual(cfg.wrong_ref_1, "what will double brackets <<ref_key_2>> do?") |
self.assertEqual(cfg.undefined_key_1, "reference to <non existing key>") |
|
self.assertEqual(cfg.nested_key_1, "some_value") |
self.assertEqual(cfg.nested_key_2, "<nested_key_1>") |
self.assertEqual(cfg.nested_key_3, "<nested_key_2>") |
self.assertEqual(cfg.reverse_nested_key_1, "<reverse_nested_key_2>") |
self.assertEqual(cfg.reverse_nested_key_2, "<reverse_nested_key_3>") |
self.assertEqual(cfg.reverse_nested_key_3, "some_value") |
self.assertEqual(cfg.mutual_key_1, "<mutual_key_2>") |
self.assertEqual(cfg.mutual_key_2, "<mutual_key_1>") |
self.assertEqual(cfg.loop_key_1, "<loop_key_1>") |
|
cfg.resolve_key_references() |
|
self.assertEqual(cfg.early_ref_key1, "before multiple words in the value is defined") |
self.assertEqual(cfg.simple_ref_1, "a value with single_reference") |
self.assertEqual(cfg.double_ref_1, "a value with twice single_referencesingle_reference") |
self.assertEqual(cfg.triple_key_1, "its here single_reference and here single_reference and here single_reference!!!") |
self.assertEqual(cfg.triple_key_2, "its here multiple words in the value and here single_reference!!!") |
self.assertEqual(cfg.ref_only_key_1, "single_reference") |
self.assertEqual(cfg.wrong_ref_1, "what will double brackets <<ref_key_2>> do?") |
self.assertEqual(cfg.undefined_key_1, "reference to <non existing key>") |
|
self.assertEqual(cfg.nested_key_1, "some_value") |
self.assertEqual(cfg.nested_key_2, "some_value") |
self.assertEqual(cfg.nested_key_3, "some_value") |
self.assertEqual(cfg.reverse_nested_key_1, "<reverse_nested_key_3>") |
self.assertEqual(cfg.reverse_nested_key_2, "some_value") |
self.assertEqual(cfg.reverse_nested_key_3, "some_value") |
self.assertEqual(cfg.mutual_key_1, "<mutual_key_1>") |
self.assertEqual(cfg.mutual_key_2, "<mutual_key_1>") |
self.assertEqual(cfg.loop_key_1, "<loop_key_1>") |
|
|
class Test_hdltool_file(unittest.TestCase): |
"Class to test the hdltool class." |
|
def test_read_good_hdltool_file(self): |
tool = HdlTool("./cdf_dir/hdltool_files/hdl_tool_quartus.cfg") |
self.assertEqual(tool.user_environment_variables, "altera_hw_tcl_keep_temp_files 1") |
|
|
class Test_hdl_buildset_file(unittest.TestCase): |
"Class to test the hdltool class." |
|
def test_read_good_hdlbuildset_file(self): |
buildset = HdlBuildset("./cdf_dir/hdlbuildset_files/hdl_buildset_unb1.cfg") |
self.assertEqual(buildset.buildset_name, "unb1") |
self.assertEqual(buildset.technology_names, "ip_stratixiv") |
self.assertEqual(buildset.lib_root_dirs, "${RADIOHDL_WORK}/libraries ${RADIOHDL_WORK}/applications ${RADIOHDL_WORK}/boards") |
|
def test_read_wrong_hdlbuildset_file(self): |
self.assertRaises(ConfigFileException, HdlBuildset, "./cdf_dir/hdlbuildset_files/hdl_buildset_wrong.cfg") |
|
|
class Test_hdllib_file(unittest.TestCase): |
"Class to test the hdllib class." |
|
def test_read_good_hdllib_file(self): |
lib = HdlLib("./cdf_dir/hdllib_files/test_hdllib.cfg") |
self.assertEqual(lib.hdl_lib_name, "technology") |
self.assertEqual(lib.hdl_library_clause_name, "technology_lib") |
self.assertEqual(lib.hdl_lib_technology, "") |
|
def test_read_wrong_hdllib_file(self): |
self.assertRaises(ConfigFileException, HdlLib, "./cdf_dir/hdllib_files/hdllib_wrong.cfg") |
|
|
if __name__ == '__main__': |
unittest.main(verbosity=2) |
/radiohdl/trunk/core/test/t_hdl_configtree.py
0,0 → 1,70
import unittest |
from configtree import * |
from hdl_configtree import * |
|
|
class Test_construction(unittest.TestCase): |
"Class to the various ways of construction" |
|
def test_wrong_filename(self): |
"Test constructor with non-existing rootdir" |
self.assertRaises(ConfigFileException, ConfigTree, "/Is/Not/A/Valid/Directory", "dict.txt") |
|
def test_empty_dictfile(self): |
"Test constructor with empty config file" |
tree = ConfigTree("./cdf_dir/empty_file", "empty_dict.txt") |
self.assertEqual(len(tree.configfiles), 1) |
|
def test_comment_only_dictfile(self): |
"Test constructor with comment-only config files" |
tree = ConfigTree("./cdf_dir/empty_file", "comment_only_dict.txt") |
self.assertEqual(len(tree.configfiles), 1) |
|
|
class Test_tree_behaviour(unittest.TestCase): |
"Class to test the 'tree' functionality of the class" |
|
def test_tree_with_configfiles(self): |
"Test constructor with a tree with configfiles all containing a 'key_1' label" |
"that holds its relative path in the tree" |
tree = ConfigTree("./cdf_dir/tree/cfgfile", "dict.txt") |
for cfg in list(tree.configfiles.values()): |
# print cfg.ID, cfg.content |
expected_value = cfg.ID.replace("./cdf_dir/tree/cfgfile", "top_dir").replace("/dict.txt", "") |
self.assertEqual(expected_value, cfg.key_1) |
|
def test_hdllib_tree(self): |
"Test if we can read in a tree with hdllib files." |
tree = HdlLibTree("./cdf_dir/tree/hdllib", "test_hdllib.cfg") |
self.assertEqual(len(tree.configfiles), 2) |
util = tree.configfiles['util'] |
self.assertEqual(util.hdl_library_clause_name, 'util_lib') |
self.assertEqual(util.synth_files, 'src/vhdl/util_logic.vhd src/vhdl/util_heater_pkg.vhd src/vhdl/util_heater.vhd') |
technology = tree.configfiles['technology'] |
self.assertEqual(technology.hdl_library_clause_name, 'technology_lib') |
self.assertEqual(technology.synth_files, 'technology_pkg.vhd $RADIOHDL_BUILD_DIR/<buildset_name>/modelsim/technology/technology_select_pkg.vhd') |
|
def test_hdlbuildset_tree(self): |
"Test if we can read in a tree with hdlbuildset files." |
tree = HdlBuildsetTree("./cdf_dir/tree/hdlbuildset", "hdl_buildset_*.cfg") |
self.assertEqual(len(tree.configfiles), 2) |
rsp = tree.configfiles['rsp'] |
self.assertEqual(rsp.technology_names, 'ip_virtex4') |
self.assertEqual(rsp.model_tech_altera_lib, '/home/software/modelsim_altera_libs/<synth_tool_version>') |
unb1 = tree.configfiles['unb1'] |
self.assertEqual(unb1.technology_names, 'ip_stratixiv') |
self.assertEqual(unb1.model_tech_altera_lib, '/home/software/modelsim_altera_libs/<synth_tool_version>') |
|
def test_hdltool_tree(self): |
"Test if we can read in a tree with hdltool files." |
tree = HdlToolTree("./cdf_dir/tree/hdltool", "hdl_tool_*.cfg") |
self.assertEqual(len(tree.configfiles), 2) |
altera = tree.configfiles['./cdf_dir/tree/hdltool/hdl_tool_altera.cfg'] |
self.assertEqual(altera.altera_rootdir, "${ALTERA_DIR}/altera") |
quartus = tree.configfiles['./cdf_dir/tree/hdltool/hdl_tool_quartus.cfg'] |
self.assertEqual(quartus.quartus_rootdir, "${QUARTUS_DIR}/quartus") |
|
|
if __name__ == '__main__': |
unittest.main(verbosity=2) |
|
/radiohdl/trunk/core/check_config
0,0 → 1,167
#!/usr/bin/env python3 |
############################################################################### |
# |
# Copyright (C) 2018 |
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> |
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands |
# |
# This program is free software: you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation, either version 3 of the License, or |
# (at your option) any later version. |
# |
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
# |
# $Id: generate_ip_libs.py 18842 2018-08-29 10:47:05Z overeem $ |
# |
############################################################################### |
|
import os |
from os.path import expandvars, isfile, isdir |
from argparse import ArgumentParser |
from hdl_configfile import HdlBuildset, HdlTool |
from configfile import ConfigFileException |
|
|
def _do_basic_key_checking(cfgfile, indent=""): |
# Check that all key references are solved |
print("{}Checking references...".format(indent), end=' ') |
all_refs_solved = cfgfile.resolve_key_references() |
if all_refs_solved: |
print("OK") |
else: |
print("\n{}ERROR: The following reference cannot be solved: {}".format(indent, cfgfile.unresolved_refs)) |
|
# Check that all key required keys contain values |
print("{}Checking required keys...".format(indent), end=' ') |
empty_keys = [] |
for key in cfgfile.required_keys: |
if cfgfile.content[key] == "": |
empty_keys.append(key) |
if not empty_keys: |
print("OK") |
else: |
print("\n{}ERROR: The following required keys don't have a value: {}".format(indent, empty_keys)) |
|
|
def expand_all_vars(dir_name): |
_dirname = dir_name |
while '$' in _dirname: |
# print(_dirname) |
_dirname = expandvars(_dirname) |
return _dirname |
|
|
def _check_quartus_configfile(cfgfile, tool_types): |
# check required dirs |
for required_dir in ["quartus_rootdir", "quartus_rootdir_override", "niosdir"]: |
print(" Checking {}...".format(required_dir), end=' ') |
|
if isdir(expand_all_vars(cfgfile[required_dir])): |
print("OK") |
else: |
print("\n ERROR: path {} does not exist!".format(cfgfile[required_dir])) |
|
# check _paths variables |
required_paths = ["{}_paths".format(tool) for tool in tool_types] |
for path_key in [key for key in list(cfgfile.content.keys()) if key.endswith("_paths")]: |
paths = [expand_all_vars(pathname) for pathname in cfgfile[path_key].replace("\t", " ").split(" ") if pathname != ""] |
print(" Checking {}...".format(path_key)) |
if not paths: |
print(" no paths defined.") |
else: |
for path in paths: |
if isdir(path): |
print(" {}: OK".format(path)) |
else: |
if path_key in required_paths: |
print(" {}: DOES NOT EXIST!".format(path)) |
else: |
print(" {}: does not exist but is not required".format(path)) |
|
# check IP generation |
print(" Checking ip generation...") |
ip_tools = [tool for tool in cfgfile.ip_tools.replace("\t", " ").split(" ") if tool != ''] |
for ip_tool in ip_tools: |
opt_key = "{}_default_options".format(ip_tool) |
if opt_key not in list(cfgfile.content.keys()): |
print(" {}: key is MISSING!".format(opt_key)) |
else: |
print(" {}: OK".format(opt_key)) |
|
# check environment variables |
for envvar_key in [key for key in list(cfgfile.content.keys()) if key.endswith("_environment_variables")]: |
items = [item for item in cfgfile[envvar_key].replace("\t", " ").split(" ") if item != ""] |
print(" Checking {}...".format(envvar_key)) |
if not items: |
print(" no variables defined.") |
else: |
if len(items) % 2 == 0: |
print(" number of values is correct") |
else: |
print(" expected even number of values (not {})".format(len(items))) |
|
|
if __name__ == '__main__': |
|
keys = ['QUARTUS_DIR', 'ALTERA_DIR', 'MENTOR_DIR', 'MODELSIM_ALTERA_LIBS_DIR'] |
for key in keys: |
if key not in os.environ: |
print("{} not in os.environ".format(key)) |
|
# setup parser and parse the arguments. |
argparser = ArgumentParser(description='Check to content of your hdl_buildset file and the corresponding hdl_tool file.') |
argparser.add_argument('buildset', help="Filename like 'hdl_buildset_<buildset>.cfg'") |
args = argparser.parse_args() |
|
# construct full name of buildsetfile and read the file |
full_buildsetfile_name = expandvars("${RADIOHDL_CONFIG}/hdl_buildset_%s.cfg" % (args.buildset)) |
print("Reading {}...".format(full_buildsetfile_name)) |
buildset_info = HdlBuildset(full_buildsetfile_name) |
|
_do_basic_key_checking(buildset_info) |
|
# check if lib_root_dirs exist |
print("Checking defined library directories...", end=' ') |
lib_dirs = [expand_all_vars(libdir) for libdir in buildset_info.lib_root_dirs.replace("\t", " ").split(" ") |
if libdir != ''] |
wrong_dirs = [] |
for libdir in lib_dirs: |
if not isdir(libdir): |
wrong_dirs.append(libdir) |
if not wrong_dirs: |
print("OK") |
else: |
print("\nERROR: The following library rootdir do not exist: ", wrong_dirs) |
|
# Check tools |
subtoolnames = [subtool for subtool in buildset_info.block_design_names.replace("\t", " ").split(" ") if subtool != ''] |
toolnames = [buildset_info.synth_tool_name, buildset_info.sim_tool_name] |
for toolname in toolnames: |
print("Checking tool {}...".format(toolname), end=' ') |
if toolname not in buildset_info.section_headers: |
print("\n Warning: No sectionheader found.", end=' ') |
tool_dir = "{}_dir".format(toolname) |
if tool_dir not in list(buildset_info.content.keys()): |
print("\n ERROR: Key {} is missing.".format(tool_dir), end=' ') |
else: |
os.environ[tool_dir.upper()] = buildset_info[tool_dir] |
tool_configfile = expandvars("${RADIOHDL_CONFIG}/hdl_tool_%s.cfg" % (toolname)) |
if not isfile(tool_configfile): |
print("\n Warning: File {} is missing!".format(tool_configfile), end=' ') |
else: |
try: |
print("\n Reading {}...".format(tool_configfile)) |
tool_info = HdlTool(tool_configfile) |
_do_basic_key_checking(tool_info, indent=" ") |
except ConfigFileException as excp: |
print("\n ERROR: File contains an error: {}".format(excp)) |
|
if toolname == "quartus": |
_check_quartus_configfile(tool_info, toolnames+subtoolnames) |
radiohdl/trunk/core/check_config
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/core/common_radiohdl.py
===================================================================
--- radiohdl/trunk/core/common_radiohdl.py (nonexistent)
+++ radiohdl/trunk/core/common_radiohdl.py (revision 4)
@@ -0,0 +1,83 @@
+
+import os
+import inspect
+
+
+def listify(obj):
+ """
+ Can be used to force method input to a list.
+ """
+ if isinstance(obj, list):
+ return obj
+ else:
+ return [obj]
+
+ # try:
+ # return list(obj)
+ # except TypeError:
+ # return [obj]
+
+
+def unlistify(obj):
+ """
+ Converts 1-element list to x.
+ """
+ # The isinstance() built-in function is recommended over the type()
+ # built-in function for testing the type of an object
+ if isinstance(obj, list):
+ if len(obj) == 1:
+ return obj[0]
+ return obj
+
+
+def remove_from_list_string(list_str, item_str, sep=' '):
+ """Treat the string list_str as a list of items that are separated by sep and then
+ remove the specified item_str string from the list and return the list as a
+ string of items separated by sep. Also remove any duplicate items.
+ """
+ _list_str = list_str.split(sep)
+ _list_str = unique(_list_str)
+ _list_str.remove(item_str)
+ return sep.join(_list_str)
+
+
+def unique(in_list):
+ """
+ Extract unique list elements (without changing the order like set() does)
+ """
+ result = []
+ for item in in_list:
+ if item in result:
+ continue
+ result.append(item)
+ return result
+
+
+def method_name(caller_depth=0):
+ """
+ Returns the name of the caller method.
+ """
+ # Note: inspect.stack()[0][3] would return the name of this method.
+ return inspect.stack()[caller_depth+1][3]
+
+
+def mkdir(path):
+ """Recursively create leave directory and intermediate directories if they do not already exist."""
+ expand_path = os.path.expandvars(path) # support using environment variables in the file path
+ expand_path = os.path.expanduser(expand_path) # support using ~ in the file path
+ if not os.path.exists(expand_path):
+ os.makedirs(expand_path)
+
+
+def expand_file_path_name(fpn, dir_path=''):
+ """ Expand environment variables in fpn to get file_path_name.
+ - if it is an absolute path return file_path_name else
+ - if it still has a local file path prepend dir_path to the file_path_name and return dir_path + file_path_name.
+ """
+ file_path_name = os.path.expandvars(fpn) # support using environment variables in the file path
+ file_path_name = os.path.expanduser(file_path_name) # support using ~ in the file path
+ if os.path.isabs(file_path_name):
+ return file_path_name # use absolute path to file
+
+ # derive path to file from the directory path and a directory path to the file
+ return os.path.join(os.path.expandvars(dir_path), file_path_name)
Index: radiohdl/trunk/core/config_variable.py
===================================================================
--- radiohdl/trunk/core/config_variable.py (nonexistent)
+++ radiohdl/trunk/core/config_variable.py (revision 4)
@@ -0,0 +1,46 @@
+#!/usr/bin/env python3
+###############################################################################
+#
+# Copyright (C) 2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+import sys
+import os
+from os.path import expandvars, dirname, basename
+from argparse import ArgumentParser
+from configfile import ConfigFile
+
+if __name__ == '__main__':
+ # setup parser and parse the arguments.
+ argparser = ArgumentParser(description='Options and arguments for showing hdl_config keys values')
+ argparser.add_argument('configfile', help="Filename like 'hdl_buildset_.cfg'")
+ argparser.add_argument('keyname', help="Name of the key to show the value of.")
+ args = argparser.parse_args()
+
+ # resolve full name of configfile and force it to be explicit absolute or relative.
+ full_configfile_name = expandvars(args.configfile)
+ if full_configfile_name[0] != '/':
+ full_configfile_name = "./" + full_configfile_name
+ # read the file
+ cfg_info = ConfigFile(full_configfile_name)
+ cfg_info.resolve_key_references()
+
+ print("{}\n".format(os.path.expandvars(cfg_info.get_value(args.keyname, must_exist=True))))
+
radiohdl/trunk/core/config_variable.py
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/core/configfile.py
===================================================================
--- radiohdl/trunk/core/configfile.py (nonexistent)
+++ radiohdl/trunk/core/configfile.py (revision 4)
@@ -0,0 +1,291 @@
+###############################################################################
+#
+# Copyright (C) 2014-2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+
+"""Class for accessing the values of a configuration file of RadioHDL.
+
+ The contents of the configuration file consist of a series of key - value
+ pairs. These key - value pairs are read from the file and kept in a
+ single dictionary of keys and values that can be accessed via .content.
+
+ The format of the configuration file is similar to that of an ini file. For ini
+ files Python has the ConfigParser package, but that is not used here because
+ we need other parsing rules than the ones implemented in ConfigParser.
+ The parsing is done during the allocation of the class.
+
+ Like an ini file the configurationfile can contain one or more sections. The
+ first section is common, has no header and always included. The specific
+ sections have a header that is marked by [section header]. The square brackets
+ '[' and ']' are used to identify the section header. If the 'section header' is
+ included in the argument 'sections' of the constructor then the keys of that
+ section will be included in the dictionary.
+
+ 'sections' = None --> ignore fileSections to include all sections in
+ the dict.
+ 'sections' = [] --> empty list to include only the common first
+ section in the dict.
+ 'sections' = ['section header' ...] -->
+ dedicated list of one or more section header
+ strings to include these specific sections,
+ and also the common first section, in the
+ dict.
+
+ The key and value string in the dictionary file are separated by '='. Hence
+ the '=' character can not be used in keys. The '=' can be used in values,
+ because subsequent '=' on the same line are part of the value.
+ Each key must start on a new line and may not contain whitespace.
+ The value string can extend over one or multiple lines.
+
+ Comment in line is supported by preceding it with a '#'. The '#' and the
+ text after it on the line are stripped. The remainder of the line before
+ the '#' is still interpreted.
+
+ Example:
+ # This is a comment section
+ # a key starts on a new line and extends until the '='
+ # a key and its values are separated by '='
+
+ key=string # this is a comment and the key is still interpreted
+ key=string
+ key =string
+ key = string
+
+ # a key with multiple values in its string
+ key = value value value
+
+ # how the values are separated depends on the dictionary user
+ key = value, value, value
+ key = value value
+
+ # a key with many values can have its string extend on multiple lines,
+ # the newline is replaced by a ' ' and any indent is removed
+ key =
+ value
+ value
+ value
+
+ # empty lines and spaces are allowed
+ key = value
+"""
+
+import os.path
+import re
+from collections import OrderedDict
+
+__all__ = ['CFG_COMMENT_CHAR', 'CFG_ASSIGNMENT_CHAR', 'ConfigFileException', 'ConfigFile']
+
+CFG_COMMENT_CHAR = '#'
+CFG_ASSIGNMENT_CHAR = '='
+
+
+class ConfigFileException(Exception):
+ "Exception class used in the ConfigFile class"
+ pass
+
+
+class ConfigFile(object):
+ """
+ :filename The full filename of the configfile. May contain environment variables.
+ :sections Optional. May contain a list of sections names. The key-value pairs in the other sections
+ are ignored.
+ :required_keys Optional. May contain a list of all keys that must exist in the configfile. If one or more
+ of those keys is missing in the configfile an exception is raised.
+ """
+ _CONFIGFILE_ATTRIBUTES = ['_own_attr_', 'filename', 'location', 'sections', 'required_keys',
+ '__content__', 'section_headers', 'unresolved_refs', 'warnings']
+
+ def __init__(self, filename, sections=None, required_keys=[]):
+ """
+ Store the dictionaries from all fileName files in rootDir.
+ :raise ConfigFileException
+ """
+ full_filename = os.path.expanduser(os.path.expandvars(filename))
+ if not os.path.isfile(full_filename):
+ raise ConfigFileException("configfile '%s' not found" % full_filename)
+
+ # Crucial: define dict for storing our (simulated) attributes
+ self.__dict__['_own_attr_'] = {}
+ self.__content__ = OrderedDict()
+
+ self.filename = os.path.basename(full_filename)
+ self.location = os.path.dirname(full_filename)
+ self.sections = sections
+ self.required_keys = required_keys
+ self.section_headers = []
+ self.unresolved_refs = []
+ self.warnings = ''
+
+ # Try to read the configuration file.
+ self._read_file()
+
+ # Check if all required keys are available
+ for required_key in self.required_keys:
+ if required_key not in self.__content__:
+ raise ConfigFileException("configfile '%s' missing key '%s'" % (filename, required_key))
+
+ def __getattr__(self, name):
+ """
+ Catch read-access to attributes to fetch values from the content dictionary.
+ :raise AtttributeError
+ """
+ if name in self._CONFIGFILE_ATTRIBUTES:
+ return self.__dict__['_own_attr_'][name]
+
+ if name in self.__dict__['_own_attr_']['__content__']:
+ return self.__dict__['_own_attr_']['__content__'][name]
+
+ print('%s object has no attribute %s' % (str(self.__class__.__name__), str(name)))
+
+ if not hasattr(self, name):
+ raise AttributeError("%r object has no attribute %r" % (self.__class__.__name__, name))
+
+ return getattr(self, name)
+
+ def __setattr__(self, name, value):
+ """
+ Catch write-access to attributes to store values in the content dictionary.
+ :raise AtttributeError
+ """
+ if name in self._CONFIGFILE_ATTRIBUTES:
+ self.__dict__['_own_attr_'][name] = value
+ elif name in self.__dict__['_own_attr_']['__content__']:
+ self.__dict__['_own_attr_']['__content__'][name] = value
+ else:
+ if not hasattr(self, name):
+ raise AttributeError("%r object has no attribute %r" % (self.__class__.__name__, name))
+ setattr(self, name, value)
+
+ def __getitem__(self, key):
+ "Also allow access to the information as item."
+ return self.__getattr__(key)
+
+ def __setitem__(self, key, value):
+ "Also allow access to the information as item."
+ self.__setattr__(key, value)
+
+ def _add_kv_pair(self, key, value, include_in_section):
+ """
+ Internal function for adding a key-value pair in a neat way.
+ """
+ # print("add_kv_pair: key={}, value={}\n".format(key, value))
+ if not include_in_section:
+ return
+ if key.find(' ') > 0:
+ self.warnings += "Error: Key may not contain spaces: file '{}/{}', key '{}'"\
+ .format(self.location, self.filename, key)
+ elif key != '':
+ self.__content__[key] = value.strip() # Update dict with key and value
+
+ def _read_file(self):
+ """
+ Read the dictionary information the filePathName file.
+ The dictionary will contain all key-value pairs as well as a
+ 'section_headers' key that contains all the sections found in the file
+ (regardless if the keys of that section where included in the dict or not).
+ :raise ConfigFileException
+ """
+ include_section = True # default include all sections
+ key = ''
+ value = ''
+ linenr = 0
+ with open("{}/{}".format(self.location, self.filename), 'r') as configfile:
+ for line in configfile:
+ linenr += 1
+ ln = line.split(CFG_COMMENT_CHAR, 1)[0] # Strip comment from line
+ if len(ln) == 0:
+ continue
+ section_begin = ln.find('[') # Search for [section] header in this line
+ section_end = ln.find(']')
+ # section MUST start at first character of the line
+ if section_begin == 0 and section_end > 0:
+ self._add_kv_pair(key, value, include_section) # complete action on current key
+ key = ''
+ value = ''
+ # administrate new section
+ section_header = ln[1:section_end].strip() # new section header
+ self.section_headers.append(section_header)
+ include_section = True # default include this new section
+ if self.sections is not None:
+ if section_header not in self.sections:
+ include_section = False # skip this section
+ else:
+ key_end = ln.find(CFG_ASSIGNMENT_CHAR) # Search for key in this line
+ if key_end > 0:
+ self._add_kv_pair(key, value, include_section) # complete action on current key
+ key = ln[0:key_end].strip() # start with new key
+ value = ln[key_end+1:].strip() # and new value
+ else:
+ # no assignment char found, append this line to the current value
+ value += ' ' # replace newline by space to separate values
+ value += ln.strip() # append value
+ if value.strip() != '' and key == '':
+ self.warnings += "Warning: value without a key: file '{}/{}', line {} ({})"\
+ .format(self.location, self.filename, linenr, value)
+ value = ''
+ self._add_kv_pair(key, value, include_section) # complete action on current key
+
+ if self.warnings != '':
+ raise ConfigFileException(self.warnings)
+
+ @property
+ def content(self):
+ # print(self.__content__)
+ "The content of the configfile as ordered dictionary."
+ return self.__content__
+
+ @property
+ def ID(self):
+ "Returns uniq ID (string) to identify this particular file. Fullfilename is used."
+ return "{}/{}".format(self.location, self.filename)
+
+ def resolve_key_references(self):
+ """
+ Replaces in all values the references to keys () with the value of that key.
+ Note that this operation is irreversable.
+ """
+ ref_pattern = r"<(.+?)>"
+ prog = re.compile(ref_pattern)
+ # print('__content__={}'.format(self.__content__.items()))
+ # loop over all items of the dict
+ for key, value in list(self.__content__.items()):
+ # any reference in the value?
+ matchlist = list(set(prog.findall(value)))
+ for reference in matchlist:
+ if reference in list(self.__content__.keys()):
+ self.__content__[key] = re.sub("<{}>".format(reference), self.__content__[reference], value)
+ value = self.__content__[key]
+ else:
+ self.unresolved_refs.append("<{}>".format(reference))
+ return len(self.unresolved_refs) == 0
+
+ def get_value(self, key, must_exist=False):
+ """
+ Get the value of a key. If the key does not exist and that is allowed 'None' is returned, in case the
+ key should have been there an exception is raised.
+ """
+ if key in self.__content__:
+ return self.__content__[key]
+
+ if must_exist:
+ raise ConfigFileException("Key '%s' does not exist in configfile %s/%s." % (key, self.location, self.filename))
+
+ return None
Index: radiohdl/trunk/core/configtree.py
===================================================================
--- radiohdl/trunk/core/configtree.py (nonexistent)
+++ radiohdl/trunk/core/configtree.py (revision 4)
@@ -0,0 +1,123 @@
+###############################################################################
+#
+# Copyright (C) 2014-2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+import sys
+import os
+import os.path
+import re
+from common_radiohdl import listify
+from configfile import ConfigFile, ConfigFileException
+
+
+class ConfigTree(object):
+
+ def __init__(self, rootdirs, filename, sections=None):
+ """
+ Collect the information of all configuration files that are present under the rootdirs.
+ """
+ # Save construction arguments
+ self.rootdirs = listify(rootdirs)
+ self.filename = filename
+ self.sections = listify(sections)
+
+ # Define result variables
+ self._configfiles = {}
+
+ # search and read the config files.
+ self._read_all_configfiles()
+ if len(self._configfiles) == 0:
+ raise ConfigFileException("No '%s' files found in directory tree(s) '%s'." % (filename, rootdirs))
+
+ def _read_all_configfiles(self):
+ """
+ Recursively search the rootdirs to find the configfiles and add the content to our admin.
+ """
+ ref_pattern = self.filename.replace("*", "(.+?)")
+ name_mask = re.compile(ref_pattern+"$")
+ for rootdir in self.rootdirs:
+ for root, _, files in os.walk(rootdir):
+ for some_filename in files:
+ if name_mask.search(some_filename):
+ cfgfile = self._factory_constructor("{}/{}".format(root, some_filename))
+ # check for duplicates
+ if cfgfile.ID in list(self._configfiles.keys()):
+ raise ConfigFileException("File with id '%s' found twice (at '%s' and '%s')"
+ % (cfgfile.ID, self._configfiles[cfgfile.ID].location, cfgfile.location))
+ self._configfiles[cfgfile.ID] = cfgfile
+
+ def _factory_constructor(self, full_filename):
+ """
+ Function for returning the readin configfile. Derived classes *must* redefine this function.
+ """
+ return ConfigFile(full_filename, sections=self.sections)
+
+ @property
+ def configfiles(self):
+ return self._configfiles
+
+ def remove_files_from_tree(self, files_to_remove):
+ """
+ Remove the given list of configfiles from our configfile administration.
+ :raise KeyError when one of the files does not exist in our admin.
+ """
+ for cfgfileID in files_to_remove:
+ self._configfiles.pop(cfgfileID)
+
+ def limit_tree_to(self, files_to_keep):
+ """
+ Limit the configfile collection in our admin to the ones given in the files_to_keep argument.
+ """
+ for cfgfile in self._configfiles:
+ if cfgfile.ID not in files_to_keep:
+ self._configfiles.pop(cfgfile.ID)
+
+ def get_key_values(self, key, configfiles=None, must_exist=False):
+ """
+ Get the value of a key in all configfiles. If the key does not exist in a configfile and
+ the flag must_exist is False then None is added to the result list. When the flag must_exist
+ is true and the key is not defined in a configfile then an exception is raised.
+ The configfiles to search in may be limited to 'configfiles' otherwise the whole tree is used.
+ :return List of values
+ :raises ConfigFileException
+ """
+ if configfiles is None:
+ configfiles = self._configfiles
+
+ result = []
+ for cfgfile in configfiles:
+ result.append(cfgfile.get_value(key, must_exist))
+ return result
+
+ def get_configfiles(self, key, values=None, user_configfiles=None):
+ """
+ Get a list with all configfiles that contain the key with a value specified in values.
+ If values==None then a list of all configfiles is returned that contain the key.
+ The configfiles to search in may be restricted to the user_configfiles.
+ """
+ file_list = list(self._configfiles.values()) if not user_configfiles else user_configfiles
+
+ result = []
+ for cfgfile in file_list:
+ if cfgfile not in result and key in cfgfile.content:
+ if values is None or cfgfile.content[key] in values:
+ result.append(cfgfile)
+ return result
Index: radiohdl/trunk/core/export_config_variables.py
===================================================================
--- radiohdl/trunk/core/export_config_variables.py (nonexistent)
+++ radiohdl/trunk/core/export_config_variables.py (revision 4)
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+###############################################################################
+#
+# Copyright (C) 2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+import sys
+import os
+from os.path import expandvars, dirname, basename
+from argparse import ArgumentParser
+from configfile import ConfigFile
+
+if __name__ == '__main__':
+ # setup parser and parse the arguments.
+ argparser = ArgumentParser(description="Options and arguments for constructing an 'export' command for shell based on the content of a hdltool config file.")
+ argparser.add_argument('configfile', help="Filename like 'hdl_buildset_.cfg'")
+ argparser.add_argument('keynames', help="Name(s) of the key(s) to show the value of. Use comma to seperate multiple keys.")
+ argparser.add_argument('--varnames', help="Name(s) of the environment variable(s) the keys are mapped to. Default the keynames in capitals are used as environment variable names.")
+ argparser.add_argument('--is-group', help="The keynames refer to groups of environment variables that must be set.",
+ action="store_true")
+ argparser.add_argument('--optional', help="The keynames are optional. When them do not exist not error is generated",
+ action="store_true")
+ args = argparser.parse_args()
+
+ # resolve full name of configfile and force it to be explicit absolute or relative.
+ full_configfile_name = expandvars(args.configfile)
+ if full_configfile_name[0] != '/':
+ full_configfile_name = "./" + full_configfile_name
+ # read the file
+ cfg_info = ConfigFile(full_configfile_name)
+ cfg_info.resolve_key_references()
+
+ # parse the keys if they are no group references
+ if not args.is_group:
+ # setup key- and variable- names
+ keys = args.keynames.split(',')
+ if args.varnames:
+ env_vars = args.varnames.split(',')
+ if len(keys) != len(env_vars):
+ argparser.error("Number of variable names must match the number of keys.")
+ else:
+ env_vars = []
+ for key in keys:
+ env_vars.append(key.upper())
+
+ # finally construct an export command for the key value pairs.
+ for idx, key in enumerate(keys):
+ print("export {}='{}'\n".format(env_vars[idx],
+ os.path.expandvars(cfg_info.get_value(key, must_exist=not(args.optional)))))
+ sys.exit(0)
+
+ # Each key contains key-value pairs that must be exported in stead of a value
+ if args.varnames:
+ argparser.error("The option --varnames can not be used in combination with the option --is-group.")
+
+ # print("args.keynames=%s" % str(args.keynames))
+ keys = args.keynames.split(',')
+ for key in keys:
+ kv_pairs = cfg_info.get_value(key, must_exist=not(args.optional))
+ # currently 'by definition' the value we got has the format: [ [...]]
+ # check we have an even number of items
+ # print("KV_pairs={}".format(kv_pairs))
+ if kv_pairs is None:
+ continue
+ items = kv_pairs.split()
+ if len(items) % 2:
+ argparser.error("Key '{}' should contain an even number of items ({}).".format(key, items))
+ for idx in range(0, len(items)//2, 2):
+ print("export {}='{}'\n".format(items[idx].upper(), os.path.expandvars(items[idx+1])))
+
radiohdl/trunk/core/export_config_variables.py
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/core/export_hdllib_variables.py
===================================================================
--- radiohdl/trunk/core/export_hdllib_variables.py (nonexistent)
+++ radiohdl/trunk/core/export_hdllib_variables.py (revision 4)
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+###############################################################################
+#
+# Copyright (C) 2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+import sys
+import os
+from os.path import expandvars, dirname, basename
+from argparse import ArgumentParser
+from hdl_configfile import HdlBuildset
+from hdl_configtree import HdlLibTree
+
+if __name__ == '__main__':
+ # setup parser and parse the arguments.
+ argparser = ArgumentParser(description='Options and arguments for exporting hdllib keys values')
+ argparser.add_argument('buildset', help="Filename like 'hdl_buildset_.cfg'")
+ argparser.add_argument('libname', help="Name of the library to search in.")
+ argparser.add_argument('keys', help="Name of variable(s) to export.")
+ args = argparser.parse_args()
+
+ # read the buildset file
+ full_buildsetfile_name = expandvars("${RADIOHDL_CONFIG}/hdl_buildset_%s.cfg" % (args.buildset))
+ buildset_info = HdlBuildset(full_buildsetfile_name)
+ buildset_info.resolve_key_references()
+
+ # find out where the hdllibs files are and read them in
+ root_dirs = [expandvars(rootdir) for rootdir in buildset_info.lib_root_dirs.replace("\t", " ").split(" ")
+ if rootdir != '']
+ lib_tree = HdlLibTree(rootdirs=root_dirs, filename="hdllib.cfg")
+ for key in args.keys.split(','):
+ print("export {}='{}'\n".format(
+ key.lower(),
+ os.path.expandvars(lib_tree.configfiles[args.libname].get_value(key=key, must_exist=True))))
+
+
radiohdl/trunk/core/export_hdllib_variables.py
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/core/generate_ip_libs
===================================================================
--- radiohdl/trunk/core/generate_ip_libs (nonexistent)
+++ radiohdl/trunk/core/generate_ip_libs (revision 4)
@@ -0,0 +1,203 @@
+#!/usr/bin/env python3
+###############################################################################
+#
+# Copyright (C) 2014-2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+
+import sys
+import os
+from os.path import expandvars, dirname, basename
+from subprocess import call, STDOUT
+from common_radiohdl import listify, mkdir
+from argparse import ArgumentParser
+from hdl_configfile import HdlBuildset, HdlTool
+from hdl_configtree import HdlLibTree
+
+
+def run_qmegawiz(buildset, outputdir, hdllib, vhdl_files, options):
+ """
+ Run qmegawiz for the configuration in the given hdllib.
+ The script takes care that the exit code of qmegawiz is returned to the caller.
+ """
+ extra_options = hdllib.get_value("qmegawiz_extra_options", False)
+ if not extra_options:
+ extra_options = ""
+
+ error_code = 0
+ for vhdl_file in vhdl_files:
+ script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset
+ script += 'cd %s\n' % outputdir
+ script += 'cp %s/%s .\n' % (hdllib.location, vhdl_file)
+ script += 'set -o pipefail\n'
+ # echo line without 'Info:' to make sure grep it's exit code is 0
+ script += '(echo " " ; qmegawiz %s %s %s 2>&1) | grep -iv Info:\n' \
+ % (options, extra_options, vhdl_file)
+ script += 'exit_code=$?\n'
+ script += 'rm %s\n' % vhdl_file
+ script += 'exit $exit_code\n'
+ # execute script
+ print("compiling {} ... ".format(vhdl_file))
+ return_code = call(script, stdout=None, stderr=STDOUT, shell=True)
+ # qmegawiz is very sloppy with it's exitcodes. We assume 0 is OK although this not always the case. :-(
+ if return_code == 0:
+ print("*** Generation (probably) OK\n")
+ else:
+ print("*** Error during generation, exitcode={}\n".format(return_code))
+ error_code |= return_code
+ return error_code
+
+
+def run_qsys(buildset, outputdir, hdllib, vhdl_files, options):
+ """
+ Run qsys for the configuration in the given hdllib.
+ The script takes care that the exit code of qsys is returned to the caller.
+ """
+ extra_options = hdllib.get_value("qsys-generate_extra_options", False)
+ if not extra_options:
+ extra_options = ""
+
+ error_code = 0
+ for vhdl_file in vhdl_files:
+ script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset
+ script += 'cd %s\n' % outputdir
+ script += 'cp %s/%s .\n' % (hdllib.location, vhdl_file)
+ #script += 'cd %s\n' % hdllib.location
+ script += 'set -o pipefail\n'
+ # echo line without 'Info:' to make sure grep it's exit code is 0
+ script += '(echo " " ; qsys-generate %s %s %s --search-path=%s --output-directory=%s 2>&1) | grep -iv Info:\n' \
+ % (vhdl_file, options, extra_options, "outputdir,$", outputdir)
+ script += 'exit_code=$?\n'
+ script += 'rm %s\n' % vhdl_file
+ script += 'exit $exit_code\n'
+ # execute script
+ print("compiling {} ... , output-dir = {}".format(vhdl_file, outputdir))
+ return_code = call(script, stdout=None, stderr=STDOUT, shell=True)
+ if return_code == 0:
+ print("*** Generation OK\n")
+ else:
+ print("*** Error during generation, exitcode={}\n".format(return_code))
+ error_code |= return_code
+ return error_code
+
+
+def run_quartus_sh(buildset, outputdir, hdllib, tcl_files, options):
+ """
+ Run quartus_sh for the configuration in the given hdllib.
+ The script takes care that the exit code of quartus_sh is returned to the caller.
+ """
+ extra_options = hdllib.get_value("quartus_sh_extra_options", False)
+ if not extra_options:
+ extra_options = ""
+
+ error_code = 0
+ for tcl_file in tcl_files:
+ script = '. ${RADIOHDL_GEAR}/quartus/set_quartus %s\n' % buildset
+ script += 'cd %s/%s\n' % (outputdir, hdllib.quartus_sh_ip_srcdir)
+ script += 'set -o pipefail\n'
+ # echo line without 'Info:' to make sure grep it's exit code is 0
+ script += '(echo " " ; quartus_sh %s %s -t %s 2>&1) | grep -iv Info:\n' \
+ % (options, extra_options, tcl_file)
+ script += 'exit_code=$?\n'
+ script += 'exit $exit_code\n'
+ # execute script
+ print("compiling {} ... ".format(tcl_file))
+ return_code = call(script, stdout=None, stderr=STDOUT, shell=True)
+ if return_code == 0:
+ print("*** Generation OK\n")
+ else:
+ print("*** Error during generation, exitcode={}\n".format(return_code))
+ error_code |= return_code
+ return error_code
+
+
+def expand_all_vars(dir_name):
+ _dirname = dir_name
+ while '$' in _dirname:
+ # print(_dirname)
+ _dirname = expandvars(_dirname)
+ return _dirname
+
+
+if __name__ == '__main__':
+ # setup parser and parse the arguments.
+ argparser = ArgumentParser(description='Generate the IP libraries for all technologies of the given buildset')
+ argparser.add_argument('buildset', help="Filename like 'hdl_buildset_.cfg'")
+ args = argparser.parse_args()
+
+ # resolve full name of buildsetfile and force it to be explicit absolute or relative.
+ full_buildsetfile_name = os.path.join(os.getenv('RADIOHDL_CONFIG'), 'hdl_buildset_{}.cfg'.format(args.buildset))
+ print('full_buildsetfile_name={}'.format(full_buildsetfile_name))
+ if full_buildsetfile_name[0] != '/':
+ full_buildsetfile_name = "./" + full_buildsetfile_name
+ # read the file
+ buildset_info = HdlBuildset(full_buildsetfile_name)
+ buildset_info.resolve_key_references()
+
+ # read in all hdllib configfiles
+ root_dirs = [expand_all_vars(rootdir) for rootdir in buildset_info.lib_root_dirs.replace("\t", " ").split(" ")
+ if rootdir != '']
+ lib_tree = HdlLibTree(rootdirs=root_dirs, filename="hdllib.cfg", sections="generate_ip_libs")
+
+ # read in the tool environment settings
+ tool_config_file = os.path.join(os.getenv('RADIOHDL_CONFIG'), 'hdl_tool_{}.cfg'.format(buildset_info.synth_tool_name))
+ print('tool_config_file={}'.format(tool_config_file))
+ tool_info = HdlTool(tool_config_file)
+ tool_info.resolve_key_references()
+ ip_tools = [tool for tool in tool_info.ip_tools.replace("\t", " ").split(" ")
+ if tool != '']
+
+ files_with_errors = []
+ for technology in listify(buildset_info.technology_names):
+ print()
+ print("Generating IP libraries for technology:", technology)
+ # for all tools supported by quartus
+ for ip_tool in ip_tools:
+ tool_options = tool_info['{}_default_options'.format(ip_tool)]
+ ip_tool_key = "{}_ip_files".format(ip_tool)
+ # for all hdllib.cfg files found
+ for ip_lib_name in sorted(lib_tree.configfiles.keys())[::-1]: # TODO reverse order issue!
+ ip_lib_info = lib_tree.configfiles[ip_lib_name]
+ # if technology matches and there are files defined for the current tool
+ if ip_lib_info.hdl_lib_technology == technology and ip_tool_key in ip_lib_info.content:
+ # we have a match do the compilation
+ print("==> Processing {} with {}".format(ip_lib_info.ID, ip_tool))
+ outputdir = os.path.join(os.getenv('RADIOHDL_BUILD_DIR'), '{}/{}/'.format(args.buildset, ip_tool))
+ mkdir(outputdir)
+ vhdl_files = [name for name in ip_lib_info[ip_tool_key].replace("\t", " ").split(" ")
+ if name != '']
+ if ip_tool == 'qmegawiz':
+ err_code = run_qmegawiz(args.buildset, outputdir, ip_lib_info, vhdl_files, tool_options)
+ elif ip_tool == 'qsys-generate':
+ err_code = run_qsys(args.buildset, outputdir, ip_lib_info, vhdl_files, tool_options)
+
+ elif ip_tool == 'quartus_sh':
+ err_code = run_quartus_sh(args.buildset, outputdir, ip_lib_info, vhdl_files, tool_options)
+ else:
+ raise NameError("Hdllib file in %s contains a unknown tool (%s) for generating IP." %
+ (ip_lib_info.ID, ip_tool))
+ if err_code:
+ files_with_errors.append(ip_lib_info.ID)
+
+ if files_with_errors:
+ print("##### The following files had compile errors:")
+ print(" ", files_with_errors)
+ else:
+ print("+++++ No errors during compilation! +++++\n")
radiohdl/trunk/core/generate_ip_libs
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/core/generate_qsys
===================================================================
--- radiohdl/trunk/core/generate_qsys (nonexistent)
+++ radiohdl/trunk/core/generate_qsys (revision 4)
@@ -0,0 +1,218 @@
+#!/usr/bin/env python3
+###############################################################################
+#
+# Copyright (C) 2015
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+###############################################################################
+
+"""
+Purpose:
+. Generate an Altera QSYS file from a base QSYS file and user supplied list of regs.
+Usage:
+. python generate_qsys.py
+"""
+
+from common import *
+
+def _to_element_str(reg_name, reg_base_addr):
+ """
+ Returns a template XML 'element' filled in with reg_name and reg_base_addr.
+ """
+ ELEMENT_TEMPLATE = """
+ element HDL_REG_NAME.mem
+ {
+ datum baseAddress
+ {
+ value = HDL_REG_BASE_ADDR;
+ type = "long";
+ }
+ datum _sortIndex
+ {
+ value = "8";
+ type = "int";
+ }
+ datum sopceditor_expanded
+ {
+ value = "0";
+ type = "boolean";
+ }
+ }
+ """
+ return ELEMENT_TEMPLATE.replace('HDL_REG_NAME', reg_name).replace('HDL_REG_BASE_ADDR', str(reg_base_addr))
+
+def _to_interface_str(reg_name):
+ """
+ Returns a template XML 'interface' filled in with reg_name.
+ """
+ INTERFACE_TEMPLATE = """
+
+
+
+
+
+
+
+ """
+ return INTERFACE_TEMPLATE.replace('HDL_REG_NAME', reg_name)
+
+def _append_to_modules_mid_str(modules_mid_str, reg_name, reg_base_addr, reg_end_addr):
+ """
+ The modules_mid section contains one line (dataSlaveMapParam) for all start- and end addresses.
+ Append the start and end address of our register to this line.
+ """
+ DATASLAVEMAPPARAM_TEMPLATE = " "
+ return modules_mid_str + DATASLAVEMAPPARAM_TEMPLATE.replace('HDL_REG_NAME', reg_name).replace('HDL_REG_BASE_ADDR', str(reg_base_addr)).replace('HDL_REG_END_ADDR', str(reg_end_addr))
+
+def _to_module_str(reg_name, reg_addr_w):
+ """
+ Returns a template XML 'module' filled in with reg_name and reg_addr_w.
+ """
+ MODULE_TEMPLATE = """
+
+
+
+
+
+
+ """
+ return MODULE_TEMPLATE.replace('HDL_REG_NAME', reg_name).replace('HDL_REG_ADDR_W', str(reg_addr_w))
+
+def _to_connection_str(reg_name, reg_base_addr):
+ """
+ Returns a template XML 'connection' filled in with reg_name and reg_base_addr.
+ """
+ CONNECTION_TEMPLATE = """
+
+
+
+
+
+
+
+ """
+ return CONNECTION_TEMPLATE.replace('HDL_REG_NAME', reg_name).replace('HDL_REG_BASE_ADDR', str(reg_base_addr))
+
+
+def generate_qsys(input_qsys, regs, output_filename):
+ """
+ Creates an XML QSYS file (output_filename) from a base QSYS and a user-supplied list of registers to add (regs).
+ . regs = [ (reg_name, reg_base_addr, reg_span), .. ]
+ """
+ # Read the base QSYS contents into a string
+ with open (input_qsys, "r") as base_qsys_file:
+ data=base_qsys_file.read()
+
+ # We'll split the base QSYS string up in 5 sections.
+ # . Note that string.split() throws away the delimiter so we'll restore those later.
+ elements = data.split(']]>', 1)[0]
+ parameters = data.split(']]>', 1)[1].split('', 1)[0]
+ interfaces = data.split(']]>', 1)[1].split('', 1)[1].split('', 1)[1].split('', 1)[1].split('')[0]
+ modules_mid = data.split(']]>', 1)[1].split('', 1)[1].split('')[1].split(']]>',1)[0]
+ modules_tail = data.split(']]>', 1)[1].split('', 1)[1].split('')[1].split(']]>',1)[1]
+ connections = data.split(']]>', 1)[1].split('', 1)[1].split('\n' + \
+ parameters + \
+ '\n' + \
+ interfaces + \
+ '' + \
+ modules_mid + \
+ ']]>\n' + \
+ modules_tail + \
+ '\n'
+
+ # Write the QSYS string to the output_file.
+ output_file = open(output_filename, "w")
+ output_file.write(qsys_str)
+ output_file.close()
+
+
+################################################################################
+# Example main on execution of this file
+################################################################################
+if __name__ == '__main__':
+ base_qsys_path = 'qsys_input.qsys'
+ regs = [('reg_my_peripheral', 16384, 3), ('reg_another_peripheral', 17152, 6)]
+ generate_qsys(base_qsys_path, regs, 'qsys_generated.qsys')
Index: radiohdl/trunk/core/hdl_configfile.py
===================================================================
--- radiohdl/trunk/core/hdl_configfile.py (nonexistent)
+++ radiohdl/trunk/core/hdl_configfile.py (revision 4)
@@ -0,0 +1,82 @@
+###############################################################################
+#
+# Copyright (C) 2014-2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+
+from configfile import ConfigFile
+
+__all__ = ['HdlTool', 'HdlBuildset', 'HdlLib']
+
+
+class HdlTool(ConfigFile):
+ """
+ Class the represents the content of a hdltool_.cfg configuration file.
+ """
+ _HDLTOOL_ATTRIBUTES = []
+
+ def __init__(self, filename, sections=None):
+ """
+ Read the hdltoolset configuration file and check presence of the required keys.
+ :raise ConfigFileException
+ """
+ super(HdlTool, self).__init__(filename, sections, required_keys=self._HDLTOOL_ATTRIBUTES)
+
+
+class HdlBuildset(ConfigFile):
+ """
+ Class the represents the content of a hdl_buildset_.cfg configuration file.
+ """
+ _HDLBUILDSET_ATTRIBUTES = ['buildset_name', 'technology_names', 'family_names', 'block_design_names',
+ 'lib_root_dirs', 'sim_tool_name', 'sim_tool_version',
+ 'synth_tool_name', 'synth_tool_version']
+
+ def __init__(self, filename, sections=None):
+ """
+ Read the hdlbuildset configuration file and check presence of the required keys.
+ :raise ConfigFileException
+ """
+ super(HdlBuildset, self).__init__(filename, sections, required_keys=self._HDLBUILDSET_ATTRIBUTES)
+
+ @property
+ def ID(self):
+ "Returns uniq ID (string) to identify this particular file."
+ return self.buildset_name
+
+
+class HdlLib(ConfigFile):
+ """
+ Class the represents the content of a hdllib.cfg configuration file.
+ """
+ _HDLLIB_ATTRIBUTES = ['hdl_lib_name', 'hdl_library_clause_name', 'hdl_lib_uses_synth',
+ 'hdl_lib_uses_sim', 'hdl_lib_technology', 'synth_files',
+ 'test_bench_files']
+
+ def __init__(self, filename, sections=None):
+ """
+ Read the hdllib configuration file and check presence of the required keys.
+ :raise ConfigFileException
+ """
+ super(HdlLib, self).__init__(filename, sections, required_keys=self._HDLLIB_ATTRIBUTES)
+
+ @property
+ def ID(self):
+ "Returns uniq ID (string) to identify this particular file."
+ return self.hdl_lib_name
Index: radiohdl/trunk/core/hdl_configtree.py
===================================================================
--- radiohdl/trunk/core/hdl_configtree.py (nonexistent)
+++ radiohdl/trunk/core/hdl_configtree.py (revision 4)
@@ -0,0 +1,75 @@
+###############################################################################
+#
+# Copyright (C) 2014-2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+
+from hdl_configfile import HdlTool, HdlBuildset, HdlLib
+from configtree import ConfigTree
+
+__all__ = ['HdlToolTree', 'HdlBuildsetTree', 'HdlLibTree']
+
+
+class HdlToolTree(ConfigTree):
+ """
+ Class the represents the content of a set of hdltool_.cfg configuration files.
+ """
+ def __init__(self, rootdirs, filename, sections=None):
+ """
+ Read the hdltool configuration files and stores them in this tree.
+ :raise ConfigFileException
+ """
+ super(HdlToolTree, self).__init__(rootdirs, filename, sections)
+
+ def _factory_constructor(self, full_filename):
+ "Function for returning the readin configfile."
+ return HdlTool(full_filename)
+
+
+class HdlBuildsetTree(ConfigTree):
+ """
+ Class the represents the content of a set of hdl_buildset_.cfg configuration files.
+ """
+ def __init__(self, rootdirs, filename, sections=None):
+ """
+ Read the hdlbuildset configuration files and stores them in this tree.
+ :raise ConfigFileException
+ """
+ super(HdlBuildsetTree, self).__init__(rootdirs, filename, sections)
+
+ def _factory_constructor(self, full_filename):
+ "Function for returning the readin configfile."
+ return HdlBuildset(full_filename)
+
+
+class HdlLibTree(ConfigTree):
+ """
+ Class the represents the content of a set of hdllib.cfg configuration files.
+ """
+ def __init__(self, rootdirs, filename, sections=None):
+ """
+ Reads the hdllib configuration files and stores them in this tree.
+ :raise ConfigFileException
+ """
+ super(HdlLibTree, self).__init__(rootdirs, filename, sections)
+
+ def _factory_constructor(self, full_filename):
+ "Function for returning the readin configfile."
+ return HdlLib(full_filename)
Index: radiohdl/trunk/core/hdl_libraries_wizard.py
===================================================================
--- radiohdl/trunk/core/hdl_libraries_wizard.py (nonexistent)
+++ radiohdl/trunk/core/hdl_libraries_wizard.py (revision 4)
@@ -0,0 +1,649 @@
+###############################################################################
+#
+# Copyright (C) 2014
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+###############################################################################
+
+"""HDL configuration for building simulation and synthesis targets.
+
+ There should be one hdl_buildset_.cfg file per buildset somewhere in the
+ toolRootDir and at least one hdllib.cfg file somewhere in the libRootDir.
+ Every HDL library that is in the libRootDir can be found if it has a hdllib.cfg file.
+ Together the hdl_buildset_.cfg and hdllib.cfg files contain all the keys and
+ values that are sufficient to be able to build the targets for the HDL
+ library. The possible targets are:
+
+ - compile to created the library binaries for simulation
+ - synthesize to created an image that can be loaded ion the FPGA
+ - verify VHDL test benches in simulation
+ - verify Python test cases via the MM control interface in simulation
+ - validate Python test cases on hardware via the MM control interface
+
+ The contents of the cfg files consist of a series of key - value pairs
+ that are read into a dictionary as defined in hdl_configfile.py. Whether
+ the key is a valid key depends on the application that interprets the
+ dictionary.
+
+ The methods can have the library dictionary or the library name as
+ argument. The default arguments are the self.libs.dicts and the
+ corresponding self.lib_names. The argument can be a list or a single value.
+ Similar the return can be a list or a single value, because a list of one
+ element is unlistified.
+
+"""
+
+import sys
+import fnmatch
+from os import listdir, walk, getenv
+from os.path import expandvars, isabs, join, isfile
+import shutil
+from distutils.dir_util import copy_tree
+from argparse import ArgumentParser
+import collections
+import common_radiohdl as cm
+from configfile import ConfigFile
+from hdl_configfile import HdlBuildset
+from hdl_configtree import HdlLibTree
+
+__all__ = ['HdlLibrariesWizard']
+
+
+class HdlLibrariesWizard:
+
+ def __init__(self, toolRootDir, toolFileName, libFileName='hdllib.cfg', libFileSections=None):
+ """Get tool dictionary info from toolRootDir and all HDL library dictionary info for it
+
+ - self.tool.dicts = single dictionary that contains the tool info (only one tool dict in dicts list)
+ - self.libs.dicts = list of dictionaries that contains the info of the HDL libraries.
+
+ The libRootDir parameter is defined in the hdl_buildset_.cfg file and is the root directory from where the hdllib.cfg
+ files are searched for.
+
+ - self.lib_names = the library names of self.libs.dicts
+
+ In parallel to the self.libs.dicts list of dictionaries a list of self.lib_names is created to be able to identify
+ a HDL library dict also by its library name. Iherefore it is important that the indexing of parallel lists remains
+ intact at all times.
+
+ - self.technologyNames = the technologyNames parameter is defined in the hdl_buildset_.cfg file. All generic HDL
+ libraries and these technology specific libraries are kept. If self.technologyNames is:
+ [] : Keep all HDL libraries that were found.
+ ['ip_stratixiv', 'ip_arria10'] : The HDL libraries with a hdl_lib_technology that is not '' or does not match one of the technologies
+ in technologyNames are removed from the list of HDL library dictionaries.
+
+ - self.removed_libs = contains the HDL library dicts that have been removed from self.libs.dicts, because they are for
+ a technology that is not within technologyNames.
+
+ Keep lists of all unavailable library names that were found at the hdl_lib_uses_synth, hdl_lib_uses_ip, hdl_lib_uses_sim and
+ hdl_lib_include_ip keys in the self.libs.dicts:
+
+ - self.unavailable_use_libs = self.unavailable_use_synth_libs + self.unavailable_use_ip_libs + self.unavailable_use_sim_libs
+ - self.unavailable_include_ip_libs
+
+ Unavailable used libraries can be missing for a valid reason when they are not required (e.g. IP for another technology). Being able to
+ ignore missing libraries does require that the entities from these libraries are instantiated as components in the VHDL. The difference
+ between a removed library and an unavailable library is that for a removed library the HDL config information is still known, whereas
+ for an unavailable library it is not. Therefore the library clause names for referred but unavailable HDL libraries are disclosed at the
+ 'hdl_lib_disclose_library_clause_names' keys of the libraries that use them and kept in a dictionary:
+
+ - self.disclosed_library_clause_names
+
+ """
+ print("HdlLibrariesWizard(toolRootDir=%s, toolFileName=%s, libFileName=%s, libFileSections=%s)"
+ % (toolRootDir, toolFileName, libFileName, libFileSections))
+ self.toolRootDir = toolRootDir # TODO almost obsolete
+
+ # read the buildset file. This file contains major information about paths, technologies, and so on
+ full_buildsetfile_name = "%s/%s" % (toolRootDir, toolFileName)
+ buildset_info = HdlBuildset(full_buildsetfile_name)
+ buildset_info.resolve_key_references()
+ self.buildset = buildset_info.content
+
+ # HDL library config files
+ self.libRootDirs = [expandvars(rootdir) for rootdir in self.buildset['lib_root_dirs'].replace("\t", " ").split(" ")
+ if rootdir != '']
+ self.libs = HdlLibTree(rootdirs=self.libRootDirs,
+ filename=libFileName,
+ sections=libFileSections) # library dict files
+ if len(self.libs.configfiles) == 0:
+ sys.exit('Error : No HDL library config files found')
+ print("Found %d hdllib files:" % len(self.libs.configfiles))
+
+ # Substitute key words occurring in hdllib.cfg files with their value.
+ self.substitute_key_words()
+
+ self.familyNames = self.buildset['family_names'].split()
+ print("### self.familyNames = ", self.familyNames)
+
+ # Keep the generic HDL libraries and remove those that do not match the specified IP technologies
+ self.technologyNames = self.buildset['technology_names'].split()
+ print("### self.technologyNames = ", self.technologyNames)
+ self.removed_libs = {}
+
+ buildset_files = []
+ for root, dirs, files in walk(join(getenv("RADIOHDL_GEAR"), 'config')):
+ for name in files:
+ if fnmatch.fnmatch(name, 'hdl_buildset_*.cfg'):
+ buildset_files.append(join(root, name))
+ all_buildset_names = [bs[bs.rfind('_')+1:bs.rfind('.')] for bs in buildset_files]
+ # print(all_buildset_names)
+
+ for cfglib_name in list(self.libs.configfiles.keys()):
+ techname = self.libs.configfiles[cfglib_name]['hdl_lib_technology']
+ if (techname != '' and techname not in self.technologyNames):
+ # keep the removed libs we need the content of those libs later.
+ self.removed_libs[cfglib_name] = self.libs.configfiles[cfglib_name]
+ else:
+ # accept only projects for active buildset_name
+ # this method asume the hdl_lib_name is starting with the buildset_name and ending with
+ # the project name seperated by a '_'
+ # for example unb2b_
+ for buildset_name in sorted(all_buildset_names)[::-1]:
+ if buildset_name == self.buildset['buildset_name']:
+ continue
+ if buildset_name+'_' in self.libs.configfiles[cfglib_name]['hdl_lib_name']:
+ # keep the removed libs we need the content of those libs later.
+ self.removed_libs[cfglib_name] = self.libs.configfiles[cfglib_name]
+
+ self.libs.remove_files_from_tree(list(self.removed_libs.keys()))
+ print(len(self.removed_libs), "REMOVED LIBS:", sorted(self.removed_libs))
+
+ # Keep list of used HDL library names
+ self.lib_names = list(self.libs.configfiles.keys())
+ print(len(self.lib_names), "KEPT LIBS:", sorted(self.lib_names))
+
+ # No need to check for duplicates since HdlLibTree did that already.
+
+ # create dictionary of library names with library clause names that are disclosed at the 'hdl_lib_disclose_library_clause_names' keys.
+ self.disclosed_library_clause_names = {}
+ for lib in list(self.libs.configfiles.values()):
+ if lib.get_value('hdl_lib_disclose_library_clause_names'):
+ key_values = lib.get_value('hdl_lib_disclose_library_clause_names').split()
+ lib_name = key_values[0::2]
+ lib_clause_name = key_values[1::2]
+ lib_pairs = list(zip(lib_name, lib_clause_name))
+ # No need to check for duplicate lib_names, because a dictionary cannot have duplicate keys
+ for lp in lib_pairs:
+ self.disclosed_library_clause_names[lp[0]] = lp[1]
+ # Check whether the used libraries from the self.libs.dicts keys indeed exist, otherwise remove them from the dictionary key
+ # string and add the used library name to the list of unavailable used library names and check that the library use clause
+ # name was disclosed at the 'hdl_lib_disclose_library_clause_names' key. In this way other methods do not have to check a
+ # used library does indeed exist.
+ self.unavailable_use_synth_libs = []
+ self.unavailable_use_ip_libs = []
+ self.unavailable_use_sim_libs = []
+ self.unavailable_include_ip_libs = []
+ for lib in list(self.libs.configfiles.values()):
+ use_synth_libs = []
+ use_ip_libs = []
+ use_sim_libs = []
+ include_ip_libs = []
+ if lib.get_value('hdl_lib_uses_synth'):
+ use_synth_libs = lib.get_value('hdl_lib_uses_synth').split()
+ if lib.get_value('hdl_lib_uses_ip'):
+ use_ip_libs += lib.get_value('hdl_lib_uses_ip').split()
+ if lib.get_value('hdl_lib_uses_sim'):
+ use_sim_libs += lib.get_value('hdl_lib_uses_sim').split()
+ if lib.get_value('hdl_lib_include_ip'):
+ include_ip_libs = lib.get_value('hdl_lib_include_ip').split()
+ for use_name in use_synth_libs:
+ if (use_name not in self.lib_names) and (use_name not in self.removed_libs):
+ lib['hdl_lib_uses_synth'] = cm.remove_from_list_string(lib['hdl_lib_uses_synth'], use_name)
+ self.unavailable_use_synth_libs.append(use_name)
+ if use_name not in list(self.disclosed_library_clause_names.keys()):
+ sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_synth' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name))
+ for use_name in use_ip_libs:
+ if (use_name not in self.lib_names) and (use_name not in self.removed_libs):
+ lib['hdl_lib_uses_ip'] = cm.remove_from_list_string(lib['hdl_lib_uses_ip'], use_name)
+ self.unavailable_use_ip_libs.append(use_name)
+ if use_name not in list(self.disclosed_library_clause_names.keys()):
+ sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_ip' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name))
+ for use_name in use_sim_libs:
+ if (use_name not in self.lib_names) and (use_name not in self.removed_libs):
+ lib['hdl_lib_uses_sim'] = cm.remove_from_list_string(lib['hdl_lib_uses_sim'], use_name)
+ self.unavailable_use_sim_libs.append(use_name)
+ if use_name not in list(self.disclosed_library_clause_names.keys()):
+ sys.exit("Error : Unavailable library %s at 'hdl_lib_uses_sim' key is not disclosed at 'hdl_lib_disclose_library_clause_names' key in library %s" % (use_name, lib_name))
+ for use_name in include_ip_libs:
+ if (use_name not in self.lib_names) and (use_name not in self.removed_libs):
+ lib['hdl_lib_include_ip'] = cm.remove_from_list_string(lib['hdl_lib_include_ip'], use_name)
+ self.unavailable_include_ip_libs.append(use_name)
+ if use_name not in list(self.disclosed_library_clause_names.keys()):
+ sys.exit("Error : Unavailable library %s at 'hdl_lib_include_ip' key in library %s is not disclosed at any 'hdl_lib_disclose_library_clause_names' key" % (use_name, lib_name))
+ # remove all duplicates from the list
+ self.unavailable_use_synth_libs = cm.unique(self.unavailable_use_synth_libs)
+ self.unavailable_use_ip_libs = cm.unique(self.unavailable_use_ip_libs)
+ self.unavailable_use_sim_libs = cm.unique(self.unavailable_use_sim_libs)
+ self.unavailable_include_ip_libs = cm.unique(self.unavailable_include_ip_libs) # list of include_ip_use_libs
+ self.unavailable_use_libs = self.unavailable_use_synth_libs + self.unavailable_use_ip_libs + self.unavailable_use_sim_libs
+ self.unavailable_use_libs = cm.unique(self.unavailable_use_libs) # aggregate list of use_*_libs
+
+ # The Key value pairs defined in hdltool.cfg can be used in hdllib.cfg files. See hdllib.cfg of technology library
+ def substitute_key_words(self):
+ for lib in list(self.libs.configfiles.values()):
+ for lib_key, lib_value in list(lib.content.items()):
+ for tool_key, tool_value in list(self.buildset.items()):
+ tool_key_string = '<%s>' % tool_key
+ if tool_key_string in lib_value:
+ lib[lib_key] = lib_value.replace(tool_key_string, tool_value)
+
+ def check_library_names(self, check_lib_names, lib_names=None):
+ """Check that HDL library names exists within the list of library names, if not then exit with Error message.
+ The list of library names can be specified via the argument lib_names, or it defaults to the list of
+ self.lib_names of HDL libraries that were found in the toolRootDir for the libFileName of this object.
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+ for check_lib_name in cm.listify(check_lib_names):
+ if check_lib_name not in cm.listify(lib_names):
+ sys.exit('Error : Unknown HDL library name %s found with %s' % (check_lib_name, cm.method_name()))
+
+ def get_used_libs(self, build_type, lib_dict, arg_include_ip_libs=[]):
+ """Get the list of used HDL libraries from the lib_dict that this library directly depends on, so only at this HDL library hierachy level.
+
+ Which libraries are actually used depends on the build_type. The build_type can be:
+ '' uses all libraries from 'hdl_lib_uses_synth', 'hdl_lib_uses_ip' and 'hdl_lib_uses_sim' in the lib_dict
+ 'sim' uses all libraries from 'hdl_lib_uses_synth', 'hdl_lib_uses_ip' and 'hdl_lib_uses_sim' in the lib_dict
+ 'synth' uses all libraries from 'hdl_lib_uses_synth' in the lib_dict and from 'hdl_lib_uses_ip' it only uses the IP
+ libraries that are mentioned in the local 'hdl_lib_include_ip' key or in the global arg_include_ip_libs
+
+ The 'hdl_lib_uses_*' keys all appear locally in the same hdllib.cfg file. The 'hdl_lib_include_ip' key appears at this level or at
+ a higher level (design) library hdllib.cfg file to select which of all available 'hdl_lib_uses_ip' IP libraries will actually be
+ used in the design. The 'hdl_lib_include_ip' cannot appear in a lower level hdllib.cfg, because a lower level HDL library cannot
+ depend on a higher level HDL library. Therefore the IP libraries that need to be included from 'hdl_lib_uses_ip' will be known in
+ include_ip_libs.
+ """
+ # Get local library dependencies
+ use_synth_libs = []
+ use_ip_libs = []
+ use_sim_libs = []
+ include_ip_libs = []
+ if 'hdl_lib_uses_synth' in lib_dict.content:
+ use_synth_libs = lib_dict['hdl_lib_uses_synth'].split()
+ if 'hdl_lib_uses_ip' in lib_dict.content:
+ use_ip_libs += lib_dict['hdl_lib_uses_ip'].split()
+ if 'hdl_lib_uses_sim' in lib_dict.content:
+ use_sim_libs += lib_dict['hdl_lib_uses_sim'].split()
+ if 'hdl_lib_include_ip' in lib_dict.content:
+ include_ip_libs = lib_dict['hdl_lib_include_ip'].split()
+
+ # Append include_ip_libs from this level to the global list of arg_include_ip_libs
+ include_ip_libs = list(arg_include_ip_libs) + include_ip_libs
+
+ # Get the actually use_libs for lib_dict
+ use_libs = use_synth_libs + use_ip_libs + use_sim_libs # default include all IP, so ignore include_ip_libs
+ if build_type == 'sim':
+ use_libs = use_synth_libs + use_ip_libs + use_sim_libs # for simulation included all IP, so ignore include_ip_libs
+ if build_type == 'synth':
+ use_libs = use_synth_libs
+ # For synthesis only keep the local use_ip_libs if it is mentioned in the global include_ip_libs. Vice versa also only
+ # include the global include_ip_libs if they appear in a local use_ip_libs, to avoid that an IP library that is mentioned
+ # in the global include_ip_libs gets included while it is not instantiated anywhere in the design.
+ for ip_lib in use_ip_libs:
+ if ip_lib in include_ip_libs:
+ use_libs += [ip_lib]
+
+ # Remove any duplicate library names from the lists
+ use_libs = cm.unique(use_libs)
+ include_ip_libs = cm.unique(include_ip_libs)
+
+ # Remove libraries that are in the removed technologies (use list() to take copy)
+ for use_name in list(use_libs):
+ if use_name in self.removed_libs:
+ use_libs.remove(use_name)
+ for use_name in list(include_ip_libs):
+ if use_name in self.removed_libs:
+ include_ip_libs.remove(use_name)
+
+ return use_libs, include_ip_libs
+
+ def derive_all_use_libs(self, build_type, lib_name, arg_include_ip_libs=[]):
+ """Recursively derive a complete list of all HDL libraries that the specified HDL lib_name library depends on, so from this
+ HDL library down the entire hierachy.
+
+ The hdl_lib_uses_* key only needs to contain all libraries that are declared at the VHDL LIBRARY clauses of the
+ source files in this VHDL library. This derive_all_use_libs() will recursively find all deeper level VHDL libraries as well.
+
+ The arg_include_ip_libs selects the IP library to keep from 'hdl_lib_uses_ip'. The include_ip_libs is passed on
+ through the recursion hierarchy via arg_include_ip_libs to ensure that the from the top level library down all
+ multiple choice IP libraries in 'hdl_lib_uses_ip' that need to be included are indeed included. The multiple choice IP
+ libraries in 'hdl_lib_uses_ip' that are not in include_ip_libs are excluded.
+
+ Note:
+ . Only the generic HDL libraries and the technology specific libraries that match self.technologyNames are used,
+ because the other technology libraries have been removed from self.libs.dicts already at __init__() and from the
+ library dependency lists in get_used_libs()
+ . If Python breaks because recursion limit is reached, then two hdllib.cfg probably mutually use eachother which is
+ not allowed.
+ """
+ # use list() to take local copy, to avoid next that default empty list argument arg_include_ip_libs=[] gets disturbed
+ include_ip_libs = list(arg_include_ip_libs)
+ if lib_name in self.lib_names:
+ all_use_libs = [lib_name]
+ lib_dict = self.libs.configfiles[lib_name]
+ use_libs, include_ip_libs = self.get_used_libs(build_type, lib_dict, include_ip_libs)
+
+ for use_lib in use_libs:
+ if use_lib not in all_use_libs:
+ all_use_libs.append(use_lib)
+ # use recursion to include all used libs
+ all_use_libs += self.derive_all_use_libs(build_type, use_lib, include_ip_libs)
+ # remove all duplicates from the list
+ return cm.unique(all_use_libs)
+ else:
+ sys.exit('Error : Unknown HDL library name %s in %s()' % (lib_name, cm.method_name()))
+
+ def derive_lib_order(self, build_type, lib_name, lib_names=None):
+ """Derive the dependency order for all HDL libraries in lib_names that HDL library lib_name depends on.
+ """
+ if lib_names is None:
+ # At first entry derive the list of all HDL libraries that lib_name depends on
+ lib_names = self.derive_all_use_libs(build_type, lib_name)
+
+ # Derive the order of all HDL libraries that lib_name depends on, start with the order of lib_names
+ lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names)
+ # use list() to take local copy to avoid modifying list order of self.lib_names which matches self.libs.dicts list order
+ lib_order = list(lib_names)
+ for lib_dict in lib_dicts:
+ lib_name = lib_dict['hdl_lib_name']
+ use_libs, _ = self.get_used_libs('', lib_dict, [])
+ for use_lib in use_libs:
+ if use_lib in lib_names:
+ if lib_order.index(use_lib) > lib_order.index(lib_name):
+ lib_order.remove(use_lib)
+ lib_order.insert(lib_order.index(lib_name), use_lib) # move used lib to just before this lib
+ # use recursion to keep on reordering the lib_order until it is stable
+ if lib_names != lib_order:
+ lib_order = self.derive_lib_order(build_type, lib_name, lib_order)
+ return lib_order
+
+ def get_lib_dicts_from_lib_names(self, lib_names=None):
+ """Get list the HDL libraries lib_dicts from list of HDL libraries lib_names and preseve the library order.
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+
+ # Cannot use:
+ # lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names)
+ # because then the order of self.libs.dicts is used
+ lib_dicts = []
+ for lib_name in cm.listify(lib_names):
+ lib_dicts.append(self.libs.configfiles[lib_name])
+ return lib_dicts
+
+ def get_lib_names_from_lib_dicts(self, lib_dicts=None):
+ """Get list the HDL libraries lib_names from list of HDL libraries lib_dicts and preseve the library order.
+ """
+ lib_names = self.libs.get_key_values('hdl_lib_name', lib_dicts)
+ return lib_names
+
+ def get_tool_build_dir(self, build_type):
+ """Get the central tool build directory.
+
+ The build_type can be:
+ 'sim' uses the 'sim_tool_name' key in the self.buildset
+ 'synth' uses the 'synth_tool_name' key in the self.buildset
+ When another name is used that name is used directly as toolname in the construction of the path.
+
+ The function returns a tuple with the following four components:
+ - the absolute path to the central main build directory
+ - the buildset_name key value as subdirectory
+ - the toolname as subdirectory (derived from *_tool_name or the given value of 'build_type')
+ - project_deeper_subdir. See explanation below.
+
+ The project file will be located in the build dir or at some levels deeper in the build dir.
+ These optional extra subdirectory levels allow for relative file reference from project file
+ location. This is useful to be able to keep memory initialisation files in the library build
+ directory that are referred to using some fixed ../../ path in the HDL code.
+ - project_deeper_subdir = '' when project_dir_depth_ = 0 or not in buildset
+ - project_deeper_subdir = 'p/' when project_dir_depth_ = 1
+ - project_deeper_subdir = 'p/p/' when project_dir_depth_ = 2,
+ - project_deeper_subdir = 'p/p/p/' when project_dir_depth_ = 3, etc
+ """
+ # Determine build_maindir
+ build_maindir = expandvars('${RADIOHDL_BUILD_DIR}')
+ if not isabs(build_maindir):
+ sys.exit('Error : The build_dir value must be an absolute path')
+
+ # Determine build_buildset_dir
+ build_buildset_dir = self.buildset['buildset_name']
+
+ # Determine build_tooldir
+ tool_name_key = build_type + '_tool_name'
+ if tool_name_key in self.buildset:
+ build_tooldir = self.buildset[tool_name_key]
+ else:
+ build_tooldir = build_type
+
+ # Determine project_deeper_subdir
+ project_dir_depth_key = 'project_dir_depth_' + build_type
+ if project_dir_depth_key not in self.buildset:
+ project_deeper_subdir = ''
+ else:
+ project_deeper_subdir = 'p/' * int(self.buildset[project_dir_depth_key])
+
+ return build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir
+
+ def get_lib_build_dirs(self, build_type, lib_dicts=None):
+ """Get the subdirectories within the central tool build directory for all HDL libraries in the specified list of lib_dicts.
+
+ The build_type can be:
+ 'sim' uses the 'sim_tool_name' key in the self.buildset
+ 'synth' uses the 'synth_tool_name' key in the self.buildset
+
+ The build dir key value must be an absolute directory path. The lib build dir consists of
+ - the absolute path to the central main build directory
+ - the buildset_name key value as subdirectory
+ - the tool_name_key value as subdirectory
+ - the library name as library subdirectory
+ - zero or more extra subdirectory levels to allow for relative file reference from project file location
+ """
+ if lib_dicts is None:
+ lib_dicts = list(self.libs.configfiles.values())
+ build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type)
+ build_dirs = []
+ for lib_dict in cm.listify(lib_dicts):
+ lib_name = lib_dict['hdl_lib_name']
+ build_dirs.append(join(build_maindir, build_buildset_dir, build_tooldir, lib_name, project_deeper_subdir)) # central build main directory with subdirectory per library
+ return cm.unlistify(build_dirs)
+
+ def create_lib_order_files(self, build_type, lib_names=None):
+ """Create the compile order file '_lib_order.txt' for all HDL libraries in the specified list of lib_names.
+
+ The file is stored in the sim build directory of the HDL library.
+ The file is read by commands.do in Modelsim to avoid having to derive the library compile order in TCL.
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+
+ lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
+ for lib_dict in lib_dicts:
+ lib_name = lib_dict['hdl_lib_name']
+ lib_order = self.derive_lib_order(build_type, lib_name)
+ file_name = lib_name + '_lib_order.txt'
+ file_path = self.get_lib_build_dirs('sim', lib_dicts=lib_dict)
+ cm.mkdir(file_path)
+ filePathName = join(file_path, file_name)
+ with open(filePathName, 'w') as fp:
+ for lib in lib_order:
+ fp.write('%s ' % lib)
+ print("Created {} lib-order files".format(len(lib_dicts)))
+
+ # Methods to create sub directories at various levels in the build directory as defined in HDL tool config file
+ def create_sub_directory_in_build_main_dir(self, build_type, subdir_name):
+ """Create / in the central / directory
+ """
+ build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type)
+ subdir_path = join(build_maindir, subdir_name)
+ cm.mkdir(subdir_path)
+
+ def create_sub_directory_in_build_buildset_dir(self, build_type, subdir_name):
+ """Create / in the central // directory.
+ """
+ build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type)
+ subdir_path = join(build_maindir, build_buildset_dir, subdir_name)
+ cm.mkdir(subdir_path)
+
+ def create_sub_directory_in_build_tool_dir(self, build_type, subdir_name):
+ """Create / in the central /// directory.
+ """
+ build_maindir, build_buildset_dir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir(build_type)
+ subdir_path = join(build_maindir, build_buildset_dir, build_tooldir, subdir_name)
+ cm.mkdir(subdir_path)
+
+ def create_sub_directory_in_build_lib_dir(self, build_type, subdir_name, lib_names=None):
+ """Create / in project local build directory / for all HDL libraries in the specified list of lib_names.
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+ lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names)
+ for lib_dict in lib_dicts:
+ lib_path = self.get_lib_build_dirs('sim', lib_dicts=lib_dict)
+ subdir_path = join(lib_path, subdir_name)
+ cm.mkdir(subdir_path)
+ print("Created {} subdirectories".format(len(lib_dicts)))
+
+ def copy_files(self, build_type, lib_names=None):
+ """
+ Copy all source directories and source files listed at the _copy_files key.
+ The build_type selects the _copy_files key using the _tool_name key value
+ from the hdl_buildset_.cfg.
+ The _copy_files key expects a source and a destination pair per listed directory or file:
+ - The sources need to be specified with absolute path or relative to the HDL library source directory
+ where the hdllib.cfg is stored
+ - The destinations need to be specified with absolute path or relative to HDL library build directory
+ where the project file (e.g. mpf, qpf) gets stored
+
+ Arguments:
+ - lib_names : zero or more HDL libraries
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+
+ lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
+ tool_name_key = build_type + '_tool_name'
+ tool_name_value = self.buildset[tool_name_key]
+ tool_name_copy_key = tool_name_value + '_copy_files'
+ lib_count = 0
+ dir_count = 0
+ file_count = 0
+ for lib_dict in lib_dicts:
+ if tool_name_copy_key in lib_dict.content:
+ lib_count += 1
+ lib_path = lib_dict.location
+ build_dir_path = self.get_lib_build_dirs(build_type, lib_dicts=lib_dict)
+ cm.mkdir(build_dir_path)
+ key_values = lib_dict[tool_name_copy_key].split()
+ sources = key_values[0::2]
+ destinations = key_values[1::2]
+ file_io = list(zip(sources, destinations))
+ for fpn_io in file_io:
+ sourcePathName = cm.expand_file_path_name(fpn_io[0], lib_path)
+ destinationPath = cm.expand_file_path_name(fpn_io[1], build_dir_path)
+ # print("Copy '{}'' to '{}'".format(sourcePathName, destinationPath))
+ if isfile(sourcePathName):
+ file_count += 1
+ shutil.copy(sourcePathName, destinationPath) # copy file
+ else:
+ dir_count += 1
+ copy_tree(sourcePathName, destinationPath) # copy directory tree (will create new destinationPath directory)
+ print("Copied {} files and {} directories for {} libraries".format(file_count, dir_count, lib_count))
+
+
+if __name__ == '__main__':
+ # Parse command line arguments
+ buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(expandvars('$RADIOHDL_CONFIG'))
+ if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")])
+ argparser = ArgumentParser(description='Hdl_config shows several selections of all of your hdllib.cfg files.')
+ argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect))
+ argparser.add_argument('--toplib', default=None, required=False, help='top library to show more information about.')
+ args = argparser.parse_args()
+
+ # check arguments
+ if args.buildset not in buildsetSelect:
+ print('buildset %s is not supported' % args.buildset)
+ print("Supported buildset are:", buildsetSelect)
+ sys.exit(1)
+ args.buildsetFile = 'hdl_buildset_' + args.buildset + '.cfg'
+
+ # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories
+ hdl = HdlLibrariesWizard(toolRootDir=expandvars('${RADIOHDL_CONFIG}'),
+ toolFileName=args.buildsetFile,
+ libFileName='hdllib.cfg')
+
+ print('#')
+ print('# HdlLibrariesWizard:')
+ print('#')
+ for libname in list(hdl.libs.configfiles.keys()):
+ print("\n", libname)
+ libinfo = hdl.libs.configfiles[libname]
+ for k, v in libinfo.content.items():
+ print(k, '=', v)
+ print('')
+
+ print('')
+ print('Library paths :')
+ for libname in list(hdl.libs.configfiles.keys()):
+ print(' ', hdl.libs.configfiles[libname].location)
+
+ print('')
+ print('Library file names :"')
+ for libname in list(hdl.libs.configfiles.keys()):
+ print(' ', libname)
+
+ print('')
+ print('Library section headers :')
+ for libname, libinfo in hdl.libs.configfiles.items():
+ print(' %-52s : %s' % (libname, libinfo['section_headers']))
+
+ print('')
+ print('Build directories for simulation:')
+ for build_dir in hdl.get_lib_build_dirs('sim'):
+ print(' ', build_dir)
+
+ print('')
+ print('Build directories for synthesis:')
+ for build_dir in hdl.get_lib_build_dirs('synth'):
+ print(' ', build_dir)
+
+ print('')
+ print('Removed library names = \n', list(hdl.removed_libs.keys()))
+
+ print('')
+ print("Unavailable library names in any 'hdl_lib_uses_synth' key = \n", hdl.unavailable_use_synth_libs)
+ print("Unavailable library names in any 'hdl_lib_uses_ip' key = \n", hdl.unavailable_use_ip_libs)
+ print("Unavailable library names in any 'hdl_lib_uses_sim' key = \n", hdl.unavailable_use_sim_libs)
+ print("Unavailable library names in any 'hdl_lib_uses_*' key = \n", hdl.unavailable_use_libs)
+ print('')
+ print("Unavailable library names in any 'hdl_lib_include_ip' key = \n", hdl.unavailable_include_ip_libs)
+
+ print('')
+ print("Used library clause names that are explicitly disclosed at the 'hdl_lib_disclose_library_clause_names' keys:")
+ for key in list(hdl.disclosed_library_clause_names.keys()):
+ print(' %-52s : %s' % (key, hdl.disclosed_library_clause_names[key]))
+
+ if args.toplib:
+ for build_type in ['sim', 'synth']:
+ print('')
+ print('derive_all_use_libs for %s of %s = \n'
+ % (build_type, args.toplib), hdl.derive_all_use_libs(build_type, args.toplib))
+ print('')
+ print('derive_lib_order for %s of %s = \n'
+ % (build_type, args.toplib), hdl.derive_lib_order(build_type, args.toplib))
+
+
Index: radiohdl/trunk/core/hdl_raw_access.py
===================================================================
--- radiohdl/trunk/core/hdl_raw_access.py (nonexistent)
+++ radiohdl/trunk/core/hdl_raw_access.py (revision 4)
@@ -0,0 +1,201 @@
+###############################################################################
+#
+# Copyright (C) 2014-2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id$
+#
+###############################################################################
+
+import re
+import os.path
+from configfile import *
+from configtree import ConfigTree
+
+__all__ = ['RawConfigFile', 'RawConfigTree']
+
+"""
+File that implements the configfile <-> configtree concept but this time with the
+intention to modify the keys and/or values in those configfiles. So the content of
+the configfiels is kept as raw as possible.
+"""
+
+
+class RawConfigFile(object):
+ """
+ Class that holds the raw content of a configfile. To simplify the manipulation of the
+ content the file is internally stored as lines.
+ """
+ def __init__(self, filename):
+ """
+ Read the hdl configuration file and check presence of the required keys.
+ :raise ConfigFileException
+ """
+ full_filename = os.path.expanduser(os.path.expandvars(filename))
+ if not os.path.isfile(full_filename):
+ raise ConfigFileException("configfile '%s' not found" % full_filename)
+
+ self.filename = full_filename
+ self.content = open(self.filename, 'r').readlines()
+
+ @property
+ def ID(self):
+ "Returns uniq ID (string) to identify this particular file. Fullfilename is used."
+ return self.filename
+
+ def _save_content(self, verbose=False):
+ """
+ Write the content to the file.
+ """
+ with open(self.filename, 'w') as fp:
+ fp.writelines(self.content)
+
+ if verbose:
+ print(self.filename)
+
+ def change_value(self, key, new_value, verbose):
+ """
+ Change the value of the given key. The old value may be empty, be on one or multiple lines.
+ The new value may use \n characters to create a new multiline value.
+ """
+ # Search the key in the lines
+ prog = re.compile("^{}[ \t]*{}".format(key, CFG_ASSIGNMENT_CHAR))
+ for (linenr, line) in enumerate(self.content):
+ # search if line starts with this key
+ match = prog.search(line)
+ if not match:
+ continue
+
+ # replace the value that is on this line with the whole new value
+ value_start = match.end()
+ line = line[0:value_start] + ' ' + new_value.replace("\\n", "\n") + "\n"
+ self.content[linenr] = line
+
+ # to support removing old multiline values we have to skip lines until we find a
+ # sectionheader|other key|empty line or are at the end of the file
+ linenr += 1
+ while linenr < len(self.content):
+ if not re.match(r"(\[[a-zA-Z0-9_]+\]|[a-zA-Z0-9_]+[ \t]*{}|^[ \t]*$)".format(CFG_ASSIGNMENT_CHAR), self.content[linenr]):
+ self.content.pop(linenr)
+ else:
+ break
+
+ self._save_content(verbose)
+ break
+
+ def append_key_value(self, key, value, verbose):
+ """
+ Append the given key and value to the end of the configfile.
+ \n characters can be used both in the key and the value to start at a new line.
+ """
+ self.content.append("{} {} {}\n".format(key.replace("\\n", "\n"),
+ CFG_ASSIGNMENT_CHAR,
+ value.replace("\\n", "\n")))
+ self._save_content(verbose)
+
+ def rename_key(self, old_key, new_key, verbose):
+ """
+ Change the name of a key.
+ """
+ # Search the key in the lines
+ prog = re.compile("^{}[ \t]*{}".format(old_key, CFG_ASSIGNMENT_CHAR))
+ for (linenr, line) in enumerate(self.content):
+ # search if line starts with this old_key
+ match = prog.search(line)
+ if not match:
+ continue
+
+ # change the name of the key
+ value_start = match.end()
+ line = "{} {}{}\n".format(new_key.replace("\\n", "\n"), CFG_ASSIGNMENT_CHAR, line[value_start:])
+ self.content[linenr] = line
+ self._save_content(verbose)
+ break
+
+ def remove_key(self, key, verbose):
+ """
+ Remove a key and value pair from the dictfile.
+ """
+ # difficulty here is that we can delete the lines immediately because the enumeration over the
+ # file content gets messed up. So we setup the variables first_line and last_line that mark
+ # the part of the list that has to be removed. After the enumeration we cut the lines.
+
+ # First search the key in the lines
+ searching_key = True
+ last_line = len(self.content)
+ key_mask = re.compile(r"^{}[ \t]*{}".format(key, CFG_ASSIGNMENT_CHAR))
+ end_of_value_mask = re.compile(r"(\[[a-zA-Z0-9_]+\]|[a-zA-Z0-9_]+[ \t]*{})".format(CFG_ASSIGNMENT_CHAR))
+ for (linenr, line) in enumerate(self.content):
+ if searching_key:
+ # search if line starts with this key
+ match = key_mask.search(line)
+ if match:
+ first_line = linenr
+ searching_key = False
+ else:
+ # not searching for the key anymore, we now have to find the and of the value.
+ # to support removing old multiline values we have to skip lines until we find a
+ # sectionheader|other key or are at the end of the file
+ if not end_of_value_mask.match(self.content[linenr]):
+ continue
+ last_line = linenr
+ break
+
+ del self.content[first_line:last_line]
+ self._save_content(verbose)
+
+ def insert_key_at_linenr(self, new_key, new_value, linenumber, verbose):
+ """
+ Insert a new key = value pair in the configfile at linenumber. The first line has number 1.
+ """
+ if linenumber > len(self.content):
+ return self.append_key_value(new_key, new_value, verbose)
+
+ # Read dict file into string and insert new key = value pair at insertLineNr
+ new_line = "{} {} {}\n".format(new_key.replace("\\n", "\n"), CFG_ASSIGNMENT_CHAR, new_value)
+ self.content.insert(linenumber-1, new_line)
+ self._save_content(verbose)
+
+ def insert_key_value_before_key(self, new_key, new_value, before_key, verbose):
+ """
+ Insert a new key = value pair in the configfile just before another key..
+ """
+ # Search the key in the lines
+ prog = re.compile("^{}[ \t]*{}".format(before_key, CFG_ASSIGNMENT_CHAR))
+ for (linenr, line) in enumerate(self.content):
+ # search if line starts with this key
+ match = prog.search(line)
+ if not match:
+ continue
+
+ return self.insert_key_at_linenr(new_key, new_value, linenr+1, verbose)
+
+
+class RawConfigTree(ConfigTree):
+ """
+ Class the represents the collection of 'raw content' configfiles.
+ """
+ def __init__(self, rootdirs, filename, sections=None):
+ """
+ Read the raw configuration files and stores them in this tree.
+ :raise ConfigFileException
+ """
+ super(RawConfigTree, self).__init__(rootdirs, filename, sections)
+
+ def _factory_constructor(self, full_filename):
+ "Function for returning the readin configfile."
+ return RawConfigFile(full_filename)
Index: radiohdl/trunk/core/modelsim_config
===================================================================
--- radiohdl/trunk/core/modelsim_config (nonexistent)
+++ radiohdl/trunk/core/modelsim_config (revision 4)
@@ -0,0 +1,472 @@
+#! /usr/bin/env python3
+###############################################################################
+#
+# Copyright (C) 2014
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+###############################################################################
+
+"""HDL configuration for building Modelsim simulation targets.
+
+ Usage:
+ > python ${RADIOHDL_GEAR}/oneclick/base/modelsim_config.py -t unb1
+"""
+
+import sys
+import os.path
+from os import listdir
+from argparse import ArgumentParser
+import common_radiohdl as cm
+import hdl_libraries_wizard
+from configfile import ConfigFile
+
+
+class ModelsimConfig(hdl_libraries_wizard.HdlLibrariesWizard):
+
+ def __init__(self, toolRootDir, buildsetFile, libFileName):
+ """Get Modelsim tool info from toolRootDir and all HDL library info from libRootDir.
+
+ This class uses the default keys and the keys from the libFileSections in the libFileName config file.
+
+ Arguments:
+ - toolRootDir : Root directory from where the hdl_buildset_.cfg file is searched for.
+ - buildsetFile : Default HDL tools configuration file name
+ - libFileName : Default HDL library configuration file name
+
+ The libRootDir is defined in the hdl_buildset_.cfg file and is the root directory from where the hdllib.cfg
+ files are searched for.
+
+ Files:
+ - hdl_buildset_.cfg : HDL tool configuration dictionary file. One central file per buildset.
+
+ - hdllib.cfg : HDL library configuration dictionary file. One file for each HDL library.
+
+ - modelsim_project_files.txt
+ The modelsim_project_files.txt file is a dictionary file with the list the Modelsim project files for all HDL
+ libraries that were found in the libRootDir. The keys are the library names and the values are the paths to the
+ corresponding modelsim project files. The modelsim_project_files.txt file is created by
+ create_modelsim_project_files_file() and is read by the TCL commands.do file in Modelsim. Creating the file in
+ Python and then reading this in TCL makes the commands.do much simpler.
+
+ - .mpf : Modelsim project file for a certain HDL library based on the hdllib.cfg. The file is created by
+ create_modelsim_project_file().
+
+ - _lib_order.txt
+ The _lib_order.txt file contains the library compile order for a certain HDL library. The files are
+ created by create_lib_order_files() in the same build directory as where the Modelsim project file is stored.
+ The _lib_order.txt files are read by the TCL commands.do file in Modelsim. Creating the files in Python
+ and then reading them in TCL makes the commands.do much simpler.
+ """
+ libFileSections = ['modelsim_project_file']
+ hdl_libraries_wizard.HdlLibrariesWizard.__init__(self, toolRootDir, buildsetFile, libFileName, libFileSections)
+
+ def read_compile_order_from_mpf(self, mpfPathName):
+ """Utility to read the compile order of the project files from an existing .mpf."""
+ # read .mpf to find all project files
+ project_file_indices = []
+ project_file_names = []
+ with open(mpfPathName, 'r') as fp:
+ for line in fp:
+ words = line.split()
+ if words:
+ key = words[0]
+ if key.find('Project_File_') >= 0 and key.find('Project_File_P_') == -1:
+ project_file_indices.append(key[len('Project_File_'):])
+ project_file_names.append(words[2])
+ # read .mpf again to find compile order for the project files
+ compile_order = list(range(len(project_file_names)))
+ with open(mpfPathName, 'r') as fp:
+ for line in fp:
+ words = line.split()
+ if words:
+ key = words[0]
+ if key.find('Project_File_P_') >= 0:
+ project_file_index = project_file_indices.index(key[len('Project_File_P_'):])
+ project_file_name = project_file_names[project_file_index]
+ k = words.index('compile_order')
+ k = int(words[k + 1])
+ compile_order[k] = project_file_name
+ return compile_order
+
+ def read_hdl_libraries_technology_file(self, technologyName, filePath=None):
+ """Read the list of technology HDL libraries from a file.
+
+ Arguments:
+ - technologyName : refers to the hdl_libraries_.txt file
+ - filePath : path to hdl_libraries_.txt, when None then the file is
+ read in the default toolRootDir
+ """
+ fileName = 'hdl_libraries_ip_' + technologyName + '.txt' # use fixed file name format
+ if filePath is None:
+ toolDir = os.path.expandvars('$RADIOHDL_BUILD_DIR')
+ toolSubDir = self.buildset['buildset_name']
+ fileNamePath = os.path.join(toolDir, toolSubDir, fileName) # default file path
+ else:
+ fileNamePath = os.path.join(filePath, fileName) # specified file path
+ tech_dict = ConfigFile(fileNamePath).content
+ return tech_dict
+
+ def create_modelsim_lib_compile_ip_files(self, lib_names=None):
+ """
+ Create the '_lib_compile_ip.txt' file for all HDL libraries in the specified list of lib_names.
+ The file is stored in the sim build directory of the HDL library.
+ The file is read by commands.do in Modelsim to know which IP needs to be compiled before the library is compiled.
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+
+ count = 0
+ lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
+ for lib_dict in lib_dicts:
+ if 'modelsim_compile_ip_files' in lib_dict.content:
+ count += 1
+ compile_ip_files = lib_dict['modelsim_compile_ip_files'].split()
+ lib_name = lib_dict['hdl_lib_name']
+ file_name = lib_name + '_lib_compile_ip.txt'
+ file_path = self.get_lib_build_dirs('sim', lib_dicts=lib_dict)
+ cm.mkdir(file_path)
+ filePathName = os.path.join(file_path, file_name)
+ with open(filePathName, 'w') as fp:
+ for fpn in compile_ip_files:
+ # Write the expanded file path name for _lib_compile_ip.txt so that it can be executed directly from its location in SVN using the Modelsim "do"-command in the commands.do.
+ # An alternative would be to write the basename, so only _lib_compile_ip.txt, but that would require copying the basename file to the mpf build directory
+ efpn = os.path.expandvars(fpn)
+ fp.write('%s ' % efpn)
+ print("Created {} compile-ip files".format(count))
+
+ def simulation_configuration(self, list_mode=False):
+ """Prepare settings for simulation configuration.
+ The output format is string or list, dependent on list_mode.
+ Return tuple of project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization.
+ """
+ # project_sim_p_defaults
+ project_sim_p_defaults = 'Generics {} timing default -std_output {} -nopsl 0 +notimingchecks 0 selected_du {} -hazards 0 -sdf {} ok 1 -0in 0 -nosva 0 +pulse_r {} -absentisempty 0 -multisource_delay {} +pulse_e {} vopt_env 1 -coverage 0 -sdfnoerror 0 +plusarg {} -vital2.2b 0 -t default -memprof 0 is_vopt_flow 0 -noglitch 0 -nofileshare 0 -wlf {} -assertdebug 0 +no_pulse_msg 0 -0in_options {} -assertfile {} -sdfnowarn 0 -Lf {} -std_input {}'
+
+ # project_sim_p_search_libraries
+ if list_mode:
+ project_sim_p_search_libraries = self.buildset['modelsim_search_libraries'].split()
+ else:
+ project_sim_p_search_libraries = '-L {}'
+ if 'modelsim_search_libraries' in self.buildset:
+ project_sim_p_search_libraries = '-L {'
+ for sl in self.buildset['modelsim_search_libraries'].split():
+ project_sim_p_search_libraries += sl
+ project_sim_p_search_libraries += ' '
+ project_sim_p_search_libraries += '}'
+
+ # project_sim_p_otherargs
+ # Note:
+ # E.g. the vsim-8684 load warning does not occur when the simulation is loaded via double click, but it
+ # does occur when the simulation is relaoded via the command line, because in the command line history
+ # the +nowarn8684 is then for some reason not preserved by Modelsim.
+ otherargs = ''
+ otherargs = '+nowarn8684 +nowarn8683 -quiet'
+ otherargs = '+nowarn8684 +nowarn8683'
+ otherargs = '+nowarn8684 +nowarn8683 +nowarnTFMPC +nowarnPCDPC' # nowarn on verilog IP connection mismatch warnings
+ if list_mode:
+ project_sim_p_otherargs = otherargs.split()
+ else:
+ project_sim_p_otherargs = 'OtherArgs {' + otherargs + '}'
+
+ # project_sim_p_optimization
+ project_sim_p_optimization = 'is_vopt_opt_used 2' # = when 'Enable optimization' is not selected in GUI
+ project_sim_p_optimization = 'is_vopt_opt_used 1 voptargs {OtherVoptArgs {} timing default VoptOutFile {} -vopt_keep_delta 0 -0in 0 -fvopt {} VoptOptimize:method 1 -vopt_00 2 +vopt_notimingcheck 0 -Lfvopt {} VoptOptimize:list .vopt_opt.nb.canvas.notebook.cs.page1.cs.g.spec.listbox -Lvopt {} +vopt_acc {} VoptOptimize .vopt_opt.nb.canvas.notebook.cs.page1.cs -vopt_hazards 0 VoptOptimize:Buttons .vopt_opt.nb.canvas.notebook.cs.page1.cs.g.spec.bf 0InOptionsWgt .vopt_opt.nb.canvas.notebook.cs.page3.cs.zf.ze -0in_options {}}' # = when 'Enable optimization' is selected in GUI for full visibility
+
+ return project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization
+
+ def create_modelsim_project_file(self, lib_names=None):
+ """
+ Create the Modelsim project file for all technology libraries and RTL HDL libraries.
+
+ Arguments:
+ - lib_names : one or more HDL libraries
+
+ Library mapping:
+ - Technology libraries that are available, but not used are mapped to work.
+ - Unavailable libraries are also mapped to work. The default library clause name is
+ with postfix '_lib'. This is a best effort guess, because it is impossible to know the library clause name
+ for an unavailable library. If the best effort guess is not suitable, then the workaround is to create a
+ place holder directory with hdllib.cfg that defines the actual library clause name as it appears in the
+ VHDL for the unavailable HDL library. unavailable library names occur when e.g. a technology IP library
+ is not available in the toolRootDir because it is not needed, or it may indicate a spelling error.
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+
+ lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
+ print("SELF.BUILDSET=", self.buildset)
+ for lib_dict in lib_dicts:
+ # Open mpf
+ lib_name = lib_dict['hdl_lib_name']
+ mpf_name = lib_name + '.mpf'
+ mpf_path = self.get_lib_build_dirs('sim', lib_dicts=lib_dict)
+ cm.mkdir(mpf_path)
+ mpfPathName = os.path.join(mpf_path, mpf_name)
+ with open(mpfPathName, 'w') as fp:
+ # Write [Library] section for all used libraries
+ fp.write('[Library]\n')
+
+ # . map used vendor technology libs to their target directory
+ # for technologyName in self.technologyNames:
+ # tech_dict = self.read_hdl_libraries_technology_file(technologyName)
+ # for lib_clause, lib_work in tech_dict.items():
+ # fp.write('%s = %s\n' % (lib_clause, lib_work))
+
+ for familyName in self.familyNames:
+ tech_dict = self.read_hdl_libraries_technology_file(familyName)
+ for lib_clause, lib_work in tech_dict.items():
+ fp.write('%s = %s\n' % (lib_clause, lib_work))
+
+ # . not used vendor technology libs are not compiled but are mapped to work to avoid compile error when mentioned in the LIBRARY clause
+ for removed_lib in sorted(self.removed_libs):
+ fp.write('%s = work\n' % self.removed_libs[removed_lib]['hdl_library_clause_name'])
+
+ # . unavailable used libs are not compiled but are mapped to work to avoid compile error when mentioned in the LIBRARY clause
+ for unavailable_use_name in sorted(self.unavailable_use_libs):
+ # if the unavailable library is not in the dictionary of disclosed unavailable library clause names, then assume that the library clause
+ # name has the default postfix '_lib'.
+ if unavailable_use_name in self.disclosed_library_clause_names:
+ fp.write('%s = work\n' % self.disclosed_library_clause_names[unavailable_use_name])
+ else:
+ fp.write('%s_lib = work\n' % unavailable_use_name)
+
+ # . all used libs for this lib_name
+ use_lib_names = self.derive_all_use_libs('sim', lib_name)
+ use_lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=use_lib_names)
+ use_lib_build_sim_dirs = self.get_lib_build_dirs('sim', lib_dicts=use_lib_dicts)
+ use_lib_clause_names = self.libs.get_key_values('hdl_library_clause_name', use_lib_dicts)
+ for lib_clause, lib_dir in zip(use_lib_clause_names, cm.listify(use_lib_build_sim_dirs)):
+ lib_work = os.path.join(lib_dir, 'work')
+ fp.write('%s = %s\n' % (lib_clause, lib_work))
+
+ # . work
+ fp.write('work = work\n')
+
+ # . others modelsim default libs
+ model_tech_dir = os.path.expandvars(self.buildset['modelsim_dir'])
+ fp.write('others = %s\n' % os.path.join(model_tech_dir, 'modelsim.ini'))
+
+ # Write [Project] section for all used libraries
+ fp.write('[Project]\n')
+ fp.write('Project_Version = 6\n') # must be >= 6 to fit all
+ fp.write('Project_DefaultLib = work\n')
+ fp.write('Project_SortMethod = unused\n')
+
+ # - project files
+ synth_files = lib_dict['synth_files'].split()
+ test_bench_files = lib_dict['test_bench_files'].split()
+ project_files = synth_files + test_bench_files
+ if 'modelsim_compile_ip_files' in lib_dict.content:
+ compile_ip_files = lib_dict['modelsim_compile_ip_files'].split()
+ project_files += compile_ip_files
+ fp.write('Project_Files_Count = %d\n' % len(project_files))
+ for i, fn in enumerate(project_files):
+ filePathName = cm.expand_file_path_name(fn, lib_dict.location)
+ fp.write('Project_File_%d = %s\n' % (i, filePathName))
+
+ project_file_p_defaults_hdl = 'vhdl_novitalcheck 0 group_id 0 cover_nofec 0 vhdl_nodebug 0 vhdl_1164 1 vhdl_noload 0 vhdl_synth 0 vhdl_enable0In 0 vlog_1995compat 0 last_compile 0 vhdl_disableopt 0 cover_excludedefault 0 vhdl_vital 0 vhdl_warn1 1 vhdl_warn2 1 vhdl_explicit 1 vhdl_showsource 0 cover_covercells 0 vhdl_0InOptions {} vhdl_warn3 1 vlog_vopt {} cover_optlevel 3 voptflow 1 vhdl_options {} vhdl_warn4 1 toggle - ood 0 vhdl_warn5 1 cover_noshort 0 compile_to work cover_nosub 0 dont_compile 0 vhdl_use93 2002 cover_stmt 1'
+ project_file_p_defaults_vhdl = 'file_type vhdl'
+ project_file_p_defaults_verilog = 'file_type verilog'
+ project_file_p_defaults_tcl = 'last_compile 0 compile_order -1 file_type tcl group_id 0 dont_compile 1 ood 1'
+
+ project_folders = []
+ offset = 0
+
+ nof_synth_files = len(synth_files)
+ if nof_synth_files > 0:
+ project_folders.append('synth_files')
+ for i in range(nof_synth_files):
+
+ # Add file type specific settings
+ file_ext = synth_files[i].split('.')[-1]
+ if file_ext == 'vhd' or file_ext == 'vhdl':
+ project_file_p_defaults_file_specific = project_file_p_defaults_vhdl
+ elif file_ext == 'v':
+ project_file_p_defaults_file_specific = project_file_p_defaults_verilog
+ else:
+ print('\nERROR - Undefined file extension in synth_files:', lib_name, synth_files[i])
+ sys.exit()
+
+ fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % (
+ offset+i, project_folders[-1], offset+i, project_file_p_defaults_hdl+' '+project_file_p_defaults_file_specific))
+ offset = nof_synth_files
+
+ nof_test_bench_files = len(test_bench_files)
+ if nof_test_bench_files > 0:
+ project_folders.append('test_bench_files')
+ for i in range(nof_test_bench_files):
+
+ # Add file type specific settings
+ file_ext = test_bench_files[i].split('.')[-1]
+ if file_ext == 'vhd' or file_ext == 'vho' or file_ext == 'vhdl':
+ project_file_p_defaults_file_specific = project_file_p_defaults_vhdl
+ elif file_ext == 'v':
+ project_file_p_defaults_file_specific = project_file_p_defaults_verilog
+ else:
+ print('\nERROR - Undefined file extension in test_bench_files:', lib_name, test_bench_files[i])
+ sys.exit()
+
+ fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % (
+ offset+i, project_folders[-1], offset+i, project_file_p_defaults_hdl+' '+project_file_p_defaults_file_specific))
+ offset += nof_test_bench_files
+
+ if 'modelsim_compile_ip_files' in lib_dict.content:
+ nof_compile_ip_files = len(compile_ip_files)
+ if nof_compile_ip_files > 0:
+ project_folders.append('compile_ip_files')
+ for i in range(nof_compile_ip_files):
+ fp.write('Project_File_P_%d = folder %s compile_order %d %s\n' % (
+ offset + i, project_folders[-1], offset + i, project_file_p_defaults_tcl))
+ offset += nof_compile_ip_files
+
+ # - project folders
+ fp.write('Project_Folder_Count = %d\n' % len(project_folders))
+ for i, fd in enumerate(project_folders):
+ fp.write('Project_Folder_%d = %s\n' % (i, fd))
+ fp.write('Project_Folder_P_%d = folder {Top Level}\n' % i)
+
+ # - simulation configurations
+ fp.write('Project_Sim_Count = %d\n' % len(test_bench_files))
+ project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization = self.simulation_configuration()
+ for i, fn in enumerate(test_bench_files):
+ fName = os.path.basename(fn)
+ tbName = os.path.splitext(fName)[0]
+ fp.write('Project_Sim_%d = %s\n' % (i, tbName))
+ for i, fn in enumerate(test_bench_files):
+ fName = os.path.basename(fn)
+ tbName = os.path.splitext(fName)[0]
+ fp.write('Project_Sim_P_%d = folder {Top Level} additional_dus work.%s %s %s %s %s\n' % (
+ i, tbName, project_sim_p_defaults, project_sim_p_search_libraries, project_sim_p_otherargs, project_sim_p_optimization))
+
+ # Write [vsim] section
+ fp.write('[vsim]\n')
+ fp.write('RunLength = 0 ps\n')
+ fp.write('resolution = 1fs\n')
+ fp.write('IterationLimit = 5000\n') # According to 'verror 3601' the default is 5000, typically 100 is enough, but e.g. the ip_stratixiv_phy_xaui_0 requires more.
+ fp.write('DefaultRadix = decimal\n')
+ print("Created {} project files".format(len(lib_dicts)))
+
+ def create_modelsim_project_files_file(self, lib_names=None):
+ """Create file with list of the Modelsim project files for all HDL libraries.
+
+ Arguments:
+ - lib_names : one or more HDL libraries
+ """
+ fileName = 'modelsim_project_files.txt' # use fixed file name
+ build_maindir, build_buildsetdir, build_tooldir, project_deeper_subdir = self.get_tool_build_dir('sim')
+ fileNamePath = os.path.join(build_maindir, build_buildsetdir, build_tooldir, fileName) # and use too build dir for file path
+ if lib_names is None:
+ lib_names = self.lib_names
+ with open(fileNamePath, 'w') as fp:
+ lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
+ mpf_paths = self.get_lib_build_dirs('sim', lib_dicts=lib_dicts)
+ for lib_name, mpf_path in zip(cm.listify(lib_names), cm.listify(mpf_paths)):
+ fp.write('%s = %s\n' % (lib_name, mpf_path))
+ print("Created project file {}".format(fileNamePath))
+
+
+if __name__ == '__main__':
+ # Mode
+ # 0 = Create Modelsim mpf files for all hdllib.cfg
+ # 1 = Read compile order from mpf for a single and write itinto the hdllib.cfg.
+ # This is useful to avoid having to manually edit the compile order for an existing $UNB .mpf into the hdllib.cfg.
+ # The compile order is important for the synth_files that need to be in hierarchical order. The test_bench_files are typically
+ # independent so these may be put in alphabetical order. The compile order is read from the .mpf and saved in the
+ # hdllib.cfg. The hdllib.cfg still does need some manual editing to set the proper key and paths.
+ mode = 0
+
+ buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(os.path.expandvars('$RADIOHDL_CONFIG'))
+ if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")])
+ # Parse command line arguments
+ argparser = ArgumentParser(description='Modelsim creates/updates all your modelsim environment(s).')
+ argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect))
+ argparser.add_argument('-v', '--verbosity', required=False, type=int, default=0, help='verbosity >= 0 for more info')
+ args = argparser.parse_args()
+
+ # check arguments
+ if args.buildset not in buildsetSelect:
+ print('buildset %s is not supported' % args.buildset)
+ print("Supported buildset are:", buildsetSelect)
+ sys.exit(1)
+ args.buildsetFile = 'hdl_buildset_' + args.buildset + '.cfg'
+
+ # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories
+ msim = ModelsimConfig(toolRootDir=os.path.expandvars('$RADIOHDL_CONFIG'),
+ buildsetFile=args.buildsetFile,
+ libFileName='hdllib.cfg')
+
+ if mode == 0:
+ # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories
+ if args.verbosity >= 2:
+ print('#')
+ print('# ModelsimConfig:')
+ print('#')
+ print('')
+ print('HDL library paths that are found in %s:' % msim.libRootDirs)
+ for lib in sorted(msim.libs.configfiles.values()):
+ print(' ', lib.location)
+
+ if args.verbosity >= 2:
+ print('')
+ print('Build directories for simulation:')
+ for sim_dir in msim.get_lib_build_dirs('sim'):
+ print(' ', sim_dir)
+
+ print('')
+ print('Create library compile order files for simulation...')
+ msim.create_lib_order_files('sim')
+ # sys.exit(0)
+
+ print('')
+ print('Create library compile ip files...')
+ msim.create_modelsim_lib_compile_ip_files()
+
+ print('')
+ print('Create modelsim projects list file...')
+ msim.create_modelsim_project_files_file()
+
+ print('')
+ print('Create sub directory in project dir for all HDL libraries that are found in %s...' % msim.libRootDirs)
+ msim.create_sub_directory_in_build_lib_dir('sim', 'mmfiles') # should match c_mmf_local_dir_path in mm_file_pkg.vhd
+
+ print('')
+ print('Copy directories and files from HDL library source tree to project dir for all HDL libraries that are found in %s...' % msim.libRootDirs)
+ msim.copy_files('sim')
+
+ print('')
+ print('Create Modelsim Project Files for technology %s and all HDL libraries in %s...' % (msim.technologyNames, msim.libRootDirs))
+ msim.create_modelsim_project_file()
+ # sys.exit(0)
+
+ if mode == 1:
+ # for lib_name in ['ado','ap','bf','bist','blp','bp','cdo','cim','cir','cp','cr','dc','eth','fmf','i2c','lvds','pfs','pft2','rcuh','ri','rsp','rsr','rsu','sens','serdes','si','st','tbbi','tdsh']:
+ for lib_name in ['tst']:
+ # Read compile order from existing .mpf
+ # First manually create rudimentary hdllib.cfg file for the library with lib name and clause filled in. Then run this script to get
+ # the ordered list of src and tb files. Then manualy edit the hdllib.cfg to put the files at the synth or sim key.
+ # mpfPathName = os.path.expandvars('$UNB/Firmware/designs/%s/build/synth/quartus/sopc_%s_sim/%s.mpf' % (lib_name, lib_name, lib_name))
+ # mpfPathName = os.path.expandvars('$UNB/Firmware/modules/Lofar/%s/build/sim/modelsim/%s.mpf' % (lib_name, lib_name))
+ # mpfPathName = os.path.expandvars('$UNB/Firmware/modules/%s/build/sim/modelsim/%s.mpf' % (lib_name, lib_name))
+ mpfPathName = os.path.expandvars('$RSP/%s/build/sim/modelsim/%s.mpf' % (lib_name, lib_name))
+ compile_order = msim.read_compile_order_from_mpf(mpfPathName)
+ # Append the compile_order list to the lib_name dictionary hdllib.cfg file
+ lib_dict = msim.libs.get_configfiles(key='hdl_lib_name', values=lib_name)
+ lib_path = msim.libs.get_filePath(lib_dict)
+ filePathName = os.path.join(lib_path, 'hdllib.cfg')
+ print('')
+ print('Save modelsim compile order for', lib_name, 'in HDL library config file', filePathName)
+ msim.libs.append_key_to_dict_file(filePathName, 'files', compile_order)
radiohdl/trunk/core/modelsim_config
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/core/modify_configfiles
===================================================================
--- radiohdl/trunk/core/modify_configfiles (nonexistent)
+++ radiohdl/trunk/core/modify_configfiles (revision 4)
@@ -0,0 +1,168 @@
+#!/usr/bin/env python3
+###############################################################################
+#
+# Copyright (C) 2014-2018
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# $Id: configfile_modifier.py 18609 2018-07-18 08:06:30Z overeem $
+#
+###############################################################################
+
+"""
+Interactive program to modify all configfiles found in the hierarchical directory
+structure under the given top directory.
+"""
+
+from argparse import ArgumentParser
+from hdl_raw_access import RawConfigTree
+
+# Define a simple menu system that is based on a dict that contains the menu actions:
+# the keys are the valid strings the user may enter
+# the values are lists: the first element is the menu tekst, the second the function to call and
+# the remaining elememts (if any) are the arguments to ask the user
+# All arguments are stored in a kwargs structure and passed to the functions that is called.
+
+
+def get_menu_choice(menu, title):
+ """
+ Iterate over the menu dict, show the menu choices and ask for input till valid input is received.
+ """
+ print("\n", title)
+ print("-" * len(title))
+ input_ok = False
+ while not input_ok:
+ for key in sorted(menu.keys()):
+ print("{} {}".format(key, menu[key][0]))
+ choice = input("\n >>: ")
+ if choice not in list(menu.keys()):
+ print("ERROR: This input is not a valid menu choice. Try again.")
+ else:
+ input_ok = True
+ return menu[choice]
+
+
+def execute_menu_line(line_spec, verbose):
+ """
+ Given a menu line specification it asks the user for the specified arguments, stores the values in a
+ kwargs structure and finally call the specified function with this kwargs.
+ """
+ print("\n--- {} ---".format(line_spec[0]))
+ nr_args = len(line_spec) - 2
+ if nr_args < 0:
+ raise SyntaxError("Invalid formatted menuline definition: {}.\nNeed at least two items in the list".format(line_spec))
+ if nr_args == 0:
+ return line_spec[1]()
+ # Iterate over the remaining items and get values for them
+ kwargs = {"verbose": verbose}
+ for spec_idx in range(2, len(line_spec)):
+ answer = input(line_spec[spec_idx].capitalize().replace("_", " ") + ": ")
+ kwargs[line_spec[spec_idx]] = answer
+ line_spec[1](**kwargs)
+
+
+# ## Implementation of the menu commands
+# Note: cleaner would to implement this with the Strategy pattern but we want to keep the code
+# to be readable for everyone. ;-)
+def change_value_of_key(**kwargs):
+ key = kwargs.pop("key")
+ new_value = kwargs.pop("new_value")
+ verbose = kwargs.pop("verbose")
+ global tree
+ for filename in sorted(tree.configfiles.keys()):
+ tree.configfiles[filename].change_value(key, new_value, verbose)
+
+
+def append_key_value(**kwargs):
+ key = kwargs.pop("new_key")
+ new_value = kwargs.pop("new_value")
+ verbose = kwargs.pop("verbose")
+ global tree
+ for filename in sorted(tree.configfiles.keys()):
+ tree.configfiles[filename].append_key_value(key, new_value, verbose)
+
+
+def insert_key_at_linenr(**kwargs):
+ new_key = kwargs.pop("new_key")
+ new_value = kwargs.pop("new_value")
+ linenumber = int(kwargs.pop("linenumber"))
+ verbose = kwargs.pop("verbose")
+ global tree
+ for filename in sorted(tree.configfiles.keys()):
+ tree.configfiles[filename].insert_key_at_linenr(new_key, new_value, linenumber, verbose)
+
+
+def insert_key_value_before_key(**kwargs):
+ new_key = kwargs.pop("new_key")
+ new_value = kwargs.pop("new_value")
+ before_key = kwargs.pop("before_key")
+ verbose = kwargs.pop("verbose")
+ global tree
+ for filename in sorted(tree.configfiles.keys()):
+ tree.configfiles[filename].insert_key_value_before_key(new_key, new_value, before_key, verbose)
+
+
+def rename_key(**kwargs):
+ old_key = kwargs.pop("old_key")
+ new_key = kwargs.pop("new_key")
+ verbose = kwargs.pop("verbose")
+ global tree
+ for filename in sorted(tree.configfiles.keys()):
+ tree.configfiles[filename].rename_key(old_key, new_key, verbose)
+
+
+def remove_key(**kwargs):
+ key = kwargs.pop("key")
+ verbose = kwargs.pop("verbose")
+ global tree
+ for filename in sorted(tree.configfiles.keys()):
+ tree.configfiles[filename].remove_key(key, verbose)
+
+
+def end_menu():
+ global running
+ running = False
+
+
+if __name__ == '__main__':
+ # setup parser and parse the arguments.
+ argparser = ArgumentParser(description='Options and arguments for modifying collections of configfiles.')
+ argparser.add_argument('filename', help="Filename like 'hdl_buildset_.cfg'")
+ argparser.add_argument('rootdir', help="Top directory to start the search for configfiles.")
+ argparser.add_argument('-v', '--verbose', help="Show more information on what happens.", action="store_true")
+ args = argparser.parse_args()
+
+ tree = RawConfigTree(args.rootdir, args.filename)
+ print("Found {} configfiles in {}".format(len(tree.configfiles), args.rootdir))
+ if args.verbose:
+ for filename in sorted(tree.configfiles.keys()):
+ print(filename)
+
+ # define the menu including actions
+ # choice choice description function to call arguments to ask for
+ menu = {'1': ["Change value", change_value_of_key, "key", "new_value"],
+ '2': ["Append key", append_key_value, "new_key", "new_value"],
+ '3': ["Insert key at linenr", insert_key_at_linenr, "new_key", "new_value", "linenumber"],
+ '4': ["Insert key before other key", insert_key_value_before_key, "new_key", "new_value", "before_key"],
+ '5': ["Rename key", rename_key, "old_key", "new_key"],
+ '6': ["Remove key", remove_key, "key"],
+ 'q': ["Exit", end_menu]
+ }
+
+ running = True
+ while running:
+ execute_menu_line(get_menu_choice(menu, "Menu for changing multiple configfiles"), args.verbose)
+
radiohdl/trunk/core/modify_configfiles
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/core/qsys_input.qsys
===================================================================
--- radiohdl/trunk/core/qsys_input.qsys (nonexistent)
+++ radiohdl/trunk/core/qsys_input.qsys (revision 4)
@@ -0,0 +1,669 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ qsys_input_onchip_memory2_0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ INTERACTIVE_ASCII_OUTPUT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SIMPLE_PERIODIC_INTERRUPT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ cpu_0.jtag_debug_module
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ]]>
+ ]]>
+
+
+
+
+ ADDRESS_STALL 1 CELL_LEVEL_BACK_ANNOTATION_DISABLED 0 COMPILER_SUPPORT 1 DSP 1 DSP_SHIFTER_BLOCK 1 DUMP_ASM_LAB_BITS_FOR_POWER 1 EMUL 0 ENABLE_ADVANCED_IO_ANALYSIS_GUI_FEATURES 1 EPCS 1 ESB 0 FAKE1 0 FAKE2 0 FAKE3 0 FITTER_USE_FALLING_EDGE_DELAY 1 GENERATE_DC_ON_CURRENT_WARNING_FOR_INTERNAL_CLAMPING_DIODE 1 HARDCOPY 0 HAS_18_BIT_MULTS 1 HAS_ACE_SUPPORT 1 HAS_ADJUSTABLE_OUTPUT_IO_TIMING_MEAS_POINT 1 HAS_ADVANCED_IO_INVERTED_CORNER 1 HAS_ADVANCED_IO_POWER_SUPPORT 1 HAS_ADVANCED_IO_TIMING_SUPPORT 1 HAS_ALM_SUPPORT 1 HAS_ATOM_AND_ROUTING_POWER_MODELED_TOGETHER 0 HAS_AUTO_DERIVE_CLOCK_UNCERTAINTY_SUPPORT 1 HAS_AUTO_FIT_SUPPORT 1 HAS_BALANCED_OPT_TECHNIQUE_SUPPORT 1 HAS_BENEFICIAL_SKEW_SUPPORT 1 HAS_BITLEVEL_DRIVE_STRENGTH_CONTROL 1 HAS_BSDL_FILE_GENERATION 1 HAS_CGA_SUPPORT 1 HAS_CHECK_NETLIST_SUPPORT 1 HAS_CLOCK_REGION_CHECKER_ENABLED 1 HAS_CORE_JUNCTION_TEMP_DERATING 0 HAS_CROSSTALK_SUPPORT 0 HAS_CUSTOM_REGION_SUPPORT 1 HAS_DATA_DRIVEN_ACVQ_HSSI_SUPPORT 0 HAS_DDB_FDI_SUPPORT 0 HAS_DESIGN_ANALYZER_SUPPORT 1 HAS_DETAILED_IO_RAIL_POWER_MODEL 1 HAS_DETAILED_LEIM_STATIC_POWER_MODEL 0 HAS_DETAILED_LE_POWER_MODEL 1 HAS_DETAILED_ROUTING_MUX_STATIC_POWER_MODEL 0 HAS_DETAILED_THERMAL_CIRCUIT_PARAMETER_SUPPORT 1 HAS_DEVICE_MIGRATION_SUPPORT 1 HAS_DIAGONAL_MIGRATION_SUPPORT 0 HAS_EMIF_TOOLKIT_SUPPORT 1 HAS_FAMILY_VARIANT_MIGRATION_SUPPORT 0 HAS_FANOUT_FREE_NODE_SUPPORT 1 HAS_FAST_FIT_SUPPORT 1 HAS_FITTER_EARLY_TIMING_ESTIMATE_SUPPORT 1 HAS_FITTER_ECO_SUPPORT 1 HAS_FIT_NETLIST_OPT_RETIME_SUPPORT 1 HAS_FIT_NETLIST_OPT_SUPPORT 1 HAS_FORMAL_VERIFICATION_SUPPORT 1 HAS_FPGA_XCHANGE_SUPPORT 1 HAS_FSAC_LUTRAM_REGISTER_PACKING_SUPPORT 0 HAS_FULL_DAT_MIN_TIMING_SUPPORT 1 HAS_FULL_INCREMENTAL_DESIGN_SUPPORT 1 HAS_FUNCTIONAL_SIMULATION_SUPPORT 1 HAS_GLITCH_FILTERING_SUPPORT 1 HAS_HC_READY_SUPPORT 1 HAS_HIGH_SPEED_LOW_POWER_TILE_SUPPORT 1 HAS_HOLD_TIME_AVOIDANCE_ACROSS_CLOCK_SPINE_SUPPORT 1 HAS_HSPICE_WRITER_SUPPORT 1 HAS_HSSI_POWER_CALCULATOR 1 HAS_IBISO_WRITER_SUPPORT 0 HAS_INCREMENTAL_DAT_SUPPORT 1 HAS_INCREMENTAL_SYNTHESIS_SUPPORT 1 HAS_IO_ASSIGNMENT_ANALYSIS_SUPPORT 1 HAS_IO_DECODER 1 HAS_IO_PLACEMENT_OPTIMIZATION_SUPPORT 1 HAS_IO_SMART_RECOMPILE_SUPPORT 0 HAS_JITTER_SUPPORT 1 HAS_JTAG_SLD_HUB_SUPPORT 1 HAS_LOGIC_LOCK_SUPPORT 1 HAS_MICROPROCESSOR 0 HAS_MIF_SMART_COMPILE_SUPPORT 1 HAS_MINMAX_TIMING_MODELING_SUPPORT 1 HAS_MIN_TIMING_ANALYSIS_SUPPORT 1 HAS_MUX_RESTRUCTURE_SUPPORT 1 HAS_NEW_HC_FLOW_SUPPORT 0 HAS_NEW_SERDES_MAX_RESOURCE_COUNT_REPORTING_SUPPORT 1 HAS_NEW_VPR_SUPPORT 1 HAS_NONSOCKET_TECHNOLOGY_MIGRATION_SUPPORT 1 HAS_NO_JTAG_USERCODE_SUPPORT 0 HAS_OPERATING_SETTINGS_AND_CONDITIONS_REPORTING_SUPPORT 1 HAS_PAD_LOCATION_ASSIGNMENT_SUPPORT 0 HAS_PARTIAL_RECONFIG_SUPPORT 0 HAS_PHYSICAL_NETLIST_OUTPUT 0 HAS_PHYSICAL_ROUTING_SUPPORT 1 HAS_PIN_SPECIFIC_VOLTAGE_SUPPORT 1 HAS_PLDM_REF_SUPPORT 1 HAS_POWER_ESTIMATION_SUPPORT 1 HAS_PRELIMINARY_CLOCK_UNCERTAINTY_NUMBERS 0 HAS_PRE_FITTER_FPP_SUPPORT 0 HAS_PRE_FITTER_LUTRAM_NETLIST_CHECKER_ENABLED 1 HAS_PVA_SUPPORT 1 HAS_RCF_SUPPORT 1 HAS_RCF_SUPPORT_FOR_DEBUGGING 0 HAS_RED_BLACK_SEPARATION_SUPPORT 0 HAS_RE_LEVEL_TIMING_GRAPH_SUPPORT 1 HAS_RISEFALL_DELAY_SUPPORT 1 HAS_SIGNAL_PROBE_SUPPORT 1 HAS_SIGNAL_TAP_SUPPORT 1 HAS_SIMULATOR_SUPPORT 0 HAS_SPLIT_IO_SUPPORT 1 HAS_SPLIT_LC_SUPPORT 1 HAS_SYNTH_FSYN_NETLIST_OPT_SUPPORT 1 HAS_SYNTH_NETLIST_OPT_RETIME_SUPPORT 1 HAS_SYNTH_NETLIST_OPT_SUPPORT 1 HAS_TECHNOLOGY_MIGRATION_SUPPORT 1 HAS_TEMPLATED_REGISTER_PACKING_SUPPORT 1 HAS_TIME_BORROWING_SUPPORT 0 HAS_TIMING_DRIVEN_SYNTHESIS_SUPPORT 1 HAS_TIMING_INFO_SUPPORT 1 HAS_TIMING_OPERATING_CONDITIONS 1 HAS_TIMING_SIMULATION_SUPPORT 1 HAS_TITAN_BASED_MAC_REGISTER_PACKER_SUPPORT 1 HAS_USER_HIGH_SPEED_LOW_POWER_TILE_SUPPORT 1 HAS_USE_FITTER_INFO_SUPPORT 0 HAS_VCCPD_POWER_RAIL 1 HAS_VERTICAL_MIGRATION_SUPPORT 1 HAS_VIEWDRAW_SYMBOL_SUPPORT 0 HAS_VIO_SUPPORT 1 HAS_VIRTUAL_DEVICES 0 HAS_WYSIWYG_DFFEAS_SUPPORT 1 HAS_XIBISO_WRITER_SUPPORT 1 INCREMENTAL_DESIGN_SUPPORTS_COMPATIBLE_CONSTRAINTS 1 INSTALLED 0 IS_CONFIG_ROM 0 IS_DEFAULT_FAMILY 0 IS_HARDCOPY_FAMILY 0 LVDS_IO 1 M10K_MEMORY 0 M144K_MEMORY 1 M20K_MEMORY 0 M4K_MEMORY 0 M512_MEMORY 0 M9K_MEMORY 1 MLAB_MEMORY 1 MRAM_MEMORY 0 NOT_LISTED 0 NO_RPE_SUPPORT 0 NO_SUPPORT_FOR_LOGICLOCK_CONTENT_BACK_ANNOTATION 1 NO_SUPPORT_FOR_STA_CLOCK_UNCERTAINTY_CHECK 0 NO_TDC_SUPPORT 0 POSTFIT_BAK_DATABASE_EXPORT_ENABLED 1 POSTMAP_BAK_DATABASE_EXPORT_ENABLED 1 PROGRAMMER_SUPPORT 1 QFIT_IN_DEVELOPMENT 0 QMAP_IN_DEVELOPMENT 0 RAM_LOGICAL_NAME_CHECKING_IN_CUT_ENABLED 1 REPORTS_METASTABILITY_MTBF 1 REQUIRES_INSTALLATION_PATCH 0 REQUIRES_LIST_OF_TEMPERATURE_AND_VOLTAGE_OPERATING_CONDITIONS 1 RESERVES_SIGNAL_PROBE_PINS 0 RESOLVE_MAX_FANOUT_EARLY 1 RESOLVE_MAX_FANOUT_LATE 0 RESPECTS_FIXED_SIZED_LOCKED_LOCATION_LOGICLOCK 1 RESTRICTED_USER_SELECTION 0 RISEFALL_SUPPORT_IS_HIDDEN 0 SUPPORTS_ADDITIONAL_OPTIONS_FOR_UNUSED_IO 1 SUPPORTS_CRC 1 SUPPORTS_DIFFERENTIAL_AIOT_BOARD_TRACE_MODEL 1 SUPPORTS_DSP_BALANCING_BACK_ANNOTATION 0 SUPPORTS_GENERATION_OF_EARLY_POWER_ESTIMATOR_FILE 1 SUPPORTS_GLOBAL_SIGNAL_BACK_ANNOTATION 1 SUPPORTS_MAC_CHAIN_OUT_ADDER 1 SUPPORTS_RAM_PACKING_BACK_ANNOTATION 0 SUPPORTS_REG_PACKING_BACK_ANNOTATION 0 SUPPORTS_SIGNALPROBE_REGISTER_PIPELINING 1 SUPPORTS_SINGLE_ENDED_AIOT_BOARD_TRACE_MODEL 1 SUPPORTS_USER_MANUAL_LOGIC_DUPLICATION 1 TMV_RUN_CUSTOMIZABLE_VIEWER 1 TMV_RUN_INTERNAL_DETAILS 1 TMV_RUN_INTERNAL_DETAILS_ON_IO 0 TMV_RUN_INTERNAL_DETAILS_ON_IOBUF 1 TMV_RUN_INTERNAL_DETAILS_ON_LCELL 0 TMV_RUN_INTERNAL_DETAILS_ON_LRAM 0 TRANSCEIVER_3G_BLOCK 1 TRANSCEIVER_6G_BLOCK 1 USES_ACV_FOR_FLED 1 USES_ADB_FOR_BACK_ANNOTATION 1 USES_ASIC_ROUTING_POWER_CALCULATOR 0 USES_DATA_DRIVEN_PLL_COMPUTATION_UTIL 1 USES_DEV 1 USES_ICP_FOR_ECO_FITTER 0 USES_LIBERTY_TIMING 0 USES_POWER_SIGNAL_ACTIVITIES 1 USES_THIRD_GENERATION_TIMING_MODELS_TIS 1 USE_ADVANCED_IO_POWER_BY_DEFAULT 1 USE_ADVANCED_IO_TIMING_BY_DEFAULT 1 USE_BASE_FAMILY_DDB_PATH 0 USE_OCT_AUTO_CALIBRATION 0 USE_RISEFALL_ONLY 1 USE_SEPARATE_LIST_FOR_TECH_MIGRATION 1 USE_SINGLE_COMPILER_PASS_PLL_MIF_FILE_WRITER 1 USE_TITAN_IO_BASED_IO_REGISTER_PACKER_UTIL 1 WYSIWYG_BUS_WIDTH_CHECKING_IN_CUT_ENABLED 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: radiohdl/trunk/core/quartus_config
===================================================================
--- radiohdl/trunk/core/quartus_config (nonexistent)
+++ radiohdl/trunk/core/quartus_config (revision 4)
@@ -0,0 +1,304 @@
+#! /usr/bin/env python3
+###############################################################################
+#
+# Copyright (C) 2014
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+###############################################################################
+
+"""HDL configuration for building Quartus synthesis targets.
+
+ Usage:
+ > python ${RADIOHDL_GEAR}/core/quartus_config -t unb1
+"""
+
+import sys
+from os import listdir
+import os.path
+from argparse import ArgumentParser
+import common_radiohdl as cm
+import hdl_libraries_wizard
+
+
+class QuartusConfig(hdl_libraries_wizard.HdlLibrariesWizard):
+
+ def __init__(self, toolRootDir, toolFileName, libFileName='hdllib.cfg'):
+ """Get Quartus tool info from toolRootDir and all HDL library info from libRootDir.
+
+ This class uses the default keys and the keys from the libFileSections in the libFileName config file.
+
+ Arguments:
+ - toolRootDir : Root directory from where the hdl_buildset_.cfg file is searched for.
+ - toolFileName : Default HDL tools configuration file name
+ - libFileName : Default HDL library configuration file name
+
+ The libRootDir is defined in the hdl_buildset_.cfg file and is the root directory from where the hdllib.cfg
+ files are searched for.
+
+ The technologyNames parameter is defined in the hdl_buildset_.cfg file. All generic HDL libraries and these
+ technology specific libraries are kept.
+
+ Files:
+ - hdl_buildset_.cfg : HDL tool configuration dictionary file. One central file per buildset.
+
+ - hdllib.cfg : HDL library configuration dictionary file. One file for each HDL library.
+
+ - .qpf : Quartus project file (QPF) for a certain HDL library based on the hdllib.cfg. The file is created by
+ create_quartus_project_file().
+
+ - .qsf : Quartus settings file (QSF) for a certain HDL library based on the hdllib.cfg. The file is created by
+ create_quartus_settings_file(). There is one QSF per Quartus synthesis project.
+ """
+ print("QuartusConfig(toolRootDir=%s, toolFileName=%s, libFileName=%s)" % (toolRootDir, toolFileName, libFileName))
+ libFileSections = ['quartus_project_file']
+ hdl_libraries_wizard.HdlLibrariesWizard.__init__(self, toolRootDir, toolFileName, libFileName, libFileSections)
+
+ def create_quartus_ip_lib_file(self, lib_names=None):
+ """Create the Quartus IP file _lib.qip for all HDL libraries. The .qip file contains the list of files that are given
+ by the synth_files key and the quartus_*_file keys.
+
+ Note:
+ . Use post fix '_lib' in QIP file name *_lib.qip to avoid potential conflict with *.qip that may come with the IP.
+ . The HDL library *_lib.qip files contain all files that are listed by the synth_files key. Hence when these qip files are included then
+ the Quartus project will analyse all files even if there entity is not instantiated in the design. This is fine, it is unnecessary
+ to parse the hierarchy of the synth_top_level_entity VHDL file to find and include only the source files that are actually used.
+
+ Arguments:
+ - lib_names : one or more HDL libraries
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+
+ lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=lib_names)
+ for lib_dict in lib_dicts:
+ # Open qip
+ lib_name = lib_dict['hdl_lib_name']
+ qip_name = lib_name + '_lib.qip'
+ qip_path = self.get_lib_build_dirs('synth', lib_dicts=lib_dict)
+ cm.mkdir(qip_path)
+ qipPathName = cm.expand_file_path_name(qip_name, qip_path)
+ with open(qipPathName, 'w') as fp:
+ if lib_dict.get_value('synth_files'):
+ fp.write('# synth_files\n')
+ synth_files = lib_dict['synth_files'].split()
+ for fn in synth_files:
+ filePathName = cm.expand_file_path_name(fn, lib_dict.location)
+
+ file_ext = fn.split('.')[-1]
+ if file_ext == 'vhd' or file_ext == 'vhdl':
+ file_type = 'VHDL_FILE'
+ elif file_ext == 'v':
+ file_type = 'VERILOG_FILE'
+ else:
+ print('\nERROR - Undefined file extension in synth_files:', fn)
+ sys.exit()
+
+ fp.write('set_global_assignment -name %s %s -library %s\n' % (file_type, filePathName, lib_name + '_lib'))
+
+ if lib_dict.get_value('quartus_vhdl_files'):
+ fp.write('\n')
+ fp.write('# quartus_vhdl_files\n')
+ quartus_vhdl_files = lib_dict['quartus_vhdl_files'].split()
+ for fn in quartus_vhdl_files:
+ filePathName = cm.expand_file_path_name(fn, lib_dict.location)
+
+ file_ext = fn.split('.')[-1]
+ if file_ext == 'vhd' or file_ext == 'vhdl':
+ file_type = 'VHDL_FILE'
+ elif file_ext == 'v':
+ file_type = 'VERILOG_FILE'
+ else:
+ print('\nERROR - Undefined file extension in quartus_vhdl_files:', fn)
+ sys.exit()
+
+ fp.write('set_global_assignment -name VHDL_FILE %s -library %s\n' % (filePathName, lib_name + '_lib'))
+
+ if lib_dict.get_value('quartus_qip_files'):
+ fp.write('\n')
+ fp.write('# quartus_qip_files\n')
+ quartus_qip_files = lib_dict['quartus_qip_files'].split()
+ for fn in quartus_qip_files:
+ filePathName = cm.expand_file_path_name(fn, lib_dict.location)
+ fp.write('set_global_assignment -name QIP_FILE %s\n' % filePathName)
+
+ if lib_dict.get_value('quartus_tcl_files'):
+ fp.write('\n')
+ fp.write('# quartus_tcl_files\n')
+ quartus_tcl_files = lib_dict['quartus_tcl_files'].split()
+ for fn in quartus_tcl_files:
+ filePathName = cm.expand_file_path_name(fn, lib_dict.location)
+ fp.write('set_global_assignment -name SOURCE_TCL_SCRIPT_FILE %s\n' % filePathName)
+
+ if lib_dict.get_value('quartus_sdc_files'):
+ fp.write('\n')
+ fp.write('# quartus_sdc_files\n')
+ quartus_sdc_files = lib_dict['quartus_sdc_files'].split()
+ for fn in quartus_sdc_files:
+ filePathName = cm.expand_file_path_name(fn, lib_dict.location)
+ fp.write('set_global_assignment -name SDC_FILE %s\n' % filePathName)
+ print("Created {} .qip files".format(len(lib_dicts)))
+
+ def create_quartus_project_file(self, lib_names=None):
+ """Create the Quartus project file (QPF) for all HDL libraries that have a toplevel entity key synth_top_level_entity.
+
+ Note:
+ . Default if the synth_top_level_entity key is defined but left empty then the top level entity has the same name as the lib_name in hdl_lib_name.
+ Otherwise synth_top_level_entity can specify another top level entity name in the library. Each HDL library can only have one Quartus project
+ file
+ . The project revision has the same name as the lib_name and will result in a .sof FPGA image file.
+ . For each additional revision a subdirectory can be used.
+ This subdirectory can be named 'revisions/' and lists a number of revisions as subdirectories. Each revision will have a separate hdllib.cfg file and a
+ .vhd file with the toplevel entity. The toplevel .vhd file specifies the for the revision in the generics.
+
+ Arguments:
+ - lib_names : one or more HDL libraries
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+ lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
+ syn_dicts = self.libs.get_configfiles(key='synth_top_level_entity', values=None, user_configfiles=lib_dicts)
+ for syn_dict in syn_dicts:
+ # Open qpf for each HDL library that has a synth_top_level_entity
+ lib_name = syn_dict['hdl_lib_name']
+ qpf_name = lib_name + '.qpf'
+ qpf_path = self.get_lib_build_dirs('synth', lib_dicts=syn_dict)
+ cm.mkdir(qpf_path)
+ qpfPathName = cm.expand_file_path_name(qpf_name, qpf_path)
+ with open(qpfPathName, 'w') as fp:
+ fp.write('PROJECT_REVISION = "%s"\n' % lib_name)
+ print("Created {} .qpf files".format(len(syn_dicts)))
+
+ def create_quartus_settings_file(self, lib_names=None):
+ """Create the Quartus settings file (QSF) for all HDL libraries that have a toplevel entity key synth_top_level_entity.
+
+ Note:
+ . No support for revisions, so only one qsf per qpf
+
+ Arguments:
+ - lib_names : one or more HDL libraries
+ """
+ if lib_names is None:
+ lib_names = self.lib_names
+ lib_dicts = self.libs.get_configfiles(key='hdl_lib_name', values=lib_names)
+ syn_dicts = self.libs.get_configfiles(key='synth_top_level_entity', values=None, user_configfiles=lib_dicts)
+ for syn_dict in syn_dicts:
+ # Open qsf for each HDL library that has a synth_top_level_entity
+ lib_name = syn_dict['hdl_lib_name']
+ top_level_entity = syn_dict['synth_top_level_entity']
+ if top_level_entity == '':
+ top_level_entity = lib_name
+ qsf_path = self.get_lib_build_dirs('synth', lib_dicts=syn_dict)
+ cm.mkdir(qsf_path)
+
+ # One qsf per lib_name
+ qsf_name = lib_name + '.qsf'
+ qsfPathName = cm.expand_file_path_name(qsf_name, qsf_path)
+ with open(qsfPathName, 'w') as fp:
+ fp.write('# synth_top_level_entity\n')
+ fp.write('set_global_assignment -name TOP_LEVEL_ENTITY %s\n' % top_level_entity)
+
+ fp.write('\n')
+ fp.write('# quartus_qsf_files\n')
+ quartus_qsf_files = syn_dict['quartus_qsf_files'].split()
+ for fn in quartus_qsf_files:
+ filePathName = cm.expand_file_path_name(fn, syn_dict.location)
+ fp.write('set_global_assignment -name SOURCE_TCL_SCRIPT_FILE %s\n' % filePathName)
+
+ fp.write('\n')
+ fp.write('# All used HDL library *_lib.qip files in order with top level last\n')
+ use_lib_order = self.derive_lib_order('synth', lib_name)
+ # use_lib_dicts = self.libs.get_configfiles('hdl_lib_name', values=use_lib_order) # uses original libs.dicts order, but
+ use_lib_dicts = self.get_lib_dicts_from_lib_names(lib_names=use_lib_order) # must preserve use_lib_order order to ensure that top level design qip with sdc file is include last in qsf
+ for lib_dict in cm.listify(use_lib_dicts):
+ qip_path = self.get_lib_build_dirs('synth', lib_dicts=lib_dict)
+ qip_name = lib_dict['hdl_lib_name'] + '_lib.qip'
+ qipPathName = cm.expand_file_path_name(qip_name, qip_path)
+ fp.write('set_global_assignment -name QIP_FILE %s\n' % qipPathName)
+
+ if syn_dict.get_value('quartus_ip_files'):
+ # print(syn_dict['quartus_ip_files'])
+ fp.write('\n')
+ fp.write('# All used HDL library *.ip files in order with top level last\n')
+ quartus_ip_files = syn_dict['quartus_ip_files'].split()
+ for fn in quartus_ip_files:
+ filePathName = cm.expand_file_path_name(fn)
+ fp.write('set_global_assignment -name IP_FILE %s\n' % filePathName)
+
+ fp.write('\n')
+ print("Created {} .qsf files".format(len(syn_dicts)))
+
+
+if __name__ == '__main__':
+ # Parse command line arguments
+ buildsetSelect = sorted([cfgfile[13:-4] for cfgfile in listdir(os.getenv('RADIOHDL_CONFIG'))
+ if cfgfile.startswith("hdl_buildset_") and cfgfile.endswith(".cfg")])
+ argparser = ArgumentParser(description='Quartus_config creates/updates all your quartus projectfiles.')
+ argparser.add_argument('buildset', help='choose buildset %s' % (buildsetSelect))
+ argparser.add_argument('-v', '--verbosity', required=False, type=int, default=0, help='verbosity >= 0 for more info')
+ args = argparser.parse_args()
+
+ # check arguments
+ if args.buildset not in buildsetSelect:
+ print('buildset %s is not supported' % args.buildset)
+ print("Supported buildset are:", buildsetSelect)
+ sys.exit(1)
+ args.buildsetFile = 'hdl_buildset_' + args.buildset + '.cfg'
+
+ # Read the dictionary info from all HDL tool and library configuration files in the current directory and the sub directories
+ qsyn = QuartusConfig(toolRootDir=os.getenv('RADIOHDL_CONFIG'),
+ toolFileName=args.buildsetFile,
+ libFileName='hdllib.cfg')
+
+ if args.verbosity >= 2:
+ print('#')
+ print('# QuartusConfig:')
+ print('#')
+ print('')
+ print('HDL library paths that are found in $%s:' % qsyn.libRootDirs)
+ for p in sorted(qsyn.libs.configfiles.values()):
+ print(' ', p.location)
+
+ if args.verbosity >= 1:
+ print('')
+ print('HDL libraries with a top level entity for synthesis that are found in $%s:' % qsyn.libRootDirs)
+ print(' %-40s' % 'HDL library', ': Top level entity')
+ syn_dicts = qsyn.libs.get_configfiles(key='synth_top_level_entity')
+ for d in syn_dicts:
+ if d['synth_top_level_entity'] == '':
+ print(' %-40s' % d['hdl_lib_name'], ':', d['hdl_lib_name'])
+ else:
+ print(' %-40s' % d['hdl_lib_name'], ':', d['synth_top_level_entity'])
+
+ print('')
+ print('Create Quartus IP library qip files for all HDL libraries in $%s.'
+ % qsyn.libRootDirs)
+ qsyn.create_quartus_ip_lib_file()
+
+ print('')
+ print('Copy Quartus directories and files from HDL library source tree to build_dir for all HDL libraries that are found in $%s.'
+ % qsyn.libRootDirs)
+ qsyn.copy_files('synth')
+
+ print('')
+ print('Create Quartus project files (QPF) for technology %s and all HDL libraries with a top level entity for synthesis that are found in $%s.'
+ % (qsyn.technologyNames, qsyn.libRootDirs))
+ qsyn.create_quartus_project_file()
+
+ print('')
+ print('Create Quartus settings files (QSF) for technology %s and all HDL libraries with a top level entity for synthesis that are found in $%s.'
+ % (qsyn.technologyNames, qsyn.libRootDirs))
+ qsyn.create_quartus_settings_file()
radiohdl/trunk/core/quartus_config
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/doc/HDL User manual.docx
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: radiohdl/trunk/doc/HDL User manual.docx
===================================================================
--- radiohdl/trunk/doc/HDL User manual.docx (nonexistent)
+++ radiohdl/trunk/doc/HDL User manual.docx (revision 4)
radiohdl/trunk/doc/HDL User manual.docx
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: radiohdl/trunk/doc/HDL User manual.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: radiohdl/trunk/doc/HDL User manual.pdf
===================================================================
--- radiohdl/trunk/doc/HDL User manual.pdf (nonexistent)
+++ radiohdl/trunk/doc/HDL User manual.pdf (revision 4)
radiohdl/trunk/doc/HDL User manual.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: radiohdl/trunk/doc/HDL programmers manual.docx
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: radiohdl/trunk/doc/HDL programmers manual.docx
===================================================================
--- radiohdl/trunk/doc/HDL programmers manual.docx (nonexistent)
+++ radiohdl/trunk/doc/HDL programmers manual.docx (revision 4)
radiohdl/trunk/doc/HDL programmers manual.docx
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: radiohdl/trunk/doc/HDL programmers manual.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: radiohdl/trunk/doc/HDL programmers manual.pdf
===================================================================
--- radiohdl/trunk/doc/HDL programmers manual.pdf (nonexistent)
+++ radiohdl/trunk/doc/HDL programmers manual.pdf (revision 4)
radiohdl/trunk/doc/HDL programmers manual.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: radiohdl/trunk/doc/HDLgear overview.pptx
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: radiohdl/trunk/doc/HDLgear overview.pptx
===================================================================
--- radiohdl/trunk/doc/HDLgear overview.pptx (nonexistent)
+++ radiohdl/trunk/doc/HDLgear overview.pptx (revision 4)
radiohdl/trunk/doc/HDLgear overview.pptx
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: radiohdl/trunk/doc/HDLgear.eap
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: radiohdl/trunk/doc/HDLgear.eap
===================================================================
--- radiohdl/trunk/doc/HDLgear.eap (nonexistent)
+++ radiohdl/trunk/doc/HDLgear.eap (revision 4)
radiohdl/trunk/doc/HDLgear.eap
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: radiohdl/trunk/doc/hdltool_readme.txt
===================================================================
--- radiohdl/trunk/doc/hdltool_readme.txt (nonexistent)
+++ radiohdl/trunk/doc/hdltool_readme.txt (revision 4)
@@ -0,0 +1,380 @@
+
+g) Tool start scripts
+
+The definitions for actually running Modelsim and Quartus are not kept in the ~/.bashrc file or the setup script but are
+set in a tool start script:
+
+ ${RADIOHDL_GEAR}/modelsim/run_modelsim # calls set_quartus and starts the Modelsim GUI for simulation
+ ${RADIOHDL_GEAR}/quartus/run_quartus # calls set_quartus and starts the Quartus GUI for synthesis
+
+The paths to these tool start scripts are defined in setup_radiohdl.sh. In addition to the advantages mentioned above for the environment setup scripts,
+the advantages of using a seperate tool start script is:
+
+ - different versions of the tool can be started in parallel on the same machine, because the tool start script settings
+ only apply to the started tool environment
+
+
+
+i) How to start Quartus for RadioHDL
+
+For building a SOPC system use:
+ > run_sopc unb1 unb1_minimal_sopc
+ > run_app unb1 unb1_minimal_sopc # calls: run_bsp, run_reg, run_mif
+ > run_app_clean unb1 unb1_minimal_sopc app=unb_osy
+ > run_qcomp unb1 unb1_minimal_sopc
+ > run_all_sopc unb1 unb1_minimal_sopc # sequentially running: run_sopc + run_app + run_qcomp
+ > run_rbf unb1 unb1_minimal_sopc
+ > run_sof unb1 unb1_minimal_sopc 0
+
+For building a QSYS system use:
+ > run_qsys unb1 unb1_minimal_qsys
+ > run_sopc unb1 unb1_minimal_sopc # (normally not needed but the unb1_minimal_qsys revision has a GENERATE sopc-OR-qsys section)
+ > run_app unb1 unb1_minimal_qsys use=qsys
+ > run_qcomp unb1 unb1_minimal_qsys
+ > run_all_qsys unb1 unb1_minimal_qsys # sequentially running: run_qsys + run_app + run_qcomp
+ > run_rbf unb1 unb1_minimal_qsys
+ > run_sof unb1 unb1_minimal_qsys 0
+
+
+j) How to start Modelsim for UNB
+
+GUI:
+
+ > unb_msim & # for UNB
+ > aaf_msim & # for AARTFAAC
+ > paasar_msim & # for PAASAR
+
+See the setup_unb.sh environment script and ASTRON_RP_1354_unb_minimal.pdf for more description.
+
+
+n) How to use RadioHDL for Lofar RSP
+
+* The Lofar Station firmware is kept in a separate SVN repository at:
+
+ https://svn.astron.nl/Station
+
+ The firmware for the RSP board is kept in:
+
+ https://svn.astron.nl/Station/trunk/RSP
+
+ In setup_radiohdl.sh add the path to the local SVN checkout of the Station
+ firmware:
+
+ export RSP=${SVN}/../Station/trunk/RSP
+
+ and add ${RADIOHDL_GEAR}/ise to the PATH environment variable.
+
+* To compile the Xilinx ISE10.1.03 models with Modelsim 6.6c under linux do:
+
+ The compxlib adds the Xilinx libraries to the [libraries] section in the
+ /home/software/Mentor/6.6c/modeltech/modelsim.ini file. Therefore make
+ sure to first copy this original installation modelsim.ini file, so that
+ we can restore it.
+
+ cd /home/software/modelsim_xilinx_libs/ise/10.1.03
+ sudo mkdir vhdl
+ sudo mkdir verilog
+ sudo /home/software/Xilinx/ISE/10.1/ISE/bin/lin/compxlib -s mti_se -f all -l vhdl -dir vhdl -p /home/software/Mentor/6.6c/modeltech/linux_x86_64
+ sudo /home/software/Xilinx/ISE/10.1/ISE/bin/lin/compxlib -s mti_se -f all -l verilog -dir verilog -p /home/software/Mentor/6.6c/modeltech/linux_x86_64
+
+ Use the library mappings in the modelsim.ini that was modified by compxlib
+ to create:
+
+ tools/ise/create hdl_libraries_ip_virtex4.txt
+
+ The modelsim_config.py using hdl_libraries_ip_virtex4.txt to map the Xilinx
+ library files in each HDL library project files. Therefore the central
+ mapping in the Modelsim installation modelsim.ini file is unwanted and not
+ needed.
+
+* Create tools/hdl_buildset_rsp.cfg HDL tool configuration dictionary file for buildset 'rsp'
+
+* Create bash scripts to start up ISE based on the buildset 'rsp' in tools/ise:
+ run_ise
+ \--> set_ise
+ \--> ise_version.sh
+ \--> ise_generic.sh
+
+ This is similar as for other tools like Modelsim, Quartus. The advantage of
+ this approach is that the tool settings are only made when the tool is ran
+ and not in the .bashrc file. These bash scripts are kept in SVN and thus the
+ same tool settings are used by all engineers.
+
+* Add 'rsp' buildset for Modelsim and ISE versions to tools/modelsim/set_modelsim.
+
+* To start the ISE GUI do:
+ > run_ise rsp &
+
+* To start the Modelsim GUI do:
+ > run_modelsim rsp &
+
+
+3) HDL environment configuration files
+
+d) hdl_buildset_.cfg key descriptions
+
+- project_dir_depth_sim =
+ The project file will be located in the build dir or at some levels deeper in the build dir.
+ These optional extra subdirectory levels allow for relative file reference from project file
+ location. This is useful to be able to keep memory initialisation files in the library build
+ directory that are referred to using some fixed ../../ path in the HDL code.
+ . project_deeper_subdir = '' when project_dir_depth_ = 0 or not in tool_dict
+ . project_deeper_subdir = 'p/' when project_dir_depth_ = 1
+ . project_deeper_subdir = 'p/p/' when project_dir_depth_ = 2,
+ . project_deeper_subdir = 'p/p/p/' when project_dir_depth_ = 3, etc
+
+- project_dir_depth_synth =
+ Same purpose as project_dir_depth_sim, but for synthesis project file location in build tree.
+
+
+
+5) Build directory location
+
+The Modelsim and Quartus build location central outside the $HDL sources directory tree, whereby the
+subdirectory names are defined by the corresponding keysin the hdl_buildset_.cfg:
+
+ ${RADIOHDL_BUILD_DIR}//
+
+eg.
+
+ ${RADIOHDL_BUILD_DIR}/unb1/modelsim/common
+
+The advantage of the central directory build tree is that it can easily be removed (using rm -rf) and
+recreated (using modelsim_config.py and quartus_config.py). For synthesis recreation of targets like sof files can take much
+time though.
+
+
+
+100) To do
+
+a) quartus_* keys and synth_top_level_entity
+ . The quartus_* keys are now source oriented. Instead it may be better to redefine them as target oriented. Eg. a
+ quartus_create_qsf key that defines to create a qsf file using the information listed in the values.
+ Whether a key is source oriented or target oriented depends on whether its files are used for one or more targets.
+ In general if a file is used for more targets then source oriented is preferred to avoid having to list the file
+ name twice. If a file is used only for one target then target oriented is preferred to be more clear about the
+ purpose of the key.
+ . The synth_top_level_entity enforces the creation of a qpf and qsf. This kind of hidden behavior is not so nice.
+ Instead it is more clear to have an explicit quartus_create_qpf and quartus_create_qsf key to define this.
+
+b) Generate Quartus IP key
+ The generate_ip.sh scripts for generating the MegaWizard or QSYS IP components in fact are merely a wrapper script
+ around the qsys-generate command. The generate_ip.sh may seem an unnecessary intermediate step if the IP is
+ generated automatically. The IP could be generated automatically based on a megawizard key or a qsys key that
+ has the description file as value. However the advantage of a generate_ip.sh script is that it can hide whether the
+ MegaWizard or QSYS needs to be used to generate the IP, so in that way a 'quartus_generate_ip' key can fit both:
+
+ quartus_copy_files =
+ generate_ip.sh
+ _.qsys
+ quartus_generate_ip = generate_ip.sh
+
+ The 'quartus_copy_files' key is used to copy the IP generation source file and the generation script to the
+ build directory. The 'quartus_generate_ip' key identifies the script that needs to be ran when the IP has to be
+ generated. Eg. a --generate_ip command line argument for quartus_config.py (rather than a separate
+ quartus_generate_ip.py script) can then generate the IP for all libraries that have such a key. The IP can then
+ be generated outside the SVN tree. The $IP_DIR path compile_ip.tcl needs to be adjusted to generated/ and the
+ IP then gets generated in:
+
+ $RADIOHDL_BUILD_DIR//quartus//generated
+
+ For generated IP that is kept in SVN that IP could still remain there.
+
+ The hdllib.cfg should then also define a IP toolname subdirectory in build dir, eg.:
+
+ // = $RADIOHDL_BUILD_DIR/qsys or
+ $RADIOHDL_BUILD_DIR/megawizard
+
+ or more general $RADIOHDL_BUILD_DIR/ip?
+ The $RADIOHDL_BUILD_DIR now has a modelsim and quartus subdir:
+
+ $RADIOHDL_BUILD_DIR//modelsim -- made by modelsim_config.py using sim_tool_name from hdl_buildset_.cfg
+ $RADIOHDL_BUILD_DIR//quartus -- made by quartus_config.py using synth_tool_name from hdl_buildset_.cfg
+
+ The IP can be put in a subdir using eg 'ip_tool_name' = quartus_ip:
+
+ $RADIOHDL_BUILD_DIR//quartus_ip -- made by quartus_config.py using a new ip_tool_name from hdl_buildset_.cfg
+
+ or can it be put in the synth_tool_name directory:
+
+ $RADIOHDL_BUILD_DIR//quartus
+
+ or do we need tool_name_megawizard and tool_name_qsys to be able to create:
+
+ //
+ $RADIOHDL_BUILD_DIR/unb1/megawizard -- Altera MegaWizard
+ $RADIOHDL_BUILD_DIR/unb1/qsys -- Altera QSYS
+ $RADIOHDL_BUILD_DIR/unb1/coregen -- Xilinx
+
+ Probably it is not so important whether the IP is generated by MegaWizard or Qsys, because that selection is
+ already covered by the generate_ip.sh scripts. In the hdl_buildset_.cfg both MegaWizard and Qsys can be regarded as
+ being part of the Quartus tool. Therefore using ip_tool_name provides sufficient distinction in IP build
+ sub directory. However the IP could also be generated into the synth_tool_name build directory and then even
+ the ip_tool_name key is not needed, because the synth_tool_name sub directory also suits the Quartus IP
+ generation.
+
+ Conclusion:
+ - Using synth_tool_name = quartus is also sufficient/suitable to define the build subdirectory for IP generation.
+ Having a dedicate ip_tool_name could be nice, to more clearly see in the build tree which libraries have IP.
+
+c) regression test script
+ * For pure HDL tests the modelsim_regression_test.py script can simulate VHDL test benches that are listed at
+ the 'regression_test_vhdl' key and report the result.
+ * For Python test cases another key can be defined 'regression_test_py_hdl'. The values they may contain the entire command
+ to run the Python test case with the HDL test bench. Note that the pure VHDL test benches could be perphaps also be
+ regarded as a special case of the Python MM - VHDL tests, ie. as a test without MM.
+ * Another bash or Python script that synthesises a set of designs to check that they still run through synthesis ok.
+
+d) multiple libRootDirs for finding hdllib.cfg files
+ The libRootDir is now defined via a the 'lib_root_dir' key in the hdl_buildset_.cfg.
+ Currently hdlib.cfg files are search from one rootDir by find_all_dict_file_paths() in common_dict_file.py. It
+ would be usefule to be able to specify multiple rootDirs for the search path. This allows finding eg. all
+ hdllib.cfg in two different directory trees without having to specifiy their common higher directory root which
+ could be a very large tree to search through. Furthermore by being able to specify the rootDirs more precisely
+ avoids finding unintended hdllib.cfg files. Support for multiple rootdirs needs to be implemented in
+ common_dict_file.py because the results from all root dirs need to be in a common object.
+
+e) Python peripherals
+ The Python peripherals are still in the $UNB/Software/python/peripherals directory. At some time we need to move
+ these also to RadioHDL. The peripherals could be located central again or local in a src/python directory. A first
+ step can be to svn copy the $UNB/Software/python dir to ${RADIOHDL_WORK}/software/python to become independent of the
+ $UNB tree. An intermediate scheme is also possible whereby the periperal is kept local but copied to a central
+ build/python directory by means of a python_config.py script. The advantage of a central directory is that the periperals
+ are grouped so that only a single Python search path is needed. The disadvantage of having a fixed central
+ location in SVN is that peripherals that are application specific also need to be located there. Another option
+ may be to use a synbolic link from a central directory to each local Python peripheral.
+
+
+f) Improve support IP for multiple FPGA device types and Quartus tool versions
+
+The IP is FPGA type specific (because it needs to be defined in the Qsys source file) and tool version specific
+(because some parameters and even port IO may change). Currently there is only one IP directory per FPGA
+technology (eg. ip_arria10) so there is no further separation into device family type and tool version. The
+disadvantage of this scheme is that only one version of Quartus can be supported. For a minor version
+change it may not be necessary to upgrade, but for a major version change or for a device family type (eg. from
+engineering sample to production sample) change it probably is. To preserve the old version IP it is best to
+treat the both the FPGA device version id and the Quartus tool version as a new technology. For example for
+Arria10 we now use Quartus 15.0 and device family of UniBoard2 v0 and the IP for that is kept in:
+
+ ${RADIOHDL_WORK}/libraries/technology/ip_arria10/
+
+This can be renamed in:
+
+ ${RADIOHDL_WORK}/libraries/technology/ip_arria10_device_10AX115U4F45I3SGES_quartus_15.0/
+
+For a directory name it is allowed to use a '.' instead of a '_'. The directory name is not mandatory, but the name convention is
+to define the FPGA technology as a triplet:
+
+ ip__device__quartus_
+
+A future version of the IP can be kept in:
+
+ ${RADIOHDL_WORK}/libraries/technology/ip_arria10_device_10AX115U4F45I3SGES_quartus_16.0/
+
+The technology_pkg.vhd then gets;
+
+ c_tech_arria10_device_10AX115U4F45I3SGES_quartus_14_1 = ...;
+ c_tech_arria10_device_10AX115U4F45I3SGES_quartus_15_0 = ...;
+ c_tech_arria10 = c_tech_arria10_device_10AX115U4F45I3SGES_quartus_15_0; -- optional default
+
+The hdllib.cfg of the specific technology IP library then has key (only one value):
+
+ hdl_lib_technology = ip_arria10_device_10AX115U4F45I3SGES_quartus_15_0
+
+The hdl_buildset_.cfg can support multiple technologies eg. to be able to simulate a system with more than one FPGA that are
+of different technology (eg. an application with Uniboard1 and Uniboard2):
+
+ technology_names = ip_stratixiv
+ ip_arria10_device_10AX115U4F45I3SGES_quartus_15_0
+
+All libraries that have hdl_lib_technology value that is not in the list of technology_names are removed from the dictionary list
+by hdl_config.py, so these IP libraries will not be build.
+
+The build directory currently contains:
+
+ //
+
+This scheme is probably still sufficent to also support the FPGA technology as a triplet. However it may be necessary to rename the
+library key values in the IP hdllib.cfg to contain the full triplet information, so eg.
+
+ hdl_lib_name = ip_arria10_fifo
+ hdl_library_clause_name = ip_arria10_fifo_lib
+
+then becomes:
+
+ hdl_lib_name = ip_arria10_device_10AX115U4F45I3SGES_quartus_15_0_fifo
+ hdl_library_clause_name = ip_arria10_device_10AX115U4F45I3SGES_quartus_15_0_fifo_lib
+
+this is a bit awkward. If only one Quartus version and only one device type are supported per buildset, then all these versions can keep
+the same basic hdl_lib_name and hdl_library_clause_name because the IP libraries that are not used can be removed from the build.
+Alternatively the hdllib_config.py could support multiple technology version IP libraries that use the same logical library name and use
+clause.
+
+The purpose is to be able to handle in parallel different FPGA vendors, different FPGA types and different tool version. We do not have
+to support all combinations, but only the combinations that we actually use. Eg. for the FPGA type this implies that we only support the FPGA types
+that are actually used on our board. If we make a new board with another FPGA, then we add the technology triplet for that FPGA.
+
+
+g) Improve buildset scheme
+
+The buildset defines the combination of Modelsim version and Quartus version. Currently there are buildsets 'unb1', 'unb2' and 'unb2a'. This
+buildset scheme can be improved because:
+
+- for python they are defined by the hdl_buildset_.cfg, but for the run_* bash scripts they are defined in set_quartus,
+ can they be defined in a common source (eg. base on hdl_buildset_.cfg set an environment variable and uses that for bash). The bash
+ script must then be ran from the same terminal as where the python config script was used to set the environment variable, because otherwise
+ the environment variable is not set or may not be correct.
+- the buildsets are tight to a board name 'unb1' (is that oke?) or should we use more general buildset names, or do we need a symbolic buildset names at all?
+- there is also a 'site' level in the bash scripts set_quartus (is that still needed?)
+
+
+h) Declare IP libraries to ensure default binding in simulation.
+
+Currently the IP library is declared in the technology VHDL file e.g. like 'LIBRARY ip_arria10_ddr4_4g_1600_altera_emif_150;' in tech_ddr_arria10.vhd.
+This IP library clause is ignored by synthesis. The IP library must be mapped for simulation, because otherwise Modelsim gives
+an error when it compiles the VHDL. Therefore the IP library can then not be excluded for simulation with 'hdl_lib_include_ip' key.
+Alternatively the LIBRARY clause could be omitted if the IP library is added to the -L libraries search list of each simulation configuration the
+Modelsim project file. This can be achieved adding the IP library to the modelsim_search_libraries key in the hdl_buildset_unb2.cfg. However the problem is
+then that if the IP library is not mapped to a directory then Modelsim will issue an error when it tries to search it.
+--> For now keep the 'hdl_lib_include_ip' but only use it for synthesis. For simulation the 'hdl_lib_include_ip' is ignored. Which is fine because
+ for simulation there is no need to exclude IP libraries.
+
+
+
+101) More ideas
+
+a) zip scripts
+ A zip script can gather all sources that are needed for a particular RadioHDL view point, eg.
+
+ - zip all required libraries for a certain level library --> useful for somebody who wants to reuse a HDL library.
+ - zip all code necessary to run Python test cases on HW target --> useful for somebody who only wants to use the HW.
+ - zip all tool environent code --> useful for somebody who wants to use our tool flow but not our HDL.
+
+ Related to this is (how) can we more clearly divide up the RadioHDL/ directory to eg. reuse only parts of it and
+ to develop these in other locations/repositories (eg. GIT). Eg. the applications/ directory may not be needed or
+ even suitable in RadioHDL/ because applications could be kept elsewhere, even in another repository at another
+ institute.
+
+b) support dynamic generation of IP
+ Very preliminary ideas:
+ Currently the MegaWizard or QSYS component description file is fixed and created manually in advance via the
+ GUI. In future the component description file could be created based on parameters that are defined in the
+ hdllib.cfg or even parameters that depend on the requirements from the design. In a dynamic flow the hdllib.cfg
+ for IP could even not exist as a file, but only as a dictionary in the script.
+
+c) Link RadioHDL developments with the OneClick MyHDL developments.
+ The hdllib.cfg dictionary format seems useful also in the OneClick flow. For some created libraries the hdllib.cfg
+ may not exist as a file and but only as the dictionary in the script. The various methods in modelsim_config.py
+ and quartus_config.py can also be reused in a OneClick flow.
+
+
+102) Know errors
+
+a) ** Fatal: Error occurred in protected context. when loading a simulation in Modelsim
+ - Example:
+ # Loading ip_stratixiv_phy_xaui_lib.ip_stratixiv_phy_xaui_0(rtl)
+ # ** Fatal: Error occurred in protected context.
+ # Time: 0 fs Iteration: 0 Instance: /tb_<...>//ip_stratixiv_phy_xaui_0_inst////// File: nofile
+ # FATAL ERROR while loading design
+
+ Make sure that the StratixIV IP search libraries are defined by modelsim_search_libraries in the hdl_buildset_.cfg.
Index: radiohdl/trunk/ise/hdl_libraries_ip_virtex4.txt
===================================================================
--- radiohdl/trunk/ise/hdl_libraries_ip_virtex4.txt (nonexistent)
+++ radiohdl/trunk/ise/hdl_libraries_ip_virtex4.txt (revision 4)
@@ -0,0 +1,19 @@
+# Used by modelsim_config.py to create library paths in the HDL library project files
+# VHDL
+unisim = $MODEL_TECH_XILINX_LIB/vhdl/unisim
+unimacro = $MODEL_TECH_XILINX_LIB/vhdl/unimacro
+simprim = $MODEL_TECH_XILINX_LIB/vhdl/simprim
+xilinxcorelib = $MODEL_TECH_XILINX_LIB/vhdl/XilinxCoreLib
+secureip = $MODEL_TECH_XILINX_LIB/vhdl/secureip
+aim = $MODEL_TECH_XILINX_LIB/vhdl/abel/aim
+pls = $MODEL_TECH_XILINX_LIB/vhdl/abel/pls
+cpld = $MODEL_TECH_XILINX_LIB/vhdl/cpld
+
+# Verilog
+unisims_ver = $MODEL_TECH_XILINX_LIB/verilog/unisims_ver
+unimacro_ver = $MODEL_TECH_XILINX_LIB/verilog/unimacro_ver
+uni9000_ver = $MODEL_TECH_XILINX_LIB/verilog/uni9000_ver
+simprims_ver = $MODEL_TECH_XILINX_LIB/verilog/simprims_ver
+xilinxcorelib_ver = $MODEL_TECH_XILINX_LIB/verilog/XilinxCoreLib_ver
+aim_ver = $MODEL_TECH_XILINX_LIB/verilog/aim_ver
+cpld_ver = $MODEL_TECH_XILINX_LIB/verilog/cpld_ver
Index: radiohdl/trunk/ise/ise_generic.sh
===================================================================
--- radiohdl/trunk/ise/ise_generic.sh (nonexistent)
+++ radiohdl/trunk/ise/ise_generic.sh (revision 4)
@@ -0,0 +1,48 @@
+#!/bin/bash
+###############################################################################
+#
+# Copyright (C) 2014
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+###############################################################################
+
+echo "Run ise_generic.sh"
+
+# Derive generic ISE tool version related paths from $ISE_DIR that gets defined in ise_version.sh
+
+# Add to the $PATH, only once to avoid double entries
+pathadd ${ISE_DIR}/bin/lin
+
+#WARNING:Place:957 - Placer has detected that XIL_PLACE_ALLOW_LOCAL_BUFG_ROUTING has been set. This environment variable
+# has been deprecated. An ERROR in clock placement rules can be demoted to a WARNING by using the CLOCK_DEDICATED_ROUTE
+# constraint on a specific component pin in the .ucf file.
+
+#set XIL_PLACE_ALLOW_LOCAL_BUFG_ROUTING=1
+
+# ERROR:Pack:1653 - At least one timing constraint is impossible to meet because
+# component delays alone exceed the constraint. A timing constraint summary
+# below shows the failing constraints (preceded with an Asterisk (*)). Please
+# use the Timing Analyzer (GUI) or TRCE (command line) with the Mapped NCD and
+# PCF files to identify which constraints and paths are failing because of the
+# component delays alone. If the failing path(s) is mapped to Xilinx components
+# as expected, consider relaxing the constraint. If it is not mapped to
+# components as expected, re-evaluate your HDL and how synthesis is optimizing
+# the path. To allow the tools to bypass this error, set the environment
+# variable XIL_TIMING_ALLOW_IMPOSSIBLE to 1.
+
+set XIL_TIMING_ALLOW_IMPOSSIBLE=1
+
radiohdl/trunk/ise/ise_generic.sh
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/ise/ise_version.sh
===================================================================
--- radiohdl/trunk/ise/ise_version.sh (nonexistent)
+++ radiohdl/trunk/ise/ise_version.sh (revision 4)
@@ -0,0 +1,30 @@
+#!/bin/bash
+###############################################################################
+#
+# Copyright (C) 2016
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+###############################################################################
+
+ISE_VERSION=${1}
+echo "Select ISE version: ${ISE_VERSION}"
+
+# Set path to ISE version
+export ISE_DIR=/home/software/Xilinx/ISE/${ISE_VERSION}/ISE
+
+# Select the path to the technology libraries that is used in the [libraries] section of the modelsim.ini
+export MODEL_TECH_XILINX_LIB=/home/software/modelsim_xilinx_libs/ise/${ISE_VERSION}
radiohdl/trunk/ise/ise_version.sh
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: radiohdl/trunk/ise/run_impact
===================================================================
--- radiohdl/trunk/ise/run_impact (nonexistent)
+++ radiohdl/trunk/ise/run_impact (revision 4)
@@ -0,0 +1,30 @@
+#!/bin/bash
+###############################################################################
+#
+# Copyright (C) 2016
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+###############################################################################
+
+# General tool and project settings
+# - use '.
© copyright 1999-2024
OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.