add match lowering

This commit is contained in:
NotAFile 2022-04-05 00:02:45 +02:00
parent da5258a11a
commit 0307d0537c
2 changed files with 49 additions and 4 deletions

View File

@ -66,17 +66,52 @@ fn lower_expression(
Ok(rtlil::SigSpec::Wire(expr_wire_name)) Ok(rtlil::SigSpec::Wire(expr_wire_name))
} }
ExprKind::Literal(lit) => Ok(rtlil::SigSpec::Const( ExprKind::Literal(lit) => Ok(rtlil::SigSpec::Const(
todo!(), ctx.types
.elab_as_u32(lit)
.expect("const does not fit in 32 bits") as i64,
ctx.types.get_width(expr.typ).expect("signal has no size"), ctx.types.get_width(expr.typ).expect("signal has no size"),
)), )),
ExprKind::Match(_) => todo!(), ExprKind::Match(match_) => {
let cases = match_
.arms
.iter()
.map(|(pat, val)| {
Ok((
lower_expression(ctx, module, pat)?,
rtlil::CaseRule {
assign: vec![(
rtlil::SigSpec::Wire(expr_wire_name.clone()),
lower_expression(ctx, module, val)?,
)],
switches: vec![],
},
))
})
.collect::<Result<Vec<_>, CompileError>>()
.unwrap();
let root_switch = rtlil::SwitchRule {
signal: lower_expression(ctx, module, &match_.expr)?,
cases,
};
let root_case = rtlil::CaseRule {
assign: vec![],
switches: vec![root_switch],
};
let proc = rtlil::Process {
id: module.make_genid("match"),
root_case,
sync_rules: vec![],
};
module.add_process(proc);
Ok(rtlil::SigSpec::Wire(expr_wire_name))
}
} }
} }
fn lower_comb( fn lower_comb(
ctx: &mut Context, ctx: &mut Context,
module: &mut rtlil::Module, module: &mut rtlil::Module,
block: typed_ir::Block, block: &typed_ir::Block,
) -> Result<(), CompileError> { ) -> Result<(), CompileError> {
for (num, sig) in block.signals.iter().enumerate() { for (num, sig) in block.signals.iter().enumerate() {
let sig_id = format!("\\$sig_{}", sig.id.0); let sig_id = format!("\\$sig_{}", sig.id.0);
@ -101,7 +136,7 @@ fn lower_comb(
Ok(()) Ok(())
} }
pub fn lower_block(context: &mut Context, block: typed_ir::Block) -> Result<String, CompileError> { pub fn lower_block(context: &mut Context, block: &typed_ir::Block) -> Result<String, CompileError> {
let mut writer = rtlil::ILWriter::new(); let mut writer = rtlil::ILWriter::new();
let mut ir_module = rtlil::Module::new(make_pubid("test")); let mut ir_module = rtlil::Module::new(make_pubid("test"));

View File

@ -150,6 +150,16 @@ impl TypingContext {
} }
} }
pub fn elab_as_u32(&self, data: &ElabData) -> Option<u32> {
match &data.value {
ElabValue::Infer => None,
ElabValue::Concrete(val) => match val {
ElabValueData::U32(val) => Some(*val),
ElabValueData::Bytes(_val) => None,
},
}
}
pub fn make_logic_size(&self, width: u32) -> Type { pub fn make_logic_size(&self, width: u32) -> Type {
let widthnum = self.make_elabnum_u32(width); let widthnum = self.make_elabnum_u32(width);
self.parameterize(self.primitives.logic, &[GenericArg::Elab(widthnum)]) self.parameterize(self.primitives.logic, &[GenericArg::Elab(widthnum)])