Restructure process declaration and instantiation

This commit is contained in:
Guojie Luo 2022-04-10 13:29:28 +08:00
parent eb2b2da020
commit 22b24e174d
2 changed files with 90 additions and 70 deletions

View File

@ -79,6 +79,20 @@ impl UnitContext {
ty_active: None,
}
}
pub fn drop(&mut self) -> Self {
let ret = Self {
lvalues: self.lvalues.iter().map(|x| x.clone()).collect(),
rvalues: self.rvalues.iter().map(|x| x.clone()).collect(),
data: self.data.take(),
raw_name_to_arg: self.raw_name_to_arg.drain().collect(),
raw_name_to_value: self.raw_name_to_value.drain().collect(),
raw_name_to_shadow: self.raw_name_to_shadow.drain().collect(),
bb_head: self.bb_head.drain(..).collect(),
ty_active: self.ty_active.take(),
};
self.clear();
ret
}
pub fn new_data(&mut self, kind: UnitKind, name: UnitName, sig: Signature) {
self.data = Some(UnitData::new(kind, name, sig));

View File

@ -1,12 +1,13 @@
use crate::cst::{
AlwaysStatement, ModuleContext, Number, SymbolDeclaration, SymbolInfo, SymbolKind, Tag, Tools,
UnitContext,
};
use json::JsonValue;
use llhd::{
ir::{ExtUnit, Module, Signature, UnitBuilder, UnitData, UnitId, UnitKind, Value},
ty::{int_ty, signal_ty},
};
use std::collections::{HashMap, HashSet};
use std::collections::HashMap;
#[allow(unused_imports)]
use log::{debug, error, info, trace, warn};
@ -22,26 +23,23 @@ impl ModuleDeclaration {
let wire_info = &SymbolDeclaration::get_wire_info(json);
let param_info = &SymbolDeclaration::get_param_info(json);
let mut arg_to_raw_name = HashMap::new();
let entity_name = SymbolDeclaration::get_entity_name(json, &mut context);
let entity_signature = {
let mut signature = Signature::new();
let raw_name_to_arg = &mut context.unit_ctx.raw_name_to_arg;
let symbol = &mut context.symbol;
for (name, width) in input_info {
let arg = signature.add_input(signal_ty(int_ty(*width)));
arg_to_raw_name.insert(arg, name.to_string());
context
.symbol
.insert(name.to_string(), SymbolInfo::new(SymbolKind::Input, *width));
let sym_info = SymbolInfo::new(SymbolKind::Input, *width);
raw_name_to_arg.insert(name.clone(), arg);
symbol.insert(name.clone(), sym_info);
}
for (name, width) in output_info {
let arg = signature.add_output(signal_ty(int_ty(*width)));
arg_to_raw_name.insert(arg, name.to_string());
context.symbol.insert(
name.to_string(),
SymbolInfo::new(SymbolKind::Output, *width),
);
let sym_info = SymbolInfo::new(SymbolKind::Output, *width);
raw_name_to_arg.insert(name.clone(), arg);
symbol.insert(name.clone(), sym_info);
}
signature
@ -52,16 +50,16 @@ impl ModuleDeclaration {
{
let mut entity_builder = UnitBuilder::new_anonymous(&mut entity_data);
let mut value_set = HashSet::new();
let mut raw_name_set = HashSet::new();
let mut zeros = HashMap::new();
// set port names
for (arg, raw_name) in arg_to_raw_name {
for (raw_name, &arg) in &context.unit_ctx.raw_name_to_arg {
let arg_value = entity_builder.arg_value(arg);
entity_builder.set_name(arg_value, raw_name.to_string());
value_set.insert(arg_value);
raw_name_set.insert(raw_name.to_string());
entity_builder.set_name(arg_value, raw_name.clone());
context
.unit_ctx
.raw_name_to_value
.insert(raw_name.clone(), arg_value);
}
let mut declare = |info_list: &Vec<(String, usize, Option<&JsonValue>)>,
@ -79,7 +77,7 @@ impl ModuleDeclaration {
match kind {
SymbolKind::Reg | SymbolKind::Wire => {
for (name, width, _) in info_list {
if !raw_name_set.contains(name) {
if !context.unit_ctx.raw_name_to_value.contains_key(name) {
let n = name.to_string();
let w = width.clone();
let zero = if zeros.contains_key(&w) {
@ -91,7 +89,10 @@ impl ModuleDeclaration {
};
let value = entity_builder.ins().sig(zero);
entity_builder.set_name(value, n);
value_set.insert(value);
context
.unit_ctx
.raw_name_to_value
.insert(name.clone(), value);
}
}
}
@ -110,66 +111,71 @@ impl ModuleDeclaration {
declare(&wire_info, SymbolKind::Wire);
declare(&param_info, SymbolKind::Param);
// declare and implement processes
let json_always_statement = &Tools::match_tags(
vec![json],
vec![
Tag::MODULE_DECLARATION,
Tag::MODULE_ITEM_LIST,
Tag::ALWAYS_STATEMENT,
],
);
let ext_to_proc: Vec<(ExtUnit, UnitId)> = json_always_statement
.iter()
.map(|&x| {
let proc_id = AlwaysStatement::codegen(x, &mut context).unwrap();
let proc = context.module.unit(proc_id);
//proc.verify();
let ext_proc =
entity_builder.add_extern(proc.name().clone(), proc.sig().clone());
(ext_proc, proc_id)
})
.collect();
// clear UnitContext before declare processes
let entity_ctx = context.unit_ctx.drop();
let entity = &entity_builder.unit();
let mut name_to_value = HashMap::new();
for value in value_set {
let name = entity.get_name(value).unwrap().to_string();
name_to_value.insert(name, value);
}
// instantiate processes
for (ext_proc, proc_id) in ext_to_proc {
let proc = &context.module.unit(proc_id);
let inputs: Vec<Value> = proc
.input_args()
.into_iter()
.map(|x| {
let name = &proc.get_name(x).unwrap().to_string();
name_to_value[name]
})
.collect();
let outputs: Vec<Value> = proc
.output_args()
.into_iter()
.map(|x| {
let name = &proc.get_name(x).unwrap().to_string();
name_to_value[name]
})
.collect();
entity_builder.ins().inst(ext_proc, inputs, outputs);
}
// declare and instantiate processes
Self::instantiate_processes(json, &mut entity_builder, &entity_ctx, &mut context);
entity_builder.finish();
}
context.module.add_unit(entity_data);
debug!(
"module codegen >>>>>>>>>\n{}<<<<<<<<<",
">>>>>>>>>{0}>>>>>>>>>\n{1}<<<<<<<<<{0}<<<<<<<<<",
" module-codegen ",
context.module.dump()
);
context.module
}
fn instantiate_processes(
json: &JsonValue,
entity_builder: &mut UnitBuilder,
entity_ctx: &UnitContext,
context: &mut ModuleContext,
) {
let json_always_statement = &Tools::match_tags(
vec![json],
vec![
Tag::MODULE_DECLARATION,
Tag::MODULE_ITEM_LIST,
Tag::ALWAYS_STATEMENT,
],
);
// declare processes
let ext_to_proc: Vec<(ExtUnit, UnitId)> = json_always_statement
.iter()
.map(|&x| {
let proc_id = AlwaysStatement::codegen(x, context).unwrap();
let proc = context.module.unit(proc_id);
let ext_proc = entity_builder.add_extern(proc.name().clone(), proc.sig().clone());
(ext_proc, proc_id)
})
.collect();
// instantiate processes
for (ext_proc, proc_id) in ext_to_proc {
let proc = &context.module.unit(proc_id);
let inputs: Vec<Value> = proc
.input_args()
.into_iter()
.map(|x| {
let name = &proc.get_name(x).unwrap().to_string();
entity_ctx.raw_name_to_value[name]
})
.collect();
let outputs: Vec<Value> = proc
.output_args()
.into_iter()
.map(|x| {
let name = &proc.get_name(x).unwrap().to_string();
entity_ctx.raw_name_to_value[name]
})
.collect();
entity_builder.ins().inst(ext_proc, inputs, outputs);
}
}
}