diff --git a/src/hir/expr/methodcall.rs b/src/hir/expr/methodcall.rs index 942b8d0..8732ad7 100644 --- a/src/hir/expr/methodcall.rs +++ b/src/hir/expr/methodcall.rs @@ -31,6 +31,18 @@ impl IsExpr for ExprMethodCall { let subject_type: &Type = &typed_subject.type_of().unwrap(); match (subject_type, method.as_str()) { + (Type::Word(1), method@"mux") => { + assert_eq!(args.len(), 2); + let arg0: Expr = args[0].clone(); + let arg1: Expr = args[1].clone(); + let typed_arg0 = arg0.typeinfer(ctx.clone())?; + let typed_arg1 = arg1.typeinfer(ctx.clone())?; + if typed_arg0.type_of().unwrap() != typed_arg1.type_of().unwrap() { + return Err(TypeError::Unknown); + } + let typ: Arc = typed_arg0.type_of().unwrap(); + Ok(ExprNode::MethodCall(ExprMethodCall(typed_subject, method.into(), vec![typed_arg0, typed_arg1])).with_type(typ)) + }, (Type::Word(n), method@("eq" | "lt" | "gt" | "lte" | "gte")) => { assert_eq!(args.len(), 1); let arg: Expr = args[0].clone(); @@ -81,6 +93,9 @@ impl IsExpr for ExprMethodCall { let subject_type = &*subject.type_of().unwrap(); let result_value = match (subject_type, name.as_str()) { + (Type::Word(1), "mux") => { + todo!(); // TODO + }, (Type::Word(_n), "eq") => { let v = (subject_value.unwrap_word() == arg_values.first().unwrap().unwrap_word()) as u64; Value::Word(1, v) diff --git a/src/verilog.rs b/src/verilog.rs index 3768e5e..b5d4e52 100644 --- a/src/verilog.rs +++ b/src/verilog.rs @@ -113,7 +113,9 @@ impl<'a> Verilog<'a> { Component::Reg(name, typ, clk, /* rst, */ expr) => { //let clock_ssa = self.verilog_expr(clk)?; let connect_ssa = self.verilog_expr(&expr)?; - writeln!(self.writer, " reg [31:0] {name};")?; + let width = if let Type::Word(n) = typ.as_ref() { n } else { panic!() }; + let max_bit = width - 1; + writeln!(self.writer, " reg [{max_bit}:0] {name};")?; writeln!(self.writer, " always @(posedge {clk}) begin")?; writeln!(self.writer, " {name} <= {connect_ssa};")?; writeln!(self.writer, " end")?; @@ -169,9 +171,24 @@ impl<'a> Verilog<'a> { } match m.method().as_str() { "add" => { - writeln!(self.writer, " wire [31:0] {gs} = {subject_ssa} + {};", args_ssa.join(", "))?; + writeln!(self.writer, " wire [31:0] {gs} = {subject_ssa} + {};", args_ssa[0])?; }, - _ => panic!(), + "and" => { + writeln!(self.writer, " wire [31:0] {gs} = {subject_ssa} && {};", args_ssa[0])?; + }, + "or" => { + writeln!(self.writer, " wire [31:0] {gs} = {subject_ssa} || {};", args_ssa[0])?; + }, + "not" => { + writeln!(self.writer, " wire [31:0] {gs} = ~{subject_ssa};")?; + }, + "eq" => { + writeln!(self.writer, " wire [31:0] {gs} = {subject_ssa} == {};", args_ssa[0])?; + }, + "mux" => { + writeln!(self.writer, " wire [31:0] {gs} = {subject_ssa} ? {};", args_ssa.join(" : "))?; + }, + _ => panic!("Unknown method: {}", m.method()), } Ok(gs) },