diff --git a/src/cmd/script.rs b/src/cmd/script.rs index 847563059..87ef56966 100644 --- a/src/cmd/script.rs +++ b/src/cmd/script.rs @@ -34,6 +34,10 @@ pub struct ScriptArgs { #[arg(short = 'D', long, action = ArgAction::Append, global = true, help_heading = "General Script Options")] pub define: Vec, + /// Add an include directory + #[arg(short = 'I', long, action = ArgAction::Append, global = true, help_heading = "General Script Options")] + pub incdir: Vec, + /// Remove source annotations from the generated script #[arg(long, help_heading = "General Script Options")] pub no_source_annotations: bool, @@ -179,6 +183,12 @@ pub enum ScriptFormat { #[arg(long, action = ArgAction::Append, alias = "vcom-arg")] vcom_args: Vec, }, + /// Cadence Xcelium script + Xcelium { + /// Use relative paths + #[arg(long)] + relative_path: bool, + }, /// Cadence Genus script Genus, /// Xilinx Vivado synthesis script @@ -246,6 +256,7 @@ pub fn run(sess: &Session, args: &ScriptArgs) -> Result<()> { ScriptFormat::Synopsys { .. } => vec!["synopsys", "synthesis"], ScriptFormat::Formality => vec!["synopsys", "synthesis", "formality"], ScriptFormat::Riviera { .. } => vec!["riviera", "simulation"], + ScriptFormat::Xcelium { .. } => vec!["xcelium", "simulation"], ScriptFormat::Genus => vec!["genus", "synthesis"], ScriptFormat::Vivado { .. } => concat(vivado_targets, &["synthesis"]), ScriptFormat::VivadoSim { .. } => concat(vivado_targets, &["simulation"]), @@ -366,6 +377,10 @@ pub fn run(sess: &Session, args: &ScriptArgs) -> Result<()> { tera_context.insert("vcom_args", vcom_args); include_str!("../script_fmt/riviera_tcl.tera") } + ScriptFormat::Xcelium { relative_path } => { + tera_context.insert("relativize_path", relative_path); + include_str!("../script_fmt/xcelium_f.tera") + } ScriptFormat::Genus => include_str!("../script_fmt/genus_tcl.tera"), ScriptFormat::Vivado { no_simset, only } | ScriptFormat::VivadoSim { no_simset, only } => { only_args = only.clone(); @@ -478,8 +493,13 @@ fn emit_template( tera_context.insert("all_defines", &all_defines); all_incdirs.sort(); + let user_incdirs: Vec = args.incdir.iter().map(PathBuf::from).collect(); let all_incdirs: IndexSet = if emit_incdirs { - all_incdirs.into_iter().map(|p| p.to_path_buf()).collect() + all_incdirs + .into_iter() + .map(|p| p.to_path_buf()) + .chain(user_incdirs.iter().cloned()) + .collect() } else { IndexSet::new() }; @@ -530,6 +550,7 @@ fn emit_template( .iter() .map(|p| p.to_path_buf()) .collect::>(); + incdirs.extend(user_incdirs.iter().cloned()); incdirs.sort(); incdirs }, diff --git a/src/script_fmt/xcelium_f.tera b/src/script_fmt/xcelium_f.tera new file mode 100644 index 000000000..4efe4e3a9 --- /dev/null +++ b/src/script_fmt/xcelium_f.tera @@ -0,0 +1,13 @@ +# {{ HEADER_AUTOGEN }} +{%- for group in srcs %} +{% if source_annotations %}# {{ group.metadata }}{% endif %} +{%- for incdir in group.incdirs %} ++incdir+{% if relativize_path and incdir is starting_with(root) %}{{ incdir | replace(from=root, to='$ROOT') }}{% else %}{{ incdir }}{% endif %} +{%- endfor %} +{%- for define in group.defines %} ++define+{{ define.0 }}{% if define.1 %}={{ define.1 }}{% endif %} +{%- endfor %} +{%- for file in group.files %} +{% if relativize_path and file is starting_with(root) %}{{ file | replace(from=root, to='$ROOT') }}{% else %}{{ file }}{% endif %} +{%- endfor %} +{%- endfor %}