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:
parent
a7645b2e10
commit
ef0ecb12cc
|
@ -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"
|
||||
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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])
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue