Work on a correct instantiation of ExtUnit

This commit is contained in:
Guojie Luo 2022-02-25 21:30:15 +08:00
parent b0ffc2cfaa
commit e46dbbcd7c
15 changed files with 232 additions and 63 deletions

View File

@ -3,7 +3,7 @@ extern crate clap;
extern crate json;
use clap::Arg;
use cst_to_llhd::cst::{CodeReporter, DescriptionList, Tag, Tools};
use cst_to_llhd::cst::{CodeReporter, DescriptionList, Logger, Tag, Tools};
use std::{
process::{Command, Stdio},
result::Result,
@ -119,6 +119,8 @@ fn main_inner() -> Result<(), std::io::Error> {
println!("{}", module.dump());
}
Logger::print();
Ok(())
}

View File

@ -1,19 +1,16 @@
use crate::cst::{ModuleContext, ProceduralTimingControlStatement, Tag, Tools};
use crate::cst::{Logger, ModuleContext, ProceduralTimingControlStatement, Tag, Tools};
use json::JsonValue;
use llhd::ir::{Signature, Unit, UnitBuilder, UnitData, UnitKind, UnitName};
use llhd::ir::{Signature, UnitBuilder, UnitData, UnitId, UnitKind, UnitName};
use llhd::ty::{int_ty, signal_ty};
use std::collections::HashMap;
pub struct AlwaysStatement {}
impl AlwaysStatement {
pub fn codegen<'a>(json: &JsonValue, context: &'a mut ModuleContext) -> Unit<'a> {
let mut proc_data = UnitData::new(
UnitKind::Process,
UnitName::local(format!("{}.always.{}", context.name, context.process.len())),
Signature::new(),
);
let mut _proc_builder = UnitBuilder::new_anonymous(&mut proc_data);
let proc_id = context.module.add_unit(proc_data);
context.process.push(proc_id);
pub fn codegen(json: &JsonValue, context: &mut ModuleContext) -> UnitId {
let me = "AlwaysStatement::codegen()";
assert!(context.lvalues.is_empty());
assert!(context.rvalues.is_empty());
match json["children"][0]["tag"].as_str() {
Some(Tag::ALWAYS) => {
@ -28,16 +25,47 @@ impl AlwaysStatement {
ProceduralTimingControlStatement::codegen(json_statement[0], context);
}
Some(Tag::ALWAYS_COMB) => {
println!("TODO: implmenent AlwaysComb::codegen()");
Logger::insert(format!("TODO: implmenent AlwaysComb::codegen()"));
}
Some(x) => {
println!("FIXME: missing {}", x);
Logger::insert(format!("FIXME: missing {}", x));
}
_ => {
panic!();
}
}
context.module.unit(proc_id)
let mut arg_name = HashMap::new();
let proc_signature = {
let mut ret = Signature::new();
for lvalue in &context.lvalues {
if context.symbol_info.contains_key(lvalue) {
let width = context.symbol_info[lvalue].width.clone();
let arg = ret.add_output(signal_ty(int_ty(width)));
arg_name.insert(arg, lvalue);
} else {
Logger::insert(format!("FIXME: {} not found in {}", lvalue, me));
}
}
ret
};
let mut proc_data = UnitData::new(
UnitKind::Process,
UnitName::local(format!("{}.always.{}", context.name, context.process.len())),
proc_signature,
);
let mut proc_builder = UnitBuilder::new_anonymous(&mut proc_data);
for (arg, name) in arg_name {
let value = proc_builder.arg_value(arg);
proc_builder.set_name(value, name.to_string());
}
let proc_id = context.module.add_unit(proc_data);
context.process.push(proc_id);
context.lvalues.clear();
context.rvalues.clear();
proc_id
}
}

View File

@ -1,10 +1,10 @@
use crate::cst::ModuleContext;
use crate::cst::{Logger, ModuleContext};
use json::JsonValue;
pub struct CaseStatement {}
impl CaseStatement {
pub fn codegen(_json: &JsonValue, _context: &ModuleContext) {
println!("TODO: implement CaseStatement::codegen()");
Logger::insert(format!("TODO: implement CaseStatement::codegen()"));
}
}

View File

