make operators work via desugaring
This commit is contained in:
parent
95d9313cdd
commit
057511f56c
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -77,5 +77,6 @@ pub fn get_builtins() -> Vec<Callable> {
|
|||
make_binop_callable("xor", "$xor"),
|
||||
make_binop_callable("xnor", "$xnor"),
|
||||
make_unnop_callable("not", "$not"),
|
||||
make_unnop_callable("reduce_or", "$reduce_or"),
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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<rtlil::SigSpec, CompileError> {
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Expression<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Expression<'a> {
|
||||
Ident(&'a str),
|
||||
Literal(u64),
|
||||
|
|
Loading…
Reference in New Issue