Fix a bug in ExtUnit initiation

This commit is contained in:
Guojie Luo 2022-05-10 20:03:52 +08:00
parent f25d2c1f89
commit d9fdc66ee4
4 changed files with 63 additions and 43 deletions

View File

@ -5,7 +5,7 @@ extern crate json;
use clap::Arg;
use cst_to_llhd::cst::{Tag, Tools};
use json::JsonValue;
use std::{collections::HashMap, fs::File, io::Read, result::Result};
use std::{fs::File, io::Read, result::Result};
#[allow(unused_imports)]
use log::{debug, error, info, trace, warn};
@ -40,7 +40,7 @@ fn main_inner() -> Result<(), String> {
let json_top = json::parse(contents.as_str()).unwrap();
assert!(json_top.len() == 1);
let ref json_modules: HashMap<String, &JsonValue> = {
let ref json_modules: Vec<(String, &JsonValue)> = {
let sv_file_name = json_top.entries().next().unwrap().0;
info!(r#"codegen from CST to LLHD for "{}" ..."#, sv_file_name);
let json_tree = &json_top[sv_file_name]["tree"];

View File

@ -6,7 +6,7 @@ use clap::Arg;
use cst_to_llhd::cst::{Tag, Tools};
use json::JsonValue;
use llhd::opt::{Pass, PassContext};
use std::{collections::HashMap, iter::FromIterator, result::Result};
use std::result::Result;
#[allow(unused_imports)]
use log::{debug, error, info, trace, warn};
@ -45,22 +45,20 @@ fn main_inner() -> Result<(), std::io::Error> {
})
.collect();
let ref json_modules: HashMap<String, &JsonValue> =
HashMap::from_iter(json_top_list.iter().flat_map(|json_top| {
let json_modules: Vec<_> = {
let sv_file_name = json_top.entries().next().unwrap().0;
let json_tree = &json_top[sv_file_name]["tree"];
Tools::match_tags(
vec![json_tree],
vec![Tag::DESCRIPTION_LIST, Tag::MODULE_DECLARATION],
)
.iter()
.map(|&json| (Tools::module_name(json), json))
.collect()
};
json_modules
}));
let ref json_modules: Vec<(String, &JsonValue)> = json_top_list
.iter()
.flat_map(|json_top| {
let sv_file_name = json_top.entries().next().unwrap().0;
let json_tree = &json_top[sv_file_name]["tree"];
Tools::match_tags(
vec![json_tree],
vec![Tag::DESCRIPTION_LIST, Tag::MODULE_DECLARATION],
)
.iter()
.map(|&json| (Tools::module_name(json), json))
.collect::<Vec<_>>()
})
.collect();
let contexts = Tools::resolve_dependencies(json_modules);
for (_, context_ref) in contexts {

View File

@ -1,5 +1,5 @@
use crate::cst::{
AlwaysStatement, Expression, ModuleContext, NetVariableAssignment, SymbolDeclaration,
AlwaysStatement, Expression, ModuleContext, NetVariableAssignment, Number, SymbolDeclaration,
SymbolKind, Tag, Tools, UnitContext,
};
use json::JsonValue;
@ -177,23 +177,21 @@ impl<'a> ModuleDeclaration {
Tag::PAREN_GROUP,
Tag::PORT_ACTUAL_LIST,
];
let pos_port_expr = [
let pos_port_expr_path = [
Tag::PORT_ACTUAL_LIST,
Tag::ACTUAL_POSITIONAL_PORT,
Tag::EXPRESSION,
Tag::REFERENCE_CALL_BASE,
];
let named_port_name = [
let named_port_name_path = [
Tag::PORT_ACTUAL_LIST,
Tag::ACTUAL_NAMED_PORT,
Tag::SYMBOL_IDENTIFIER,
];
let named_port_expr = [
let named_port_arg_path = [
Tag::PORT_ACTUAL_LIST,
Tag::ACTUAL_NAMED_PORT,
Tag::PAREN_GROUP,
Tag::EXPRESSION,
Tag::REFERENCE_CALL_BASE,
];
warn!("TODO: to support complex arguments in ExtUnit instantiation");
@ -208,16 +206,16 @@ impl<'a> ModuleDeclaration {
let name = json_types[0]["text"].to_string();
let json_ports = &Tools::match_tags(vec![x], port_path.to_vec());
let json_named_port_names =
Tools::match_tags(json_ports.clone(), named_port_name.to_vec());
let json_named_port_exprs =
Tools::match_tags(json_ports.clone(), named_port_expr.to_vec());
Tools::match_tags(json_ports.clone(), named_port_name_path.to_vec());
let json_named_port_args =
Tools::match_tags(json_ports.clone(), named_port_arg_path.to_vec());
let json_pos_port_exprs =
Tools::match_tags(json_ports.clone(), pos_port_expr.to_vec());
Tools::match_tags(json_ports.clone(), pos_port_expr_path.to_vec());
let named_port_list: HashMap<String, _> = json_named_port_names
.into_iter()
.map(|x| x["text"].to_string())
.zip(json_named_port_exprs.into_iter())
.zip(json_named_port_args.into_iter())
.collect();
let pos_port_list: HashMap<usize, _> = json_pos_port_exprs
.iter()
@ -246,25 +244,47 @@ impl<'a> ModuleDeclaration {
let ext_context = ext_context_rc.as_ref().borrow();
let ext_entity = ext_context.module.entities().next().unwrap();
let (inputs, outputs) = if named_port_list.len() > 0 {
let mut arg_to_val = |arg| -> Option<_> {
let named_port_symbol_path =
[Tag::PAREN_GROUP, Tag::EXPRESSION, Tag::REFERENCE_CALL_BASE];
let named_port_number_path =
[Tag::PAREN_GROUP, Tag::EXPRESSION, Tag::NUMBER];
let sig_name = ext_entity.get_name(ext_entity.arg_value(arg)).unwrap();
let json_symbol = Tools::match_tags(
vec![named_port_list[sig_name]],
named_port_symbol_path.to_vec(),
);
if json_symbol.len() == 1 {
let symbol = &Expression::gen_reference_name(json_symbol[0], context);
Some(context.unit_ctx.raw_name_to_value[symbol])
} else {
let json_number = Tools::match_tags(
vec![named_port_list[sig_name]],
named_port_number_path.to_vec(),
);
if json_number.len() == 1 {
let number = Number::parse(json_number[0]);
let mut builder = UnitContext::builder(&mut context.unit_ctx.data);
Some(builder.ins().const_int(number))
} else {
debug!(
"FIXME: unsupported ExtUnit arguments {}",
named_port_list[sig_name]
);
None
}
}
};
let inputs: Vec<_> = ext_entity
.sig()
.inputs()
.map(|arg| {
let sig_name = ext_entity.get_name(ext_entity.arg_value(arg)).unwrap();
let json_expr = named_port_list[sig_name];
let symbol = &Expression::gen_reference_name(json_expr, context);
context.unit_ctx.raw_name_to_value[symbol]
})
.flat_map(|arg| arg_to_val(arg))
.collect();
let outputs: Vec<_> = ext_entity
.sig()
.outputs()
.map(|arg| {
let sig_name = ext_entity.get_name(ext_entity.arg_value(arg)).unwrap();
let json_expr = named_port_list[sig_name];
let symbol = &Expression::gen_reference_name(json_expr, context);
context.unit_ctx.raw_name_to_value[symbol]
})
.flat_map(|arg| arg_to_val(arg))
.collect();
(inputs, outputs)
} else {

View File

@ -199,8 +199,10 @@ impl Tools {
}
pub fn resolve_dependencies<'a>(
json_modules: &HashMap<String, &'a JsonValue>,
json_list: &Vec<(String, &'a JsonValue)>,
) -> HashMap<String, Rc<RefCell<ModuleContext<'a>>>> {
let ref json_modules: HashMap<String, &JsonValue> =
HashMap::from_iter(json_list.iter().map(|(k, v)| (k.clone(), *v)));
let names_found: HashSet<String> =
HashSet::from_iter(json_modules.iter().map(|(name, _)| name.clone()));
let mut names_unfound = HashSet::new();