From 2d6d91d5d9a33b97ce15b64a4f95f793fae0f3f6 Mon Sep 17 00:00:00 2001 From: Michael Rogenmoser Date: Wed, 5 Apr 2023 19:00:20 +0200 Subject: [PATCH] script: Template precision --- src/cmd/script.rs | 150 ++++++++++++---------------------------------- 1 file changed, 38 insertions(+), 112 deletions(-) diff --git a/src/cmd/script.rs b/src/cmd/script.rs index e93a25d8..bb396fc5 100644 --- a/src/cmd/script.rs +++ b/src/cmd/script.rs @@ -344,7 +344,7 @@ pub fn run(sess: &Session, matches: &ArgMatches) -> Result<()> { "genus" => emit_template(sess, GENUS_TCL_TPL, matches, targets, srcs), "vivado" => emit_template(sess, VIVADO_TCL_TPL, matches, targets, srcs), "vivado-sim" => emit_template(sess, VIVADO_TCL_TPL, matches, targets, srcs), - "precision" => emit_precision_tcl(sess, matches, targets, srcs, abort_on_error), + "precision" => emit_template(sess, PRECISION_TCL_TPL, matches, targets, srcs), "template" => { let custom_tpl_path = Path::new(matches.get_one::("template").unwrap()); let custom_tpl_str = @@ -989,114 +989,40 @@ fn emit_riviera_tcl( Ok(()) } -/// Emit a script to add sources to Mentor Precision -fn emit_precision_tcl( - sess: &Session, - matches: &ArgMatches, - targets: TargetSet, - srcs: Vec, - abort_on_error: bool, -) -> Result<()> { - // Find the common_path between session and all source files - let mut file_paths = vec![sess.root]; - for src in &srcs { - for file in &src.files { - let p = match file { - SourceFile::File(p) => p, - _ => continue, - }; - file_paths.push(p) - } - } - let root = common_path_all(file_paths).unwrap(); - - // Print the script header - println!("# {}", HEADER_AUTOGEN); - println!("# Precision does not take relative paths into account when specifying include dirs."); - println!("# Define the common ROOT anyway if needed for patching file paths. "); - println!("set ROOT {}", root.to_str().unwrap()); - println!("set_input_dir $ROOT"); - println!("setup_design -search_path $ROOT"); - - // Find all the include dirs as precision only allows to set these globally - let mut defines: Vec<(String, Option)> = vec![]; - for src in &srcs { - defines.extend( - src.defines - .iter() - .map(|(k, &v)| (k.to_string(), v.map(String::from))), - ); - } - defines.extend( - targets - .iter() - .map(|t| (format!("TARGET_{}", t.to_uppercase()), None)), - ); - add_defines_from_matches(&mut defines, matches); - defines.sort(); - if !defines.is_empty() { - let mut lines = vec!["setup_design -defines { \\".to_owned()]; - for (k, v) in defines { - let mut s = format!(" +define+{}", k); - if let Some(v) = v { - s.push('='); - s.push_str(&v); - } - s.push_str(" \\"); - lines.push(s); - } - lines.push("}".to_owned()); - println!("\n# Set globally all defines for the (S)Verilog sources."); - println!("{}", lines.join("\n")); - } - - // Add the source files depending on group - for src in srcs { - separate_files_in_group( - src, - |f| match f { - SourceFile::File(p) => match p.extension().and_then(std::ffi::OsStr::to_str) { - Some("sv") | Some("v") | Some("vp") => Some(SourceType::Verilog), - Some("vhd") | Some("vhdl") => Some(SourceType::Vhdl), - _ => None, - }, - _ => None, - }, - |src, ty, files| { - let mut lines = vec![]; - match ty { - SourceType::Verilog => { - lines.push(tcl_catch_prefix("add_input_file", abort_on_error)); - lines.push("-format SystemVerilog2012".to_owned()); - if !src.clone().get_incdirs().is_empty() { - lines.push("-search_path {".to_owned()); - for i in src.clone().get_incdirs() { - lines.push(format!(" {}", i.to_str().unwrap())); - } - lines.push("}".to_owned()); - } - } - SourceType::Vhdl => { - lines.push(tcl_catch_prefix("add_input_file", abort_on_error)); - lines.push("-format vhdl_2008".to_owned()); - } - } - lines.push("{".to_owned()); - for file in files { - let p = match file { - SourceFile::File(p) => p, - _ => continue, - }; - lines.push(format!(" {}", p.to_str().unwrap())); - } - lines.push("} \\".to_owned()); - println!(); - println!("{}", lines.join(" \\\n ")); - if abort_on_error { - println!("{}", tcl_catch_postfix()); - } - }, - ); - } - Ok(()) -} +static PRECISION_TCL_TPL: &str = "\ +# {{ HEADER_AUTOGEN }} +# Precision does not take relative paths into account when specifying include dirs. +# Define the common ROOT anyway if needed for patching file paths. +set ROOT {{ root }} +set_input_dir $ROOT +setup_design -search_path $ROOT +{% for define in all_defines %}\ + {% if loop.first %}\ + \n# Set globally all defines for the (S)Verilog sources.\n\ + setup_design -defines { \\\n {% endif %}\ + +define+{{ define.0 | upper }}{% if define.1 %}={{ define.1 }}{% endif %}\ + {% if loop.last %}\n\n{% else %} \\\n {% endif %}\ +{% endfor %}\ +{% for group in srcs %}\ + {% if abort_on_error %}if {[catch { {% endif %}\ + add_input_file \\\n \ + {% if group.file_type == 'verilog' %}\ + -format SystemVerilog2012 \\\n \ + {% for incdir in group.incdirs %}\ + {% if loop.first %}-search_path { \\\n {% endif %}\ + {{ incdir }}\ + {% if loop.last %} \\\n } \\\n {% else %} \\\n {% endif %}\ + {% endfor %}\ + {% elif group.file_type == 'vhdl' %}\ + -format vhdl_2008 \\\n \ + {% endif %}\ + { \\\n \ + {% for file in group.files %}\ + {{ file }}\ + {% if loop.last %} \\\n {% else %} \\\n {% endif %}\ + {% endfor %}\ + } \\\n\ + {% if abort_on_error %}}]} {return 1}\n\ + {% endif %}\n\ +{% endfor %}\n\ +";