Skip to content

Commit 4efc739

Browse files
committed
Add optional parametrization for "reg" keyword
1 parent 12e4d3b commit 4efc739

15 files changed

Lines changed: 8476 additions & 7166 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "sus_compiler"
33
description = "Compiler for the SUS Hardware Design Language"
4-
version = "0.4.0"
4+
version = "0.5.0-dev"
55
authors = ["Lennart Van Hirtum <lennart.vanhirtum@gmail.com>"]
66
license = "GPL-3.0-or-later"
77
repository = "https://github.com/pc2/sus-compiler"
@@ -42,9 +42,9 @@ pulldown-cmark = { version = "0.13", default-features = false, features = ["html
4242

4343
# Tree sitter
4444
tree-sitter = "0.26.6"
45-
tree-sitter-sus = {version = "~0.4.0", path = "./tree-sitter-sus"}
45+
tree-sitter-sus = {version = "~0.5.0-dev", path = "./tree-sitter-sus"}
4646

47-
sus-proc-macro = {version = "~0.4.0", path = "./sus-proc-macro"}
47+
sus-proc-macro = {version = "~0.5.0-dev", path = "./sus-proc-macro"}
4848

4949
# calyx-ir = {version = "0.6.1", optional = true}
5050
# calyx-opt = {version = "0.6.1", optional = true}

src/flattening/flatten.rs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,36 +1690,61 @@ impl<'l, 'c: 'l> FlatteningContext<'l, '_> {
16901690
self.alloc_local_name(clock_name_span, clock_name, NamedLocal::ClockDecl(clock_id));
16911691
}
16921692

1693-
fn flatten_write_modifiers(&self, cursor: &mut Cursor<'c>) -> WriteModifiers {
1693+
fn flatten_reg_modifier(&mut self, cursor: &mut Cursor<'c>) -> RegExpression {
1694+
let whole_span = cursor.span();
1695+
cursor.go_down(kind!("reg_modifier"), move |cursor| {
1696+
let reg_parameter = if cursor.optional_field(field!("reg_param")) {
1697+
let bracket_span = BracketSpan::from_outer(cursor.span());
1698+
cursor.go_down_content(kind!("parenthesis_expression"), move |cursor| {
1699+
let expr_id = self.flatten_subexpr(cursor);
1700+
Some((expr_id, bracket_span))
1701+
})
1702+
} else {
1703+
None
1704+
};
1705+
RegExpression {
1706+
whole_span,
1707+
reg_parameter,
1708+
}
1709+
})
1710+
}
1711+
1712+
fn flatten_write_modifiers(&mut self, cursor: &mut Cursor<'c>) -> WriteModifiers {
16941713
if cursor.optional_field(field!("write_modifiers")) {
1695-
let modifiers_span = cursor.span();
1696-
let mut initial_count = 0;
1697-
let mut reg_count = 0;
1714+
let mut initial_kw_span: Option<Span> = None;
1715+
let mut regs: Vec<RegExpression> = Vec::new();
16981716
cursor.list(kind!("write_modifiers"), |cursor| {
16991717
let kw_kind = cursor.kind();
1700-
if kw_kind == kw!("reg") {
1701-
reg_count += 1;
1718+
if kw_kind == kind!("reg_modifier") {
1719+
regs.push(self.flatten_reg_modifier(cursor));
17021720
} else if kw_kind == kw!("initial") {
1703-
initial_count += 1;
1721+
let span = cursor.span();
1722+
if let Some(prev_kw) = initial_kw_span {
1723+
self.errors
1724+
.error(span, "This write already has an 'initial' keyword")
1725+
.info(prev_kw, "Previous 'initial' keyword");
1726+
} else {
1727+
initial_kw_span = Some(span);
1728+
}
17041729
} else {
17051730
unreachable!()
17061731
}
17071732
});
1708-
match (initial_count, reg_count) {
1709-
(0, num_regs) => WriteModifiers::Connection {
1710-
num_regs,
1711-
regs_span: modifiers_span,
1712-
},
1713-
(1, 0) => WriteModifiers::Initial {
1714-
initial_kw_span: modifiers_span,
1715-
},
1716-
_other => unreachable!(),
1733+
if let Some(initial_kw_span) = initial_kw_span {
1734+
for r in &regs {
1735+
self.errors
1736+
.error(
1737+
r.whole_span,
1738+
"Cannot both place pipeline regs on an 'initial' write.",
1739+
)
1740+
.info(initial_kw_span, "'Initial' keyword used here");
1741+
}
1742+
WriteModifiers::Initial { initial_kw_span }
1743+
} else {
1744+
WriteModifiers::Connection { regs }
17171745
}
17181746
} else {
1719-
WriteModifiers::Connection {
1720-
num_regs: 0,
1721-
regs_span: cursor.span().empty_span_at_front(),
1722-
}
1747+
WriteModifiers::Connection { regs: Vec::new() }
17231748
}
17241749
}
17251750

src/flattening/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,12 @@ impl WireReference {
401401
}
402402
}
403403

404+
#[derive(Debug)]
405+
pub struct RegExpression {
406+
pub whole_span: Span,
407+
pub reg_parameter: Option<(FlatID, BracketSpan)>,
408+
}
409+
404410
/// In a [Write], this represents what kind of write it is, based on keywords `reg` or `initial`
405411
#[derive(Debug)]
406412
pub enum WriteModifiers {
@@ -409,7 +415,7 @@ pub enum WriteModifiers {
409415
/// int v
410416
/// reg reg v = a * 3
411417
/// ```
412-
Connection { num_regs: i64, regs_span: Span },
418+
Connection { regs: Vec<RegExpression> },
413419
/// Set the initial value of a `state` register
414420
/// ```sus
415421
/// state int count

src/flattening/typecheck/clock_check.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ impl<'l> TypeCheckingContext<'l> {
9494
.unwrap_or(Physical(ClockID::UNKNOWN));
9595
let mut target_span = wr.to.root_span;
9696

97-
match wr.write_modifiers {
98-
WriteModifiers::Connection { .. } => {
97+
match &wr.write_modifiers {
98+
WriteModifiers::Connection { regs } => {
9999
if let Some(condition_domain) =
100100
self.get_condition_domain(expr.parent_condition)
101101
&& let Physical(target_phys) = &mut target_domain
@@ -108,10 +108,18 @@ impl<'l> TypeCheckingContext<'l> {
108108
"the runtime condition",
109109
);
110110
}
111+
for r in regs {
112+
if let Some(param) = r.reg_parameter {
113+
self.must_be_generative(
114+
param.0,
115+
"the number of pipeline regs parameter",
116+
);
117+
}
118+
}
111119
}
112120
WriteModifiers::Initial { initial_kw_span } => {
113121
target_domain = Generative;
114-
target_span = initial_kw_span;
122+
target_span = *initial_kw_span;
115123
}
116124
}
117125
wr.target_domain.set_initial(target_domain);

src/instantiation/execute.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -863,16 +863,25 @@ impl<'l> ExecutionContext<'l> {
863863
domain: ClockID,
864864
) -> ExecutionResult<()> {
865865
let_unwrap!(
866-
WriteModifiers::Connection {
867-
num_regs,
868-
regs_span: _,
869-
},
866+
WriteModifiers::Connection { regs },
870867
&write_to.write_modifiers
871868
);
869+
870+
let mut num_regs = 0;
871+
for r in regs {
872+
if let Some(param) = &r.reg_parameter {
873+
num_regs += self
874+
.generation_state
875+
.get_generation_small_int::<i64>(param.0)?;
876+
} else {
877+
num_regs += 1;
878+
}
879+
}
880+
872881
let (target_wire, path) =
873882
self.wire_ref_to_real_path(&write_to.to, original_instruction, domain)?;
874883

875-
self.instantiate_write_to_wire(target_wire, path, from, *num_regs, write_span);
884+
self.instantiate_write_to_wire(target_wire, path, from, num_regs, write_span);
876885
Ok(())
877886
}
878887

src/to_string.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -427,12 +427,17 @@ impl UniCell<ClockDomain> {
427427
impl Display for WriteModifiers {
428428
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
429429
match self {
430-
WriteModifiers::Connection { num_regs, .. } => {
431-
for _ in 0..*num_regs {
432-
f.write_str("reg ")?;
433-
}
434-
Ok(())
435-
}
430+
WriteModifiers::Connection { regs } => write!(
431+
f,
432+
"{}",
433+
display_join(" ", regs.iter(), |f, r| {
434+
f.write_str("reg")?;
435+
if r.reg_parameter.is_some() {
436+
f.write_str("(...)")?;
437+
}
438+
Ok(())
439+
})
440+
),
436441
WriteModifiers::Initial { .. } => f.write_str("initial"),
437442
}
438443
}

sus-proc-macro/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "sus-proc-macro"
33
description = "Proc-macros for use in the sus-compiler"
4-
version = "0.4.0"
4+
version = "0.5.0-dev"
55
authors = ["Lennart Van Hirtum <lennart.vanhirtum@gmail.com>"]
66
license = "GPL-3.0-or-later"
77
repository = "https://github.com/pc2/sus-compiler"
@@ -15,7 +15,7 @@ edition = "2024"
1515

1616
# Tree sitter
1717
tree-sitter = "0.26.6"
18-
tree-sitter-sus = {version = "~0.4.0", path = "../tree-sitter-sus"}
18+
tree-sitter-sus = {version = "~0.5.0-dev", path = "../tree-sitter-sus"}
1919
regex = "1.11.1"
2020

2121
# proc_macro utils

test.sus

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,3 +1888,8 @@ module PositiveAndNegativeLatencyOffset {
18881888
LatencyOffset#(T: type bool, OFFSET: 3) pos
18891889
LatencyOffset#(T: type bool, OFFSET: -3) neg
18901890
}
1891+
1892+
module ParametrizeableRegs {
1893+
int x = 5
1894+
reg(5) int y = x
1895+
}

test.sus_codegen.sv

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test.sus_errors.txt

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)