Rename intermediate variables in processes

This commit is contained in:
Guojie Luo 2022-03-19 00:46:28 +08:00
parent 9682ad0340
commit dcf133128f
5 changed files with 111 additions and 51 deletions

View File

@ -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;
}
}
}

View File

@ -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())
}
}

View File

@ -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);

View File

@ -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());

View File

@ -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());