Chage some error!() and panic!() to warn!()

and mark the messages with "PITFALL" (keng)
To-Do: support the integer type
This commit is contained in:
Guojie Luo 2023-05-05 05:43:12 +00:00
parent a7645b2e10
commit ef0ecb12cc
11 changed files with 128 additions and 39 deletions

View File

@ -19,3 +19,8 @@ pretty_env_logger = "0.4"
[[bin]] [[bin]]
name = "sv-to-llhd" name = "sv-to-llhd"
path = "src/bin/sv-to-llhd.rs" path = "src/bin/sv-to-llhd.rs"
[[bin]]
name = "cst-to-llhd"
path = "src/bin/cst-to-llhd.rs"

View File

@ -30,5 +30,5 @@ ARGS:
``` ```
### Dependencies ### Dependencies
* [verible-verilog-syntax](https://github.com/chipsalliance/verible/releases) in your PATH * [verible-verilog-syntax](https://github.com/chipsalliance/verible/releases/tag/v0.0-2076-gc48d80ca) in your PATH
* *nix commands `tr` and `sed` * *nix commands `tr` and `sed`

View File

@ -17,7 +17,7 @@ pub struct AlwaysStatement {}
impl AlwaysStatement { impl AlwaysStatement {
pub fn codegen<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) -> Option<UnitId> { pub fn codegen<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) -> Option<UnitId> {
match json["children"][0]["tag"].as_str() { match json["children"][0]["tag"].as_str() {
Some(Tag::ALWAYS) => Some(Self::gen_always(json, context)), Some(Tag::ALWAYS) => Self::gen_always(json, context),
Some(Tag::ALWAYS_COMB) => { Some(Tag::ALWAYS_COMB) => {
error!("TODO: implmenent '{}'", Tag::ALWAYS_COMB); error!("TODO: implmenent '{}'", Tag::ALWAYS_COMB);
None None
@ -28,7 +28,7 @@ impl AlwaysStatement {
} }
} }
fn gen_always<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) -> UnitId { fn gen_always<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) -> Option<UnitId> {
let (json_event_expression_list, json_statement) = { let (json_event_expression_list, json_statement) = {
let json_always = Tools::match_tags( let json_always = Tools::match_tags(
vec![json], vec![json],
@ -50,7 +50,15 @@ impl AlwaysStatement {
Tag::EVENT_EXPRESSION_LIST, Tag::EVENT_EXPRESSION_LIST,
], ],
); );
assert_eq!(json_event_control.len(), 1); if json_event_control.len() != 1 {
warn!(
"PITFALL: skip {} '{}' in {}",
Tag::EVENT_CONTROL,
&json_children[0],
Tag::ALWAYS_STATEMENT
);
return None;
}
(json_event_control[0], &json_children[1]) (json_event_control[0], &json_children[1])
}; };
@ -127,7 +135,7 @@ impl AlwaysStatement {
Tools::beautify(&mut context.unit_ctx); Tools::beautify(&mut context.unit_ctx);
context.unit_ctx.clear(); context.unit_ctx.clear();
context.module.add_unit(context.unit_ctx.drop_data()) Some(context.module.add_unit(context.unit_ctx.drop_data()))
} }
fn gen_event_expression_list<'a>( fn gen_event_expression_list<'a>(
@ -260,7 +268,9 @@ impl AlwaysStatement {
} }
_ => { _ => {
let _neq = builder.ins().neq(prb_init, prb); let _neq = builder.ins().neq(prb_init, prb);
context.syntax_table.insert_value(builder.unit(), _neq, json); context
.syntax_table
.insert_value(builder.unit(), _neq, json);
(String::from("impledge"), builder.ins().neq(prb_init, prb)) (String::from("impledge"), builder.ins().neq(prb_init, prb))
} }
}; };

View File

