start plumbing through signals

This commit is contained in:
NotAFile 2022-01-17 21:04:22 +01:00
parent e45f4ba142
commit 7d6f172ad9
1 changed files with 31 additions and 11 deletions

View File

@ -63,13 +63,19 @@ pub struct Signal {
/// the user-visible name of the signal
pub name: String,
/// the id of the signal in RTLIL
pub il_id: Option<String>,
pub il_id: String,
/// the type of the signal
pub typ: Type,
// unique ID of the signal
// pub uid: u64,
}
impl Signal {
fn sigspec(&self) -> rtlil::SigSpec {
rtlil::SigSpec::Wire(self.il_id.to_owned())
}
}
struct Context {
/// map callable name to callable
callables: BTreeMap<String, Callable>,
@ -77,6 +83,17 @@ struct Context {
signals: BTreeMap<String, Signal>
}
impl Context {
fn get_signal(&self, signame: &str) -> Option<&Signal> {
self.signals.get(signame)
}
fn try_get_signal(&self, signame: &str) -> Result<&Signal, CompileError> {
self.get_signal(signame)
.ok_or(CompileError::new(CompileErrorKind::UndefinedReference(signame.to_owned())))
}
}
fn lower_process_statement(
ctx: &Context,
module: &mut rtlil::Module,
@ -214,7 +231,10 @@ fn lower_expression(
) -> Result<rtlil::SigSpec, CompileError> {
let expr = desugar_expression(expr.clone());
match expr {
parser::Expression::Ident(ident) => Ok(rtlil::SigSpec::Wire(make_pubid(ident))),
parser::Expression::Ident(ident) => {
let signal = ctx.try_get_signal(ident)?;
Ok(signal.sigspec())
},
parser::Expression::Call(call) => {
let args_resolved = call
.args
@ -261,7 +281,7 @@ fn lower_assignment(
module: &mut rtlil::Module,
assignment: parser::Assign,
) -> Result<(), CompileError> {
let target_id = rtlil::SigSpec::Wire(make_pubid(assignment.lhs));
let target_id = ctx.try_get_signal(assignment.lhs)?.sigspec();
let return_wire = lower_expression(ctx, module, &assignment.expr)?;
module.add_connection(&target_id, &return_wire);
Ok(())
@ -279,23 +299,23 @@ pub fn lower_module(pa_module: parser::Module) -> Result<String, CompileError> {
};
writer.write_line("autoidx 1");
for (idx, port) in pa_module.ports.iter().enumerate() {
let sig = Signal {
name: port.net.name.to_owned(),
il_id: make_pubid(port.net.name),
typ: Type::Wire(GenericParam::Solved(port.net.width.unwrap_or(1) as u32))
};
let sig = context.signals.entry(port.net.name.to_owned()).or_insert(sig);
let dir_option = match port.direction {
parser::PortDirection::Input => rtlil::PortOption::Input(idx as i32 + 1),
parser::PortDirection::Output => rtlil::PortOption::Output(idx as i32 + 1),
};
let wire = rtlil::Wire::new(
make_pubid(port.net.name),
sig.il_id.to_owned(),
port.net.width.unwrap_or(1) as u32,
Some(dir_option),
);
ir_module.add_wire(wire);
let sig = Signal {
name: port.net.name.to_owned(),
il_id: None,
typ: Type::Wire(GenericParam::Solved(port.net.width.unwrap_or(1) as u32))
};
context.signals.insert(port.net.name.to_owned(), sig);
}
for item in pa_module.items {
match item {