From 7521366272166a0cee937ac36c55203790ed6406 Mon Sep 17 00:00:00 2001 From: Mora Unie Youer Date: Sun, 27 Apr 2025 13:15:19 +0300 Subject: feat: read truth table from file --- k1533_chips.txt | 64 +++++++++++++++++++++++ src/main.rs | 157 ++++++++++++++++++++++---------------------------------- tests/1.txt | 12 +++++ 3 files changed, 137 insertions(+), 96 deletions(-) create mode 100644 k1533_chips.txt create mode 100644 tests/1.txt diff --git a/k1533_chips.txt b/k1533_chips.txt new file mode 100644 index 0000000..6292e54 --- /dev/null +++ b/k1533_chips.txt @@ -0,0 +1,64 @@ +// Формат файла: +// <элемент> <номер страницы справочника> ... +// ... <наименование микросхемы> ... +// ... <ток потребления при высоком уровне> <ток потребления при низком уровне> (в "мкА") ... +// ... <входной ток высокого уровня> <входной ток низкого уровня> (в "мкА") ... +// ... <выходной ток высокого уровня> <выходной ток низкого уровня> (в "мкА") ... +// ... <задержка выключения> <задержка включения> (в "нс") + +// Логические элементы И-НЕ (КР1533ЛА) +2xNAND4 222 КР1533ЛА1 400 1500 20 100 70000 70000 11 10 +1xNAND8 224 КР1533ЛА2 360 900 20 100 70000 70000 10 12 +4xNAND2 226 КР1533ЛА3 850 3000 20 100 70000 70000 11 8 +3xNAND3 228 КР1533ЛА4 600 2200 20 100 112000 112000 11 10 +//// С повышенной нагрузочной способностью +4xNAND2 238 КР1533ЛА21 22000 22000 20 200 112000 112000 8 7 +2xNAND4 240 КР1533ЛА22 800 3900 20 100 112000 112000 8 7 +3xNAND3 244 КР1533ЛА24 1200 5800 20 100 112000 112000 8 8 +//// С открытым коллекторным выходом +2xNANDC4 230 КР1533ЛА7 400 1500 20 100 112000 112000 45 18 +4xNANDC2 232 КР1533ЛА8 850 3000 20 100 100 100 54 28 +4xNANDC2 234 КР1533ЛА9 850 300 20 100 112000 112000 54 28 +3xNANDC3 236 КР1533ЛА10 600 2200 20 100 100 100 54 18 +//// С открытым коллекторным выходом и повышенной нагрузочной способностью +3xNANDC3 242 КР1533ЛА23 1600 7800 20 100 100000 100000 33 12 + + +// Логические элементы ИЛИ-НЕ (КР1533ЛЕ) +4xNOR2 246 КР1533ЛЕ1 2200 4000 20 100 112000 112000 12 10 +3xNOR3 248 КР1533ЛЕ4 1800 4000 20 100 112000 112000 15 9 +//// С повышенной нагрузочной способностью +4xNOR2 250 КР1533ЛЕ10 22000 22000 20 100 112000 112000 8 7 +//// С открытым коллекторным выходом +//// С открытым коллекторным выходом и повышенной нагрузочной способностью +4xNOR2 252 КР1533ЛЕ11 2800 9000 20 100 100 100 33 12 + + +// Логические элементы И (КР1533ЛИ) +4xAND2 254 КР1533ЛИ1 2400 4000 20 100 112000 112000 14 10 +3xAND3 258 КР1533ЛИ3 1800 3000 20 100 112000 112000 10 13 +2xAND4 262 КР1533ЛИ6 2000 2000 20 100 112000 112000 26 10 +//// С повышенной нагрузочной способностью +4xAND2 264 КР1533ЛИ8 3000 9300 20 100 112000 112000 9 9 +3xAND3 266 КР1533ЛИ10 2300 7000 20 100 112000 112000 10 9 +//// С открытым коллекторным выходом +4xAND2 256 КР1533ЛИ2 2400 4000 20 100 100 100 54 15 +3xAND3 260 КР1533ЛИ4 1800 3000 20 200 100 100 56 20 +//// С открытым коллекторным выходом и повышенной нагрузочной способностью + + +// Логические элементы ИЛИ (КР1533ЛЛ) +4xOR2 262 КР1533ЛЛ1 4000 4900 20 100 112000 112000 14 12 +//// С повышенной нагрузочной способностью +4xOR2 270 КР1533ЛЛ4 5000 10600 20 100 112000 112000 9 12 +//// С открытым коллекторным выходом +//// С открытым коллекторным выходом и повышенной нагрузочной способностью + + +// Логические элементы НЕ (КР1533ЛН) +6xNOT1 272 КР1533ЛН1 1100 4200 20 100 70000 70000 11 8 +//// С повышенной нагрузочной способностью +6xNOT1 279 КР1533ЛН8 3000 12000 20 100 112000 112000 7 6 +//// С открытым коллекторным выходом +6xNOTC1 274 КР1533ЛН2 1100 3800 20 100 100 100 54 14 +//// С открытым коллекторным выходом и повышенной нагрузочной способностью diff --git a/src/main.rs b/src/main.rs index 95d5b7b..bc22521 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,44 +37,6 @@ impl Cube { } } -fn cube_to_string(n: usize, cube: &Cube) -> String { - let mut s = String::new(); - - let Cube { mut t, mut f } = *cube; - for _ in 0..n { - match (t & 1, f & 1) { - (1, 0) => s.push('1'), - (0, 1) => s.push('0'), - (0, 0) => s.push('x'), - _ => unreachable!(), - } - - t >>= 1; - f >>= 1; - } - - s.chars().rev().collect() -} - -fn cube_to_var_string(vars: &[&str], cube: &Cube) -> String { - let mut used_vars: Vec = Vec::with_capacity(vars.len()); - - let Cube { mut t, mut f } = *cube; - for i in (0..vars.len()).rev() { - match (t & 1, f & 1) { - (1, 0) => used_vars.push(vars[i].into()), - (0, 1) => used_vars.push(format!("{}'", vars[i])), - (0, 0) => (), - _ => unreachable!(), - } - - t >>= 1; - f >>= 1; - } - - used_vars.into_iter().rev().join(" * ") -} - fn minimize_prime_implicants(n: usize, minterms: &[usize], maxterms: &[usize]) -> Vec { let minterms_set: HashSet<_> = minterms.iter().copied().collect(); let maxterms_set: HashSet<_> = maxterms.iter().copied().collect(); @@ -131,35 +93,6 @@ fn minimize_prime_implicants(n: usize, minterms: &[usize], maxterms: &[usize]) - final_cubes } -fn print_prime_implicants_table(n: usize, minterms: &[usize], prime_implicants: &[Cube]) { - println!("Prime implicants:"); - for (i, prime_implicant) in prime_implicants.iter().enumerate() { - let cube_str = cube_to_string(n, prime_implicant); - println!("{i}: {cube_str}"); - } - - println!(); - println!("Prime Implicants Table (PIT):"); - print!(" "); - println!( - "{}", - (0..minterms.len()) - .map(|i| format!(" {} ", minterms[i])) - .join("") - ); - for (i, prime_implicant) in prime_implicants.iter().enumerate() { - print!("{i}"); - for &minterm in minterms { - if prime_implicant.covers(minterm) { - print!(" x "); - } else { - print!(" "); - } - } - println!(); - } -} - fn solve_prime_implicants_table(minterms: &[usize], prime_implicants: &[Cube]) -> Vec { let mut table: HashSet<(usize, usize)> = (0..prime_implicants.len()) .cartesian_product(0..minterms.len()) @@ -254,7 +187,7 @@ fn solve_prime_implicants_table(minterms: &[usize], prime_implicants: &[Cube]) - fn minimize(n: usize, minterms: &[usize], maxterms: &[usize]) -> Vec { let prime_implicants = minimize_prime_implicants(n, minterms, maxterms); - print_prime_implicants_table(n, minterms, &prime_implicants); + // print_prime_implicants_table(n, minterms, &prime_implicants); solve_prime_implicants_table(minterms, &prime_implicants) } @@ -431,36 +364,68 @@ fn cubes_to_wired_or(cubes: &[Cube], vars: &[&str]) -> Logic { } fn main() { - let vars = &["X4", "X3", "X2", "X1"]; - // let minterms = [0, 1, 2, 3, 4]; // Термы со значением 1 - // let maxterms = [5, 6, 7, 8, 9]; // Термы со значением 0 - // let minterms = [0, 1, 2, 3, 4, 5, 6, 7]; // Термы со значением 1 - // let maxterms = [9]; // Термы со значением 0 - let minterms = [0, 3, 4, 7]; // Термы со значением 1 - let maxterms = [1, 2, 5, 6]; // Термы со значением 0 - - let min_cubes = minimize(4, &minterms, &maxterms); - - println!("Итоговые термы: "); - for cube in min_cubes { - println!( - "{} -> {}", - cube_to_string(4, &cube), - cube_to_var_string(vars, &cube) - ); + let mut args = std::env::args().skip(1); + let chip_series_file_path = args.next().unwrap(); + let truth_table_file_path = args.next().unwrap(); + + // TODO: make a use of this + let _chip_series_file = std::fs::read_to_string(chip_series_file_path).unwrap(); + + let truth_table_file = std::fs::read_to_string(truth_table_file_path).unwrap(); + + // Parsing truth table + let mut truth_table_lines = truth_table_file.lines(); + + let truth_table_inputs = truth_table_lines + .next() + .map(|line| line.split_whitespace().collect_vec()) + .unwrap(); + let truth_table_outputs = truth_table_lines + .next() + .map(|line| line.split_whitespace().collect_vec()) + .unwrap(); + + let mut truth_table_minterms = vec![vec![]; truth_table_outputs.len()]; + let mut truth_table_maxterms = vec![vec![]; truth_table_outputs.len()]; + for line in truth_table_lines { + let (input, output) = line.split_once(char::is_whitespace).unwrap(); + if input.len() != truth_table_inputs.len() || output.len() != truth_table_outputs.len() { + panic!("Truth table is incorrect: invalid input/output size"); + } + + let input_term = usize::from_str_radix(input, 2).unwrap(); + for (i, ch) in output.chars().enumerate() { + match ch { + '1' => truth_table_minterms[i].push(input_term), + '0' => truth_table_maxterms[i].push(input_term), + '-' => (), + _ => panic!("Truth table is incorrect: invalid char in output section"), + } + } } - let cubes = minimize(4, &minterms, &maxterms); - let inv_cubes = minimize(4, &maxterms, &minterms); + for (output, (minterms, maxterms)) in truth_table_outputs + .into_iter() + .zip(truth_table_minterms.into_iter().zip(truth_table_maxterms)) + { + let cubes = minimize(truth_table_inputs.len(), &minterms, &maxterms); + let inv_cubes = minimize(truth_table_inputs.len(), &maxterms, &minterms); - println!("{}", cubes_to_dnf(&cubes, vars)); - println!("{}", cubes_to_nand(&cubes, vars)); - println!("{}", cubes_to_cnf(&inv_cubes, vars)); - println!("{}", cubes_to_nor(&inv_cubes, vars)); - println!("{}", cubes_to_wired_or(&inv_cubes, vars)); + println!("{output} = {}", cubes_to_dnf(&cubes, &truth_table_inputs)); + println!("{output} = {}", cubes_to_nand(&cubes, &truth_table_inputs)); + println!( + "{output} = {}", + cubes_to_cnf(&inv_cubes, &truth_table_inputs) + ); + println!( + "{output} = {}", + cubes_to_nor(&inv_cubes, &truth_table_inputs) + ); + println!( + "{output} = {}", + cubes_to_wired_or(&inv_cubes, &truth_table_inputs) + ); - // dbg!(cubes_to_dnf(&cubes, vars)); - // dbg!(cubes_to_nand(&cubes, vars)); - // dbg!(cubes_to_cnf(&inv_cubes, vars)); - // dbg!(cubes_to_nor(&inv_cubes, vars)); + println!(); + } } diff --git a/tests/1.txt b/tests/1.txt new file mode 100644 index 0000000..e42f1fe --- /dev/null +++ b/tests/1.txt @@ -0,0 +1,12 @@ +X4 X3 X2 X1 +F1 F2 F3 +0000 111 +0001 110 +0010 110 +0011 111 +0100 111 +0101 010 +0110 010 +0111 011 +1000 0-- +1001 00- -- cgit v1.2.3-70-g09d2