Add UnitData in ModuleContext/UnitContext

This commit is contained in:
Guojie Luo 2022-03-18 19:34:03 +08:00
parent 80dc88afee
commit 9682ad0340
3 changed files with 56 additions and 33 deletions

View File

@ -1,6 +1,6 @@
use crate::cst::{Expression, ModuleContext, Statement, SymbolKind, Tag, Tools};
use json::JsonValue;
use llhd::ir::{Signature, UnitBuilder, UnitData, UnitId, UnitKind, UnitName, Value};
use llhd::ir::{Signature, UnitId, UnitKind, UnitName, Value};
use llhd::ty::{int_ty, signal_ty, Type};
use std::collections::{HashMap, HashSet};
@ -10,24 +10,21 @@ use log::{debug, error, info, trace, warn};
pub struct AlwaysStatement {}
impl AlwaysStatement {
pub fn codegen(json: &JsonValue, context: &mut ModuleContext) -> UnitId {
pub fn codegen(json: &JsonValue, context: &mut ModuleContext) -> Option<UnitId> {
match json["children"][0]["tag"].as_str() {
Some(Tag::ALWAYS) => {
//Self::gen_always(json, context);
info!("HACK: only support 'always @(...)' at this point");
}
Some(Tag::ALWAYS) => Some(Self::gen_always(json, context)),
Some(Tag::ALWAYS_COMB) => {
error!("TODO: implmenent '{}'", Tag::ALWAYS_COMB);
None
}
Some(x) => {
error!("FIXME: case '{}' missing", x);
None
}
_ => {
panic!("unknown error at CST node '{}'", json);
}
}
Self::gen_always(json, context) // hack
}
fn gen_always(json: &JsonValue, context: &mut ModuleContext) -> UnitId {
@ -60,10 +57,10 @@ impl AlwaysStatement {
// first traversal
assert!(context.lvalues.is_empty());
assert!(context.rvalues.is_empty());
Self::gen_event_expression_list(json_event_expression_list, context, None);
Self::gen_event_expression_list(json_event_expression_list, context);
Statement::codegen(json_statement, context);
assert!(context.arg_to_raw_name.is_empty());
assert!(context.unit_ctx.arg_to_raw_name.is_empty());
let proc_signature = {
let mut ret = Signature::new();
@ -74,7 +71,10 @@ impl AlwaysStatement {
let width = symbol.width.clone();
let arg = ret.add_output(signal_ty(int_ty(width)));
context.arg_to_raw_name.insert(arg, lvalue.to_string());
context
.unit_ctx
.arg_to_raw_name
.insert(arg, lvalue.to_string());
} else {
error!("FIXME: symbol '{}' not found", lvalue);
}
@ -92,7 +92,10 @@ impl AlwaysStatement {
if symbol.kind != SymbolKind::Param {
let width = symbol.width.clone();
let arg = ret.add_input(signal_ty(int_ty(width)));
context.arg_to_raw_name.insert(arg, rvalue.to_string());
context
.unit_ctx
.arg_to_raw_name
.insert(arg, rvalue.to_string());
}
} else {
error!("FIXME: symbol '{}' not found", rvalue);
@ -102,7 +105,7 @@ impl AlwaysStatement {
ret
};
let mut unit_data = UnitData::new(
context.unit_ctx.new_data(
UnitKind::Process,
UnitName::local(format!(
"{}.always.{}",
@ -111,24 +114,19 @@ impl AlwaysStatement {
)),
proc_signature,
);
let proc_builder = UnitBuilder::new_anonymous(&mut unit_data);
// second traversal
Self::gen_event_expression_list(json_event_expression_list, context, Some(proc_builder));
Self::gen_event_expression_list(json_event_expression_list, context);
Statement::codegen(json_statement, context);
context.arg_to_raw_name.clear();
context.unit_ctx.arg_to_raw_name.clear();
context.lvalues.clear();
context.rvalues.clear();
context.module.add_unit(unit_data)
context.module.add_unit(context.unit_ctx.drop_data())
}
fn gen_event_expression_list(
json: &JsonValue,
context: &mut ModuleContext,
proc_builder: Option<UnitBuilder>,
) {
fn gen_event_expression_list(json: &JsonValue, context: &mut ModuleContext) {
let mut sensitivity_list = Vec::new();
let json_expressions = Tools::match_tags(
@ -167,14 +165,15 @@ impl AlwaysStatement {
}
}
if proc_builder.is_some() {
let builder = &mut proc_builder.unwrap();
if context.unit_ctx.data.is_some() {
let arg_to_raw_name = context.unit_ctx.arg_to_raw_name.clone();
let mut builder = context.unit_ctx.builder();
let mut arg_value_to_raw_name = HashMap::new();
let mut raw_name_to_value = HashMap::new();
let mut raw_name_to_prb = HashMap::new();
for (arg, name) in &context.arg_to_raw_name {
let value = builder.arg_value(*arg);
for (arg, name) in arg_to_raw_name {
let value = builder.arg_value(arg);
builder.set_name(value, name.to_string());
arg_value_to_raw_name.insert(value, name.to_string());
raw_name_to_value.insert(name.to_string(), value);

View File

@ -1,6 +1,6 @@
use linked_hash_map::LinkedHashMap;
use linked_hash_set::LinkedHashSet;
use llhd::ir::{Arg, Module};
use llhd::ir::{Arg, Module, Signature, UnitBuilder, UnitData, UnitKind, UnitName};
use std::{collections::HashMap, fmt};
pub struct ModuleContext {
@ -8,10 +8,14 @@ pub struct ModuleContext {
pub module: Module,
pub symbol: LinkedHashMap<String, SymbolInfo>,
pub tags: Vec<&'static str>,
// unit-specific members
pub arg_to_raw_name: HashMap<Arg, String>,
pub lvalues: LinkedHashSet<String>,
pub rvalues: LinkedHashSet<String>,
pub unit_ctx: UnitContext,
}
pub struct UnitContext {
pub data: Option<UnitData>,
pub arg_to_raw_name: HashMap<Arg, String>,
}
pub struct SymbolInfo {
@ -47,13 +51,33 @@ impl ModuleContext {
module: Module::new(),
symbol: LinkedHashMap::new(),
tags: Vec::new(),
arg_to_raw_name: HashMap::new(),
lvalues: LinkedHashSet::new(),
rvalues: LinkedHashSet::new(),
unit_ctx: UnitContext::new(),
}
}
}
impl UnitContext {
pub fn new() -> Self {
Self {
arg_to_raw_name: HashMap::new(),
data: None,
}
}
pub fn new_data(&mut self, kind: UnitKind, name: UnitName, sig: Signature) {
self.data = Some(UnitData::new(kind, name, sig));
}
pub fn drop_data(&mut self) -> UnitData {
self.data.take().unwrap()
}
pub fn builder(&mut self) -> UnitBuilder {
UnitBuilder::new_anonymous(self.data.as_mut().unwrap())
}
}
impl SymbolInfo {
pub fn new(kind: SymbolKind, width: usize) -> Self {
Self {

View File

@ -112,12 +112,12 @@ impl ModuleDeclaration {
let ext_to_proc: Vec<(ExtUnit, UnitId)> = json_always_statement
.iter()
.map(|&x| {
AlwaysStatement::codegen(x, &mut context);
let proc = context.module.processes().last().unwrap();
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())
(ext_proc, proc_id)
})
.collect();