Remove lvalues and rvalues from context
This commit is contained in:
parent
88632042e2
commit
e53cee4959
|
@ -126,9 +126,8 @@ name = "cst-to-llhd"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"indexmap",
|
||||||
"json",
|
"json",
|
||||||
"linked-hash-map",
|
|
||||||
"linked_hash_set",
|
|
||||||
"llhd",
|
"llhd",
|
||||||
"log",
|
"log",
|
||||||
"num",
|
"num",
|
||||||
|
@ -155,6 +154,12 @@ dependencies = [
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
@ -183,6 +188,16 @@ dependencies = [
|
||||||
"quick-error",
|
"quick-error",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -216,21 +231,6 @@ version = "0.2.121"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
|
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linked-hash-map"
|
|
||||||
version = "0.5.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linked_hash_set"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588"
|
|
||||||
dependencies = [
|
|
||||||
"linked-hash-map",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "llhd"
|
name = "llhd"
|
||||||
version = "0.16.0"
|
version = "0.16.0"
|
||||||
|
|
|
@ -12,8 +12,7 @@ llhd = "*"
|
||||||
log = "*"
|
log = "*"
|
||||||
num = "0.3.1"
|
num = "0.3.1"
|
||||||
num-bigint = "0.3.3"
|
num-bigint = "0.3.3"
|
||||||
linked_hash_set = "*"
|
indexmap = "*"
|
||||||
linked-hash-map = "*"
|
|
||||||
pretty_env_logger = "0.4"
|
pretty_env_logger = "0.4"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
cst::{Expression, ModuleContext, Statement, SymbolKind, Tag, UnitContext},
|
cst::{Expression, ModuleContext, Statement, SymbolKind, Tag, UnitContext},
|
||||||
tools::Tools,
|
tools::{EventControl, Tools},
|
||||||
};
|
};
|
||||||
|
use indexmap::{map::IndexMap, set::IndexSet};
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
use linked_hash_map::LinkedHashMap as HashMap;
|
|
||||||
use llhd::{
|
use llhd::{
|
||||||
ir::{Signature, UnitId, UnitKind, UnitName, Value},
|
ir::{Signature, UnitId, UnitKind, UnitName, Value},
|
||||||
ty::{int_ty, signal_ty},
|
ty::{int_ty, signal_ty},
|
||||||
|
@ -55,41 +55,44 @@ impl AlwaysStatement {
|
||||||
(json_event_control[0], &json_children[1])
|
(json_event_control[0], &json_children[1])
|
||||||
};
|
};
|
||||||
|
|
||||||
// first traversal
|
let proc_names = EventControl::process_names(json);
|
||||||
assert!(context.unit_ctx.is_empty());
|
|
||||||
Self::gen_event_expression_list(json_event_expression_list, context);
|
|
||||||
Statement::codegen(json_statement, context);
|
|
||||||
|
|
||||||
assert!(context.unit_ctx.raw_name_to_arg.is_empty());
|
assert!(context.unit_ctx.raw_name_to_arg.is_empty());
|
||||||
let proc_signature = {
|
let proc_signature = {
|
||||||
let mut ret = Signature::new();
|
let mut sig = Signature::new();
|
||||||
|
|
||||||
for lvalue in &context.unit_ctx.lvalues {
|
for lvalue in &proc_names.lvalues {
|
||||||
if context.symbol.contains_key(lvalue) {
|
if context.symbol.contains_key(lvalue) {
|
||||||
let symbol = &context.symbol[lvalue];
|
let symbol = &context.symbol[lvalue];
|
||||||
assert_ne!(symbol.kind, SymbolKind::Param);
|
assert_ne!(symbol.kind, SymbolKind::Param);
|
||||||
|
|
||||||
let width = symbol.value.width.clone();
|
let width = symbol.value.width.clone();
|
||||||
let arg = ret.add_output(signal_ty(int_ty(width)));
|
let arg = sig.add_output(signal_ty(int_ty(width)));
|
||||||
context.unit_ctx.raw_name_to_arg.insert(lvalue.clone(), arg);
|
context.unit_ctx.raw_name_to_arg.insert(lvalue.clone(), arg);
|
||||||
} else {
|
} else {
|
||||||
error!("FIXME: symbol '{}' not found", lvalue);
|
error!("FIXME: symbol '{}' not found", lvalue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let rvalues: Vec<String> = context
|
let mut rvalues = [
|
||||||
.unit_ctx
|
proc_names.posedges.clone(),
|
||||||
.rvalues
|
proc_names.negedges.clone(),
|
||||||
.iter()
|
proc_names.levels.clone(),
|
||||||
.filter(|&x| !context.unit_ctx.lvalues.contains(x))
|
proc_names.ctrl_values.clone(),
|
||||||
.map(|x| x.clone())
|
proc_names.rvalues.clone(),
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.fold(IndexSet::new(), |acc, hs| acc.union(hs).cloned().collect());
|
||||||
|
rvalues = rvalues
|
||||||
|
.into_iter()
|
||||||
|
.filter(|x| !proc_names.lvalues.contains(x))
|
||||||
.collect();
|
.collect();
|
||||||
for rvalue in &rvalues {
|
for rvalue in &rvalues {
|
||||||
if context.symbol.contains_key(rvalue) {
|
if context.symbol.contains_key(rvalue) {
|
||||||
let symbol = &context.symbol[rvalue];
|
let symbol = &context.symbol[rvalue];
|
||||||
if symbol.kind != SymbolKind::Param {
|
if symbol.kind != SymbolKind::Param {
|
||||||
let width = symbol.value.width.clone();
|
let width = symbol.value.width.clone();
|
||||||
let arg = ret.add_input(signal_ty(int_ty(width)));
|
let arg = sig.add_input(signal_ty(int_ty(width)));
|
||||||
context.unit_ctx.raw_name_to_arg.insert(rvalue.clone(), arg);
|
context.unit_ctx.raw_name_to_arg.insert(rvalue.clone(), arg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -97,7 +100,7 @@ impl AlwaysStatement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
sig
|
||||||
};
|
};
|
||||||
|
|
||||||
context.unit_ctx.new_data(
|
context.unit_ctx.new_data(
|
||||||
|
@ -110,8 +113,15 @@ impl AlwaysStatement {
|
||||||
proc_signature,
|
proc_signature,
|
||||||
);
|
);
|
||||||
|
|
||||||
// second traversal
|
Self::gen_event_expression_list(
|
||||||
Self::gen_event_expression_list(json_event_expression_list, context);
|
json_event_expression_list,
|
||||||
|
proc_names
|
||||||
|
.rvalues
|
||||||
|
.union(&proc_names.ctrl_values)
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
context,
|
||||||
|
);
|
||||||
Statement::codegen(json_statement, context);
|
Statement::codegen(json_statement, context);
|
||||||
|
|
||||||
Tools::beautify(&mut context.unit_ctx);
|
Tools::beautify(&mut context.unit_ctx);
|
||||||
|
@ -120,8 +130,12 @@ impl AlwaysStatement {
|
||||||
context.module.add_unit(context.unit_ctx.drop_data())
|
context.module.add_unit(context.unit_ctx.drop_data())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_event_expression_list<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) {
|
fn gen_event_expression_list<'a>(
|
||||||
let mut sensitivity_list = HashMap::new();
|
json: &'a JsonValue,
|
||||||
|
rvalues: IndexSet<String>,
|
||||||
|
context: &mut ModuleContext<'a>,
|
||||||
|
) {
|
||||||
|
let mut sensitivity_list = IndexMap::new();
|
||||||
|
|
||||||
let json_expressions = Tools::match_tags(
|
let json_expressions = Tools::match_tags(
|
||||||
vec![json],
|
vec![json],
|
||||||
|
@ -133,18 +147,15 @@ impl AlwaysStatement {
|
||||||
|
|
||||||
match json_children[0]["tag"].as_str() {
|
match json_children[0]["tag"].as_str() {
|
||||||
Some(Tag::POS_EDGE) => {
|
Some(Tag::POS_EDGE) => {
|
||||||
let symbol =
|
let symbol = Expression::gen_reference_name(&json_children[1]["children"][0]);
|
||||||
Expression::gen_reference_name(&json_children[1]["children"][0], context);
|
|
||||||
sensitivity_list.insert(symbol, Tag::POS_EDGE);
|
sensitivity_list.insert(symbol, Tag::POS_EDGE);
|
||||||
}
|
}
|
||||||
Some(Tag::NEG_EDGE) => {
|
Some(Tag::NEG_EDGE) => {
|
||||||
let symbol =
|
let symbol = Expression::gen_reference_name(&json_children[1]["children"][0]);
|
||||||
Expression::gen_reference_name(&json_children[1]["children"][0], context);
|
|
||||||
sensitivity_list.insert(symbol, Tag::NEG_EDGE);
|
sensitivity_list.insert(symbol, Tag::NEG_EDGE);
|
||||||
}
|
}
|
||||||
Some(Tag::EXPRESSION) => {
|
Some(Tag::EXPRESSION) => {
|
||||||
let symbol =
|
let symbol = Expression::gen_reference_name(&json_children[0]["children"][0]);
|
||||||
Expression::gen_reference_name(&json_children[0]["children"][0], context);
|
|
||||||
sensitivity_list.insert(symbol, Tag::EVENT_EXPRESSION);
|
sensitivity_list.insert(symbol, Tag::EVENT_EXPRESSION);
|
||||||
}
|
}
|
||||||
_ => panic!("unknown error at CST node '{}'", json),
|
_ => panic!("unknown error at CST node '{}'", json),
|
||||||
|
@ -156,12 +167,11 @@ impl AlwaysStatement {
|
||||||
let raw_name_to_value = &mut unit_ctx.raw_name_to_value;
|
let raw_name_to_value = &mut unit_ctx.raw_name_to_value;
|
||||||
let raw_name_to_shadow = &mut unit_ctx.raw_name_to_shadow;
|
let raw_name_to_shadow = &mut unit_ctx.raw_name_to_shadow;
|
||||||
let raw_name_to_arg = &unit_ctx.raw_name_to_arg;
|
let raw_name_to_arg = &unit_ctx.raw_name_to_arg;
|
||||||
let rvalues = &unit_ctx.rvalues;
|
|
||||||
|
|
||||||
let mut builder = UnitContext::builder(&mut unit_ctx.data);
|
let mut builder = UnitContext::builder(&mut unit_ctx.data);
|
||||||
|
|
||||||
let mut arg_value_to_raw_name = HashMap::new();
|
let mut arg_value_to_raw_name = IndexMap::new();
|
||||||
let mut raw_name_to_prb_init = HashMap::new();
|
let mut raw_name_to_prb_init = IndexMap::new();
|
||||||
for (name, arg) in raw_name_to_arg {
|
for (name, arg) in raw_name_to_arg {
|
||||||
let value = builder.arg_value(*arg);
|
let value = builder.arg_value(*arg);
|
||||||
context
|
context
|
||||||
|
@ -202,9 +212,9 @@ impl AlwaysStatement {
|
||||||
builder.append_to(bb_init);
|
builder.append_to(bb_init);
|
||||||
let inputs: Vec<Value> = builder.unit().input_args().collect();
|
let inputs: Vec<Value> = builder.unit().input_args().collect();
|
||||||
let events: Vec<Value> = inputs
|
let events: Vec<Value> = inputs
|
||||||
.iter()
|
.into_iter()
|
||||||
.filter(|x| sensitivity_list.contains_key(&arg_value_to_raw_name[&x]))
|
.filter(|&x| sensitivity_list.contains_key(&arg_value_to_raw_name[&x]))
|
||||||
.map(|&x| {
|
.map(|x| {
|
||||||
let raw_name = &arg_value_to_raw_name[&x];
|
let raw_name = &arg_value_to_raw_name[&x];
|
||||||
let prb = builder.ins().prb(x);
|
let prb = builder.ins().prb(x);
|
||||||
raw_name_to_prb_init.insert(raw_name, prb);
|
raw_name_to_prb_init.insert(raw_name, prb);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
use indexmap::map::IndexMap;
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
use linked_hash_map::LinkedHashMap;
|
|
||||||
use linked_hash_set::LinkedHashSet;
|
|
||||||
use llhd::{
|
use llhd::{
|
||||||
ir::{
|
ir::{
|
||||||
Arg, Block, Inst, Module, Signature, Unit, UnitBuilder, UnitData, UnitKind, UnitName, Value,
|
Arg, Block, Inst, Module, Signature, Unit, UnitBuilder, UnitData, UnitKind, UnitName, Value,
|
||||||
|
@ -13,15 +12,12 @@ use std::{collections::HashMap, fmt};
|
||||||
pub struct ModuleContext<'a> {
|
pub struct ModuleContext<'a> {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub module: Module,
|
pub module: Module,
|
||||||
pub symbol: LinkedHashMap<String, SymbolInfo<'a>>,
|
pub symbol: IndexMap<String, SymbolInfo<'a>>,
|
||||||
pub unit_ctx: UnitContext,
|
pub unit_ctx: UnitContext,
|
||||||
pub syntax_table: SyntaxTable<'a>,
|
pub syntax_table: SyntaxTable<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UnitContext {
|
pub struct UnitContext {
|
||||||
pub lvalues: LinkedHashSet<String>,
|
|
||||||
pub rvalues: LinkedHashSet<String>,
|
|
||||||
|
|
||||||
pub data: Option<UnitData>,
|
pub data: Option<UnitData>,
|
||||||
|
|
||||||
pub raw_name_to_arg: HashMap<String, Arg>,
|
pub raw_name_to_arg: HashMap<String, Arg>,
|
||||||
|
@ -71,7 +67,7 @@ impl<'a> ModuleContext<'a> {
|
||||||
Self {
|
Self {
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
module: Module::new(),
|
module: Module::new(),
|
||||||
symbol: LinkedHashMap::new(),
|
symbol: IndexMap::new(),
|
||||||
unit_ctx: UnitContext::new(),
|
unit_ctx: UnitContext::new(),
|
||||||
syntax_table: SyntaxTable::new(json),
|
syntax_table: SyntaxTable::new(json),
|
||||||
}
|
}
|
||||||
|
@ -81,8 +77,6 @@ impl<'a> ModuleContext<'a> {
|
||||||
impl UnitContext {
|
impl UnitContext {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
lvalues: LinkedHashSet::new(),
|
|
||||||
rvalues: LinkedHashSet::new(),
|
|
||||||
data: None,
|
data: None,
|
||||||
raw_name_to_arg: HashMap::new(),
|
raw_name_to_arg: HashMap::new(),
|
||||||
raw_name_to_value: HashMap::new(),
|
raw_name_to_value: HashMap::new(),
|
||||||
|
@ -93,8 +87,6 @@ impl UnitContext {
|
||||||
}
|
}
|
||||||
pub fn drop(&mut self) -> Self {
|
pub fn drop(&mut self) -> Self {
|
||||||
let ret = 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(),
|
data: self.data.take(),
|
||||||
raw_name_to_arg: self.raw_name_to_arg.drain().collect(),
|
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_value: self.raw_name_to_value.drain().collect(),
|
||||||
|
@ -114,8 +106,6 @@ impl UnitContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.lvalues.clear();
|
|
||||||
self.rvalues.clear();
|
|
||||||
self.raw_name_to_arg.clear();
|
self.raw_name_to_arg.clear();
|
||||||
self.raw_name_to_value.clear();
|
self.raw_name_to_value.clear();
|
||||||
self.raw_name_to_shadow.clear();
|
self.raw_name_to_shadow.clear();
|
||||||
|
@ -125,8 +115,6 @@ impl UnitContext {
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.data.is_none()
|
self.data.is_none()
|
||||||
&& self.lvalues.is_empty()
|
|
||||||
&& self.rvalues.is_empty()
|
|
||||||
&& self.raw_name_to_arg.is_empty()
|
&& self.raw_name_to_arg.is_empty()
|
||||||
&& self.raw_name_to_value.is_empty()
|
&& self.raw_name_to_value.is_empty()
|
||||||
&& self.raw_name_to_shadow.is_empty()
|
&& self.raw_name_to_shadow.is_empty()
|
||||||
|
|
|
@ -15,8 +15,8 @@ use log::{debug, error, info, trace, warn};
|
||||||
pub struct Expression {}
|
pub struct Expression {}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
pub fn gen_reference_name(json: &JsonValue, context: &mut ModuleContext) -> String {
|
pub fn gen_reference_name(json: &JsonValue) -> String {
|
||||||
Self::gen_reference_call(json, context).0
|
Self::gen_reference_call(json).0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) -> Option<Value> {
|
pub fn codegen<'a>(json: &'a JsonValue, context: &mut ModuleContext<'a>) -> Option<Value> {
|
||||||
|
@ -44,10 +44,7 @@ impl Expression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_reference_call(
|
fn gen_reference_call(json: &JsonValue) -> (String, Option<(usize, usize)>) {
|
||||||
json: &JsonValue,
|
|
||||||
context: &mut ModuleContext,
|
|
||||||
) -> (String, Option<(usize, usize)>) {
|
|
||||||
let json_symbol_identifier = Tools::match_tags(
|
let json_symbol_identifier = Tools::match_tags(
|
||||||
vec![json],
|
vec![json],
|
||||||
vec![
|
vec![
|
||||||
|
@ -97,13 +94,12 @@ impl Expression {
|
||||||
};
|
};
|
||||||
|
|
||||||
let symbol = &json_symbol_identifier[0]["text"];
|
let symbol = &json_symbol_identifier[0]["text"];
|
||||||
context.unit_ctx.rvalues.insert(symbol.to_string());
|
|
||||||
|
|
||||||
(symbol.to_string(), range)
|
(symbol.to_string(), range)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_reference_value(json: &JsonValue, context: &mut ModuleContext) -> Option<Value> {
|
fn gen_reference_value(json: &JsonValue, context: &mut ModuleContext) -> Option<Value> {
|
||||||
let (symbol, range) = Self::gen_reference_call(json, context);
|
let (symbol, range) = Self::gen_reference_call(json);
|
||||||
|
|
||||||
if context.unit_ctx.data.is_some() {
|
if context.unit_ctx.data.is_some() {
|
||||||
let unit_ctx = &mut context.unit_ctx;
|
let unit_ctx = &mut context.unit_ctx;
|
||||||
|
|
|
@ -259,7 +259,7 @@ impl<'a> ModuleDeclaration {
|
||||||
named_port_symbol_path.to_vec(),
|
named_port_symbol_path.to_vec(),
|
||||||
);
|
);
|
||||||
if json_symbol.len() == 1 {
|
if json_symbol.len() == 1 {
|
||||||
let symbol = &Expression::gen_reference_name(json_symbol[0], context);
|
let symbol = &Expression::gen_reference_name(json_symbol[0]);
|
||||||
Some(context.unit_ctx.raw_name_to_value[symbol])
|
Some(context.unit_ctx.raw_name_to_value[symbol])
|
||||||
} else {
|
} else {
|
||||||
let json_number = Tools::match_tags(
|
let json_number = Tools::match_tags(
|
||||||
|
@ -303,7 +303,7 @@ impl<'a> ModuleDeclaration {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
let json_expr = pos_port_list[&index];
|
let json_expr = pos_port_list[&index];
|
||||||
let arg = &Expression::gen_reference_name(json_expr, context);
|
let arg = &Expression::gen_reference_name(json_expr);
|
||||||
let v = context.unit_ctx.raw_name_to_value[arg];
|
let v = context.unit_ctx.raw_name_to_value[arg];
|
||||||
if arg_info.kind == SymbolKind::Input {
|
if arg_info.kind == SymbolKind::Input {
|
||||||
inputs.push(v);
|
inputs.push(v);
|
||||||
|
|
|
@ -43,7 +43,6 @@ impl NetVariableAssignment {
|
||||||
};
|
};
|
||||||
|
|
||||||
let lvalue_name = &json_lpvalue["text"].to_string();
|
let lvalue_name = &json_lpvalue["text"].to_string();
|
||||||
context.unit_ctx.lvalues.insert(lvalue_name.clone());
|
|
||||||
let lvalue = context.unit_ctx.raw_name_to_value.get(lvalue_name);
|
let lvalue = context.unit_ctx.raw_name_to_value.get(lvalue_name);
|
||||||
if lvalue.is_some() {
|
if lvalue.is_some() {
|
||||||
assert!(context.unit_ctx.data.is_some());
|
assert!(context.unit_ctx.data.is_some());
|
||||||
|
|
|
@ -36,7 +36,6 @@ impl NonblockingAssignmentStatement {
|
||||||
(json_symbol_identifier[0], &json_children[2])
|
(json_symbol_identifier[0], &json_children[2])
|
||||||
};
|
};
|
||||||
let lvalue_name = &json_lpvalue["text"].to_string();
|
let lvalue_name = &json_lpvalue["text"].to_string();
|
||||||
context.unit_ctx.lvalues.insert(lvalue_name.clone());
|
|
||||||
if context.unit_ctx.raw_name_to_value.contains_key(lvalue_name) {
|
if context.unit_ctx.raw_name_to_value.contains_key(lvalue_name) {
|
||||||
assert!(context.unit_ctx.raw_name_to_arg.contains_key(lvalue_name));
|
assert!(context.unit_ctx.raw_name_to_arg.contains_key(lvalue_name));
|
||||||
assert!(context.unit_ctx.data.is_some());
|
assert!(context.unit_ctx.data.is_some());
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{BufRead, BufReader},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
pub struct CodeReporter {
|
||||||
|
file_name: String,
|
||||||
|
line_breakers: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodeReporter {
|
||||||
|
pub fn new(file_name: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
file_name: file_name.to_string(),
|
||||||
|
line_breakers: Self::read_line_breakers(file_name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn line_no(&self, key: usize) -> usize {
|
||||||
|
self.line_no_rec(key, 0, self.line_breakers.len() - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn line(&self, line_no: usize) -> String {
|
||||||
|
let reader = BufReader::new(
|
||||||
|
File::open(self.file_name.as_str())
|
||||||
|
.expect(format!(r#"file "{}" not found"#, self.file_name.as_str()).as_str()),
|
||||||
|
);
|
||||||
|
|
||||||
|
reader.lines().nth(line_no).unwrap().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn line_count(&self) -> usize {
|
||||||
|
self.line_breakers.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_line_breakers(file_name: &str) -> Vec<usize> {
|
||||||
|
let reader = BufReader::new(
|
||||||
|
File::open(file_name).expect(format!(r#"file "{}" not found"#, file_name).as_str()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut line_breakers = Vec::new();
|
||||||
|
line_breakers.push(0);
|
||||||
|
|
||||||
|
for line in reader.lines() {
|
||||||
|
let line_no = 1 + line_breakers.last().unwrap() + line.unwrap().len();
|
||||||
|
line_breakers.push(line_no);
|
||||||
|
}
|
||||||
|
|
||||||
|
line_breakers
|
||||||
|
}
|
||||||
|
|
||||||
|
fn line_no_rec(&self, key: usize, left: usize, right: usize) -> usize {
|
||||||
|
if left + 1 >= right {
|
||||||
|
left
|
||||||
|
} else {
|
||||||
|
let mid = (left + right) / 2;
|
||||||
|
if key < self.line_breakers[mid] {
|
||||||
|
self.line_no_rec(key, left, mid)
|
||||||
|
} else {
|
||||||
|
self.line_no_rec(key, mid, right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,54 +1,74 @@
|
||||||
use crate::{cst::Tag, tools::Tools};
|
use crate::{cst::Tag, tools::Tools};
|
||||||
|
use indexmap::set::IndexSet;
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
use std::{collections::HashSet, iter::FromIterator};
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
pub struct ProcessNames {
|
||||||
|
pub posedges: IndexSet<String>,
|
||||||
|
pub negedges: IndexSet<String>,
|
||||||
|
pub levels: IndexSet<String>,
|
||||||
|
pub lvalues: IndexSet<String>,
|
||||||
|
pub rvalues: IndexSet<String>,
|
||||||
|
pub ctrl_values: IndexSet<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProcessNames {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
posedges: IndexSet::new(),
|
||||||
|
negedges: IndexSet::new(),
|
||||||
|
levels: IndexSet::new(),
|
||||||
|
lvalues: IndexSet::new(),
|
||||||
|
rvalues: IndexSet::new(),
|
||||||
|
ctrl_values: IndexSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct EventControl {}
|
pub struct EventControl {}
|
||||||
|
|
||||||
impl EventControl {
|
impl EventControl {
|
||||||
pub fn clock_and_reset_names(json: &JsonValue) -> (HashSet<String>, HashSet<String>) {
|
pub fn clock_and_reset_names(json: &JsonValue) -> (IndexSet<String>, IndexSet<String>) {
|
||||||
let mut clock_names: HashSet<String> = HashSet::new();
|
let mut clock_names: IndexSet<String> = IndexSet::new();
|
||||||
let mut reset_names: HashSet<String> = HashSet::new();
|
let mut reset_names: IndexSet<String> = IndexSet::new();
|
||||||
|
|
||||||
let json_always_statements = Tools::collect_tag(json, Tag::ALWAYS_STATEMENT);
|
let json_always_statements = Tools::collect_tag(json, Tag::ALWAYS_STATEMENT);
|
||||||
|
|
||||||
for json_always_statement in json_always_statements {
|
for json_always_statement in json_always_statements {
|
||||||
let (json_events, json_body) = Self::events_and_body(json_always_statement);
|
let (json_events, json_body) = Self::events_and_body(json_always_statement);
|
||||||
|
|
||||||
let (json_posedge_names, json_negedge_names, json_level_names) =
|
let (posedge_names, negedge_names, level_names) = Self::event_names(json_events);
|
||||||
Self::event_names(json_events);
|
|
||||||
|
|
||||||
let (json_lvalues, json_rvalues, json_ctrl_values) = Self::value_names(json_body);
|
let (lvalues, rvalues, ctrl_values) = Self::value_names(json_body);
|
||||||
let json_top_ctrl_values = Self::top_ctrl_values(json_body);
|
let top_ctrl_values = Self::top_ctrl_values(json_body);
|
||||||
|
|
||||||
let json_edge_names = [json_posedge_names.clone(), json_negedge_names.clone()].concat();
|
let edge_names: IndexSet<_> = posedge_names.union(&negedge_names).cloned().collect();
|
||||||
let json_sens_names = [json_edge_names.clone(), json_level_names.clone()].concat();
|
let sens_names: IndexSet<_> = edge_names.union(&level_names).cloned().collect();
|
||||||
|
|
||||||
let json_data_values: HashSet<String> =
|
let data_values: IndexSet<String> = lvalues.union(&rvalues).cloned().collect();
|
||||||
json_lvalues.union(&json_rvalues).cloned().collect();
|
let all_values: IndexSet<String> = data_values.union(&ctrl_values).cloned().collect();
|
||||||
let json_all_values: HashSet<String> =
|
|
||||||
json_data_values.union(&json_ctrl_values).cloned().collect();
|
|
||||||
|
|
||||||
let local_clock_names: HashSet<String> = HashSet::from_iter(
|
let local_clock_names: IndexSet<String> = IndexSet::from_iter(
|
||||||
json_edge_names
|
edge_names
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| !json_all_values.contains(x)),
|
.filter(|x| !all_values.contains(x)),
|
||||||
);
|
);
|
||||||
let local_reset_names: HashSet<String> = HashSet::from_iter(
|
let local_reset_names: IndexSet<String> = IndexSet::from_iter(
|
||||||
json_sens_names
|
sens_names
|
||||||
.clone()
|
.clone()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|x| !json_data_values.contains(x) && json_top_ctrl_values.contains(x)),
|
.filter(|x| !data_values.contains(x) && top_ctrl_values.contains(x)),
|
||||||
);
|
);
|
||||||
|
|
||||||
trace!("edge_names {:?}", json_edge_names);
|
trace!("edge_names {:?}", edge_names);
|
||||||
trace!("sens_names {:?}", json_sens_names);
|
trace!("sens_names {:?}", sens_names);
|
||||||
trace!("data_values {:?}", json_data_values);
|
trace!("data_values {:?}", data_values);
|
||||||
trace!("all_values {:?}", json_all_values);
|
trace!("all_values {:?}", all_values);
|
||||||
trace!("top_ctrl_values {:?}", json_top_ctrl_values);
|
trace!("top_ctrl_values {:?}", top_ctrl_values);
|
||||||
|
|
||||||
clock_names = clock_names.union(&local_clock_names).cloned().collect();
|
clock_names = clock_names.union(&local_clock_names).cloned().collect();
|
||||||
reset_names = reset_names.union(&local_reset_names).cloned().collect();
|
reset_names = reset_names.union(&local_reset_names).cloned().collect();
|
||||||
|
@ -59,6 +79,24 @@ impl EventControl {
|
||||||
(clock_names, reset_names)
|
(clock_names, reset_names)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn process_names(json_always_statement: &JsonValue) -> ProcessNames {
|
||||||
|
let (json_events, json_body) = Self::events_and_body(json_always_statement);
|
||||||
|
|
||||||
|
let (posedge_names, negedge_names, level_names) = Self::event_names(json_events);
|
||||||
|
|
||||||
|
let (lvalues, rvalues, ctrl_values) = Self::value_names(json_body);
|
||||||
|
|
||||||
|
let mut names = ProcessNames::new();
|
||||||
|
names.posedges = posedge_names;
|
||||||
|
names.negedges = negedge_names;
|
||||||
|
names.levels = level_names;
|
||||||
|
names.lvalues = lvalues.into_iter().collect();
|
||||||
|
names.rvalues = rvalues.into_iter().collect();
|
||||||
|
names.ctrl_values = ctrl_values.into_iter().collect();
|
||||||
|
|
||||||
|
names
|
||||||
|
}
|
||||||
|
|
||||||
fn events_and_body(json: &JsonValue) -> (Vec<&JsonValue>, &JsonValue) {
|
fn events_and_body(json: &JsonValue) -> (Vec<&JsonValue>, &JsonValue) {
|
||||||
assert_eq!(json["tag"], Tag::ALWAYS_STATEMENT);
|
assert_eq!(json["tag"], Tag::ALWAYS_STATEMENT);
|
||||||
let (json_events, json_body) = {
|
let (json_events, json_body) = {
|
||||||
|
@ -90,10 +128,12 @@ impl EventControl {
|
||||||
(json_events, json_body)
|
(json_events, json_body)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event_names(json_events: Vec<&JsonValue>) -> (Vec<String>, Vec<String>, Vec<String>) {
|
fn event_names(
|
||||||
let mut json_posedge_names = Vec::new();
|
json_events: Vec<&JsonValue>,
|
||||||
let mut json_negedge_names = Vec::new();
|
) -> (IndexSet<String>, IndexSet<String>, IndexSet<String>) {
|
||||||
let mut json_level_names = Vec::new();
|
let mut posedge_names = IndexSet::new();
|
||||||
|
let mut negedge_names = IndexSet::new();
|
||||||
|
let mut level_names = IndexSet::new();
|
||||||
|
|
||||||
let json_id = |x: &JsonValue| -> String {
|
let json_id = |x: &JsonValue| -> String {
|
||||||
let json_symbol_identifiers = Tools::collect_tag(&x, Tag::SYMBOL_IDENTIFIER);
|
let json_symbol_identifiers = Tools::collect_tag(&x, Tag::SYMBOL_IDENTIFIER);
|
||||||
|
@ -104,20 +144,22 @@ impl EventControl {
|
||||||
for json_event in json_events {
|
for json_event in json_events {
|
||||||
match json_event["children"][0]["tag"].as_str() {
|
match json_event["children"][0]["tag"].as_str() {
|
||||||
Some(Tag::POS_EDGE) => {
|
Some(Tag::POS_EDGE) => {
|
||||||
json_posedge_names.push(json_id(json_event));
|
posedge_names.insert(json_id(json_event));
|
||||||
}
|
}
|
||||||
Some(Tag::NEG_EDGE) => {
|
Some(Tag::NEG_EDGE) => {
|
||||||
json_negedge_names.push(json_id(json_event));
|
negedge_names.insert(json_id(json_event));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
json_level_names.push(json_id(json_event));
|
level_names.insert(json_id(json_event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(json_posedge_names, json_negedge_names, json_level_names)
|
(posedge_names, negedge_names, level_names)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value_names(json_body: &JsonValue) -> (HashSet<String>, HashSet<String>, HashSet<String>) {
|
fn value_names(
|
||||||
|
json_body: &JsonValue,
|
||||||
|
) -> (IndexSet<String>, IndexSet<String>, IndexSet<String>) {
|
||||||
let json_assignments = [
|
let json_assignments = [
|
||||||
Tools::collect_tag(json_body, Tag::NONBLOCKING_ASSIGNMENT_STATEMENT),
|
Tools::collect_tag(json_body, Tag::NONBLOCKING_ASSIGNMENT_STATEMENT),
|
||||||
Tools::collect_tag(json_body, Tag::NET_VARIABLE_ASSIGNMENT),
|
Tools::collect_tag(json_body, Tag::NET_VARIABLE_ASSIGNMENT),
|
||||||
|
@ -136,21 +178,21 @@ impl EventControl {
|
||||||
]
|
]
|
||||||
.concat();
|
.concat();
|
||||||
|
|
||||||
let json_lvalues = HashSet::from_iter(
|
let json_lvalues = IndexSet::from_iter(
|
||||||
json_assignments
|
json_assignments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| Tools::collect_tag(&x["children"][0], Tag::SYMBOL_IDENTIFIER))
|
.map(|x| Tools::collect_tag(&x["children"][0], Tag::SYMBOL_IDENTIFIER))
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|x| x["text"].to_string()),
|
.map(|x| x["text"].to_string()),
|
||||||
);
|
);
|
||||||
let json_rvalues = HashSet::from_iter(
|
let json_rvalues = IndexSet::from_iter(
|
||||||
json_assignments
|
json_assignments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| Tools::collect_tag(&x["children"][2], Tag::SYMBOL_IDENTIFIER))
|
.map(|x| Tools::collect_tag(&x["children"][2], Tag::SYMBOL_IDENTIFIER))
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|x| x["text"].to_string()),
|
.map(|x| x["text"].to_string()),
|
||||||
);
|
);
|
||||||
let json_ctrl_values = HashSet::from_iter(
|
let json_ctrl_values = IndexSet::from_iter(
|
||||||
json_conditions
|
json_conditions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| Tools::collect_tag(x, Tag::SYMBOL_IDENTIFIER))
|
.map(|x| Tools::collect_tag(x, Tag::SYMBOL_IDENTIFIER))
|
||||||
|
@ -161,7 +203,7 @@ impl EventControl {
|
||||||
(json_lvalues, json_rvalues, json_ctrl_values)
|
(json_lvalues, json_rvalues, json_ctrl_values)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn top_ctrl_values(json_body: &JsonValue) -> HashSet<String> {
|
fn top_ctrl_values(json_body: &JsonValue) -> IndexSet<String> {
|
||||||
let json_statement = {
|
let json_statement = {
|
||||||
let mut ret = json_body;
|
let mut ret = json_body;
|
||||||
loop {
|
loop {
|
||||||
|
@ -182,7 +224,7 @@ impl EventControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
HashSet::from_iter(
|
IndexSet::from_iter(
|
||||||
Tools::match_tags(
|
Tools::match_tags(
|
||||||
vec![json_statement],
|
vec![json_statement],
|
||||||
vec![
|
vec![
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
pub mod code_reporter;
|
||||||
pub mod event_control;
|
pub mod event_control;
|
||||||
mod tools;
|
pub mod tools;
|
||||||
|
|
||||||
pub use event_control::EventControl;
|
pub use code_reporter::CodeReporter;
|
||||||
pub use tools::{CodeReporter, Tools};
|
pub use event_control::{EventControl, ProcessNames};
|
||||||
|
pub use tools::Tools;
|
||||||
|
|
|
@ -4,8 +4,6 @@ use llhd::ir::{Block, Inst, Opcode};
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
collections::{HashMap, HashSet, VecDeque},
|
collections::{HashMap, HashSet, VecDeque},
|
||||||
fs::File,
|
|
||||||
io::{BufRead, BufReader},
|
|
||||||
iter::FromIterator,
|
iter::FromIterator,
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
@ -279,63 +277,3 @@ impl Tools {
|
||||||
modules
|
modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CodeReporter {
|
|
||||||
file_name: String,
|
|
||||||
line_breakers: Vec<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CodeReporter {
|
|
||||||
pub fn new(file_name: &str) -> Self {
|
|
||||||
Self {
|
|
||||||
file_name: file_name.to_string(),
|
|
||||||
line_breakers: Self::read_line_breakers(file_name),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn line_no(&self, key: usize) -> usize {
|
|
||||||
self.line_no_rec(key, 0, self.line_breakers.len() - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn line(&self, line_no: usize) -> String {
|
|
||||||
let reader = BufReader::new(
|
|
||||||
File::open(self.file_name.as_str())
|
|
||||||
.expect(format!(r#"file "{}" not found"#, self.file_name.as_str()).as_str()),
|
|
||||||
);
|
|
||||||
|
|
||||||
reader.lines().nth(line_no).unwrap().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn line_count(&self) -> usize {
|
|
||||||
self.line_breakers.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_line_breakers(file_name: &str) -> Vec<usize> {
|
|
||||||
let reader = BufReader::new(
|
|
||||||
File::open(file_name).expect(format!(r#"file "{}" not found"#, file_name).as_str()),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut line_breakers = Vec::new();
|
|
||||||
line_breakers.push(0);
|
|
||||||
|
|
||||||
for line in reader.lines() {
|
|
||||||
let line_no = 1 + line_breakers.last().unwrap() + line.unwrap().len();
|
|
||||||
line_breakers.push(line_no);
|
|
||||||
}
|
|
||||||
|
|
||||||
line_breakers
|
|
||||||
}
|
|
||||||
|
|
||||||
fn line_no_rec(&self, key: usize, left: usize, right: usize) -> usize {
|
|
||||||
if left + 1 >= right {
|
|
||||||
left
|
|
||||||
} else {
|
|
||||||
let mid = (left + right) / 2;
|
|
||||||
if key < self.line_breakers[mid] {
|
|
||||||
self.line_no_rec(key, left, mid)
|
|
||||||
} else {
|
|
||||||
self.line_no_rec(key, mid, right)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue