Skip to content

Commit

Permalink
Allow Tuple List Variable in INST
Browse files Browse the repository at this point in the history
  • Loading branch information
Teddy-van-Jerry committed Mar 23, 2024
1 parent 8dfe879 commit 7781d46
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "pytv"
description = "Python Templated Verilog"
repository = "https://github.com/autohdw/pytv"
authors = ["Teddy van Jerry <[email protected]>"]
version = "0.3.0"
version = "0.3.1"
readme = "README.md"
license = "GPL-3.0-or-later"
keywords = ["verilog", "python", "template", "generation"]
Expand Down
16 changes: 16 additions & 0 deletions examples/test.pytv
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,33 @@ Do nothing here!
Do nothing here either! { some content }
//! a = 2
`1 + 2` and how about here ` a * 2 `
//! dyn_ports = [
//! ("portA", "wire_a"),
//! ("portB", "wire_b"),
//! ("portC", "wire_c"),
//! ]
//! dyn_vparams = []
//! for i in range(4):
//! dyn_vparams.append((f"param{i}", i))
//! value_M = 32
//! dyn_parameters = []
//! for i in range(2):
//! dyn_parameters.append((f"name{i+10}", i + 10))
//! <INST>
//! module: test
//! name: inst_test
//! vparams:
//! N: 8
//! !mystery: dyn_vparams
//! M: `value_M`
//! parameters:
//! name1: value1
//! name2: value2
//! name`1+2`: `a`
//! !other_parameters: dyn_parameters
//! ports:
//! port1: net1
//! !other_name: dyn_ports
//! </INST>
wire x;
assign x = y;
Expand Down
13 changes: 12 additions & 1 deletion src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,18 @@ impl Convert {
#[cfg(feature = "inst")]
writeln!(
stream,
"_inst_file = open('{}', 'w')",
concat!(
"_inst_file = open('{}', 'w')\n",
"def _inst_var_map(tuples):\n",
" s = ['%s: %s\\n' % tuple for tuple in tuples]\n",
" return ' '.join(s)\n\n",
"def _verilog_ports_var_map(tuples, first_port):\n",
" s = [' .%s(%s)' % tuple for tuple in tuples]\n",
" return ('' if first_port else ',\\n') + ',\\n'.join(s)\n\n",
"def _verilog_vparams_var_map(tuples, first_vparam):\n",
" s = ['\\n parameter %s = %s' % tuple for tuple in tuples]\n",
" return ('#(' if first_vparam else ',') + ','.join(s)\n\n",
),
self.output_inst_file_name()
)?;
let mut line_type = LineType::default();
Expand Down
108 changes: 82 additions & 26 deletions src/inst.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::Convert;
use regex::{self, Regex};
use std::error::Error;
use std::io::Write;

Expand Down Expand Up @@ -65,11 +66,34 @@ impl Convert {
}
}

fn apply_protected_inst_group_regex(inst_str: &str) -> String {
let re = Regex::new(r"!(\w+):(.*)[\r\n$]").unwrap();
re.replace_all(inst_str, "__group_$1:$2\n").to_string()
}

fn inst_group_print_to_dot_inst(inst_str: &str) -> String {
let re = Regex::new(r"__group_\w+:\s*(.*)[\r\n$]").unwrap();
re.replace_all(
inst_str,
"''')\n_inst_file.write(f'{_inst_var_map($1)}')\n_inst_file.write(f'''",
)
.to_string()
}

fn print_inst<W: Write>(&self, stream: &mut W, inst_str: &str) -> Result<(), Box<dyn Error>> {
print!(
"{}",
Self::apply_protected_inst_group_regex(inst_str).as_str()
);
let inst_map: serde_yaml::Value =
serde_yaml::from_str(&self.apply_protected_verilog_regex(inst_str))?;
serde_yaml::from_str(&self.apply_protected_verilog_regex(
Self::apply_protected_inst_group_regex(inst_str).as_str(),
))?;
let mut inst_str_parsed = serde_yaml::to_string(&vec![&inst_map])?;
inst_str_parsed = self.undo_protected_brackets(inst_str_parsed.as_str());
inst_str_parsed = Self::inst_group_print_to_dot_inst(
self.undo_protected_brackets(inst_str_parsed.as_str())
.as_str(),
);
// print to .inst
writeln!(stream, "_inst_file.write(f'''{}''')", inst_str_parsed)?;
// print to .v
Expand All @@ -86,18 +110,32 @@ impl Convert {
for (key, value) in vparams.iter() {
if let (Some(key_str), Some(value_str)) = (key.as_str(), yaml_value_as_str(value)) {
let value_str = value_str.as_str();
writeln!(
stream,
"print(f'{}\\n parameter {} = {}')",
if first_vparam {
first_vparam = false;
"#("
} else {
","
},
self.escape_single_quote(self.undo_protected_brackets(key_str).as_str()),
self.escape_single_quote(self.undo_protected_brackets(value_str).as_str())
)?;
if key_str.starts_with("__group_") {
writeln!(
stream,
"print(_verilog_vparams_var_map({}, {}), end='')",
value_str,
if first_vparam {
first_vparam = false;
"True"
} else {
"False"
},
)?;
} else {
writeln!(
stream,
"print(f'{}\\n parameter {} = {}', end='')",
if first_vparam {
first_vparam = false;
"#("
} else {
","
},
self.escape_single_quote(self.undo_protected_brackets(key_str).as_str()),
self.escape_single_quote(self.undo_protected_brackets(value_str).as_str())
)?;
}
} else {
return Err("Invalid vparams found in the <INST>.".into());
}
Expand All @@ -120,18 +158,36 @@ impl Convert {
for (key, value) in ports.iter() {
if let (Some(key_str), Some(value_str)) = (key.as_str(), yaml_value_as_str(value)) {
let value_str = value_str.as_str();
writeln!(
stream,
"print(f'{} .{}({})', end='')",
if first_port {
first_port = false;
""
} else {
",\\n"
},
self.escape_single_quote(self.undo_protected_brackets(key_str).as_str()),
self.escape_single_quote(self.undo_protected_brackets(value_str).as_str())
)?;
if key_str.starts_with("__group_") {
writeln!(
stream,
"print(_verilog_ports_var_map({}, {}), end='')",
value_str,
if first_port {
first_port = false;
"True"
} else {
"False"
},
)?;
} else {
writeln!(
stream,
"print(f'{} .{}({})', end='')",
if first_port {
first_port = false;
""
} else {
",\\n"
},
self.escape_single_quote(
self.undo_protected_brackets(key_str).as_str()
),
self.escape_single_quote(
self.undo_protected_brackets(value_str).as_str()
)
)?;
}
}
}
}
Expand Down

0 comments on commit 7781d46

Please sign in to comment.