@ -70,11 +70,10 @@ impl ConditionalStatement {
let unit_ctx = &mut context.unit_ctx; let unit_ctx = &mut context.unit_ctx;
let builder = &mut UnitContext::builder(&mut unit_ctx.data); let builder = &mut UnitContext::builder(&mut unit_ctx.data);
assert!( if bb_if_true_dangled.is_none() {
bb_if_true_dangled.is_some(), warn!("PITFALL: skip CST node {}", json_if_body);
"FIXME: CST node '{}'", return None;
json_if_body }
);
let bb_next = builder.block(); let bb_next = builder.block();
// merge dangling basic blocks to bb_next // merge dangling basic blocks to bb_next
@ -137,7 +136,10 @@ impl ConditionalStatement {
let stmt = Statement::codegen(&json_child[0], context); let stmt = Statement::codegen(&json_child[0], context);
if context.unit_ctx.data.is_some() { if context.unit_ctx.data.is_some() {
assert!(stmt.is_some(), "FIXME: CST node '{}'", json_child[0]); if stmt.is_none() {
warn!("PITFALL: skip CST node {}", json_child[0]);
return None;
}
let unit_ctx = &mut context.unit_ctx; let unit_ctx = &mut context.unit_ctx;
let mut builder = UnitContext::builder(&mut unit_ctx.data); let mut builder = UnitContext::builder(&mut unit_ctx.data);

View File

@ -72,7 +72,10 @@ impl Expression {
.iter() .iter()
.flat_map(|x| Tools::match_tags(vec![json], x.to_vec())) .flat_map(|x| Tools::match_tags(vec![json], x.to_vec()))
.collect(); .collect();
assert_eq!(json_symbol_identifier.len(), 1); if json_symbol_identifier.len() != 1 {
warn!("PITFALL: skip {} {}", Tag::REFERENCE_CALL_BASE, json);
return ("PITFALL".to_string(), None);
}
let json_scalar = Tools::match_tags( let json_scalar = Tools::match_tags(
vec![json], vec![json],
@ -115,7 +118,18 @@ impl Expression {
let lo = Number::parse_dec(json_range[1]); let lo = Number::parse_dec(json_range[1]);
Some((hi, lo)) Some((hi, lo))
} }
_ => panic!("unknown error at CST node '{}'", json), _ => {
warn!(
"PITFALL: skip {} {} with {} len={} and {} len={}",
Tag::REFERENCE_CALL_BASE,
json,
Tag::DIMENSION_SCALAR,
json_scalar.len(),
Tag::DIMENSION_RANGE,
json_range.len()
);
None
}
}; };
let symbol = &json_symbol_identifier[0]["text"]; let symbol = &json_symbol_identifier[0]["text"];
@ -148,7 +162,8 @@ impl Expression {
assert_eq!(symbol_info.kind, SymbolKind::Param); assert_eq!(symbol_info.kind, SymbolKind::Param);
builder.ins().const_int(symbol_info.value.clone()) builder.ins().const_int(symbol_info.value.clone())
} else { } else {
panic!("unknown error at CST node '{}'", json); warn!("PTIFALL: skip unknown symbol {} at {}", &symbol, json);
return None;
}; };
if range.is_some() { if range.is_some() {
@ -202,10 +217,15 @@ impl Expression {
Some(value) Some(value)
} }
Some(Tag::MUL) => { Some(Tag::MUL) => {
warn!("FIXME: signed multiplication not supported"); warn!("PITFALL: signed multiplication not supported");
let value = builder.ins().umul(opd_l, opd_r); let value = builder.ins().umul(opd_l, opd_r);
Some(value) Some(value)
} }
Some(Tag::DIV) => {
warn!("PITFALL: signed division not supported");
let value = builder.ins().udiv(opd_l, opd_r);
Some(value)
}
Some(Tag::BITWISE_AND) => { Some(Tag::BITWISE_AND) => {
let value = builder.ins().and(opd_l, opd_r); let value = builder.ins().and(opd_l, opd_r);
Some(value) Some(value)
@ -276,8 +296,14 @@ impl Expression {
operands.push_front(value); operands.push_front(value);
} }
} }
assert_eq!(json_ops.len(), 0, "FIXME: {}", json); if json_ops.len() != 0 {
assert_eq!(operands.len(), 1, "FIXME: {}", json); warn!("PITFALL: skip {} with unmatched operators", json);
return None;
}
if operands.len() != 1 {
warn!("PITFALL: skip {} with unmatched operands", json);
return None;
}
operands[0] operands[0]
} else { } else {
@ -413,6 +439,19 @@ impl Expression {
let mut builder = UnitContext::builder(&mut unit_ctx.data); let mut builder = UnitContext::builder(&mut unit_ctx.data);
builder.append_to(bb_head); builder.append_to(bb_head);
if in0.is_none() {
warn!("PITFALL: skip 'in0' {}", &json_children[4]);
return None;
}
if in1.is_none() {
warn!("PITFALL: skip 'in1' {}", &json_children[2]);
return None;
}
if sel.is_none() {
warn!("PITFALL: skip 'sel' {}", &json_children[0]);
return None;
}
let arr = builder.ins().array(vec![in0.unwrap(), in1.unwrap()]); let arr = builder.ins().array(vec![in0.unwrap(), in1.unwrap()]);
let ret = builder.ins().mux(arr, sel.unwrap()); let ret = builder.ins().mux(arr, sel.unwrap());
@ -433,7 +472,13 @@ impl Expression {
let count = { let count = {
let json_count = let json_count =
Tools::match_tags(vec![&json_expr[1]], vec![Tag::EXPRESSION, Tag::NUMBER]); Tools::match_tags(vec![&json_expr[1]], vec![Tag::EXPRESSION, Tag::NUMBER]);
assert_eq!(json_count.len(), 1, "{}", &json_expr[1]); if json_count.len() != 1 {
warn!(
"PITFALL: skip non-numeric {} in replication expression",
&json_expr[1]
);
return None;
}
Number::parse(json_count[0]) Number::parse(json_count[0])
.value .value
.to_usize() .to_usize()

View File

@ -349,11 +349,14 @@ impl<'a> ModuleDeclaration {
// declare processes // declare processes
let ext_to_proc: Vec<(ExtUnit, UnitId)> = json_always_statements let ext_to_proc: Vec<(ExtUnit, UnitId)> = json_always_statements
.iter() .iter()
.map(|&x| { .filter_map(|&x| {
let proc_id = AlwaysStatement::codegen(x, context).unwrap(); if let Some(proc_id) = AlwaysStatement::codegen(x, context) {
let proc = context.module.unit(proc_id); let proc = context.module.unit(proc_id);
let ext_proc = builder.add_extern(proc.name().clone(), proc.sig().clone()); let ext_proc = builder.add_extern(proc.name().clone(), proc.sig().clone());
(ext_proc, proc_id) Some((ext_proc, proc_id))
} else {
None
}
}) })
.collect(); .collect();

View File

@ -108,8 +108,8 @@ impl NetVariableAssignment {
let unit_ctx = &mut context.unit_ctx; let unit_ctx = &mut context.unit_ctx;
if unit_ctx.data.is_some() { if unit_ctx.data.is_some() {
if opt_expr.is_none() { if opt_expr.is_none() {
error!("FIXME: CST node '{}'", json_expression.to_string()); warn!("PITFALL: skip rvalue {}", json_expression);
panic!(); return None;
} }
let bb_head = *unit_ctx.bb_head.last().unwrap(); let bb_head = *unit_ctx.bb_head.last().unwrap();

View File

@ -23,7 +23,14 @@ impl Statement {
NonblockingAssignmentStatement::codegen(json, context) NonblockingAssignmentStatement::codegen(json, context)
} }
Some(Tag::NET_VARIABLE_ASSIGNMENT) => NetVariableAssignment::codegen(json, context), Some(Tag::NET_VARIABLE_ASSIGNMENT) => NetVariableAssignment::codegen(json, context),
_ => panic!("unknown error at CST node '{}'", json), Some(tag) => {
warn!("PITFALL: skip {} {}", tag, json);
None
}
_ => {
warn!("PITFALL: skip statement {}", json);
None
}
} }
} }
@ -39,13 +46,6 @@ impl Statement {
let mut ret = None; let mut ret = None;
for json_statement in json_block_item_statement_list { for json_statement in json_block_item_statement_list {
ret = Self::codegen(json_statement, context); ret = Self::codegen(json_statement, context);
assert!(
context.unit_ctx.data.is_none()
|| (context.unit_ctx.data.is_some() && ret.is_some()),
"FIXME: CST node '{}'",
json_statement
);
} }
ret ret
} }

View File

@ -553,8 +553,15 @@ impl<'a> SymbolDeclaration {
}; };
let json_num = Tools::match_tags(vec![json], num_path.to_vec()); let json_num = Tools::match_tags(vec![json], num_path.to_vec());
assert_eq!(json_num.len(), 1); let num = if json_num.len() == 1 {
let num = Number::parse(json_num[0]); Number::parse(json_num[0])
} else {
warn!(
"PITFALL: skip non-numeric expression {} in localparam",
json
);
IntValue::zero(1)
};
let name = json_name["text"].to_string(); let name = json_name["text"].to_string();
let symbol = SymbolInfo::new(SymbolKind::Param, num, json_name); let symbol = SymbolInfo::new(SymbolKind::Param, num, json_name);
@ -609,8 +616,15 @@ impl<'a> SymbolDeclaration {
}; };
let json_num = Tools::match_tags(vec![json], num_path.to_vec()); let json_num = Tools::match_tags(vec![json], num_path.to_vec());
assert_eq!(json_num.len(), 1, "{}", json); let num = if json_num.len() == 1 {
let num = Number::parse(json_num[0]); Number::parse(json_num[0])
} else {
warn!(
"PITFALL: skip non-numeric expression {} in localparam",
json
);
IntValue::zero(1)
};
let name = json_name["text"].to_string(); let name = json_name["text"].to_string();
let symbol = SymbolInfo::new(SymbolKind::Param, num, json_name); let symbol = SymbolInfo::new(SymbolKind::Param, num, json_name);

