Compare commits

...

3 Commits

Author SHA1 Message Date
NotAFile 060b2d1078 add name idea 2022-01-17 22:01:21 +01:00
NotAFile 7d6f172ad9 start plumbing through signals 2022-01-17 21:40:13 +01:00
NotAFile e45f4ba142 start tracking signals 2022-01-17 21:02:11 +01:00
2 changed files with 48 additions and 4 deletions

View File

@ -1,4 +1,5 @@
[package]
# future name: Hylid?
name = "futilehdl"
version = "0.1.0"
edition = "2021"

View File

@ -58,8 +58,40 @@ pub struct Callable {
pub instantiate: Box<dyn Fn(&str, &[rtlil::SigSpec], &rtlil::SigSpec) -> rtlil::Cell>,
}
/// A user-defined signal
pub struct Signal {
/// the user-visible name of the signal
pub name: String,
/// the id of the signal in RTLIL
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>,
/// map signal name to Signal
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(
@ -199,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
@ -246,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(())
@ -255,20 +290,28 @@ fn lower_assignment(
pub fn lower_module(pa_module: parser::Module) -> Result<String, CompileError> {
let mut writer = rtlil::ILWriter::new();
let mut ir_module = rtlil::Module::new(make_pubid(pa_module.name));
let context = Context {
let mut context = Context {
callables: get_builtins()
.into_iter()
.map(|clb| (clb.name.to_owned(), clb))
.collect(),
signals: BTreeMap::new(),
};
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),
);