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]]
|
[[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"
|
||||||
|
|
||||||
|
|
|
@ -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`
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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])
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue