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] [package]
# future name: Hylid?
name = "futilehdl" name = "futilehdl"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"

View File

@ -58,8 +58,40 @@ pub struct Callable {
pub instantiate: Box<dyn Fn(&str, &[rtlil::SigSpec], &rtlil::SigSpec) -> rtlil::Cell>, 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 { struct Context {
/// map callable name to callable
callables: BTreeMap<String, 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( fn lower_process_statement(
@ -199,7 +231,10 @@ fn lower_expression(
) -> Result<rtlil::SigSpec, CompileError> { ) -> Result<rtlil::SigSpec, CompileError> {
let expr = desugar_expression(expr.clone()); let expr = desugar_expression(expr.clone());
match expr { 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) => { parser::Expression::Call(call) => {
let args_resolved = call let args_resolved = call
.args .args
@ -246,7 +281,7 @@ fn lower_assignment(
module: &mut rtlil::Module, module: &mut rtlil::Module,
assignment: parser::Assign, assignment: parser::Assign,
) -> Result<(), CompileError> { ) -> 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)?; let return_wire = lower_expression(ctx, module, &assignment.expr)?;
module.add_connection(&target_id, &return_wire); module.add_connection(&target_id, &return_wire);
Ok(()) Ok(())
@ -255,20 +290,28 @@ fn lower_assignment(
pub fn lower_module(pa_module: parser::Module) -> Result<String, CompileError> { pub fn lower_module(pa_module: parser::Module) -> Result<String, CompileError> {
let mut writer = rtlil::ILWriter::new(); let mut writer = rtlil::ILWriter::new();
let mut ir_module = rtlil::Module::new(make_pubid(pa_module.name)); let mut ir_module = rtlil::Module::new(make_pubid(pa_module.name));
let context = Context { let mut context = Context {
callables: get_builtins() callables: get_builtins()
.into_iter() .into_iter()
.map(|clb| (clb.name.to_owned(), clb)) .map(|clb| (clb.name.to_owned(), clb))
.collect(), .collect(),
signals: BTreeMap::new(),
}; };
writer.write_line("autoidx 1"); writer.write_line("autoidx 1");
for (idx, port) in pa_module.ports.iter().enumerate() { 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 { let dir_option = match port.direction {
parser::PortDirection::Input => rtlil::PortOption::Input(idx as i32 + 1), parser::PortDirection::Input => rtlil::PortOption::Input(idx as i32 + 1),
parser::PortDirection::Output => rtlil::PortOption::Output(idx as i32 + 1), parser::PortDirection::Output => rtlil::PortOption::Output(idx as i32 + 1),
}; };
let wire = rtlil::Wire::new( let wire = rtlil::Wire::new(
make_pubid(port.net.name), sig.il_id.to_owned(),
port.net.width.unwrap_or(1) as u32, port.net.width.unwrap_or(1) as u32,
Some(dir_option), Some(dir_option),
); );