diff --git a/Cargo.lock b/Cargo.lock index aae0753..2234c61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.51" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203" +checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd" [[package]] name = "atom" @@ -45,9 +45,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" dependencies = [ "cfg-if", "crossbeam-utils", @@ -99,9 +99,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" dependencies = [ "cfg-if", "crossbeam-utils", @@ -112,23 +112,14 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" dependencies = [ "cfg-if", "lazy_static", ] -[[package]] -name = "cst-to-llhd" -version = "0.1.0" -dependencies = [ - "clap", - "json", - "llhd", -] - [[package]] name = "either" version = "1.6.1" @@ -142,7 +133,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ "atty", - "humantime", + "humantime 1.3.0", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime 2.1.0", "log", "regex", "termcolor", @@ -176,6 +180,12 @@ dependencies = [ "quick-error", ] +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "itertools" version = "0.9.0" @@ -193,9 +203,9 @@ checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" [[package]] name = "lalrpop-util" -version = "0.19.6" +version = "0.19.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e58cce361efcc90ba8a0a5f982c741ff86b603495bb15a998412e957dcd278" +checksum = "d6d265705249fe209280676d8f68887859fa42e1d34f342fc05bd47726a5e188" [[package]] name = "lazy_static" @@ -205,9 +215,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.109" +version = "0.2.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01" +checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" + +[[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" @@ -334,9 +359,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -348,15 +373,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" dependencies = [ - "env_logger", + "env_logger 0.7.1", "log", ] [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] @@ -369,9 +394,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.10" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -426,18 +451,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.130" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -452,9 +477,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "syn" -version = "1.0.65" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -527,3 +552,16 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "x-lint" +version = "0.1.0" +dependencies = [ + "clap", + "env_logger 0.9.0", + "json", + "linked-hash-map", + "linked_hash_set", + "llhd", + "log", +] diff --git a/Cargo.toml b/Cargo.toml index c508d33..9e0e1d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,19 @@ [package] -name = "cst-to-llhd" +name = "x-lint" version = "0.1.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +log = "*" +env_logger = "*" clap = "2" json = "*" llhd = "*" +linked_hash_set = "*" +linked-hash-map = "*" + +[[bin]] +name = "x-lint" +path = "src/bin/x-lint.rs" diff --git a/README.md b/README.md index 5746f09..b797da6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ ## cst-to-llhd ``` -cst-to-llhd 0.1.0 - -Convert a Verible concrete syntax tree (CST) to an LLHD graph. +cst-to-llhd: Convert a Verible concrete syntax tree (CST) to an LLHD graph. USAGE: cst-to-llhd @@ -17,8 +15,6 @@ ARGS: ## x-lint ``` -cst-to-llhd 0.1.0 - x-lint: a linter using both CST and LLHD. USAGE: diff --git a/src/bin/cst-to-llhd.rs b/src/bin/cst-to-llhd.rs index d8a8b87..02a3267 100644 --- a/src/bin/cst-to-llhd.rs +++ b/src/bin/cst-to-llhd.rs @@ -3,8 +3,8 @@ extern crate clap; extern crate json; use clap::Arg; -use cst_to_llhd::cst::{DescriptionList, Tag}; use std::{fs::File, io::Read, result::Result}; +use x_lint::cst::{DescriptionList, Tag}; fn main() { match main_inner() { diff --git a/src/bin/x-lint.rs b/src/bin/x-lint.rs index 89f86ef..d720cb4 100644 --- a/src/bin/x-lint.rs +++ b/src/bin/x-lint.rs @@ -3,13 +3,16 @@ extern crate clap; extern crate json; use clap::Arg; -use cst_to_llhd::cst::{CodeReporter, DescriptionList, Logger, Tag, Tools}; +use env_logger; use std::{ process::{Command, Stdio}, result::Result, }; +use x_lint::cst::{CodeReporter, DescriptionList, Logger, Tag, Tools}; fn main() { + env_logger::builder().format_timestamp(None).init(); + match main_inner() { Ok(_) => (), Err(e) => { @@ -83,6 +86,8 @@ fn main_inner() -> Result<(), std::io::Error> { assert!(json_tree["tag"] == Tag::DESCRIPTION_LIST); let module_list = DescriptionList::codegen(json_tree); + + // temporary demo for (module, json_module) in module_list { for entity in module.entities() { if entity.input_args().count() == 0 || entity.output_args().count() == 0 { diff --git a/src/cst/always_statement.rs b/src/cst/always_statement.rs index 1450f70..512c882 100644 --- a/src/cst/always_statement.rs +++ b/src/cst/always_statement.rs @@ -1,14 +1,16 @@ -use crate::cst::{EventExpressionList, Logger, ModuleContext, Statement, Tag, Tools}; +use crate::cst::{EventExpressionList, ModuleContext, Statement, Tag, Tools}; use json::JsonValue; use llhd::ir::{Signature, UnitBuilder, UnitData, UnitId, UnitKind, UnitName}; use llhd::ty::{int_ty, signal_ty}; use std::collections::HashMap; +#[allow(unused_imports)] +use log::{debug, error, info, trace, warn}; + pub struct AlwaysStatement {} impl AlwaysStatement { pub fn codegen(json: &JsonValue, context: &mut ModuleContext) -> UnitId { - let me = "AlwaysStatement::codegen()"; assert!(context.lvalues.is_empty()); assert!(context.rvalues.is_empty()); @@ -25,10 +27,10 @@ impl AlwaysStatement { Self::gen_always(json_statement[0], context); } Some(Tag::ALWAYS_COMB) => { - Logger::insert(format!("TODO: implmenent AlwaysComb::codegen()")); + error!("TODO: implmenent '{}'", Tag::ALWAYS_COMB); } Some(x) => { - Logger::insert(format!("FIXME: missing {}", x)); + error!("FIXME: case '{}' missing", x); } _ => { panic!(); @@ -40,12 +42,12 @@ impl AlwaysStatement { 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(); + if context.symbol.contains_key(lvalue) { + let width = context.symbol[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)); + error!("FIXME: symbol '{}' not found", lvalue); } } for rvalue in context @@ -53,12 +55,12 @@ impl AlwaysStatement { .iter() .filter(|&x| !context.lvalues.contains(x)) { - if context.symbol_info.contains_key(rvalue) { - let width = context.symbol_info[rvalue].width.clone(); + if context.symbol.contains_key(rvalue) { + let width = context.symbol[rvalue].width.clone(); let arg = ret.add_input(signal_ty(int_ty(width))); arg_name.insert(arg, rvalue); } else { - Logger::insert(format!("FIXME: {} not found in {}", rvalue, me)); + error!("FIXME: symbol '{}' not found", rvalue); } } ret diff --git a/src/cst/case_statement.rs b/src/cst/case_statement.rs index 8c3f222..25e6510 100644 --- a/src/cst/case_statement.rs +++ b/src/cst/case_statement.rs @@ -1,10 +1,13 @@ -use crate::cst::{Logger, ModuleContext}; +use crate::cst::ModuleContext; use json::JsonValue; +#[allow(unused_imports)] +use log::{debug, error, info, trace, warn}; + pub struct CaseStatement {} impl CaseStatement { pub fn codegen(_json: &JsonValue, _context: &ModuleContext) { - Logger::insert(format!("TODO: implement CaseStatement::codegen()")); + warn!("TODO: implement CaseStatement::codegen()"); } } diff --git a/src/cst/context.rs b/src/cst/context.rs index eb42a52..6628d19 100644 --- a/src/cst/context.rs +++ b/src/cst/context.rs @@ -1,14 +1,15 @@ -use llhd::ir::{Arg, Module, UnitId}; -use std::collections::{HashMap, HashSet}; +use llhd::ir::{Module, UnitId}; +//use std::collections::{HashMap, HashSet}; +use linked_hash_map::LinkedHashMap; +use linked_hash_set::LinkedHashSet; pub struct ModuleContext { pub name: String, pub module: Module, - pub symbol_info: HashMap, - pub arg_name: HashMap, + pub symbol: LinkedHashMap, pub process: Vec, - pub lvalues: HashSet, - pub rvalues: HashSet, + pub lvalues: LinkedHashSet, + pub rvalues: LinkedHashSet, } pub struct SymbolInfo { @@ -20,11 +21,10 @@ impl ModuleContext { Self { name: String::new(), module: Module::new(), - symbol_info: HashMap::new(), - arg_name: HashMap::new(), + symbol: LinkedHashMap::new(), process: Vec::new(), - lvalues: HashSet::new(), - rvalues: HashSet::new(), + lvalues: LinkedHashSet::new(), + rvalues: LinkedHashSet::new(), } } } diff --git a/src/cst/event_expression_list.rs b/src/cst/event_expression_list.rs index 0799abc..ace869b 100644 --- a/src/cst/event_expression_list.rs +++ b/src/cst/event_expression_list.rs @@ -1,6 +1,9 @@ -use crate::cst::{Expression, Logger, ModuleContext, Tag, Tools}; +use crate::cst::{Expression, ModuleContext, Tag, Tools}; use json::JsonValue; +#[allow(unused_imports)] +use log::{debug, error, info, trace, warn}; + pub struct EventExpressionList {} impl EventExpressionList { @@ -15,13 +18,11 @@ impl EventExpressionList { match json_children[0]["tag"].as_str() { Some(Tag::POS_EDGE) => Expression::codegen(&json_children[1], context), Some(Tag::NEG_EDGE) => Expression::codegen(&json_children[1], context), - Some(x) => Logger::insert(format!("FIXME: handle {} in ", x)), + Some(x) => error!("FIXME: case '{}' missing", x), _ => panic!(), } } - Logger::insert(format!( - "TODO: complete the rest of EventExpressionList::codegen()" - )); + warn!("TODO: complete the rest of codegen"); } } diff --git a/src/cst/expression.rs b/src/cst/expression.rs index 0a08cb3..171d5b5 100644 --- a/src/cst/expression.rs +++ b/src/cst/expression.rs @@ -1,6 +1,9 @@ -use crate::cst::{Logger, ModuleContext, Tag, Tools}; +use crate::cst::{ModuleContext, Tag, Tools}; use json::JsonValue; +#[allow(unused_imports)] +use log::{debug, error, info, trace, warn}; + pub struct Expression {} impl Expression { @@ -13,11 +16,9 @@ impl Expression { } fn codegen_internal(json: &JsonValue, context: &mut ModuleContext) { - let me = "Expression::codegen()"; - match json["tag"].as_str() { Some(Tag::NUMBER) => { - Logger::insert(format!("FIXME: handle {} in {}", Tag::NUMBER, me)); + warn!("FIXME: case '{}' incomplete", Tag::NUMBER); } Some(Tag::REFERENCE_CALL_BASE) => { let json_symbol_identifier = Tools::match_tags( @@ -35,22 +36,17 @@ impl Expression { .rvalues .insert(json_symbol_identifier[0]["text"].to_string()); - Logger::insert(format!( - "TODO: complete the rest of {} in {}", - Tag::REFERENCE_CALL_BASE, - me - )); + warn!("TODO: complete the rest of '{}'", Tag::REFERENCE_CALL_BASE); } 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 - )); + warn!( + "TODO: complete the rest of '{}'", + Tag::UNARY_PREFIX_EXPRESSION + ); } Some(Tag::BINARY_EXPRESSION) => { let json_children = &json["children"]; @@ -58,11 +54,7 @@ impl Expression { 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 - )); + warn!("TODO: complete the rest of '{}'", Tag::BINARY_EXPRESSION); } Some(Tag::PAREN_GROUP) => { let json_expression = @@ -71,7 +63,7 @@ impl Expression { Self::codegen(&json_expression[0], context); } Some(x) => { - Logger::insert(format!("FIXME: handle {} in {}", x, me)); + error!("FIXME: case '{}' missing", x); } _ => panic!(), }; diff --git a/src/cst/module_declaration.rs b/src/cst/module_declaration.rs index 653addb..78fbb88 100644 --- a/src/cst/module_declaration.rs +++ b/src/cst/module_declaration.rs @@ -1,10 +1,13 @@ use crate::cst::{AlwaysStatement, ModuleContext, SymbolInfo, Tag, Tools}; use json::JsonValue; use llhd::ir::{ - ExtUnit, Module, Signature, UnitBuilder, UnitData, UnitId, UnitKind, UnitName, Value, + Arg, ExtUnit, Module, Signature, UnitBuilder, UnitData, UnitId, UnitKind, UnitName, Value, }; use llhd::ty::{int_ty, signal_ty}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; + +#[allow(unused_imports)] +use log::{debug, error, info, trace, warn}; pub struct ModuleDeclaration {} @@ -12,19 +15,36 @@ impl ModuleDeclaration { pub fn codegen(json: &JsonValue) -> Module { let mut context = ModuleContext::new(); + let mut arg_to_literal_name = HashMap::new(); + let entity_name = Self::get_entity_name(json, &mut context); - let entity_signature = Self::get_entity_signature(json, &mut context); + let entity_signature = + Self::get_entity_signature(json, &mut context, &mut arg_to_literal_name); let mut entity_data = UnitData::new(UnitKind::Entity, entity_name, entity_signature); + // build entity { - // build entity let mut entity_builder = UnitBuilder::new_anonymous(&mut entity_data); - for (arg, name) in context.arg_name.iter() { - let value = entity_builder.arg_value(*arg); - entity_builder.set_name(value, name.to_string()); + // set port names + for (arg, literal_name) in arg_to_literal_name { + let arg_value = entity_builder.arg_value(arg); + entity_builder.set_name(arg_value, literal_name); } + // declare registers + let reg_info = &Self::get_reg_info(json); + for (reg, width) in reg_info { + if !context.symbol.contains_key(reg) { + context + .symbol + .insert(reg.to_string(), SymbolInfo::new(&width)); + } else { + info!("reg '{}' has be declared as a port", reg); + } + } + + // declare and implement processes let json_always_statement = &Tools::match_tags( vec![json], vec![ @@ -36,7 +56,7 @@ impl ModuleDeclaration { let ext_to_proc: Vec<(ExtUnit, UnitId)> = json_always_statement .iter() .map(|&x| { - let proc_id = AlwaysStatement::codegen(x, &mut context); // build a process + 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()); @@ -53,6 +73,8 @@ impl ModuleDeclaration { }) .collect(); + // instantiate processes + /* for (ext_proc, proc_id) in ext_to_proc { let proc = &context.module.unit(proc_id); let inputs: Vec = proc @@ -71,8 +93,9 @@ impl ModuleDeclaration { name_to_value[name] }) .collect(); - entity_builder.ins().inst(ext_proc, inputs, outputs); // instantiate a process + entity_builder.ins().inst(ext_proc, inputs, outputs); } + */ entity_builder.finish(); } @@ -99,7 +122,11 @@ impl ModuleDeclaration { UnitName::global(context.name.to_string()) } - fn get_entity_signature(json: &JsonValue, context: &mut ModuleContext) -> Signature { + fn get_entity_signature( + json: &JsonValue, + context: &mut ModuleContext, + arg_to_literal_name: &mut HashMap, + ) -> Signature { let mut signature = Signature::new(); let json_ports = &Tools::match_tags( @@ -116,17 +143,17 @@ impl ModuleDeclaration { for (name, width) in input_info { let arg = signature.add_input(signal_ty(int_ty(width.clone()))); + arg_to_literal_name.insert(arg, name.to_string()); context - .symbol_info + .symbol .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()))); + arg_to_literal_name.insert(arg, name.to_string()); context - .symbol_info + .symbol .insert(name.to_string(), SymbolInfo::new(width)); - context.arg_name.insert(arg, name.to_string()); } signature @@ -233,11 +260,11 @@ impl ModuleDeclaration { } fn get_port_info(json_ports: &Vec<&JsonValue>, tag: &str) -> Vec<(String, usize)> { - let json_tagged_ports = &json_ports + let json_tagged_ports: &Vec<&JsonValue> = &json_ports .iter() .filter(|&x| x["children"].members().filter(|&x| x["tag"] == tag).count() > 0) .map(|&x| x) - .collect::>(); + .collect(); let bit_names = &Self::get_bit_names(json_tagged_ports); let vec_names = &Self::get_vec_names(json_tagged_ports); @@ -262,4 +289,85 @@ impl ModuleDeclaration { port_info } + + fn get_reg_info(json: &JsonValue) -> Vec<(String, usize)> { + let json_regs: Vec<&JsonValue> = Tools::match_tags( + vec![json], + vec![ + Tag::MODULE_DECLARATION, + Tag::MODULE_ITEM_LIST, + Tag::DATA_DECLARATION, + Tag::INSTANTIATION_BASE, + ], + ) + .iter() + .filter(|&x| { + Tools::match_tags( + vec![x], + vec![ + Tag::INSTANTIATION_BASE, + Tag::INSTANTIATION_TYPE, + Tag::DATA_TYPE, + Tag::DATA_TYPE_PRIMITIVE, + Tag::REG, + ], + ) + .len() + > 0 + }) + .map(|&x| x) + .collect(); + + json_regs + .iter() + .map(|&json_reg| { + let json_reg_names = &Tools::match_tags( + vec![json_reg], + vec![ + Tag::INSTANTIATION_BASE, + Tag::GATE_INSTANCE_REGISTER_VARIABLE_LIST, + Tag::REGISTER_VARIABLE, + Tag::SYMBOL_IDENTIFIER, + ], + ); + assert!(json_reg_names.len() > 0); + + let json_reg_dims = Tools::match_tags( + vec![json_reg], + vec![ + Tag::INSTANTIATION_BASE, + Tag::INSTANTIATION_TYPE, + Tag::DATA_TYPE, + Tag::PACKED_DIMENSIONS, + Tag::DECLARATION_DIMENSIONS, + Tag::DIMENSION_RANGE, + Tag::EXPRESSION, + Tag::NUMBER, + Tag::DEC_NUMBER, + ], + ); + assert!(HashSet::from([0, 2]).contains(&json_reg_dims.len())); + let width = match json_reg_dims.len() { + 2 => { + let hi_bit = json_reg_dims[0]["text"] + .to_string() + .parse::() + .unwrap(); + let lo_bit = json_reg_dims[1]["text"] + .to_string() + .parse::() + .unwrap(); + hi_bit - lo_bit + 1 + } + _ => 1, + }; + + json_reg_names + .iter() + .map(|x| (x["text"].to_string(), width)) + .collect::>() + }) + .flatten() + .collect() + } } diff --git a/src/cst/nonblocking_assignment_statement.rs b/src/cst/nonblocking_assignment_statement.rs index ede481a..c644a7c 100644 --- a/src/cst/nonblocking_assignment_statement.rs +++ b/src/cst/nonblocking_assignment_statement.rs @@ -1,6 +1,9 @@ -use crate::cst::{Expression, Logger, ModuleContext, Tag, Tools}; +use crate::cst::{Expression, ModuleContext, Tag, Tools}; use json::JsonValue; +#[allow(unused_imports)] +use log::{debug, error, info, trace, warn}; + pub struct NonblockingAssignmentStatement {} impl NonblockingAssignmentStatement { @@ -34,8 +37,6 @@ impl NonblockingAssignmentStatement { Expression::codegen(json_expression, context); - Logger::insert(format!( - "TODO: complete the rest of NonblockingAssignmentStatement::codegen()" - )); + warn!("TODO: complete the rest of codegen"); } } diff --git a/src/cst/statement.rs b/src/cst/statement.rs index 934a155..edb3231 100644 --- a/src/cst/statement.rs +++ b/src/cst/statement.rs @@ -1,9 +1,12 @@ use crate::cst::{ - CaseStatement, ConditionalStatement, Logger, ModuleContext, NonblockingAssignmentStatement, - SeqBlock, Tag, + CaseStatement, ConditionalStatement, ModuleContext, NonblockingAssignmentStatement, SeqBlock, + Tag, }; use json::JsonValue; +#[allow(unused_imports)] +use log::{debug, error, info, trace, warn}; + pub struct Statement {} impl Statement { @@ -16,7 +19,7 @@ impl Statement { NonblockingAssignmentStatement::codegen(json, context) } Some(x) => { - Logger::insert(format!("FIXME: missing {}", x)); + error!("FIXME: missing {}", x); } _ => panic!(), }; diff --git a/src/cst/tags.rs b/src/cst/tags.rs index 04173ca..d3f533a 100644 --- a/src/cst/tags.rs +++ b/src/cst/tags.rs @@ -19,6 +19,15 @@ impl Tag { pub const DIMENSION_RANGE: &'static str = "kDimensionRange"; pub const SYMBOL_IDENTIFIER: &'static str = "SymbolIdentifier"; + pub const DATA_DECLARATION: &'static str = "kDataDeclaration"; + pub const INSTANTIATION_BASE: &'static str = "kInstantiationBase"; + pub const GATE_INSTANCE_REGISTER_VARIABLE_LIST: &'static str = + "kGateInstanceRegisterVariableList"; + pub const REGISTER_VARIABLE: &'static str = "kRegisterVariable"; + pub const INSTANTIATION_TYPE: &'static str = "kInstantiationType"; + pub const DATA_TYPE: &'static str = "kDataType"; + pub const DATA_TYPE_PRIMITIVE: &'static str = "kDataTypePrimitive"; + pub const LP_VALUE: &'static str = "kLPValue"; pub const REFERENCE_CALL_BASE: &'static str = "kReferenceCallBase"; pub const REFERENCE: &'static str = "kReference"; @@ -59,11 +68,11 @@ impl Tag { pub const CASE_STATEMENT: &'static str = "kCaseStatement"; /* - pub const DATA_DECLARATION: &'static str = "kDataDeclaration"; pub const NET_DECLARATION: &'static str = "kNetDeclaration"; pub const CONTINUOUS_ASSIGNMENT_STATEMENT: &'static str = "kContinuousAssignmentStatement"; */ pub const INPUT: &'static str = "input"; pub const OUTPUT: &'static str = "output"; + pub const REG: &'static str = "reg"; }