summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main.rs128
1 files changed, 118 insertions, 10 deletions
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!();
}