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 clap::Arg;
use cst_to_llhd::cst::{Tag, Tools}; use cst_to_llhd::cst::{Tag, Tools};
use json::JsonValue; use json::JsonValue;
use std::{collections::HashMap, fs::File, io::Read, result::Result}; use std::{fs::File, io::Read, result::Result};
#[allow(unused_imports)] #[allow(unused_imports)]
use log::{debug, error, info, trace, warn}; 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(); let json_top = json::parse(contents.as_str()).unwrap();
assert!(json_top.len() == 1); 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; let sv_file_name = json_top.entries().next().unwrap().0;
info!(r#"codegen from CST to LLHD for "{}" ..."#, sv_file_name); info!(r#"codegen from CST to LLHD for "{}" ..."#, sv_file_name);
let json_tree = &json_top[sv_file_name]["tree"]; 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 cst_to_llhd::cst::{Tag, Tools};
use json::JsonValue; use json::JsonValue;
use llhd::opt::{Pass, PassContext}; use llhd::opt::{Pass, PassContext};
use std::{collections::HashMap, iter::FromIterator, result::Result}; use std::result::Result;
#[allow(unused_imports)] #[allow(unused_imports)]
use log::{debug, error, info, trace, warn}; use log::{debug, error, info, trace, warn};
@ -45,9 +45,9 @@ fn main_inner() -> Result<(), std::io::Error> {
}) })
.collect(); .collect();
let ref json_modules: HashMap<String, &JsonValue> = let ref json_modules: Vec<(String, &JsonValue)> = json_top_list
HashMap::from_iter(json_top_list.iter().flat_map(|json_top| { .iter()
let json_modules: Vec<_> = { .flat_map(|json_top| {
let sv_file_name = json_top.entries().next().unwrap().0; let sv_file_name = json_top.entries().next().unwrap().0;
let json_tree = &json_top[sv_file_name]["tree"]; let json_tree = &json_top[sv_file_name]["tree"];
Tools::match_tags( Tools::match_tags(
@ -56,11 +56,9 @@ fn main_inner() -> Result<(), std::io::Error> {
) )
.iter() .iter()
.map(|&json| (Tools::module_name(json), json)) .map(|&json| (Tools::module_name(json), json))
.collect() .collect::<Vec<_>>()
}; })
.collect();
json_modules
}));
let contexts = Tools::resolve_dependencies(json_modules); let contexts = Tools::resolve_dependencies(json_modules);
for (_, context_ref) in contexts { for (_, context_ref) in contexts {

View File

@ -1,5 +1,5 @@
use crate::cst::{ use crate::cst::{
AlwaysStatement, Expression, ModuleContext, NetVariableAssignment, SymbolDeclaration, AlwaysStatement, Expression, ModuleContext, NetVariableAssignment, Number, SymbolDeclaration,
SymbolKind, Tag, Tools, UnitContext, SymbolKind, Tag, Tools, UnitContext,
}; };
use json::JsonValue; use json::JsonValue;
@ -177,23 +177,21 @@ impl<'a> ModuleDeclaration {
Tag::PAREN_GROUP, Tag::PAREN_GROUP,
Tag::PORT_ACTUAL_LIST, Tag::PORT_ACTUAL_LIST,
]; ];
let pos_port_expr = [ let pos_port_expr_path = [
Tag::PORT_ACTUAL_LIST, Tag::PORT_ACTUAL_LIST,
Tag::ACTUAL_POSITIONAL_PORT, Tag::ACTUAL_POSITIONAL_PORT,
Tag::EXPRESSION, Tag::EXPRESSION,
Tag::REFERENCE_CALL_BASE, Tag::REFERENCE_CALL_BASE,
]; ];
let named_port_name = [ let named_port_name_path = [
Tag::PORT_ACTUAL_LIST, Tag::PORT_ACTUAL_LIST,
Tag::ACTUAL_NAMED_PORT, Tag::ACTUAL_NAMED_PORT,
Tag::SYMBOL_IDENTIFIER, Tag::SYMBOL_IDENTIFIER,
]; ];
let named_port_expr = [ let named_port_arg_path = [
Tag::PORT_ACTUAL_LIST, Tag::PORT_ACTUAL_LIST,
Tag::ACTUAL_NAMED_PORT, Tag::ACTUAL_NAMED_PORT,
Tag::PAREN_GROUP, Tag::PAREN_GROUP,
Tag::EXPRESSION,
Tag::REFERENCE_CALL_BASE,
]; ];
warn!("TODO: to support complex arguments in ExtUnit instantiation"); 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 name = json_types[0]["text"].to_string();
let json_ports = &Tools::match_tags(vec![x], port_path.to_vec()); let json_ports = &Tools::match_tags(vec![x], port_path.to_vec());
let json_named_port_names = let json_named_port_names =
Tools::match_tags(json_ports.clone(), named_port_name.to_vec()); Tools::match_tags(json_ports.clone(), named_port_name_path.to_vec());
let json_named_port_exprs = let json_named_port_args =
Tools::match_tags(json_ports.clone(), named_port_expr.to_vec()); Tools::match_tags(json_ports.clone(), named_port_arg_path.to_vec());
let json_pos_port_exprs = 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 let named_port_list: HashMap<String, _> = json_named_port_names
.into_iter() .into_iter()
.map(|x| x["text"].to_string()) .map(|x| x["text"].to_string())
.zip(json_named_port_exprs.into_iter()) .zip(json_named_port_args.into_iter())
.collect(); .collect();
let pos_port_list: HashMap<usize, _> = json_pos_port_exprs let pos_port_list: HashMap<usize, _> = json_pos_port_exprs
.iter() .iter()
@ -246,25 +244,47 @@ impl<'a> ModuleDeclaration {
let ext_context = ext_context_rc.as_ref().borrow(); let ext_context = ext_context_rc.as_ref().borrow();
let ext_entity = ext_context.module.entities().next().unwrap(); let ext_entity = ext_context.module.entities().next().unwrap();
let (inputs, outputs) = if named_port_list.len() > 0 { 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 let inputs: Vec<_> = ext_entity
.sig() .sig()
.inputs() .inputs()
.map(|arg| { .flat_map(|arg| arg_to_val(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]
})
.collect(); .collect();
let outputs: Vec<_> = ext_entity let outputs: Vec<_> = ext_entity
.sig() .sig()
.outputs() .outputs()
.map(|arg| { .flat_map(|arg| arg_to_val(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]
})
.collect(); .collect();
(inputs, outputs) (inputs, outputs)
} else { } else {

View File

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