@ -4,7 +4,7 @@ use json::JsonValue;
pub struct ConditionalStatement {}
impl ConditionalStatement {
pub fn codegen(json: &JsonValue, context: &ModuleContext) {
pub fn codegen(json: &JsonValue, context: &mut ModuleContext) {
let json_if_header = Tools::match_tags(
vec![json],
vec![
@ -35,13 +35,13 @@ impl ConditionalStatement {
}
}
fn visit_if_body(json: &JsonValue, context: &ModuleContext) {
fn visit_if_body(json: &JsonValue, context: &mut ModuleContext) {
let json_child = &json["children"];
assert_eq!(json_child.len(), 1);
Statement::codegen(&json_child[0], context);
}
fn visit_else_body(json: &JsonValue, context: &ModuleContext) {
fn visit_else_body(json: &JsonValue, context: &mut ModuleContext) {
let json_child = &json["children"];
assert_eq!(json_child.len(), 1);
Statement::codegen(&json_child[0], context);

View File

@ -1,15 +1,17 @@
use llhd::ir::{Arg, Module, UnitId};
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
pub struct ModuleContext {
pub name: String,
pub module: Module,
pub arg_info: HashMap<Arg, ArgInfo>,
pub symbol_info: HashMap<String, SymbolInfo>,
pub arg_name: HashMap<Arg, String>,
pub process: Vec<UnitId>,
pub lvalues: HashSet<String>,
pub rvalues: HashSet<String>,
}
pub struct ArgInfo {
pub name: String,
pub struct SymbolInfo {
pub width: usize,
}
@ -18,16 +20,18 @@ impl ModuleContext {
Self {
name: String::new(),
module: Module::new(),
arg_info: HashMap::new(),
symbol_info: HashMap::new(),
arg_name: HashMap::new(),
process: Vec::new(),
lvalues: HashSet::new(),
rvalues: HashSet::new(),
}
}
}
impl ArgInfo {
pub fn new(name: &String, width: &usize) -> Self {
impl SymbolInfo {
pub fn new(width: &usize) -> Self {
Self {
name: name.to_string(),
width: width.clone(),
}
}

View File

@ -1,10 +1,10 @@
use crate::cst::ModuleContext;
use crate::cst::{Logger, ModuleContext};
use json::JsonValue;
pub struct EventExpressionList {}
impl EventExpressionList {
pub fn codegen(_json: &JsonValue, _context: &ModuleContext) {
println!("TODO: implement EventExpressionList::codegen()");
Logger::insert(format!("TODO: implement EventExpressionList::codegen()"));
}
}

View File

@ -1,10 +1,63 @@
use crate::cst::ModuleContext;
use crate::cst::{Logger, ModuleContext, Tag, Tools};
use json::JsonValue;
pub struct Expression {}
impl Expression {
pub fn codegen(_json: &JsonValue, _context: &ModuleContext) {
println!("TODO: implement Expression::codegen()");
pub fn codegen(json: &JsonValue, context: &ModuleContext) {
let json_child = &json["children"];
assert_eq!(json["tag"], Tag::EXPRESSION);
assert_eq!(json_child.len(), 1);
Self::codegen_internal(&json_child[0], context);
}
fn codegen_internal(json: &JsonValue, context: &ModuleContext) {
let me = "Expression::codegen()";
match json["tag"].as_str() {
Some(Tag::NUMBER) => {
Logger::insert(format!("FIXME: handle {} in {}", Tag::NUMBER, me));
}
Some(Tag::REFERENCE_CALL_BASE) => {
Logger::insert(format!(
"FIXME: handle {} in {}",
Tag::REFERENCE_CALL_BASE,
me
));
}
Some(Tag::UNARY_PREFIX_EXPRESSION) => {
let json_children = &json["children"];
assert_eq!(json_children.len(), 2);
Self::codegen_internal(&json_children[1], context);
Logger::insert(format!(
"TODO: complete the rest of {} in {}",
Tag::UNARY_PREFIX_EXPRESSION,
me
));
}
Some(Tag::BINARY_EXPRESSION) => {
let json_children = &json["children"];
assert_eq!(json_children.len(), 3);
Self::codegen_internal(&json_children[0], context);
Self::codegen_internal(&json_children[2], context);
Logger::insert(format!(
"TODO: complete the rest of {} in {}",
Tag::BINARY_EXPRESSION,
me
));
}
Some(Tag::PAREN_GROUP) => {
let json_expression =
Tools::match_tags(vec![json], vec![Tag::PAREN_GROUP, Tag::EXPRESSION]);
assert_eq!(json_expression.len(), 1);
Self::codegen(&json_expression[0], context);
}
Some(x) => {
Logger::insert(format!("FIXME: handle {} in {}", x, me));
}
_ => panic!(),
};
}
}

View File

@ -16,7 +16,7 @@ mod tools;
use always_statement::AlwaysStatement;
use case_statement::CaseStatement;
use conditional_statement::ConditionalStatement;
use context::{ArgInfo, ModuleContext};
use context::{ModuleContext, SymbolInfo};
use event_expression_list::EventExpressionList;
use expression::Expression;
use module_declaration::ModuleDeclaration;
@ -27,4 +27,4 @@ use statement::Statement;
pub use description_list::DescriptionList;
pub use tags::Tag;
pub use tools::{CodeReporter, Tools};
pub use tools::{CodeReporter, Logger, Tools};

View File

@ -1,7 +1,7 @@
use crate::cst::{AlwaysStatement, ArgInfo, ModuleContext, Tag, Tools};
use crate::cst::{AlwaysStatement, ModuleContext, SymbolInfo, Tag, Tools};
use json::JsonValue;
use llhd::ir::{
ExtUnit, InstBuilder, Module, Signature, UnitBuilder, UnitData, UnitKind, UnitName,
ExtUnit, InstBuilder, Module, Signature, UnitBuilder, UnitData, UnitId, UnitKind, UnitName,
};
use llhd::ty::{int_ty, signal_ty};
@ -17,29 +17,38 @@ impl ModuleDeclaration {
let mut entity_builder = UnitBuilder::new_anonymous(&mut entity_data);
for (arg, arg_info) in context.arg_info.iter() {
for (arg, arg_name) in context.arg_name.iter() {
let value = entity_builder.arg_value(*arg);
entity_builder.set_name(value, arg_info.name.to_string());
entity_builder.set_name(value, arg_name.to_string());
}
let process_list: Vec<ExtUnit> = Tools::match_tags(
let json_always_statement = &Tools::match_tags(
vec![json],
vec![
Tag::MODULE_DECLARATION,
Tag::MODULE_ITEM_LIST,
Tag::ALWAYS_STATEMENT,
],
)
.iter()
.map(|&x| {
let proc = AlwaysStatement::codegen(x, &mut context);
entity_builder.add_extern(proc.name().clone(), proc.sig().clone())
})
.collect();
);
let ext_to_proc = json_always_statement
.iter()
.map(|&x| {
let proc_id = AlwaysStatement::codegen(x, &mut context);
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::<Vec<(ExtUnit, UnitId)>>();
let mut inst_builder = InstBuilder::new(&mut entity_builder);
for process in process_list {
inst_builder.inst(process, vec![], vec![]); // FIXME
for (ext_proc, proc_id) in ext_to_proc {
let unit = context.module.unit(proc_id); // FIXME: should be entity_builder.unit()
inst_builder.inst(
ext_proc,
unit.input_args().into_iter().collect(),
unit.output_args().into_iter().collect(),
);
}
entity_builder.finish();
@ -82,11 +91,17 @@ impl ModuleDeclaration {
for (name, width) in input_info {
let arg = signature.add_input(signal_ty(int_ty(width.clone())));
context.arg_info.insert(arg, ArgInfo::new(name, width));
context
.symbol_info
.insert(name.to_string(), SymbolInfo::new(width));
context.arg_name.insert(arg, name.to_string());
}
for (name, width) in output_info {
let arg = signature.add_output(signal_ty(int_ty(width.clone())));
context.arg_info.insert(arg, ArgInfo::new(name, width));
context
.symbol_info
.insert(name.to_string(), SymbolInfo::new(width));
context.arg_name.insert(arg, name.to_string());
}
signature

View File

@ -1,10 +1,41 @@
use crate::cst::ModuleContext;
use crate::cst::{Expression, Logger, ModuleContext, Tag, Tools};
use json::JsonValue;
pub struct NonblockingAssignmentStatement {}
impl NonblockingAssignmentStatement {
pub fn codegen(_json: &JsonValue, _context: &ModuleContext) {
println!("TODO: implement NonblockingAssignmentStatement::codegen()");
pub fn codegen(json: &JsonValue, context: &mut ModuleContext) {
assert_eq!(json["tag"], Tag::NONBLOCKING_ASSIGNMENT_STATEMENT);
let (json_lpvalue, json_expression) = {
let json_children = &json["children"];
assert_eq!(json_children.len(), 4);
assert_eq!(json_children[1]["tag"], "<=");
assert_eq!(json_children[3]["tag"], ";");
(&json_children[0], &json_children[2])
};
let json_symbol_identifier = Tools::match_tags(
vec![json_lpvalue],
vec![
Tag::LP_VALUE,
Tag::REFERENCE_CALL_BASE,
Tag::REFERENCE,
Tag::LOCAL_ROOT,
Tag::UNQUALIFIED_ID,
Tag::SYMBOL_IDENTIFIER,
],
);
assert_eq!(json_symbol_identifier.len(), 1);
context
.lvalues
.insert(json_symbol_identifier[0]["text"].to_string());
Expression::codegen(json_expression, context);
Logger::insert(format!(
"TODO: complete the rest of NonblockingAssignmentStatement::codegen()"
));
}
}

View File

@ -4,12 +4,15 @@ use json::JsonValue;
pub struct ProceduralTimingControlStatement {}
impl ProceduralTimingControlStatement {
pub fn codegen(json: &JsonValue, context: &ModuleContext) {
pub fn codegen(json: &JsonValue, context: &mut ModuleContext) {
assert_eq!(json["tag"], Tag::PROCEDURAL_TIMING_CONTROL_STATEMENT);
assert_eq!(json["children"].len(), 2);
let json_event_control = &json["children"][0];
let json_statement = &json["children"][1];
let (json_event_control, json_statement) = {
let json_children = &json["children"];
assert_eq!(json_children.len(), 2);
(&json_children[0], &json_children[1])
};
let json_event_expression_list = Tools::match_tags(
vec![json_event_control],

View File

@ -4,7 +4,7 @@ use json::JsonValue;
pub struct SeqBlock {}
impl SeqBlock {
pub fn codegen(json: &JsonValue, context: &ModuleContext) {
pub fn codegen(json: &JsonValue, context: &mut ModuleContext) {
let json_block_item_statement_list = {
let json_vec = Tools::match_tags(
vec![json],

View File

@ -1,13 +1,13 @@
use crate::cst::{
CaseStatement, ConditionalStatement, ModuleContext, NonblockingAssignmentStatement, SeqBlock,
Tag,
CaseStatement, ConditionalStatement, Logger, ModuleContext, NonblockingAssignmentStatement,
SeqBlock, Tag,
};
use json::JsonValue;
pub struct Statement {}
impl Statement {
pub fn codegen(json: &JsonValue, context: &ModuleContext) {
pub fn codegen(json: &JsonValue, context: &mut ModuleContext) {
match json["tag"].as_str() {
Some(Tag::SEQ_BLOCK) => SeqBlock::codegen(json, context),
Some(Tag::CONDITIONAL_STATEMENT) => ConditionalStatement::codegen(json, context),
@ -16,7 +16,7 @@ impl Statement {
NonblockingAssignmentStatement::codegen(json, context)
}
Some(x) => {
println!("FIXME: missing {}", x);
Logger::insert(format!("FIXME: missing {}", x));
}
_ => panic!(),
};

View File

@ -19,7 +19,15 @@ impl Tag {
pub const DIMENSION_RANGE: &'static str = "kDimensionRange";
pub const SYMBOL_IDENTIFIER: &'static str = "SymbolIdentifier";
pub const LP_VALUE: &'static str = "kLPValue";
pub const REFERENCE_CALL_BASE: &'static str = "kReferenceCallBase";
pub const REFERENCE: &'static str = "kReference";
pub const LOCAL_ROOT: &'static str = "kLocalRoot";
pub const EXPRESSION: &'static str = "kExpression";
pub const UNARY_PREFIX_EXPRESSION: &'static str = "kUnaryPrefixExpression";
pub const BINARY_EXPRESSION: &'static str = "kBinaryExpression";
pub const NUMBER: &'static str = "kNumber";
pub const DEC_NUMBER: &'static str = "TK_DecNumber";

View File

@ -1,4 +1,5 @@
use json::JsonValue;
use std::collections::HashSet;
use std::{
fs::File,
io::{BufRead, BufReader},
@ -20,6 +21,30 @@ impl Tools {
}
}
pub struct Logger {}
static mut LOGGER_MESSAGES: Vec<String> = Vec::new();
impl Logger {
pub fn insert(msg: String) {
unsafe {
LOGGER_MESSAGES.push(msg);
}
}
pub fn print() {
let mut msg = HashSet::new();
unsafe {
for m in &LOGGER_MESSAGES {
if !msg.contains(&m) {
println!("{}", m);
msg.insert(m);
}
}
}
}
}
pub struct CodeReporter {
file_name: String,
line_breakers: Vec<usize>,