From 04fab246ea5cd4c2711d81ac6ea6a7027ee22f8e Mon Sep 17 00:00:00 2001 From: Mora Unie Youer Date: Mon, 28 Apr 2025 12:35:04 +0300 Subject: feat: calculation of input signal current --- src/main.rs | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 118 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 4138a33..c99d2c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -401,14 +401,6 @@ impl ChipInfo<'_> { std::cmp::max(self.consumption_low, self.consumption_high) } - fn input_current(&self) -> usize { - std::cmp::min(self.input_current_low, self.input_current_high) - } - - fn output_current(&self) -> usize { - std::cmp::min(self.output_current_low, self.output_current_high) - } - fn delay(&self) -> usize { std::cmp::max(self.delay_off, self.delay_on) } @@ -613,6 +605,115 @@ fn logic_to_reduced_delay(logic: &Logic, series: &ChipSeries) -> usize { .unwrap() } +fn logic_to_input_current<'input>( + logic: &'input Logic, + series: &ChipSeries<'input>, +) -> HashMap<&'input str, (usize, usize)> { + let mut consumptions = HashMap::new(); + let mut visited = HashSet::new(); + + let mut queue = VecDeque::from([logic]); + while let Some(logic) = queue.pop_front() { + if !visited.insert(logic) { + continue; + } + + let gate = match logic { + Logic::Constant(_) => continue, + Logic::Variable(_) => continue, + + Logic::Not(logic) => { + queue.push_back(logic); + ("NOT", 1) + } + + Logic::And(logics) => { + logics.iter().for_each(|logic| queue.push_back(logic)); + ("AND", logics.len()) + } + + Logic::Or(logics) => { + logics.iter().for_each(|logic| queue.push_back(logic)); + ("OR", logics.len()) + } + + Logic::Nand(logics) => { + logics.iter().for_each(|logic| queue.push_back(logic)); + ("NAND", logics.len()) + } + + Logic::Nor(logics) => { + logics.iter().for_each(|logic| queue.push_back(logic)); + ("NOR", logics.len()) + } + }; + + let chip = series.logic_to_chip[&gate]; + + let ChipInfo { + input_current_low, + input_current_high, + .. + } = series.chip_specification[chip]; + + // Checking if children of this logic has variable + // TODO: rewrite this shit better, by generating children of any logic + match logic { + Logic::Not(l) => { + if let Logic::Variable(name) = &**l { + let (low, high) = consumptions.entry(name.as_str()).or_default(); + *low += input_current_low; + *high += input_current_high; + } + } + + Logic::And(logics) => { + for l in logics { + if let Logic::Variable(name) = l { + let (low, high) = consumptions.entry(name.as_str()).or_default(); + *low += input_current_low; + *high += input_current_high; + } + } + } + + Logic::Or(logics) => { + for l in logics { + if let Logic::Variable(name) = l { + let (low, high) = consumptions.entry(name.as_str()).or_default(); + *low += input_current_low; + *high += input_current_high; + } + } + } + + Logic::Nand(logics) => { + for l in logics { + if let Logic::Variable(name) = l { + let (low, high) = consumptions.entry(name.as_str()).or_default(); + *low += input_current_low; + *high += input_current_high; + } + } + } + + Logic::Nor(logics) => { + for l in logics { + if let Logic::Variable(name) = l { + let (low, high) = consumptions.entry(name.as_str()).or_default(); + *low += input_current_low; + *high += input_current_high; + } + } + } + + _ => (), + } + } + + consumptions +} + struct TruthTable<'input> { inputs: Vec<&'input str>, outputs: Vec<&'input str>, @@ -705,7 +806,7 @@ fn main() { let all_solutions = truth_table.solve(); const SOLUTIONS: [&str; 6] = ["DNF", "NAND", "FULL_NAND", "CNF", "NOR", "FULL_NOR"]; - for (output, solutions) in &all_solutions { + for (output, solutions) in all_solutions.iter().sorted_by_key(|(output, _)| *output) { println!("Решения для {output}:"); for (solution_type, solution) in SOLUTIONS.into_iter().zip(solutions) { println!("- {solution_type}:"); @@ -715,6 +816,7 @@ fn main() { let chips = logic_to_chips(solution, &chip_series); let full_delay = logic_to_full_delay(solution, &chip_series); let reduced_delay = logic_to_reduced_delay(solution, &chip_series); + let input_currents = logic_to_input_current(solution, &chip_series); println!(" Параметры решения:"); println!(" - Количество использованных микросхем:"); @@ -725,7 +827,7 @@ fn main() { let mut total_consumption = 0.; let mut total_used_consumption = 0.; - for (chip, (used, size)) in chips { + for (chip, (used, size)) in chips.into_iter().sorted() { let chip_info = chip_series.chip_specification[chip]; let chip_usage = used as f32 / size as f32; @@ -750,6 +852,12 @@ fn main() { println!(" - Задержка (без инверсии входных переменных): {reduced_delay} нс"); println!(" - Полное потребление схемы: {total_consumption} мкВт"); println!(" - Использованное потребление схемы: {total_used_consumption} мкВт"); + + println!(" - Потребляемый ток со входных сигналов:"); + for (input, (low_current, high_current)) in input_currents.into_iter().sorted() { + println!(" - {input} - {low_current}/{high_current} мкА"); + } + println!(); } -- cgit v1.2.3-70-g09d2