Rename intermediate variables in processes
This commit is contained in:
parent
9682ad0340
commit
dcf133128f
|
@ -55,8 +55,7 @@ impl AlwaysStatement {
|
|||
};
|
||||
|
||||
// first traversal
|
||||
assert!(context.lvalues.is_empty());
|
||||
assert!(context.rvalues.is_empty());
|
||||
assert!(context.unit_ctx.is_empty());
|
||||
Self::gen_event_expression_list(json_event_expression_list, context);
|
||||
Statement::codegen(json_statement, context);
|
||||
|
||||
|
@ -64,27 +63,25 @@ impl AlwaysStatement {
|
|||
let proc_signature = {
|
||||
let mut ret = Signature::new();
|
||||
|
||||
for lvalue in &context.lvalues {
|
||||
for lvalue in &context.unit_ctx.lvalues {
|
||||
if context.symbol.contains_key(lvalue) {
|
||||
let symbol = &context.symbol[lvalue];
|
||||
assert_ne!(symbol.kind, SymbolKind::Param);
|
||||
|
||||
let width = symbol.width.clone();
|
||||
let arg = ret.add_output(signal_ty(int_ty(width)));
|
||||
context
|
||||
.unit_ctx
|
||||
.arg_to_raw_name
|
||||
.insert(arg, lvalue.to_string());
|
||||
context.unit_ctx.arg_to_raw_name.insert(arg, lvalue.clone());
|
||||
} else {
|
||||
error!("FIXME: symbol '{}' not found", lvalue);
|
||||
}
|
||||
}
|
||||
|
||||
let rvalues: Vec<String> = context
|
||||
.unit_ctx
|
||||
.rvalues
|
||||
.iter()
|
||||
.filter(|&x| !context.lvalues.contains(x))
|
||||
.map(|x| x.to_string())
|
||||
.filter(|&x| !context.unit_ctx.lvalues.contains(x))
|
||||
.map(|x| x.clone())
|
||||
.collect();
|
||||
for rvalue in &rvalues {
|
||||
if context.symbol.contains_key(rvalue) {
|
||||
|
@ -92,10 +89,7 @@ impl AlwaysStatement {
|
|||
if symbol.kind != SymbolKind::Param {
|
||||
let width = symbol.width.clone();
|
||||
let arg = ret.add_input(signal_ty(int_ty(width)));
|
||||
context
|
||||
.unit_ctx
|
||||
.arg_to_raw_name
|
||||
.insert(arg, rvalue.to_string());
|
||||
context.unit_ctx.arg_to_raw_name.insert(arg, rvalue.clone());
|
||||
}
|
||||
} else {
|
||||
error!("FIXME: symbol '{}' not found", rvalue);
|
||||
|
@ -119,10 +113,7 @@ impl AlwaysStatement {
|
|||
Self::gen_event_expression_list(json_event_expression_list, context);
|
||||
Statement::codegen(json_statement, context);
|
||||
|
||||
context.unit_ctx.arg_to_raw_name.clear();
|
||||
context.lvalues.clear();
|
||||
context.rvalues.clear();
|
||||
|
||||
context.unit_ctx.clear();
|
||||
context.module.add_unit(context.unit_ctx.drop_data())
|
||||
}
|
||||
|
||||
|
@ -166,50 +157,64 @@ impl AlwaysStatement {
|
|||
}
|
||||
|
||||
if context.unit_ctx.data.is_some() {
|
||||
let mut imm_count = context.unit_ctx.imm_count;
|
||||
let arg_to_raw_name = context.unit_ctx.arg_to_raw_name.clone();
|
||||
let rvalues = context.unit_ctx.rvalues.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();
|
||||
let mut raw_name_to_prb0 = HashMap::new();
|
||||
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);
|
||||
builder.set_name(value, name.clone());
|
||||
arg_value_to_raw_name.insert(value, name.clone());
|
||||
raw_name_to_value.insert(name.clone(), value);
|
||||
}
|
||||
|
||||
let sensitivity_names: HashSet<String> = sensitivity_list
|
||||
.iter()
|
||||
.map(|(x, _)| x.to_string())
|
||||
.collect();
|
||||
let sensitivity_names: HashSet<String> =
|
||||
sensitivity_list.iter().map(|(x, _)| x.clone()).collect();
|
||||
let sensitivity_list_plus: Vec<(String, &str, Type)> = sensitivity_list
|
||||
.iter()
|
||||
.map(|(x, y)| {
|
||||
(
|
||||
x.to_string(),
|
||||
x.clone(),
|
||||
y.clone(),
|
||||
builder.unit().value_type(raw_name_to_value[x]),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let bb_0 = builder.named_block("0");
|
||||
let bb_shadow = builder.named_block("shadow");
|
||||
let bb_init = builder.named_block("init");
|
||||
let bb_check = builder.named_block("check");
|
||||
let bb_event = builder.named_block("event");
|
||||
|
||||
// initialize basic block "0"
|
||||
builder.append_to(bb_0);
|
||||
// initialize basic block "shadow"
|
||||
builder.append_to(bb_shadow);
|
||||
let outputs: Vec<Value> = builder.unit().output_args().collect();
|
||||
let output_shadows: Vec<Value> = outputs
|
||||
.iter()
|
||||
.map(|x| {
|
||||
let output_prb = builder.ins().prb(*x);
|
||||
builder.ins().suffix(*x, "shadow").var(output_prb)
|
||||
.filter_map(|x| {
|
||||
let name = &arg_value_to_raw_name[x];
|
||||
if rvalues.contains(name) {
|
||||
let output_prb = builder.ins().prb(*x);
|
||||
{
|
||||
builder.set_name(output_prb, format!("{}", imm_count + 1));
|
||||
imm_count += 1;
|
||||
}
|
||||
Some(builder.ins().suffix(*x, "shadow").var(output_prb))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
builder.ins().br(bb_init);
|
||||
if output_shadows.len() > 0 {
|
||||
builder.ins().br(bb_init);
|
||||
} else {
|
||||
builder.delete_block(bb_shadow);
|
||||
}
|
||||
|
||||
// initialize basic block "init"
|
||||
builder.append_to(bb_init);
|
||||
|
@ -219,8 +224,8 @@ impl AlwaysStatement {
|
|||
.filter(|x| sensitivity_names.contains(&arg_value_to_raw_name[&x]))
|
||||
.map(|x| {
|
||||
let raw_name = &arg_value_to_raw_name[&x];
|
||||
let prb = builder.ins().suffix(*x, "prb").prb(*x);
|
||||
raw_name_to_prb.insert(raw_name, prb);
|
||||
let prb = builder.ins().suffix(*x, "prb0").prb(*x);
|
||||
raw_name_to_prb0.insert(raw_name, prb);
|
||||
prb
|
||||
})
|
||||
.collect();
|
||||
|
@ -233,30 +238,50 @@ impl AlwaysStatement {
|
|||
.zip(output_shadows.iter())
|
||||
.for_each(|(output, output_shadow)| {
|
||||
let output_prb = builder.ins().prb(*output);
|
||||
{
|
||||
builder.set_name(output_prb, format!("{}", imm_count + 1));
|
||||
imm_count += 1;
|
||||
}
|
||||
builder.ins().st(*output_shadow, output_prb);
|
||||
});
|
||||
let mut zeros = HashMap::new();
|
||||
let mut last_event = None;
|
||||
for (i, (raw_name, tag, value_type)) in sensitivity_list_plus.iter().enumerate() {
|
||||
let v = raw_name_to_value[raw_name];
|
||||
let prb = raw_name_to_prb[raw_name];
|
||||
let prb1 = builder.ins().suffix(v, "prb1").prb(v);
|
||||
let prb0 = raw_name_to_prb0[raw_name];
|
||||
let prb = builder.ins().suffix(v, "prb").prb(v);
|
||||
|
||||
let (name, event) = if *tag == Tag::POS_EDGE || *tag == Tag::NEG_EDGE {
|
||||
let zero = if zeros.contains_key(value_type) {
|
||||
zeros[value_type]
|
||||
} else {
|
||||
let z = builder.ins().const_zero(value_type.unwrap_signal());
|
||||
{
|
||||
builder.set_name(z, format!("{}", imm_count + 1));
|
||||
imm_count += 1;
|
||||
}
|
||||
zeros.insert(value_type, z);
|
||||
z
|
||||
};
|
||||
let (mut n, v) = if *tag == Tag::POS_EDGE {
|
||||
let eq = builder.ins().eq(prb, zero);
|
||||
let neq = builder.ins().neq(prb1, zero);
|
||||
let eq = builder.ins().eq(prb0, zero);
|
||||
let neq = builder.ins().neq(prb, zero);
|
||||
{
|
||||
builder.set_name(eq, format!("{}", imm_count + 1));
|
||||
imm_count += 1;
|
||||
builder.set_name(neq, format!("{}", imm_count + 1));
|
||||
imm_count += 1;
|
||||
}
|
||||
("posedge".to_string(), builder.ins().and(eq, neq))
|
||||
} else {
|
||||
let neq = builder.ins().neq(prb, zero);
|
||||
let eq = builder.ins().eq(prb1, zero);
|
||||
let neq = builder.ins().neq(prb0, zero);
|
||||
let eq = builder.ins().eq(prb, zero);
|
||||
{
|
||||
builder.set_name(neq, format!("{}", imm_count + 1));
|
||||
imm_count += 1;
|
||||
builder.set_name(eq, format!("{}", imm_count + 1));
|
||||
imm_count += 1;
|
||||
}
|
||||
("negedge".to_string(), builder.ins().and(neq, eq))
|
||||
};
|
||||
if i > 0 {
|
||||
|
@ -269,7 +294,7 @@ impl AlwaysStatement {
|
|||
} else {
|
||||
"impledge".to_string()
|
||||
};
|
||||
let v = builder.ins().neq(prb, prb1);
|
||||
let v = builder.ins().neq(prb0, prb);
|
||||
(n, v)
|
||||
};
|
||||
builder.set_name(event, name);
|
||||
|
@ -289,6 +314,8 @@ impl AlwaysStatement {
|
|||
builder
|
||||
.ins()
|
||||
.br_cond(last_event.unwrap(), bb_init, bb_event);
|
||||
|
||||
context.unit_ctx.imm_count = imm_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use linked_hash_map::LinkedHashMap;
|
||||
use linked_hash_set::LinkedHashSet;
|
||||
use llhd::ir::{Arg, Module, Signature, UnitBuilder, UnitData, UnitKind, UnitName};
|
||||
use llhd::ir::{Arg, Module, Signature, UnitBuilder, UnitData, UnitKind, UnitName, Value};
|
||||
use std::{collections::HashMap, fmt};
|
||||
|
||||
pub struct ModuleContext {
|
||||
|
@ -8,14 +8,19 @@ pub struct ModuleContext {
|
|||
pub module: Module,
|
||||
pub symbol: LinkedHashMap<String, SymbolInfo>,
|
||||
pub tags: Vec<&'static str>,
|
||||
pub lvalues: LinkedHashSet<String>,
|
||||
pub rvalues: LinkedHashSet<String>,
|
||||
pub unit_ctx: UnitContext,
|
||||
}
|
||||
|
||||
pub struct UnitContext {
|
||||
pub lvalues: LinkedHashSet<String>,
|
||||
pub rvalues: LinkedHashSet<String>,
|
||||
|
||||
pub data: Option<UnitData>,
|
||||
|
||||
pub arg_to_raw_name: HashMap<Arg, String>,
|
||||
pub raw_name_to_value: HashMap<String, Value>,
|
||||
pub raw_name_to_shadow: HashMap<String, Value>,
|
||||
pub imm_count: i32,
|
||||
}
|
||||
|
||||
pub struct SymbolInfo {
|
||||
|
@ -51,8 +56,6 @@ impl ModuleContext {
|
|||
module: Module::new(),
|
||||
symbol: LinkedHashMap::new(),
|
||||
tags: Vec::new(),
|
||||
lvalues: LinkedHashSet::new(),
|
||||
rvalues: LinkedHashSet::new(),
|
||||
unit_ctx: UnitContext::new(),
|
||||
}
|
||||
}
|
||||
|
@ -61,8 +64,13 @@ impl ModuleContext {
|
|||
impl UnitContext {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
arg_to_raw_name: HashMap::new(),
|
||||
lvalues: LinkedHashSet::new(),
|
||||
rvalues: LinkedHashSet::new(),
|
||||
data: None,
|
||||
arg_to_raw_name: HashMap::new(),
|
||||
raw_name_to_value: HashMap::new(),
|
||||
raw_name_to_shadow: HashMap::new(),
|
||||
imm_count: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,8 +81,28 @@ impl UnitContext {
|
|||
self.data.take().unwrap()
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.lvalues.clear();
|
||||
self.rvalues.clear();
|
||||
self.arg_to_raw_name.clear();
|
||||
self.raw_name_to_value.clear();
|
||||
self.raw_name_to_shadow.clear();
|
||||
self.imm_count = 0;
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.data.is_none()
|
||||
&& self.lvalues.is_empty()
|
||||
&& self.rvalues.is_empty()
|
||||
&& self.arg_to_raw_name.is_empty()
|
||||
&& self.raw_name_to_value.is_empty()
|
||||
&& self.raw_name_to_shadow.is_empty()
|
||||
&& self.imm_count == 0
|
||||
}
|
||||
|
||||
pub fn builder(&mut self) -> UnitBuilder {
|
||||
UnitBuilder::new_anonymous(self.data.as_mut().unwrap())
|
||||
let data = &mut self.data;
|
||||
UnitBuilder::new_anonymous(data.as_mut().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::cst::{ModuleContext, Tag, Tools};
|
||||
use json::JsonValue;
|
||||
use llhd::ir::Value;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
@ -15,7 +16,7 @@ impl Expression {
|
|||
Self::codegen_internal(&json_child[0], context);
|
||||
}
|
||||
|
||||
fn codegen_internal(json: &JsonValue, context: &mut ModuleContext) {
|
||||
fn codegen_internal(json: &JsonValue, context: &mut ModuleContext) -> Option<Value> {
|
||||
match json["tag"].as_str() {
|
||||
Some(Tag::NUMBER) => {
|
||||
warn!("TODO: case '{}'", Tag::NUMBER);
|
||||
|
@ -53,6 +54,8 @@ impl Expression {
|
|||
Some(x) => error!("FIXME: case '{}' missing", x),
|
||||
_ => panic!("unknown error at CST node '{}'", json),
|
||||
};
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn gen_reference_call_base(json: &JsonValue, context: &mut ModuleContext) -> String {
|
||||
|
@ -69,7 +72,7 @@ impl Expression {
|
|||
assert_eq!(json_symbol_identifier.len(), 1, "{}", json.to_string());
|
||||
|
||||
let symbol = &json_symbol_identifier[0]["text"];
|
||||
context.rvalues.insert(symbol.to_string());
|
||||
context.unit_ctx.rvalues.insert(symbol.to_string());
|
||||
|
||||
warn!("TODO: case '{}'", Tag::REFERENCE_CALL_BASE);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ impl NetVariableAssignment {
|
|||
);
|
||||
assert_eq!(json_symbol_identifier.len(), 1);
|
||||
context
|
||||
.unit_ctx
|
||||
.lvalues
|
||||
.insert(json_symbol_identifier[0]["text"].to_string());
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ impl NonblockingAssignmentStatement {
|
|||
);
|
||||
assert_eq!(json_symbol_identifier.len(), 1);
|
||||
context
|
||||
.unit_ctx
|
||||
.lvalues
|
||||
.insert(json_symbol_identifier[0]["text"].to_string());
|
||||
|
||||
|
|
Loading…
Reference in New Issue