Skip to content

Commit 2306417

Browse files
authored
Merge branch 'main' into validation
2 parents 43cde4d + 47875b9 commit 2306417

File tree

29 files changed

+1004
-298
lines changed

29 files changed

+1004
-298
lines changed

crates/ast/src/control.rs

Lines changed: 102 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::{
44
use fil_utils::PortAttrs;
55
use struct_variant::struct_variant;
66

7-
#[derive(Clone)]
7+
#[derive(Clone, Debug)]
88
/// Access into a bundle
99
pub struct Access {
1010
pub start: Expr,
@@ -33,76 +33,128 @@ impl From<Expr> for Access {
3333
}
3434
}
3535

36-
/// A port mentioned in the program
37-
// XXX(rachit): the bundle and non-bundle variants can be unified because
38-
// astconv treats them the same anyways.
39-
#[derive(Clone)]
40-
pub enum Port {
41-
/// A port on this component
42-
This(Loc<Id>),
43-
/// A port on an invoke
44-
InvPort { invoke: Loc<Id>, name: Loc<Id> },
45-
/// A port represented by an index into a bundle
46-
Bundle {
47-
name: Loc<Id>,
48-
access: Vec<Loc<Access>>,
49-
},
50-
/// A bundle port on an invocation
51-
InvBundle {
52-
invoke: Loc<Id>,
53-
port: Loc<Id>,
54-
access: Vec<Loc<Access>>,
55-
},
36+
impl std::fmt::Display for Access {
37+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38+
// For now, always show as range. Could add logic to detect single indices.
39+
write!(f, "{}:{}", self.start, self.end)
40+
}
41+
}
42+
43+
/// Unified port representation
44+
#[derive(Clone, Debug)]
45+
pub struct Port {
46+
/// Base port reference
47+
pub base: PortRef,
48+
/// Optional array/bundle access
49+
pub access: Vec<Loc<Access>>,
50+
/// Source location for error reporting
51+
pub loc: fil_utils::GPosIdx,
52+
}
53+
54+
/// Base port reference
55+
#[derive(Clone, Debug, PartialEq)]
56+
pub enum PortRef {
57+
/// Reference to a port on 'this' component
58+
This { port: Loc<Id> },
59+
/// Reference to a port on an instance or invoke
60+
Instance { instance: Loc<Id>, port: Loc<Id> },
5661
}
5762

5863
impl Port {
64+
/// Create a simple port reference (this.port)
65+
pub fn this_port(port: Loc<Id>) -> Self {
66+
let loc = port.pos();
67+
Port {
68+
base: PortRef::This { port },
69+
access: Vec::new(),
70+
loc,
71+
}
72+
}
73+
74+
/// Create an instance port reference (inst.port)
75+
pub fn instance_port(instance: Loc<Id>, port: Loc<Id>) -> Self {
76+
let loc = instance.pos(); // Using first location, could union if needed
77+
Port {
78+
base: PortRef::Instance { instance, port },
79+
access: Vec::new(),
80+
loc,
81+
}
82+
}
83+
84+
/// Add array/bundle access to a port
85+
pub fn with_access(mut self, access: Vec<Loc<Access>>) -> Self {
86+
self.access = access;
87+
self
88+
}
89+
90+
/// Check if this is a bundle access
91+
pub fn is_bundle(&self) -> bool {
92+
!self.access.is_empty()
93+
}
94+
95+
/// Get the instance name if this is an instance port
96+
pub fn instance(&self) -> Option<&Loc<Id>> {
97+
match &self.base {
98+
PortRef::Instance { instance, .. } => Some(instance),
99+
_ => None,
100+
}
101+
}
102+
103+
/// Get the port name
104+
pub fn port_name(&self) -> &Loc<Id> {
105+
match &self.base {
106+
PortRef::This { port } => port,
107+
PortRef::Instance { port, .. } => port,
108+
}
109+
}
110+
111+
// Legacy constructors for backwards compatibility during migration
59112
pub fn inv_port(comp: Loc<Id>, name: Loc<Id>) -> Self {
60-
Port::InvPort { invoke: comp, name }
113+
Self::instance_port(comp, name)
61114
}
62115

63116
pub fn this(p: Loc<Id>) -> Self {
64-
Port::This(p)
117+
Self::this_port(p)
65118
}
66119

67120
pub fn bundle(name: Loc<Id>, access: Vec<Loc<Access>>) -> Self {
68-
Port::Bundle { name, access }
121+
Self::this_port(name).with_access(access)
69122
}
70123

71124
pub fn inv_bundle(
72125
invoke: Loc<Id>,
73126
port: Loc<Id>,
74127
access: Vec<Loc<Access>>,
75128
) -> Self {
76-
Port::InvBundle {
77-
invoke,
78-
port,
79-
access,
129+
Self::instance_port(invoke, port).with_access(access)
130+
}
131+
132+
pub fn resolve_exprs(mut self, bindings: &Binding<Expr>) -> Self {
133+
if !self.access.is_empty() {
134+
self.access = self
135+
.access
136+
.into_iter()
137+
.map(|i| i.map(|i| i.resolve(bindings)))
138+
.collect();
80139
}
140+
self
81141
}
142+
}
82143

83-
pub fn resolve_exprs(self, bindings: &Binding<Expr>) -> Self {
84-
match self {
85-
Port::Bundle { name, access } => Port::Bundle {
86-
name,
87-
access: access
88-
.into_iter()
89-
.map(|i| i.map(|i| i.resolve(bindings)))
90-
.collect(),
91-
},
92-
Port::InvBundle {
93-
invoke,
94-
port,
95-
access,
96-
} => Port::InvBundle {
97-
invoke,
98-
port,
99-
access: access
100-
.into_iter()
101-
.map(|i| i.map(|a| a.resolve(bindings)))
102-
.collect(),
103-
},
104-
_ => self,
144+
impl std::fmt::Display for Port {
145+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146+
match &self.base {
147+
PortRef::This { port } => write!(f, "{}", port),
148+
PortRef::Instance { instance, port } => {
149+
write!(f, "{}.{}", instance, port)
150+
}
151+
}?;
152+
153+
for access in &self.access {
154+
write!(f, "{{{}}}", access)?;
105155
}
156+
157+
Ok(())
106158
}
107159
}
108160

crates/ast/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub use component::{Component, Extern, Namespace};
1616
pub use constraint::{Constraint, OrderConstraint, OrderOp};
1717
pub use control::{
1818
Access, Bundle, BundleType, Command, Connect, Exists, Fact, ForLoop, If,
19-
Instance, Invoke, ParamLet, Port,
19+
Instance, Invoke, ParamLet, Port, PortRef,
2020
};
2121
pub use expr::{Expr, Fn, Op};
2222
pub use fil_utils::Id;

crates/filament/src/cmdline.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ pub struct Opts {
5757
#[argh(option, long = "dump-after")]
5858
pub dump_after: Vec<String>,
5959

60+
/// print out the IR after every pass
61+
#[argh(switch, long = "dump-all")]
62+
pub dump_all: bool,
63+
6064
/// print out assignments that falsify the constraints
6165
#[argh(switch, long = "show-models")]
6266
pub show_models: bool,
@@ -100,15 +104,17 @@ pub struct Opts {
100104
/// backend to use (default: verilog): calyx, verilog
101105
#[argh(option, long = "backend", default = "Backend::Verilog")]
102106
pub backend: Backend,
107+
103108
/// disable generation of counter-based FSMs in the backend.
104109
/// The default (non-counter) FSM is represented by a single bit Shift Register counting through the number of states.
105110
/// However, for components with a large number of states or a large II, it may be more efficient to use a counter-based FSM,
106111
/// where one counter loops every II states, at which point it increments the state counter.
107112
#[argh(switch, long = "no-counter-fsms")]
108113
pub no_counter_fsms: bool,
109-
/// preserves original port names during compilation.
110-
#[argh(switch, long = "preserve-names")]
111-
pub preserve_names: bool,
114+
115+
/// do not preserve original port names during compilation.
116+
#[argh(switch, long = "no-preserve-names")]
117+
pub no_preserve_names: bool,
112118

113119
// Solver specific configuration
114120
/// solver to use (default: cvc5): cvc5, z3

0 commit comments

Comments
 (0)