From 9682ad03406c878bc1ef2995238cd30e07441f28 Mon Sep 17 00:00:00 2001 From: Guojie Luo Date: Fri, 18 Mar 2022 19:34:03 +0800 Subject: [PATCH] Add UnitData in ModuleContext/UnitContext --- src/cst/always_statement.rs | 51 +++++++++++++++++------------------ src/cst/context.rs | 32 +++++++++++++++++++--- src/cst/module_declaration.rs | 6 ++--- 3 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/cst/always_statement.rs b/src/cst/always_statement.rs index c40a67d..494db14 100644 --- a/src/cst/always_statement.rs +++ b/src/cst/always_statement.rs @@ -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 { 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, - ) { + 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); diff --git a/src/cst/context.rs b/src/cst/context.rs index 7866d90..081f00f 100644 --- a/src/cst/context.rs +++ b/src/cst/context.rs @@ -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, pub tags: Vec<&'static str>, - // unit-specific members - pub arg_to_raw_name: HashMap, pub lvalues: LinkedHashSet, pub rvalues: LinkedHashSet, + pub unit_ctx: UnitContext, +} + +pub struct UnitContext { + pub data: Option, + pub arg_to_raw_name: HashMap, } 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 { diff --git a/src/cst/module_declaration.rs b/src/cst/module_declaration.rs index aaff09b..0d28733 100644 --- a/src/cst/module_declaration.rs +++ b/src/cst/module_declaration.rs @@ -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();