Skip to content

Commit 49cdf33

Browse files
authored
Implement rest of PrimitiveTypes as rewrite rules (#141)
1 parent e4c62de commit 49cdf33

File tree

5 files changed

+46
-21
lines changed

5 files changed

+46
-21
lines changed

src/asic.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,20 @@ pub fn asic_rewrites() -> Vec<egg::Rewrite<CellLang, CellAnalysis>> {
297297
rules
298298
.push(rewrite!("xor2_x1"; "(OR (AND ?b (INV ?a)) (AND ?a (INV ?b)))" => "(XOR2_X1 ?a ?b)"));
299299
rules.push(rewrite!("inv_x1"; "(INV ?a)" => "(INV_X1 ?a)"));
300-
rules.push(rewrite!("aoi_x1"; "(INV (OR (AND ?a ?b) ?c))" => "(AOI21_X1 ?a ?b ?c)"));
301-
rules.push(rewrite!("oai_x1"; "(INV (AND (OR ?a ?b) ?c))" => "(OAI21_X1 ?a ?b ?c)"));
300+
rules.push(rewrite!("aoi21_x1"; "(INV (OR (AND ?b ?c) ?a))" => "(AOI21_X1 ?a ?b ?c)"));
301+
rules.push(rewrite!("oai21_x1"; "(INV (AND (OR ?b ?c) ?a))" => "(OAI21_X1 ?a ?b ?c)"));
302+
rules.push(
303+
rewrite!("aoi22_x1"; "(INV (OR (AND ?c ?d) (AND ?a ?b)))" => "(AOI22_X1 ?a ?b ?c ?d)"),
304+
);
305+
rules.push(
306+
rewrite!("oai22_x1"; "(INV (AND (OR ?c ?d) (OR ?a ?b)))" => "(OAI22_X1 ?a ?b ?c ?d)"),
307+
);
308+
rules.push(
309+
rewrite!("aoi211_x1"; "(INV (OR ?b (OR (AND ?c ?d) ?a)))" => "(AOI211_X1 ?a ?b ?c ?d)"),
310+
);
311+
rules.push(
312+
rewrite!("oai211_x1"; "(INV (AND ?b (AND (OR ?c ?d) ?a)))" => "(OAI211_X1 ?a ?b ?c ?d)"),
313+
);
302314

303315
rules
304316
}

src/bin/emit-verilog.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55

66
use clap::Parser;
77
use egg::RecExpr;
8-
use lut_synth::{driver::Canonical, lut::LutLang, verilog::SVModule};
8+
use lut_synth::{asic::CellLang, driver::Canonical, lut::LutLang, verilog::SVModule};
99
/// Emit a LutLang Expression as a Verilog Netlist
1010
#[derive(Parser, Debug)]
1111
#[command(version, about, long_about = None)]
@@ -28,6 +28,10 @@ struct Args {
2828
/// Canonicalize the input expression
2929
#[arg(short = 'c', long, default_value_t = false)]
3030
canonicalize: bool,
31+
32+
/// Parse input as a CellLang expression
33+
#[arg(short = 'a', long, default_value_t = false)]
34+
asic: bool,
3135
}
3236

3337
fn main() -> std::io::Result<()> {
@@ -67,18 +71,27 @@ fn main() -> std::io::Result<()> {
6771
continue;
6872
}
6973
let expr = line.split("//").next().unwrap();
70-
let expr: RecExpr<LutLang> = expr
71-
.parse()
72-
.map_err(|s| std::io::Error::new(std::io::ErrorKind::Other, s))?;
74+
let module = if !args.asic {
75+
let expr: RecExpr<LutLang> = expr
76+
.parse()
77+
.map_err(|s| std::io::Error::new(std::io::ErrorKind::Other, s))?;
78+
79+
let expr = if args.canonicalize {
80+
LutLang::canonicalize_expr(expr)
81+
} else {
82+
expr
83+
};
7384

74-
let expr = if args.canonicalize {
75-
LutLang::canonicalize_expr(expr)
85+
SVModule::from_luts(expr, mod_name.clone(), args.output_names.clone())
86+
.map_err(|s| std::io::Error::new(std::io::ErrorKind::Other, s))?
7687
} else {
77-
expr
78-
};
88+
let expr: RecExpr<CellLang> = expr
89+
.parse()
90+
.map_err(|s| std::io::Error::new(std::io::ErrorKind::Other, s))?;
7991

80-
let module = SVModule::from_luts(expr, mod_name.clone(), args.output_names.clone())
81-
.map_err(|s| std::io::Error::new(std::io::ErrorKind::Other, s))?;
92+
SVModule::from_cells(expr, mod_name.clone(), args.output_names.clone())
93+
.map_err(|s| std::io::Error::new(std::io::ErrorKind::Other, s))?
94+
};
8295
print!("{}", module);
8396
break;
8497
}

src/verilog.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ impl VerilogEmission for CellLang {
802802
let inputs = self.children();
803803
let gate_type = self
804804
.get_gate_type()
805-
.expect("CellLang gates should have a primitive type");
805+
.ok_or("CellLang gates should have a primitive type".to_string())?;
806806
let port_list = gate_type.get_input_list();
807807
// TODO(matth2k): Carry through drive strength
808808
let mut prim =
@@ -882,7 +882,7 @@ impl VerilogEmission for LutLang {
882882
let inputs = self.children();
883883
let gate_type = self
884884
.get_gate_type()
885-
.expect("CellLang gates should have a primitive type");
885+
.ok_or("LutLang gates should have a primitive type".to_string())?;
886886
let port_list = gate_type.get_input_list();
887887
let mut prim = SVPrimitive::new_gate(gate_type.clone(), fresh_prim_name());
888888
for (input, port) in inputs.iter().zip(port_list) {

tests/asic/cla.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
// 2-bit CLA
44
(OR (OR (AND a1 b1) (AND (AND a0 b0) (OR a1 b1))) (AND c0 (AND (OR a1 b1) (OR a0 b0))))
5-
// CHECK: (NAND2_X1 (NAND2_X1 a1 b1) (OAI21_X1 a1 b1 (NAND2_X1 (NAND2_X1 a0 b0) (OAI21_X1 a0 b0 c0))))
5+
// CHECK: (NAND2_X1 (NAND2_X1 a1 b1) (OAI21_X1 (NAND2_X1 (NAND2_X1 a0 b0) (OAI21_X1 c0 a0 b0)) a1 b1))

tests/asic/cla.v

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ module cla (
8282
// CHECK: );
8383
// CHECK: OAI21_X1 #(
8484
// CHECK: ) __6__ (
85-
// CHECK: .A(a0),
86-
// CHECK: .B1(b0),
87-
// CHECK: .B2(c0),
85+
// CHECK: .A(c0),
86+
// CHECK: .B1(a0),
87+
// CHECK: .B2(b0),
8888
// CHECK: .ZN(__1__)
8989
// CHECK: );
9090
// CHECK: NAND2_X1 #(
@@ -95,9 +95,9 @@ module cla (
9595
// CHECK: );
9696
// CHECK: OAI21_X1 #(
9797
// CHECK: ) __8__ (
98-
// CHECK: .A(a1),
99-
// CHECK: .B1(b1),
100-
// CHECK: .B2(__2__),
98+
// CHECK: .A(__2__),
99+
// CHECK: .B1(a1),
100+
// CHECK: .B2(b1),
101101
// CHECK: .ZN(__3__)
102102
// CHECK: );
103103
// CHECK: NAND2_X1 #(

0 commit comments

Comments
 (0)