///|
pub(all) enum Direction {
Input
Output
Inout
Unspecified
} derive(Eq, Debug)
///|
pub(all) enum NetType {
Wire
Reg
Logic
Unspecified
} derive(Eq, Debug)
///|
pub(all) struct Range {
msb : Int
lsb : Int
span : @source.Span
} derive(Eq, Debug)
///|
pub fn Range::new(msb : Int, lsb : Int, span : @source.Span) -> Range {
{ msb, lsb, span }
}
///|
pub fn Range::width(self : Range) -> Int? {
let distance = if self.msb >= self.lsb {
self.msb - self.lsb + 1
} else {
self.lsb - self.msb + 1
}
if distance > 0 {
Some(distance)
} else {
None
}
}
///|
pub(all) struct Port {
name : String
direction : Direction
width : Range?
span : @source.Span
} derive(Eq, Debug)
///|
pub fn Port::new(
name : String,
direction : Direction,
width : Range?,
span : @source.Span,
) -> Port {
{ name, direction, width, span }
}
///|
pub(all) struct Signal {
name : String
net_type : NetType
width : Range?
span : @source.Span
} derive(Eq, Debug)
///|
pub fn Signal::new(
name : String,
net_type : NetType,
width : Range?,
span : @source.Span,
) -> Signal {
{ name, net_type, width, span }
}
///|
pub(all) enum Expression {
Name(String, @source.Span)
Number(String, @source.Span)
StringLiteral(String, @source.Span)
Unary(String, Expression, @source.Span)
Binary(Expression, String, Expression, @source.Span)
Index(Expression, Expression, @source.Span)
Unknown(@source.Span)
} derive(Eq, Debug)
///|
pub fn Expression::name(name : String, span : @source.Span) -> Expression {
Name(name, span)
}
///|
pub fn Expression::number(value : String, span : @source.Span) -> Expression {
Number(value, span)
}
///|
pub fn Expression::string(value : String, span : @source.Span) -> Expression {
StringLiteral(value, span)
}
///|
pub fn Expression::binary(
left : Expression,
operator : String,
right : Expression,
span : @source.Span,
) -> Expression {
Binary(left, operator, right, span)
}
///|
pub fn Expression::span(self : Expression) -> @source.Span {
match self {
Name(_, span) => span
Number(_, span) => span
StringLiteral(_, span) => span
Unary(_, _, span) => span
Binary(_, _, _, span) => span
Index(_, _, span) => span
Unknown(span) => span
}
}
///|
pub(all) struct ContinuousAssign {
target : Expression
value : Expression
span : @source.Span
} derive(Eq, Debug)
///|
pub fn ContinuousAssign::new(
target : Expression,
value : Expression,
span : @source.Span,
) -> ContinuousAssign {
{ target, value, span }
}
///|
pub(all) enum EdgeKind {
Any
Posedge
Negedge
} derive(Eq, Debug)
///|
pub(all) struct Sensitivity {
edge : EdgeKind
expression : Expression
span : @source.Span
} derive(Eq, Debug)
///|
pub(all) struct CaseArm {
choices : Array[Expression]
body : Statement
span : @source.Span
} derive(Eq, Debug)
///|
pub(all) enum Statement {
Empty(@source.Span)
Block(Array[Statement], @source.Span)
Assignment(Expression, Expression, Bool, @source.Span)
If(Expression, Statement, Statement?, @source.Span)
Case(Expression, Array[CaseArm], @source.Span)
Unknown(@source.Span)
} derive(Eq, Debug)
///|
pub fn Statement::span(self : Statement) -> @source.Span {
match self {
Empty(span) => span
Block(_, span) => span
Assignment(_, _, _, span) => span
If(_, _, _, span) => span
Case(_, _, span) => span
Unknown(span) => span
}
}
///|
pub(all) struct AlwaysBlock {
sensitivity : Array[Sensitivity]
body : Statement
span : @source.Span
} derive(Eq, Debug)
///|
pub(all) struct Connection {
port_name : String?
expression : Expression
span : @source.Span
} derive(Eq, Debug)
///|
pub(all) struct Instance {
module_name : String
instance_name : String
connections : Array[Connection]
span : @source.Span
} derive(Eq, Debug)
///|
pub(all) enum ModuleItem {
Assign(ContinuousAssign)
Always(AlwaysBlock)
Instance(Instance)
Statement(Statement)
Unknown(@source.Span)
} derive(Eq, Debug)
///|
pub(all) struct Module {
name : String
ports : Array[Port]
signals : Array[Signal]
items : Array[ModuleItem]
span : @source.Span
} derive(Eq, Debug)
///|
pub fn Module::new(
name : String,
ports : Array[Port],
signals : Array[Signal],
items : Array[ModuleItem],
span : @source.Span,
) -> Module {
{ name, ports, signals, items, span }
}
///|
pub(all) struct Design {
modules : Array[Module]
} derive(Eq, Debug)
///|
pub fn Design::new(modules : Array[Module]) -> Design {
{ modules, }
}