add match lowering
This commit is contained in:
parent
da5258a11a
commit
0307d0537c
|
@ -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"));
|
||||||
|
|
||||||
|
|
|
@ -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)])
|
||||||
|
|
Loading…
Reference in New Issue