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