View File

@ -121,6 +121,7 @@ impl Tag {
pub const ADD: &'static str = "+"; pub const ADD: &'static str = "+";
pub const SUB: &'static str = "-"; pub const SUB: &'static str = "-";
pub const MUL: &'static str = "*"; pub const MUL: &'static str = "*";
pub const DIV: &'static str = "/";
pub const BITWISE_AND: &'static str = "&"; pub const BITWISE_AND: &'static str = "&";
pub const BITWISE_OR: &'static str = "|"; pub const BITWISE_OR: &'static str = "|";
pub const BITWISE_XOR: &'static str = "^"; pub const BITWISE_XOR: &'static str = "^";
@ -145,4 +146,6 @@ impl Tag {
pub const GATEINSTANTIAN: &'static str = "kGateInstantiation"; pub const GATEINSTANTIAN: &'static str = "kGateInstantiation";
pub const PRIMITIVE_GATE_LIST: &'static str = "kPrimitiveGateInstanceList"; pub const PRIMITIVE_GATE_LIST: &'static str = "kPrimitiveGateInstanceList";
pub const PRIMITIVE_GATE: &'static str = "kPrimitiveGateInstance"; pub const PRIMITIVE_GATE: &'static str = "kPrimitiveGateInstance";
pub const FOR_LOOP_STATEMENT: &'static str = "kForLoopStatement";
} }

View File

@ -121,7 +121,14 @@ impl EventControl {
Tag::EVENT_EXPRESSION, Tag::EVENT_EXPRESSION,
], ],
); );
assert!(json_event_expressions.len() > 0); if json_event_expressions.len() == 0 {
warn!(
"PITFALL: skip {} {} with zero {}",
Tag::EVENT_CONTROL,
&json_children[0],
Tag::EVENT_EXPRESSION
);
}
(json_event_expressions, &json_children[1]) (json_event_expressions, &json_children[1])
}; };