Add UnitData in ModuleContext/UnitContext
This commit is contained in:
parent
80dc88afee
commit
9682ad0340
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue