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, 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) { pub fn new_data(&mut self, kind: UnitKind, name: UnitName, sig: Signature) {
self.data = Some(UnitData::new(kind, name, sig)); self.data = Some(UnitData::new(kind, name, sig));

View File

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