From 057511f56cfa72004ffc6b0334e16fb04d303ec0 Mon Sep 17 00:00:00 2001 From: NotAFile Date: Mon, 17 Jan 2022 19:20:51 +0100 Subject: [PATCH] make operators work via desugaring --- doc/examples/clockdiv.fut | 4 +-- doc/examples/comparator.fut | 2 +- doc/examples/halfadd.fut | 4 +-- src/builtin_cells.rs | 1 + src/frontend.rs | 58 +++++++++++++++++++++++++++++++++++-- src/parser.rs | 6 ++-- 6 files changed, 65 insertions(+), 10 deletions(-) diff --git a/doc/examples/clockdiv.fut b/doc/examples/clockdiv.fut index e400a75..aeaf901 100644 --- a/doc/examples/clockdiv.fut +++ b/doc/examples/clockdiv.fut @@ -4,9 +4,9 @@ module clockdiv_2 ( output wire out_clk ) { proc (clk) { - match (not(rst)) { + match (~rst) { 0 => out_clk = 0, - 1 => out_clk = not(out_clk) + 1 => out_clk = ~out_clk } } } diff --git a/doc/examples/comparator.fut b/doc/examples/comparator.fut index bff6212..7ec1fa3 100644 --- a/doc/examples/comparator.fut +++ b/doc/examples/comparator.fut @@ -3,5 +3,5 @@ module comparator ( input wire [8] b, output wire eq ) { - assign eq = not(reduce_or(xor(a, b))); + assign eq = ~reduce_or(a ^ b); } diff --git a/doc/examples/halfadd.fut b/doc/examples/halfadd.fut index 37ef9f1..1d59e1a 100644 --- a/doc/examples/halfadd.fut +++ b/doc/examples/halfadd.fut @@ -5,6 +5,6 @@ module halfadd ( output wire carry ) { - assign sum = xor(a, b); - assign carry = and(a, b); + assign sum = a ^ b; + assign carry = a & b; } diff --git a/src/builtin_cells.rs b/src/builtin_cells.rs index 93d942e..2e5b606 100644 --- a/src/builtin_cells.rs +++ b/src/builtin_cells.rs @@ -77,5 +77,6 @@ pub fn get_builtins() -> Vec { make_binop_callable("xor", "$xor"), make_binop_callable("xnor", "$xnor"), make_unnop_callable("not", "$not"), + make_unnop_callable("reduce_or", "$reduce_or"), ] } diff --git a/src/frontend.rs b/src/frontend.rs index c19fc65..4b78701 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -140,11 +140,64 @@ fn lower_process( Ok(()) } +fn desugar_operation<'a>(op: parser::Operation<'a>) -> parser::Call<'a> { + match op { + parser::Operation::And { a, b } => { + let a = desugar_expression(a); + let b = desugar_expression(b); + parser::Call { + name: "and".into(), + args: vec![a, b] + } + }, + parser::Operation::Or { a, b } => { + let a = desugar_expression(a); + let b = desugar_expression(b); + parser::Call { + name: "or".into(), + args: vec![a, b] + } + } + parser::Operation::Xor { a, b } => { + let a = desugar_expression(a); + let b = desugar_expression(b); + parser::Call { + name: "xor".into(), + args: vec![a, b] + } + } + parser::Operation::Not(a) => { + let a = desugar_expression(a); + parser::Call { + name: "not".into(), + args: vec![a] + } + } + } +} + +fn desugar_expression<'a>(expr: parser::Expression<'a>) -> parser::Expression<'a> { + // TODO: allow ergonomic traversal of AST + match expr { + parser::Expression::Ident(_) => expr, + parser::Expression::Literal(_) => expr, + parser::Expression::Call(mut call) => { + let new_args = call.args.into_iter().map(|argex| desugar_expression(argex)).collect(); + call.args = new_args; + parser::Expression::Call(call) + }, + parser::Expression::Operation(op) => { + parser::Expression::Call(Box::new(desugar_operation(*op))) + }, + } +} + fn lower_expression( ctx: &Context, module: &mut rtlil::Module, expr: &parser::Expression, ) -> Result { + let expr = desugar_expression(expr.clone()); match expr { parser::Expression::Ident(ident) => Ok(rtlil::SigSpec::Wire(make_pubid(ident))), parser::Expression::Call(call) => { @@ -181,9 +234,10 @@ fn lower_expression( module.add_cell(cell); Ok(output_gen_wire) } - // operations should really just desugar to callables + // TODO: instantiate operators directly here instead of desugaring, once the callable infrastructure improves + // to get better errors parser::Expression::Operation(_op) => todo!("operators not yet implemented"), - parser::Expression::Literal(lit) => Ok(rtlil::SigSpec::Const(*lit as i64, TODO_WIDTH)), + parser::Expression::Literal(lit) => Ok(rtlil::SigSpec::Const(lit as i64, TODO_WIDTH)), } } diff --git a/src/parser.rs b/src/parser.rs index 813cc59..10090a9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -59,7 +59,7 @@ pub struct Assign<'a> { pub expr: Expression<'a>, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Operation<'a> { And { a: Expression<'a>, @@ -76,13 +76,13 @@ pub enum Operation<'a> { Not(Expression<'a>), } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Call<'a> { pub name: Span<'a>, pub args: Vec>, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Expression<'a> { Ident(&'a str), Literal(u64),