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]]
name = "sv-to-llhd"
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
* [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`

View File

@ -17,7 +17,7 @@ pub struct AlwaysStatement {}
impl AlwaysStatement {
pub fn codegen<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) -> Option<UnitId> {
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) => {
error!("TODO: implmenent '{}'", Tag::ALWAYS_COMB);
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_always = Tools::match_tags(
vec![json],
@ -50,7 +50,15 @@ impl AlwaysStatement {
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])
};
@ -127,7 +135,7 @@ impl AlwaysStatement {
Tools::beautify(&mut context.unit_ctx);
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>(
@ -260,7 +268,9 @@ impl AlwaysStatement {
}
_ => {
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))
}
};

View File

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

View File

@ -72,7 +72,10 @@ impl Expression {
.iter()
.flat_map(|x| Tools::match_tags(vec![json], x.to_vec()))
.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(
vec![json],
@ -115,7 +118,18 @@ impl Expression {
let lo = Number::parse_dec(json_range[1]);
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"];
@ -148,7 +162,8 @@ impl Expression {
assert_eq!(symbol_info.kind, SymbolKind::Param);
builder.ins().const_int(symbol_info.value.clone())
} else {
panic!("unknown error at CST node '{}'", json);
warn!("PTIFALL: skip unknown symbol {} at {}", &symbol, json);
return None;
};
if range.is_some() {
@ -202,10 +217,15 @@ impl Expression {
Some(value)
}
Some(Tag::MUL) => {
warn!("FIXME: signed multiplication not supported");
warn!("PITFALL: signed multiplication not supported");
let value = builder.ins().umul(opd_l, opd_r);
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) => {
let value = builder.ins().and(opd_l, opd_r);
Some(value)
@ -276,8 +296,14 @@ impl Expression {
operands.push_front(value);
}
}
assert_eq!(json_ops.len(), 0, "FIXME: {}", json);
assert_eq!(operands.len(), 1, "FIXME: {}", json);
if json_ops.len() != 0 {
warn!("PITFALL: skip {} with unmatched operators", json);
return None;
}
if operands.len() != 1 {
warn!("PITFALL: skip {} with unmatched operands", json);
return None;
}
operands[0]
} else {
@ -413,6 +439,19 @@ impl Expression {
let mut builder = UnitContext::builder(&mut unit_ctx.data);
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 ret = builder.ins().mux(arr, sel.unwrap());
@ -433,7 +472,13 @@ impl Expression {
let count = {
let json_count =
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])
.value
.to_usize()

View File

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

View File

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

View File

@ -23,7 +23,14 @@ impl Statement {
NonblockingAssignmentStatement::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;
for json_statement in json_block_item_statement_list {
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
}

View File

@ -553,8 +553,15 @@ impl<'a> SymbolDeclaration {
};
let json_num = Tools::match_tags(vec![json], num_path.to_vec());
assert_eq!(json_num.len(), 1);
let num = Number::parse(json_num[0]);
let num = if json_num.len() == 1 {
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 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());
assert_eq!(json_num.len(), 1, "{}", json);
let num = Number::parse(json_num[0]);
let num = if json_num.len() == 1 {
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 symbol = SymbolInfo::new(SymbolKind::Param, num, json_name);

View File

@ -121,6 +121,7 @@ impl Tag {
pub const ADD: &'static str = "+";
pub const SUB: &'static str = "-";
pub const MUL: &'static str = "*";
pub const DIV: &'static str = "/";
pub const BITWISE_AND: &'static str = "&";
pub const BITWISE_OR: &'static str = "|";
pub const BITWISE_XOR: &'static str = "^";
@ -145,4 +146,6 @@ impl Tag {
pub const GATEINSTANTIAN: &'static str = "kGateInstantiation";
pub const PRIMITIVE_GATE_LIST: &'static str = "kPrimitiveGateInstanceList";
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,
],
);
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])
};