diff --git a/.gitignore b/.gitignore index b37659d..b655d0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,11 @@ __pycache__/ .mypy_cache/ build/ -dist/ \ No newline at end of file +dist/ +*.DS_Store +*.tmp +*.temp +*.docx~ +~*.docx +*.docx.tmp +*.docx.temp diff --git a/.vscode/launch.json b/.vscode/launch.json index 1fd8427..fed746c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,7 +2,7 @@ "configurations": [ { "name": "ArduinoLogique", - "type": "debugpy", + "type": "python", "request": "launch", "program": "${workspaceFolder}/arduino_logique.py", "console": "integratedTerminal" diff --git a/Components/Chips/Logical/74HC238_DEMUX_3_8.json b/Components/Chips/Logical/74HC238_DEMUX_3_8.json index 03f45e5..9aa9b7f 100644 --- a/Components/Chips/Logical/74HC238_DEMUX_3_8.json +++ b/Components/Chips/Logical/74HC238_DEMUX_3_8.json @@ -7,7 +7,7 @@ "functions": [ { "func_type": "DEMUX", - "address_pins": [1, 2, 3], + "input_pins": [1, 2, 3], "output_pins": [15, 14, 13, 12, 11, 10, 9, 7], "enable_pins": [6], "inv_enable_pins": [4, 5] diff --git a/Components/Chips/Sequential/74HC109_JK.json b/Components/Chips/Sequential/74HC109_JK.json index 57ec4be..63b36a9 100644 --- a/Components/Chips/Sequential/74HC109_JK.json +++ b/Components/Chips/Sequential/74HC109_JK.json @@ -17,8 +17,8 @@ "inv_j_input_pin": null, "k_input_pin": null, "inv_k_input_pin": 3, - "output_pin": 6, - "inv_output_pin": 7 + "output_pins": 6, + "inv_output_pins": 7 }, { "func_type": "JK_FLIP_FLOP", @@ -32,8 +32,8 @@ "inv_j_input_pin": null, "k_input_pin": null, "inv_k_input_pin": 13, - "output_pin": 10, - "inv_output_pin": 9 + "output_pins": 10, + "inv_output_pins": 9 } ], "datasheet": "https://www.alldatasheet.com/datasheet-pdf/view/15527/PHILIPS/74HC109.html" diff --git a/Components/Chips/Sequential/74HC112_JK.json b/Components/Chips/Sequential/74HC112_JK.json index ea9203d..e723146 100644 --- a/Components/Chips/Sequential/74HC112_JK.json +++ b/Components/Chips/Sequential/74HC112_JK.json @@ -17,8 +17,8 @@ "inv_j_input_pin": null, "k_input_pin": 2, "inv_k_input_pin": null, - "output_pin": 5, - "inv_output_pin": 6 + "output_pins": 5, + "inv_output_pins": 6 }, { "func_type": "JK_FLIP_FLOP", @@ -32,8 +32,8 @@ "inv_j_input_pin": null, "k_input_pin": 12, "inv_k_input_pin": null, - "output_pin": 9, - "inv_output_pin": 7 + "output_pins": 9, + "inv_output_pins": 7 } ], "datasheet": "https://www.alldatasheet.com/datasheet-pdf/view/15529/PHILIPS/74HC112.html" diff --git a/Components/Chips/Sequential/74HC163.json b/Components/Chips/Sequential/74HC163.json new file mode 100644 index 0000000..49fbeb5 --- /dev/null +++ b/Components/Chips/Sequential/74HC163.json @@ -0,0 +1,27 @@ +{ + "name": "74HC163", + "description": "Presettable synchronous 4-bit binary counter; synchronous reset", + "package": "DIP16", + "vcc_pin": 16, + "gnd_pin": 8, + "functions": [ + { + "func_type": "BINARY_COUNTER", + "clock_pin": 2, + "clock_type": "RISING_EDGE", + "reset_pin": null, + "inv_reset_pin": 1, + "count_enable_pin": 7, + "inv_count_enable_pin": null, + "load_enable_pin": null, + "inv_load_enable_pin": 9, + "up_down_input_pin": null, + "inv_up_down_input_pin": 10, + "terminal_count_pin": 15, + "ripple_clock_output_pin": null, + "data_pins": [3, 4, 5, 6], + "output_pins": [14, 13, 12, 11] + } + ], + "datasheet": "https://www.alldatasheet.com/datasheet-pdf/view/15547/PHILIPS/74HC163.html" +} \ No newline at end of file diff --git a/Components/Chips/Sequential/74HC191_CB4CLED.json b/Components/Chips/Sequential/74HC191_CB4CLED.json index 0afe11e..af698d0 100644 --- a/Components/Chips/Sequential/74HC191_CB4CLED.json +++ b/Components/Chips/Sequential/74HC191_CB4CLED.json @@ -9,6 +9,8 @@ "func_type": "BINARY_COUNTER", "clock_pin": 14, "clock_type": "RISING_EDGE", + "reset_pin": null, + "inv_reset_pin": null, "count_enable_pin": null, "inv_count_enable_pin": 4, "load_enable_pin": null, diff --git a/Components/Chips/Sequential/74HC74_D.json b/Components/Chips/Sequential/74HC74_D.json index 50bc0eb..1887187 100644 --- a/Components/Chips/Sequential/74HC74_D.json +++ b/Components/Chips/Sequential/74HC74_D.json @@ -7,27 +7,27 @@ "functions": [ { "func_type": "D_FLIP_FLOP", - "clock_pin": 3, + "clock_pin": [3], "clock_type": "RISING_EDGE", "reset_pin": null, - "inv_reset_pin": 1, + "inv_reset_pin": [1], "set_pin": null, - "inv_set_pin": 4, - "data_pin": 2, - "output_pin": 5, - "inv_output_pin": 6 + "inv_set_pin": [4], + "input_pins": [2], + "output_pins": [5], + "inv_output_pins": [6] }, { "func_type": "D_FLIP_FLOP", - "clock_pin": 11, + "clock_pin": [11], "clock_type": "RISING_EDGE", "reset_pin": null, - "inv_reset_pin": 13, + "inv_reset_pin": [13], "set_pin": null, - "inv_set_pin": 10, - "data_pin": 12, - "output_pin": 9, - "inv_output_pin": 8 + "inv_set_pin": [10], + "input_pins": [12], + "output_pins": [9], + "inv_output_pins": [8] } ], "datasheet": "https://www.alldatasheet.com/datasheet-pdf/view/15659/PHILIPS/74HC74.html" diff --git a/Mc/bascule_essai_120.zip b/Mc/bascule_essai_120.zip new file mode 100644 index 0000000..0a9e30b Binary files /dev/null and b/Mc/bascule_essai_120.zip differ diff --git a/Mc/simul61_testee_fonctionnelle (2eme approche).zip b/Mc/simul61_testee_fonctionnelle (2eme approche).zip new file mode 100644 index 0000000..e4eec63 Binary files /dev/null and b/Mc/simul61_testee_fonctionnelle (2eme approche).zip differ diff --git a/Mc/simul61_testee_fonctionnelle (2eme approche)/simul61_testee_fonctionnelle.ino b/Mc/simul61_testee_fonctionnelle (2eme approche)/simul61_testee_fonctionnelle.ino new file mode 100644 index 0000000..0284f05 --- /dev/null +++ b/Mc/simul61_testee_fonctionnelle (2eme approche)/simul61_testee_fonctionnelle.ino @@ -0,0 +1,168 @@ +#include + +const int MAX_INPUTS = 8; +const int MAX_OUTPUTS = 6; + +const int inputPins[MAX_INPUTS] = {22, 23, 24, 25, 26, 27, 28, 29}; // Broches pour I1 à I8 +const int outputPins[MAX_OUTPUTS] = {32, 33, 34, 35, 36, 37}; // Broches pour O1 à O6 + +String logicExpressions[MAX_OUTPUTS]; + +void setup() { + Serial.begin(9600); + for (int i = 0; i < MAX_INPUTS; i++) { + pinMode(inputPins[i], INPUT); + } + for (int i = 0; i < MAX_OUTPUTS; i++) { + pinMode(outputPins[i], OUTPUT); + digitalWrite(outputPins[i], LOW); + } +} + +void loop() { + if (Serial.available()) { + String input = Serial.readStringUntil('\n'); + parseMultipleExpressions(input); + } + updateOutputs(); +} + +void resetOutputs() { + for (int i = 0; i < MAX_OUTPUTS; i++) { + logicExpressions[i] = ""; + digitalWrite(outputPins[i], LOW); + } +} + +void parseMultipleExpressions(String input) { + resetOutputs(); + input.trim(); + int start = 0; + while (start < input.length()) { + int end = input.indexOf(';', start); + if (end == -1) { + end = input.length(); + } + String expression = input.substring(start, end); + parseExpression(expression); + start = end + 1; + } +} + +void parseExpression(String input) { + input.trim(); + int eqIndex = input.indexOf('='); + if (eqIndex != -1 && input.startsWith("O")) { + int outputIndex = input.substring(1, eqIndex).toInt() - 1; + if (outputIndex >= 0 && outputIndex < MAX_OUTPUTS) { + logicExpressions[outputIndex] = input.substring(eqIndex + 1); + } + } +} + +bool evaluateExpression(String expr) { + expr.trim(); + expr.replace(" ", ""); + for (int i = 0; i < MAX_INPUTS; i++) { + expr.replace("!I" + String(i + 1), String(!digitalRead(inputPins[i]))); + expr.replace("I" + String(i + 1), String(digitalRead(inputPins[i]))); + } + return evaluateComplexExpression(expr); +} + +bool evaluateComplexExpression(String expr) { + struct Stack { + bool values[64]; + char operators[64]; + int valueTop = -1; + int operatorTop = -1; + + void pushValue(bool value) { + values[++valueTop] = value; + } + + bool popValue() { + return values[valueTop--]; + } + + void pushOperator(char op) { + operators[++operatorTop] = op; + } + + char popOperator() { + return operators[operatorTop--]; + } + + char peekOperator() { + return operators[operatorTop]; + } + + bool isOperatorStackEmpty() { + return operatorTop == -1; + } + } stack; + + for (int i = 0; i < expr.length(); i++) { + char c = expr.charAt(i); + + if (c == '0' || c == '1') { + stack.pushValue(c == '1'); + } else if (c == '(') { + stack.pushOperator(c); + } else if (c == ')') { + while (!stack.isOperatorStackEmpty() && stack.peekOperator() != '(') { + char op = stack.popOperator(); + bool val2 = stack.popValue(); + bool val1 = (op == '!') ? false : stack.popValue(); + stack.pushValue(applyOperator(val1, val2, op)); + } + stack.popOperator(); + } else if (c == '&' || c == '|' || c == '!' || c == '^') { + while (!stack.isOperatorStackEmpty() && stack.peekOperator() != '(' && precedence(stack.peekOperator()) >= precedence(c)) { + char op = stack.popOperator(); + bool val2 = stack.popValue(); + bool val1 = (op == '!') ? false : stack.popValue(); + stack.pushValue(applyOperator(val1, val2, op)); + } + stack.pushOperator(c); + } + } + + while (!stack.isOperatorStackEmpty()) { + char op = stack.popOperator(); + bool val2 = stack.popValue(); + bool val1 = (op == '!') ? false : stack.popValue(); + stack.pushValue(applyOperator(val1, val2, op)); + } + + return stack.popValue(); +} + +bool applyOperator(bool a, bool b, char op) { + if (op == '&') return a && b; + if (op == '|') return a || b; + if (op == '^') return a != b; + if (op == '!') return !b; + return false; +} + +int precedence(char op) { + if (op == '!') return 4; + if (op == '&') return 3; + if (op == '^') return 2; + if (op == '|') return 1; + return 0; +} + +void updateOutputs() { + for (int i = 0; i < MAX_OUTPUTS; i++) { + if (logicExpressions[i] != "") { + bool outputValue = evaluateExpression(logicExpressions[i]); + if (outputValue) { + digitalWrite(outputPins[i], HIGH); + } else { + digitalWrite(outputPins[i], LOW); + } + } + } +} diff --git a/Mc/simul61_testee_fonctionnelle (2eme approche)/tables de verite pour testes.docx b/Mc/simul61_testee_fonctionnelle (2eme approche)/tables de verite pour testes.docx new file mode 100644 index 0000000..0b129c3 Binary files /dev/null and b/Mc/simul61_testee_fonctionnelle (2eme approche)/tables de verite pour testes.docx differ diff --git a/Mc/simul61_testee_fonctionnelle.zip b/Mc/simul61_testee_fonctionnelle.zip new file mode 100644 index 0000000..c4137f2 Binary files /dev/null and b/Mc/simul61_testee_fonctionnelle.zip differ diff --git a/Mc/simul61_testee_fonctionnelle/REDME.txt b/Mc/simul61_testee_fonctionnelle/REDME.txt new file mode 100644 index 0000000..f0b91b1 --- /dev/null +++ b/Mc/simul61_testee_fonctionnelle/REDME.txt @@ -0,0 +1,79 @@ + +1. Déclaration des Broches et Variables +MAX_INPUTS et MAX_OUTPUTS : Constantes définissant le nombre maximum d'entrées (MAX_INPUTS = 8) et de sorties (MAX_OUTPUTS = 6). +inputPins et outputPins : +inputPins : Tableau contenant les numéros de broches associés aux entrées (I1 à I8). Par exemple, inputPins[0] correspond à la broche 22, utilisée pour I1. +outputPins : Tableau contenant les numéros de broches associés aux sorties (O1 à O6). Par exemple, outputPins[0] correspond à la broche 32, utilisée pour O1. +logicExpressions : Tableau de chaînes de caractères qui stocke les expressions logiques associées à chaque sortie (O1 à O6). Chaque entrée dans le tableau contient l'expression logique pour la sortie correspondante. +2. Fonction setup() +Serial.begin(9600) : Initialise la communication série pour que l'Arduino puisse recevoir des instructions via le port série. +Configuration des broches d'entrée et de sortie : +Entrées (inputPins) : Les broches d'entrée sont configurées en tant qu'entrées (INPUT) via pinMode(). Cela permet à l'Arduino de lire l'état de chaque broche. +Sorties (outputPins) : Les broches de sortie sont configurées en tant que sorties (OUTPUT) et initialisées à LOW via digitalWrite(), garantissant que toutes les sorties sont éteintes au démarrage. +3. Fonction loop() +Vérification des données disponibles sur le port série : +Si des données sont disponibles (Serial.available()), elles sont lues via Serial.readStringUntil('\n') jusqu'à ce qu'une nouvelle ligne soit atteinte. +Appelle la fonction parseMultipleExpressions() pour analyser les expressions logiques reçues et les stocker dans le tableau logicExpressions. +Appel de updateOutputs() : Cette fonction est appelée en continu pour évaluer les expressions logiques définies et mettre à jour les sorties en conséquence. +4. Fonction resetOutputs() +Réinitialisation des sorties : Réinitialise les expressions logiques en définissant chaque entrée de logicExpressions à une chaîne vide (""). +Mise à jour des sorties : Toutes les sorties sont réinitialisées à LOW (digitalWrite(outputPins[i], LOW)), garantissant qu'elles sont désactivées lorsqu'une nouvelle commande est reçue. +5. Fonction parseMultipleExpressions(String input) +Réinitialisation des sorties : Appelle resetOutputs() pour s'assurer que toutes les anciennes expressions sont supprimées avant d'en ajouter de nouvelles. +Analyse des expressions multiples : +Divise l'entrée en plusieurs expressions logiques séparées par des points-virgules (;). +Pour chaque expression trouvée, appelle parseExpression() pour l'analyser. +6. Fonction parseExpression(String input) +Analyse d'une expression logique individuelle : +Recherche le caractère = pour identifier la sortie et l'expression logique associée. +Si l'expression commence par "O" (par exemple O1, O2, etc.), le code identifie l'indice de sortie et associe l'expression à cette sortie. +L'expression logique est alors stockée dans le tableau logicExpressions pour la sortie correspondante. +7. Fonction evaluateExpression(String expr) +Remplacement des entrées par leurs valeurs actuelles : +Supprime tous les espaces dans l'expression (expr.replace(" ", "")). +Remplace chaque occurrence de I1, I2, etc., par leur état actuel (HIGH ou LOW) en utilisant digitalRead(). +Utilise evaluateComplexExpression(expr) pour évaluer l'expression simplifiée. +8. Fonction evaluateComplexExpression(String expr) +Évaluation des expressions logiques complexes : +Utilise une structure de pile (stack) pour gérer les valeurs (0 ou 1) et les opérateurs (&, |, ^, !, (, )). +Parcours de l'expression : +Valeurs (0 ou 1) : Ajoute chaque valeur à la pile des valeurs (pushValue()). +Parenthèses : +Parenthèses ouvrantes (() : Ajoute à la pile des opérateurs. +Parenthèses fermantes ()) : Applique les opérateurs en attente jusqu'à la parenthèse ouvrante correspondante. +Opérateurs (&, |, !, ^) : Ajoute chaque opérateur à la pile des opérateurs après avoir vérifié la priorité. +Application des opérateurs : Les opérateurs sont appliqués aux valeurs extraites de la pile en fonction de leur priorité. +9. Fonction applyOperator(bool a, bool b, char op) +Application d'un opérateur logique : +Applique les opérateurs logiques aux valeurs booléennes a et b : +& (ET logique) : Retourne a && b. +| (OU logique) : Retourne a || b. +^ (XOR logique) : Retourne a != b. +! (NON logique) : Retourne !b (inverse b). +Cette fonction est utilisée lors de l'évaluation d'une expression pour appliquer les opérations logiques aux valeurs booléennes. +10. Fonction precedence(char op) +Détermine la priorité des opérateurs : +! (NON logique) : Priorité la plus élevée (4). +& (ET logique) : Priorité suivante (3). +^ (XOR logique) : Priorité inférieure à & mais supérieure à | (2). +| (OU logique) : Priorité la plus faible (1). +Cette fonction est utilisée pour s'assurer que les opérateurs sont appliqués dans le bon ordre lors de l'évaluation d'une expression. +11. Fonction updateOutputs() +Mise à jour des sorties : +Parcourt chaque sortie (O1 à O6) définie dans le tableau logicExpressions. +Si une expression logique est définie pour une sortie, elle est évaluée à l'aide de evaluateExpression(). +En fonction du résultat (true ou false), la sortie est activée (HIGH) ou désactivée (LOW) via digitalWrite(). +Fonctionnement Global du Code +Réception des expressions logiques : +L'utilisateur envoie une ou plusieurs expressions logiques via le port série, par exemple : +scss +Copier le code +O2 = (I1 & I2) | (I2 & I3); O1 = (I1 ^ I2) ^ I3; +Ces expressions sont lues par l'Arduino et analysées. +Stockage des expressions logiques : +Chaque expression est associée à une sortie spécifique (O1 à O6). +Lecture des entrées et mise à jour des sorties : +Les valeurs des entrées (I1 à I8) sont continuellement lues avec digitalRead(). +Les sorties (O1 à O6) sont mises à jour dynamiquement en fonction des valeurs actuelles des entrées et des expressions logiques définies. +Cela transforme l'Arduino en un simulateur logique programmable, capable de gérer des expressions complexes et de les évaluer en temps réel. +En résumé, ce code permet de programmer l'Arduino Mega pour simuler des circuits logiques, en permettant à l'utilisateur de définir dynamiquement des expressions logiques pour chaque sortie, qui sont continuellement mises à jour en fonction des états des entrées. \ No newline at end of file diff --git a/Mc/simul61_testee_fonctionnelle/simul61_testee_fonctionnelle.ino b/Mc/simul61_testee_fonctionnelle/simul61_testee_fonctionnelle.ino new file mode 100644 index 0000000..9ccdb15 --- /dev/null +++ b/Mc/simul61_testee_fonctionnelle/simul61_testee_fonctionnelle.ino @@ -0,0 +1,170 @@ +#include + +const int MAX_INPUTS = 8; +const int MAX_OUTPUTS = 6; + +const int inputPins[MAX_INPUTS] = {22, 23, 24, 25, 26, 27, 28, 29}; // Broches pour I1 à I8 +const int outputPins[MAX_OUTPUTS] = {32, 33, 34, 35, 36, 37}; // Broches pour O1 à O6 + +String logicExpressions[MAX_OUTPUTS]; + +void setup() { + Serial.begin(115200); + Serial.println("Je démarre"); + for (int i = 0; i < MAX_INPUTS; i++) { + pinMode(inputPins[i], INPUT); + } + for (int i = 0; i < MAX_OUTPUTS; i++) { + pinMode(outputPins[i], OUTPUT); + digitalWrite(outputPins[i], LOW); + } +} + +void loop() { + if (Serial.available()) { + String input = Serial.readStringUntil('\n'); + Serial.println(input); + parseMultipleExpressions(input); + } + updateOutputs(); +} + +void resetOutputs() { + for (int i = 0; i < MAX_OUTPUTS; i++) { + logicExpressions[i] = ""; + digitalWrite(outputPins[i], LOW); + } +} + +void parseMultipleExpressions(String input) { + resetOutputs(); + input.trim(); + int start = 0; + while (start < input.length()) { + int end = input.indexOf(';', start); + if (end == -1) { + end = input.length(); + } + String expression = input.substring(start, end); + parseExpression(expression); + start = end + 1; + } +} + +void parseExpression(String input) { + input.trim(); + int eqIndex = input.indexOf('='); + if (eqIndex != -1 && input.startsWith("O")) { + int outputIndex = input.substring(1, eqIndex).toInt() - 1; + if (outputIndex >= 0 && outputIndex < MAX_OUTPUTS) { + logicExpressions[outputIndex] = input.substring(eqIndex + 1); + } + } +} + +bool evaluateExpression(String expr) { + expr.trim(); + expr.replace(" ", ""); + for (int i = 0; i < MAX_INPUTS; i++) { + expr.replace("!I" + String(i + 1), String(!digitalRead(inputPins[i]))); + expr.replace("I" + String(i + 1), String(digitalRead(inputPins[i]))); + } + return evaluateComplexExpression(expr); +} + +bool evaluateComplexExpression(String expr) { + struct Stack { + bool values[64]; + char operators[64]; + int valueTop = -1; + int operatorTop = -1; + + void pushValue(bool value) { + values[++valueTop] = value; + } + + bool popValue() { + return values[valueTop--]; + } + + void pushOperator(char op) { + operators[++operatorTop] = op; + } + + char popOperator() { + return operators[operatorTop--]; + } + + char peekOperator() { + return operators[operatorTop]; + } + + bool isOperatorStackEmpty() { + return operatorTop == -1; + } + } stack; + + for (int i = 0; i < expr.length(); i++) { + char c = expr.charAt(i); + + if (c == '0' || c == '1') { + stack.pushValue(c == '1'); + } else if (c == '(') { + stack.pushOperator(c); + } else if (c == ')') { + while (!stack.isOperatorStackEmpty() && stack.peekOperator() != '(') { + char op = stack.popOperator(); + bool val2 = stack.popValue(); + bool val1 = (op == '!') ? false : stack.popValue(); + stack.pushValue(applyOperator(val1, val2, op)); + } + stack.popOperator(); + } else if (c == '&' || c == '|' || c == '!' || c == '^') { + while (!stack.isOperatorStackEmpty() && stack.peekOperator() != '(' && precedence(stack.peekOperator()) >= precedence(c)) { + char op = stack.popOperator(); + bool val2 = stack.popValue(); + bool val1 = (op == '!') ? false : stack.popValue(); + stack.pushValue(applyOperator(val1, val2, op)); + } + stack.pushOperator(c); + } + } + + while (!stack.isOperatorStackEmpty()) { + char op = stack.popOperator(); + bool val2 = stack.popValue(); + bool val1 = (op == '!') ? false : stack.popValue(); + stack.pushValue(applyOperator(val1, val2, op)); + } + + return stack.popValue(); +} + +bool applyOperator(bool a, bool b, char op) { + if (op == '&') return a && b; + if (op == '|') return a || b; + if (op == '^') return a != b; + if (op == '!') return !b; + return false; +} + +int precedence(char op) { + if (op == '!') return 4; + if (op == '&') return 3; + if (op == '^') return 2; + if (op == '|') return 1; + return 0; +} + +void updateOutputs() { + for (int i = 0; i < MAX_OUTPUTS; i++) { + if (logicExpressions[i] != "") { + bool outputValue = evaluateExpression(logicExpressions[i]); + if (outputValue) { + digitalWrite(outputPins[i], HIGH); + } else { + digitalWrite(outputPins[i], LOW); + } + } + } +} diff --git a/arduino_logique.py b/arduino_logique.py index 3b933a1..1eac935 100644 --- a/arduino_logique.py +++ b/arduino_logique.py @@ -5,6 +5,7 @@ draw a breadboard, etc. """ import os +import platform from pathlib import Path import tkinter as tk from breadboard import Breadboard @@ -14,7 +15,7 @@ from toolbar import Toolbar from utils import resource_path -if os.name == "darwin" or os.name == "posix": +if (os.name in ("posix", "darwin")) and "linux" not in platform.platform().lower(): from tkinter import font from tkmacosx import Button # type: ignore else: @@ -29,7 +30,7 @@ def main(): win = tk.Tk() win.title("Laboratoire virtuel de circuit logique - GIF-1002") win.geometry("1500x800") # Initial window size - win.minsize(1500, 800) # Set minimal window size + win.minsize(1500, 800) # Set minimal window size 3456 × 2234) 1500,800 win.resizable(True, True) # Disabling window resizing win.configure(bg="#333333") # Setting consistent background color @@ -103,6 +104,7 @@ def refresh_sidebar(): canvas=canvas, board=board, current_dict_circuit=sketcher.current_dict_circuit, + sketcher=sketcher, ) # Placing the menu_bar in row=0, spanning both columns menus.menu_bar.grid(row=0, column=0, columnspan=2, sticky="nsew") diff --git a/breadboard.py b/breadboard.py index 1eeb973..5fe6b4c 100644 --- a/breadboard.py +++ b/breadboard.py @@ -64,7 +64,7 @@ def fill_matrix_830_pts(self, col_distance=1, line_distance=1): ), "coord": (2 + (i % 5) + col_distance + (i // 5) * 6, line_distance), "state": FREE, - "lien": None, + "link": [(2 + col_distance, line_distance, 60 + col_distance, line_distance)], } matrix[id_top_plus] = { "id": ["mh", "moins haut", "2"], @@ -74,7 +74,7 @@ def fill_matrix_830_pts(self, col_distance=1, line_distance=1): ), "coord": (2 + (i % 5) + col_distance + (i // 5) * 6, 1 + line_distance), "state": FREE, - "lien": None, + "link": [(2 + col_distance, 1 + line_distance, 60 + col_distance, 1 + line_distance)], } matrix[id_bot_minus] = { "id": ["pb", "plus bas", "13"], @@ -84,7 +84,7 @@ def fill_matrix_830_pts(self, col_distance=1, line_distance=1): ), "coord": (2 + (i % 5) + col_distance + (i // 5) * 6, 12 + line_distance), "state": FREE, - "lien": None, + "link": [(2 + col_distance, 12 + line_distance, 60 + col_distance, 12 + line_distance)], } matrix[id_bot_plus] = { "id": ["mb", "moins bas", "14"], @@ -94,7 +94,7 @@ def fill_matrix_830_pts(self, col_distance=1, line_distance=1): ), "coord": (2 + (i % 5) + col_distance + (i // 5) * 6, 13 + line_distance), "state": FREE, - "lien": None, + "link": [(2 + col_distance, 13 + line_distance, 60 + col_distance, 13 + line_distance)], } for l in range(5): for c in range(63): @@ -107,7 +107,7 @@ def fill_matrix_830_pts(self, col_distance=1, line_distance=1): ), "coord": (c + col_distance, l + 2 + line_distance), "state": FREE, - "lien": None, + "link": [(c + col_distance, 2 + line_distance, c + col_distance, 6 + line_distance)], } id_in_matrix = str(c + col_distance) + "," + str(l + 7 + line_distance) matrix[id_in_matrix] = { @@ -118,7 +118,7 @@ def fill_matrix_830_pts(self, col_distance=1, line_distance=1): ), "coord": (c + col_distance, l + 7 + line_distance), "state": FREE, - "lien": None, + "link": [(c + col_distance, 7 + line_distance, c + col_distance, 11 + line_distance)], } def fill_matrix_1260_pts(self): diff --git a/component_sketch.py b/component_sketch.py index 872b65e..c1bae70 100644 --- a/component_sketch.py +++ b/component_sketch.py @@ -2023,6 +2023,24 @@ def draw_chip(self, x_distance, y_distance, scale=1, width=-1, direction=HORIZON dim["chipWidth"] = kwargs.get("chipWidth", dim["chipWidth"]) dim["label"] = kwargs.get("label", dim["label"]) dim["internalFunc"] = kwargs.get("internalFunc", None) + dim["io_select"] = kwargs.get("io_select", None) + # if not dim["io_select"] : + # dim["io_select"] = kwargs.get("address_pins", None) + dim["io_out_inv"] = kwargs.get("io_out_inv", None) + dim["io_enable"] = kwargs.get("io_enable", None) + dim["io_enable_inv"] = kwargs.get("io_enable_inv", None) + dim["clock_pin"] = kwargs.get("clock_pin", None) + dim["inv_clock_pin"] = kwargs.get("inv_clock_pin", None) + dim["inv_reset_pin"] = kwargs.get("inv_reset_pin", None) + dim["inv_set_pin"] = kwargs.get("inv_set_pin", None) + dim["j_input_pin"] = kwargs.get("j_input_pin", None) + dim["inv_k_input_pin"] = kwargs.get("inv_k_input_pin", None) + dim["k_input_pin"] = kwargs.get("k_input_pin", None) + + dim["count_enable_pin"] = kwargs.get("count_enable_pin", None) + dim["inv_load_enable_pin"] = kwargs.get("inv_load_enable_pin", None) + dim["inv_up_down_input_pin"] = kwargs.get("inv_up_down_input_pin", None) + dim["terminal_count_pin"] = kwargs.get("terminal_count_pin", None) dim["pwr"] = kwargs.get("pwr", None) logic_function_name = kwargs.get("logicFunctionName", None) @@ -2031,7 +2049,9 @@ def draw_chip(self, x_distance, y_distance, scale=1, width=-1, direction=HORIZON chip_id = kwargs.get("id", None) tags = kwargs.get("tags", []) chip_type = kwargs.get("type", "chip") - + io = kwargs.get("io", []) + symb_script = kwargs.get("symbScript", None) + pwr = kwargs.get("pwr", []) dim_line = (dim["pinCount"] - 0.30) * inter_space / 2 dim_column = dim["chipWidth"] * inter_space @@ -2064,7 +2084,29 @@ def draw_chip(self, x_distance, y_distance, scale=1, width=-1, direction=HORIZON params["label"] = label params["type"] = chip_type params["btnMenu"] = [1, 1, 0] + params["symbScript"] = logic_function_name + params["io"] = io + params["pwr"] = pwr + params["logicFunctionName"] = logic_function_name params["pwr"] = dim["pwr"] + params["io_select"] = dim["io_select"] + params["io_out_inv"] = dim["io_out_inv"] + params["io_enable"] = dim["io_enable"] + params["io_enable_inv"] = dim["io_enable_inv"] + params["clock_pin"] = dim["clock_pin"] + params["inv_reset_pin"] = dim["inv_reset_pin"] + params["inv_set_pin"] = dim["inv_set_pin"] + + params["inv_clock_pin"] = dim["inv_clock_pin"] + params["j_input_pin"] = dim["j_input_pin"] + params["inv_k_input_pin"] = dim["inv_k_input_pin"] + params["k_input_pin"] = dim["k_input_pin"] + + params["count_enable_pin"] = dim["count_enable_pin"] + params["inv_load_enable_pin"] = dim["inv_load_enable_pin"] + params["inv_up_down_input_pin"] = dim["inv_up_down_input_pin"] + params["terminal_count_pin"] = dim["terminal_count_pin"] + num_pins_per_side = dim["pinCount"] // 2 tag_base = "base" + chip_id tag_menu = "menu" + chip_id diff --git a/dataCDLT.py b/dataCDLT.py index deb74b1..fd98f22 100644 --- a/dataCDLT.py +++ b/dataCDLT.py @@ -1,3 +1,5 @@ +from typing import Any + PERSO = 0 HORIZONTAL = 1 VERTICAL = 2 @@ -13,3 +15,10 @@ YES = 1 LEFT = 0 RIGHT = 1 + +connexion_circuit: dict[str, list[Any]] = { + "io": [], + "wire" : [], + "pwr" : [], + "func" : [] +} diff --git a/menus.py b/menus.py index fc1a0c6..6bb32d0 100644 --- a/menus.py +++ b/menus.py @@ -12,12 +12,27 @@ import subprocess import platform import serial.tools.list_ports # type: ignore +import time from breadboard import Breadboard - -from dataCDLT import INPUT, OUTPUT, CLOCK - -if os.name == "darwin": +from component_sketch import ComponentSketcher +from dataCDLT import ( + HORIZONTAL, + RIGHT, + VERTICAL, + VERTICAL_END_HORIZONTAL, + LEFT, + PERSO, + NO, + AUTO, + FREE, + USED, + INPUT, + OUTPUT, + CLOCK, +) + +if (os.name in ("posix", "darwin")) and "linux" not in platform.platform().lower(): from tkinter import messagebox, filedialog, ttk from tkmacosx import Button # type: ignore else: @@ -75,6 +90,19 @@ class SerialPort: connection: serial.Serial | None """The serial connection object.""" + def connect(self): + """Open the serial connection.""" + try: + self.connection = serial.Serial(port=self.com_port, + baudrate=self.baud_rate, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + bytesize=serial.EIGHTBITS, + timeout=self.timeout) + print(f"Serial port {self.com_port} opened successfully.") + except serial.SerialException as e: + print(f"Error opening port {self.com_port}: {e}") + class Menus: """ @@ -93,6 +121,8 @@ def __init__( canvas: tk.Canvas, board: Breadboard, current_dict_circuit: dict, + sketcher: ComponentSketcher, + ): """ Initializes the custom menu bar. @@ -110,15 +140,17 @@ def __init__( """The Breadboard instance.""" self.current_dict_circuit: dict = current_dict_circuit """The current circuit data.""" - self.com_port: str | None = None - """The selected COM port.""" - self.selected_microcontroller = None + self.sketcher = sketcher + + self.script = "" + + self.selected_microcontroller = "Arduino Mega" """The selected microcontroller.""" self.menu_bar = tk.Frame(parent, bg="#333333") """The frame containing the menu bar buttons.""" - - self.serial_port = SerialPort(None, 115200, 1, None) + + self.serial_port = SerialPort(None, 9600, 1, None) """The serial port configuration.""" self.open_file_path: str | None = None @@ -128,7 +160,10 @@ def __init__( menus = { "Fichier": ["Nouveau", "Ouvrir", "Enregistrer", "Enregistrer sous", "Quitter"], "Microcontrôleur": ["Choisir un microcontrôleur", "Table de correspondance", "Configurer le port série"], - "Exporter": ["Vérifier", "Téléverser"], + "Circuit": [ + "Vérifier", + "Téléverser", + ], "Aide": ["Documentation", "À propos"], } @@ -141,6 +176,8 @@ def __init__( "Configurer le port série": self.configure_ports, "Table de correspondance": self.show_correspondence_table, "Choisir un microcontrôleur": self.select_microcontroller, + "Vérifier": self.checkCircuit, + "Téléverser": self.download_script, "Documentation": self.open_documentation, "À propos": self.about, } @@ -151,7 +188,7 @@ def __init__( # Display selected microcontroller label self.microcontroller_label = tk.Label( self.menu_bar, - text="(Aucun microcontrôleur n'est choisi)", + text="(Aucun microcontrôleur n'est choisi)" if not self.selected_microcontroller else self.selected_microcontroller, bg="#333333", fg="white", font=("FiraCode-Bold", 12), @@ -181,7 +218,9 @@ def select_microcontroller(self): combobox = ttk.Combobox(dialog, values=available_microcontrollers) combobox.set(self.selected_microcontroller if self.selected_microcontroller else "Choisir un microcontrôleur") combobox.pack(pady=10) - + + default_option = "Arduino Mega" # Changez ceci selon votre choix + combobox.set(default_option) # Définit l'option par défaut # Create a button to confirm the selection def confirm_selection(): selected_option = combobox.get() @@ -194,8 +233,24 @@ def confirm_selection(): confirm_button = Button(dialog, text="Confirmer", command=confirm_selection) confirm_button.pack(pady=10) - - def show_correspondence_table(self): + + # def map_mcu_pin(self, treeview=None, input_pin_ios, output_pin_ios, input_pins, output_pins): + # # Populate the table with input and output pin mappings + # self.mcu_pin= {} + # for idx, pin_io in enumerate(input_pin_ios): + # mcu_pin = input_pins[idx] + # pin_number = pin_io["id"].split("_")[-1] + # treeview.insert("", "end", values=(pin_number, "Input", mcu_pin)) + # self.mcu_pin.update({f"I{pin_number}":f"I{mcu_pin}"}) + + + # for idx, pin_io in enumerate(output_pin_ios): + # mcu_pin = output_pins[idx] + # pin_number = pin_io["id"].split("_")[-1] + # treeview.insert("", "end", values=(pin_number, "Output", mcu_pin)) + # self.mcu_pin.update({f"O{pin_number}":f"O{mcu_pin}"}) + + def show_correspondence_table(self, show=True): """Displays the correspondence table between pin_io objects and microcontroller pins in a table format.""" if self.selected_microcontroller is None: messagebox.showwarning( @@ -242,9 +297,11 @@ def show_correspondence_table(self): # Create a new window for the correspondence table table_window = tk.Toplevel(self.parent) + table_window.withdraw() table_window.title("Correspondence Table") table_window.geometry("500x350") + # if show: # Create a Treeview widget for the table tree = ttk.Treeview(table_window, columns=("ID", "Type", "MCU Pin"), show="headings", height=15) tree.pack(expand=True, fill="both", padx=10, pady=10) @@ -257,31 +314,43 @@ def show_correspondence_table(self): tree.heading("Type", text="Type") tree.heading("MCU Pin", text="MCU Pin") - # Populate the table with input, output, and clock pin mappings + #self.map_mcu_pin(tree, input_pin_ios, output_pin_ios, input_pins, output_pins) + # Populate the table with input and output pin mappings + self.mcu_pin= {} for idx, pin_io in enumerate(input_pin_ios): mcu_pin = input_pins[idx] pin_number = pin_io["id"].split("_")[-1] + # if show: tree.insert("", "end", values=(pin_number, "Input", mcu_pin)) + self.mcu_pin.update({f"I{pin_number}":f"I{mcu_pin}"}) + for idx, pin_io in enumerate(output_pin_ios): mcu_pin = output_pins[idx] pin_number = pin_io["id"].split("_")[-1] tree.insert("", "end", values=(pin_number, "Output", mcu_pin)) - - if clock_pin_ios: - clock_pin = pin_mappings["clock_pin"] - pin_number = clock_pin_ios[0]["id"].split("_")[-1] - tree.insert("", "end", values=(pin_number, "clk input", clock_pin)) - - # Add a scrollbar if the list gets too long - scrollbar = ttk.Scrollbar(table_window, orient="vertical", command=tree.yview) - tree.configure(yscroll=scrollbar.set) - scrollbar.pack(side="right", fill="y") - - # Show the table in the new window - table_window.transient(self.parent) # Set to be on top of the parent window - table_window.grab_set() # Prevent interaction with the main window until closed - table_window.mainloop() + self.mcu_pin.update({f"O{pin_number}":f"O{mcu_pin}"}) + + if show: + table_window.deiconify() + # Add a scrollbar if the list gets too long + scrollbar = ttk.Scrollbar(table_window, orient="vertical", command=tree.yview) + tree.configure(yscroll=scrollbar.set) + scrollbar.pack(side="right", fill="y") + if clock_pin_ios: + clock_pin = pin_mappings["clock_pin"] + pin_number = clock_pin_ios[0]["id"].split("_")[-1] + tree.insert("", "end", values=(pin_number, "clk input", clock_pin)) + + # Add a scrollbar if the list gets too long + scrollbar = ttk.Scrollbar(table_window, orient="vertical", command=tree.yview) + tree.configure(yscroll=scrollbar.set) + scrollbar.pack(side="right", fill="y") + + # Show the table in the new window + table_window.transient(self.parent) # Set to be on top of the parent window + table_window.grab_set() # Prevent interaction with the main window until closed + table_window.mainloop() def create_menu(self, menu_name, options, menu_commands): """ @@ -299,6 +368,8 @@ def create_menu(self, menu_name, options, menu_commands): fg="white", activebackground="#444444", activeforeground="white", + highlightbackground="#333333", # Border color when inactive + highlightcolor="#444444", # Border color when active bd=0, padx=10, pady=5, @@ -332,6 +403,8 @@ def select_menu_item(option): fg="white", activebackground="#444444", activeforeground="white", + highlightbackground="#333333", # Border color when inactive + highlightcolor="#444444", # Border color when active bd=0, anchor="w", width=250, @@ -609,16 +682,6 @@ def about(self): print("About this software") messagebox.showinfo("À propos", "ArduinoLogique v1.0\nSimulateur de circuits logiques") - def open_port(self): - """Handler for the 'Open Port' menu item.""" - try: - self.serial_port.connection = serial.Serial( - port=self.serial_port.com_port, baudrate=self.serial_port.baud_rate, timeout=self.serial_port.timeout - ) - print(f"Port série {self.serial_port.com_port} ouvert avec succès.") - except serial.SerialException as e: - print(f"Erreur lors de l'ouverture du port {self.serial_port.com_port}: {e}") - def send_data(self, data): """ Send a string of data to the microcontroller through the serial port. @@ -626,23 +689,1100 @@ def send_data(self, data): if self.serial_port.connection and self.serial_port.connection.is_open: try: # Convertir la chaîne en bytes et l'envoyer - self.serial_port.connection.write(data.encode("utf-8")) + self.serial_port.connection.write(data.encode('utf-8')) print(f"Données envoyées: {data}") + #time.sleep(0.5) + #if self.serial_port.connection.in_waiting > 0: # Vérifie s'il y a des données disponibles + data = self.serial_port.connection.readline().decode('utf-8').strip() + print(f"réponse: {data} à {self.serial_port.baud_rate} bauds") except serial.SerialException as e: print(f"Erreur lors de l'envoi des données: {e}") else: print("Le port série n'est pas ouvert. Impossible d'envoyer les données.") def close_port(self): - """Close the serial port.""" + """Upload the script to the microcontroller through the serial port.""" if self.serial_port.connection and self.serial_port.connection.is_open: self.serial_port.connection.close() print(f"Port série {self.serial_port.com_port} fermé.") else: print("Le port série est déjà fermé.") - - def download_script(self, script): - """Upload the script to the microcontroller through the serial port.""" - self.open_port() - self.send_data(script) - self.close_port() + + def download_script(self): + self.checkCircuit() + self.serial_port.connect() + self.send_data(self.script) + #self.close_port() + + def is_linked_to(self, dest, src): + res = False + c, l = src + for zone in dest: + c1, l1,c2, l2 = zone + if (c >= c1 and c<= c2 and l >= l1 and l<= l2): + res = True + break + return res + + def decodeFunc(self,inVar, funcName): + s ="" + if funcName == "NandGate": + s = f"!( {inVar[0]['val']} " + for v in inVar[1:]: + s += f"& {v['val']} " + s += ") " + elif funcName == "AndGate": + s = f"( {inVar[0]['val']} " + for v in inVar[1:]: + s += f"& {v['val']} " + s += ") " + elif funcName == "NorGate": + s = f"! ( {inVar[0]['val']} " + for v in inVar[1:]: + s += f"| {v['val']} " + s += ") " + elif funcName == "OrGate": + s = f"( {inVar[0]['val']} " + for v in inVar[1:]: + s += f"| {v['val']} " + s += ") " + elif funcName == "NotGate": + s = f"! {inVar[0]['val']} " + elif funcName == "XorGate": + s = f"( {inVar[0]['val']} " + for v in inVar[1:]: + s += f"^ {v['val']} " + s += ") " + elif funcName == "XnorGate": + s = f"! ( {inVar[0]['val']} " + for v in inVar[1:]: + s += f"| {v['val']} " + s += ") " + elif funcName == "Mux": + e =["( ","( ","( ","( ","( ","( ","( ","( "] + for v in range(8): + v2, v1, v0 = (v & 1)^1, ((v & 2) >> 1)^1, ((v & 4) >> 2)^1 + e[v] += inVar[v]['val'] + " & " + inVar[11]["einv"] + " & " + \ + v0*" !" + inVar[8]["sel"] + " & " + v1*" !" + inVar[9]["sel"] + " & " + v2*" !" + inVar[10]["sel"] + " ) " + s = " ( " + e[0] + for et in e[1:]: + s += "| " + et + s += " ) " + elif funcName == "Demux": + s ="(" + out = inVar[0]['numO'] + v2, v1, v0 = (out & 1)^1, ((out & 2) >> 1)^1, ((out & 4) >> 2)^1 + s += v0*" !" + inVar[0]['val'] + " & " + v1*"!" + inVar[1]['val'] + " & " + v2*"!" + inVar[2]['val'] + \ + " & " + inVar[3]["einv"] + " & " + inVar[4]["einv"] + " & " + inVar[5]["enb"] + s += " ) " + elif funcName == "DFlipFlop": + s ="(" + s += inVar[0]['val'] + " & CLK & " + inVar[3]['iset'] + " & " + inVar[2]['irst'] + " | !" + inVar[3]['iset'] + s += " ) " + elif funcName == "JKFlipFlop": + if inVar[4].get('iK'): + K = f"!{inVar[4]['iK']}" + else: K = inVar[4]["K"] + if inVar[1].get('clk'): + CLK = f"{inVar[1]['clk']} " + else: CLK = f"!{inVar[3]['iclk']} " + if inVar[3].get('iset'): + set = f"!{inVar[3]['iset']}" + iset = f"{inVar[3]['iset']}" + rst = f"!{inVar[2]['irst']}" + else: + set = f"!{inVar[2]['iset']}" + iset = f"{inVar[2]['iset']}" + rst = f"!{inVar[1]['irst']}" + sT =f"T{self.varTempNum} = " + sT += "((" + inVar[0]['J'] + f" & !T{self.varTempNum}_precedent) | (!{K} & T{self.varTempNum}_precedent)) & {set} & {rst} & CLK | {iset} " + sT += " ); " + s = inVar[0]['numO']*" !" + f"T{self.varTempNum} " + self.varTempNum +=1 + self.varScript += [sT] + elif funcName == "BinaryCounter": + if inVar[0]['numO'] == 0: + self.numTemp = [] + CE = inVar[6]["CE"] + iU = inVar[8]["iU"] + iL = inVar[7]["iL"] + D0 = inVar[0]["val"] + D1 = inVar[1]["val"] + D2 = inVar[0]["val"] + D3 = inVar[0]["val"] + sT = f"T{self.varTempNum} = clk & {CE} & {iL} & !T{self.varTempNum}_precedent | !{iL} & {D0} & clk | !{CE} & {iL} & clk & T{self.varTempNum}_precedent; " + self.numTemp += [self.varTempNum] + self.varTempNum +=1 + self.varScript += [sT] + sT = f"T{self.varTempNum} = (!{CE} | !T{self.varTempNum-1}_precedent | !T{self.varTempNum}_precedent) & " \ + + f"({CE} & T{self.varTempNum - 1}_precedent | T{self.varTempNum}_precedent ) & {iL} & clk | !{iL} & {D1} & clk | !{CE} & {iL} & clk & T{self.varTempNum}_precedent; " + self.numTemp += [self.varTempNum] + self.varTempNum +=1 + self.varScript += [sT] + sT = f"T{self.varTempNum} = (!{CE} | !T{self.varTempNum-2}_precedent | !T{self.varTempNum-1}_precedent | !T{self.varTempNum}_precedent) & clk & " \ + + f"({CE} & T{self.varTempNum - 2}_precedent & T{self.varTempNum - 1}_precedent | T{self.varTempNum}_precedent ) & {iL} & clk | !{iL} & {D2} & clk | !{CE} & {iL} & clk & T{self.varTempNum}_precedent; " + self.numTemp += [self.varTempNum] + self.varTempNum +=1 + self.varScript += [sT] + sT = f"T{self.varTempNum} = (!{CE} | !T{self.varTempNum-3}_precedent | !T{self.varTempNum-2}_precedent | !T{self.varTempNum-1}_precedent | !T{self.varTempNum}_precedent) & " \ + + f"({CE} & T{self.varTempNum - 3}_precedent & T{self.varTempNum - 2}_precedent & T{self.varTempNum - 1}_precedent | T{self.varTempNum}_precedent ) & {iL} & clk | !{iL} & {D3} & clk | !{CE} & {iL} & clk & T{self.varTempNum}_precedent; " + self.numTemp += [self.varTempNum] + self.varTempNum +=1 + self.varScript += [sT] + s = f"T{self.numTemp[inVar[0]['numO']]} " + + return s + + def checkCloseCircuit(self, ioOut, params={}): + #id, (c1,l1,c2,l2) = ioOut + id, [ioZone] = ioOut + #ioZone = [(c1,l1,c2,l2)] + chip_select = params.get("chip_select", []) + chip_out_inv = params.get("chip_out_inv", []) + chip_in_enable = params.get("chip_in_enable", []) + chip_in_enable_inv = params.get("chip_in_enable_inv", []) + chip_in_clock = params.get("chip_in_clock", []) + chip_in_inv_reset = params.get("chip_in_inv_reset", []) + chip_in_inv_set = params.get("chip_in_inv_set", []) + chip_in_inv_clock = params.get("chip_in_inv_clock", []) + chip_in_j = params.get("chip_in_j", []) + chip_in_k = params.get("chip_in_k", []) + chip_in_inv_k = params.get("chip_in_inv_k", []) + + chip_in_ce = params.get("count_enable_pin", []) + chip_in_inv_L = params.get("inv_load_enable_pin", []) + chip_in_inv_U = params.get("inv_up_down_input_pin", []) + chip_out_TC = params.get("terminal_count_pin", []) + + findOut = False + circuitClose = True + script = "" + #chip_out_checked = [] + + for nf,f in enumerate(self.func): + idOut, inLst, fName, outLst = deepcopy(f) + if chip_select: + chipSel = chip_select + chipSel = [list(chipS[1:]) for chipS in chipSel if chipS[0] == idOut] + if chipSel: + [chipSel] = chipSel + else: chipSel = [] + + if chip_in_enable_inv: + chipEnInv = chip_in_enable_inv + chipEnInv = [list(chipEI[1:]) for chipEI in chipEnInv if chipEI[0] == idOut] + if chipEnInv: + [chipEnInv] = chipEnInv + else: chipEnInv = [] + + if chip_in_enable: + chipEn = chip_in_enable + chipEn = [list(chipE[1:]) for chipE in chipEn if chipE[0] == idOut] + if chipEn: + [chipEn] = chipEn + else: chipEn = [] + + if chip_in_clock: + chipInClock = chip_in_clock + chipInClock = [list(chipICLK[1:]) for chipICLK in chipInClock if chipICLK[0] == idOut] + if chipInClock: + [chipInClock] =chipInClock + chipInClock = [(c1,l1) for (c1,l1,nfunc) in chipInClock if nfunc == nf] + else: chipInClock = [] + + if chip_in_inv_reset: + chipInInvReset = chip_in_inv_reset + chipInInvReset = [list(chipInInvR[1:]) for chipInInvR in chipInInvReset if chipInInvR[0] == idOut] + if chipInInvReset: + [chipInInvReset] = chipInInvReset + chipInInvReset = [(c1,l1) for (c1,l1,nfunc) in chipInInvReset if nfunc == nf] + else: chipInInvReset = [] + + if chip_in_inv_set: + chipInInvSet = chip_in_inv_set + chipInInvSet = [list(chipInInvS[1:]) for chipInInvS in chipInInvSet if chipInInvS[0] == idOut] + if chipInInvSet: + [chipInInvSet] = chipInInvSet + chipInInvSet = [(c1,l1) for (c1,l1,nfunc) in chipInInvSet if nfunc == nf] + else: chipInInvSet = [] + + if chip_in_inv_clock: + chipInInvClk = chip_in_inv_clock + chipInInvClk = [list(chipInIClk[1:]) for chipInIClk in chipInInvClk if chipInIClk[0] == idOut] + if chipInInvClk: + [chipInInvClk] = chipInInvClk + chipInInvClk = [(c1,l1) for (c1,l1,nfunc) in chipInInvClk if nfunc == nf] + else: chipInInvClk = [] + + if chip_in_j: + chipInJ = chip_in_j + chipInJ = [list(chipIJ[1:]) for chipIJ in chipInJ if chipIJ[0] == idOut] + if chipInJ: + [chipInJ] = chipInJ + chipInJ = [(c1,l1) for (c1,l1,nfunc) in chipInJ if nfunc == nf] + else: chipInJ = [] + + if chip_in_k: + chipInK = chip_in_k + chipInK = [list(chipIK[1:]) for chipIK in chipInK if chipIK[0] == idOut] + if chipInK: + [chipInK] = chipInK + chipInK = [(c1,l1) for (c1,l1,nfunc) in chipInK if nfunc == nf] + else: chipInK = [] + + if chip_in_inv_k: + chipInInvK = chip_in_inv_k + chipInInvK = [list(chipIIK[1:]) for chipIIK in chipInInvK if chipIIK[0] == idOut] + if chipInInvK: + [chipInInvK] = chipInInvK + chipInInvK = [(c1,l1) for (c1,l1,nfunc) in chipInInvK if nfunc == nf] + else: chipInInvK = [] + + if chip_in_ce: + chipInCE = chip_in_ce + chipInCE = [list(chipICE[1:]) for chipICE in chipInCE if chipICE[0] == idOut] + if chipInCE: + [chipInCE] = chipInCE + chipInCE = [(c1,l1) for (c1,l1,nfunc) in chipInCE if nfunc == nf] + else: chipInCE = [] + + if chip_in_inv_L: + chipInInvL = chip_in_inv_L + chipInInvL = [list(chipIIL[1:]) for chipIIL in chipInInvL if chipIIL[0] == idOut] + if chipInInvL: + [chipInInvL] = chipInInvL + chipInInvL = [(c1,l1) for (c1,l1,nfunc) in chipInInvL if nfunc == nf] + else: chipInInvL = [] + + if chip_in_inv_U: + chipInInvU = chip_in_inv_U + chipInInvU = [list(chipIIU[1:]) for chipIIU in chipInInvU if chipIIU[0] == idOut] + if chipInInvU: + [chipInInvU] = chipInInvU + chipInInvU = [(c1,l1) for (c1,l1,nfunc) in chipInInvU if nfunc == nf] + else: chipInInvU = [] + + if chip_out_TC: + chipOutTC = chip_out_TC + chipOutTC = [list(chipOTC[1:]) for chipOTC in chipOutTC if chipOTC[0] == idOut] + if chipOutTC: + [chipOutTC] = chipOutTC + chipOutTC = [(c1,l1) for (c1,l1,nfunc) in chipOutTC if nfunc == nf] + else: chipOutTC = [] + + if chip_out_inv: + chipOutInv = chip_out_inv + chipOutInv = [list(chipOI[1:]) for chipOI in chipOutInv if chipOI[0] == idOut] + if chipOutInv: + [chipOutInv] = chipOutInv + else: chipOutInv = [] + + inLst += chipSel + chipEnInv + chipEn + chipInClock + chipInInvReset + chipInInvSet + \ + chipInInvClk + chipInK + chipInInvK + chipInCE + chipInInvL + chipInInvU + outLst += chipOutInv + chipOutTC + for no,out in enumerate(outLst): + #if out not in chip_out_checked: + if self.is_linked_to(ioZone, out): + findOut = True + #self.script += "( " + #chip_out_checked += [out] + inFuncConst = [] + for n,inFunc in enumerate(inLst): + findIn = False + if self.is_linked_to(self.pwrP, inFunc) or self.is_linked_to(self.pwrM, inFunc): + constKey = 'val' + pos, neg = "1", "0" + for c in chipSel: + if c == inFunc: + constKey = "sel" + for c in chipEnInv: + if c == inFunc: + constKey = "einv" + pos, neg = "0", "1" + for c in chipEn: + if c == inFunc: + constKey = "enb" + for c in chipInInvReset: + if c == inFunc: + constKey = 'irst' + for c in chipInInvSet: + if c == inFunc: + constKey = 'iset' + + for c in chipInInvClk: + if c == inFunc: + constKey = 'iclk' + for c in chipInJ: + if c == inFunc: + constKey = "J" + for c in chipInK: + if c == inFunc: + constKey = "K" + for c in chipInInvK: + if c == inFunc: + constKey = "iK" + + for c in chipInCE: + if c == inFunc: + constKey = "CE" + for c in chipInInvL: + if c == inFunc: + constKey = "iL" + for c in chipInInvU: + if c == inFunc: + constKey = "iU" + + + if self.is_linked_to(self.pwrP, inFunc): + inFuncConst += [{constKey:pos, "num":n, 'numO':no}] + else: inFuncConst += [{constKey:neg, "num":n, 'numO':no}] + findIn = True + print("connecté à pwr") + if not findIn: + for n_io,io_inZone in enumerate(self.io_in): + id, [zone] = io_inZone + if self.is_linked_to(zone, inFunc): + constKey = 'val' + for c in chipSel: + if c == inFunc: + constKey = "sel" + for c in chipEnInv: + if c == inFunc: + constKey = "einv" + for c in chipEn: + if c == inFunc: + constKey = "enb" + for c in chipInInvReset: + if c == inFunc: + constKey = 'irst' + for c in chipInInvSet: + if c == inFunc: + constKey = 'iset' + for c in chipInClock: + if c == inFunc: + constKey = 'clk' + + for c in chipInInvClk: + if c == inFunc: + constKey = 'iclk' + for c in chipInJ: + if c == inFunc: + constKey = "J" + for c in chipInK: + if c == inFunc: + constKey = "K" + for c in chipInInvK: + if c == inFunc: + constKey = "iK" + + for c in chipInCE: + if c == inFunc: + constKey = "CE" + for c in chipInInvL: + if c == inFunc: + constKey = "iL" + for c in chipInInvU: + if c == inFunc: + constKey = "iU" + + #inFuncConst += [{constKey:self.mcu_pin[f"I{id[4:]}"], "num":n, "numO":no}] # [self.mcu_pin[f"I{id[4:]}"]] # ici ajouter n + inFuncConst += [{constKey:f"I{n_io+1}", "num":n_io, "numO":no}] # [self.mcu_pin[f"I{id[4:]}"]] # ici ajouter n + findIn = True + print("connecté à une ENTRÉE EXTERNE") + break + if not findIn: + for n_io, io_chipInZone in enumerate(self.chip_in_wire): + id, zone = io_chipInZone + if self.is_linked_to(zone, inFunc): + constKey = 'val' + for c in chipSel: + if c == inFunc: + constKey = "sel" + for c in chipEnInv: + if c == inFunc: + constKey = "einv" + for c in chipEn: + if c == inFunc: + constKey = "enb" + for c in chipInInvReset: + if c == inFunc: + constKey = 'irst' + for c in chipInInvSet: + if c == inFunc: + constKey = 'iset' + for c in chipInClock: + if c == inFunc: + constKey = 'clk' + + for c in chipInInvClk: + if c == inFunc: + constKey = 'iclk' + for c in chipInJ: + if c == inFunc: + constKey = "J" + for c in chipInK: + if c == inFunc: + constKey = "K" + for c in chipInInvK: + if c == inFunc: + constKey = "iK" + + for c in chipInCE: + if c == inFunc: + constKey = "CE" + for c in chipInInvL: + if c == inFunc: + constKey = "iL" + for c in chipInInvU: + if c == inFunc: + constKey = "iU" + + #inFuncConst += [{constKey:self.mcu_pin[f"I{id[4:]}"], "num":n, "numO":no}] + inFuncConst += [{constKey:f"I{n_io+1}", "num":n_io, "numO":no}] + findIn = True + print("connecté à une ENTRÉE EXTERNE par cable") # ici ajouter n {'val':self.mcu_pin[f"I{id[4:]}"], "num":n} + break + + if not findIn: ## recherche d'une sortie de chip connectée à l'entrée actuelle de la chip + findNext =False + for nextOut in self.chip_out_wire: + #id, (c1, l1) = nextOut + #outZone = deepcopy(self.board.sketcher.matrix[f"{c1},{l1}"]["link"]) + + if self.is_linked_to(nextOut, inFunc): + #for next in nextOut: + for cow in self.chip_out: + id, pts = cow[0], cow[1:] + for pt in pts: + if self.is_linked_to(nextOut, pt): + outZone =(id,[nextOut]) + print("On passe à une autre sortie...") + ######## RAPPEL RECURSIF SUR OUTZONE ###################### + if outZone not in self.chip_out_checked: + self.chip_out_checked += [outZone] + isPinOut = False + for pinOut in self.io_out: + id, [pinZoneOut] = pinOut + if self.is_linked_to(pinZoneOut, pt): + #outPrev = self.mcu_pin[f"O{id[4:]}"] + outPrev = f"O{no+1}" + constKey = 'val' + for c in chipSel: + if c == inFunc: + constKey = "sel" + for c in chipEnInv: + if c == inFunc: + constKey = "einv" + for c in chipEn: + if c == inFunc: + constKey = "enb" + + for c in chipOutTC: + if c == inFunc: + constKey = "TC" + + for c in chipOutInv: + if c == pt: + outPrev = "!" + outPrev + isPinOut = True + inFuncConst += [{constKey:outPrev, "num":n, 'numO':no}] # [self.mcu_pin[f"O{id[4:]}"]] + findNext = True + if not isPinOut: + findNext, s = self.checkCloseCircuit(outZone,params) + constKey = 'val' + for c in chipSel: + if c == inFunc: + constKey = "sel" + for c in chipEnInv: + if c == inFunc: + constKey = "einv" + for c in chipEn: + if c == inFunc: + constKey = "enb" + + for c in chipOutTC: + if c == inFunc: + constKey = "TC" + + for c in chipOutInv: + if c == pt: + s = "!" + s + + inFuncConst += [{constKey:s, "num":n, 'numO':no}] + self.chip_out_script += [(s,outZone)] + else: + # il faut voir si une sortie io n'existe pas sinon var temp + isPinOut = False + for pinOut in self.io_out: + id, [pinZoneOut] = pinOut + if self.is_linked_to(pinZoneOut, pt): + isPinOut = True + #outPrev = self.mcu_pin[f"O{id[4:]}"] + outPrev = f"O{no+1}" + constKey = 'val' + for c in chipSel: + if c == inFunc: + constKey = "sel" + for c in chipEnInv: + if c == inFunc: + constKey = "einv" + for c in chipEn: + if c == inFunc: + constKey = "enb" + + for c in chipOutTC: + if c == inFunc: + constKey = "TC" + + for c in chipOutInv: + if c == pt: + outPrev = "!" + outPrev + + inFuncConst += [{constKey:outPrev, "num":n, 'numO':no}] + if not isPinOut: + for coc in self.chip_out_script: + if coc[1] == outZone: + exp = coc[0] + constKey = 'val' + for c in chipSel: + if c == inFunc: + constKey = "sel" + for c in chipEnInv: + if c == inFunc: + constKey = "einv" + for c in chipEn: + if c == inFunc: + constKey = "enb" + + for c in chipOutTC: + if c == inFunc: + constKey = "TC" + + for c in chipOutInv: + if c == pt: + exp = "!" + exp + + inFuncConst += [{constKey:exp, "num":n, 'numO':no}] + break + findNext = True + break + if not findIn and not findNext: + self.in_outOC += [(id,inFunc)] + circuitClose = False + if findIn or findNext: + #self.script += ") " + script = self.decodeFunc(inFuncConst, fName) + if not findOut: + self.in_outOC += [ioOut] + circuitClose = False + # if not findIn and not findNext: + # circuitClose = False + + return circuitClose, script + + + + + def checkCircuit(self): + print("Lancer la vérification") + self.func = [] + self.wire = [] + (xBatNeg, yBatNeg) = self.current_dict_circuit['_battery_neg_wire']["end"] + (xBatPos, yBatPos) = self.current_dict_circuit['_battery_pos_wire']["end"] + (_, _),(colBatNeg, lineBatNeg) = self.sketcher.find_nearest_grid_point(xBatNeg, yBatNeg) + (_, _),(colBatPos, lineBatPos) = self.sketcher.find_nearest_grid_point(xBatPos, yBatPos) + #self.pwrs = [(61, 1, "-"), (61, 2, "+")] # [(col, line, "+" ou "-"), ...] + self.pwrs = [(colBatNeg, lineBatNeg, "-"), (colBatPos, lineBatPos, "+")] # [(col, line, "+" ou "-"), ...] + self.pwrChip = {"+": [], "-": [], "pwrConnected":[], "pwrNotConnected": [], "pwrMissConnected": []} # , "pwrNOTUSED": [], "pwrCC": [] + self.io_in, self.io_out = [], [] + self.chip_in, self.chip_out = [], [] + self.chip_ioCC, self.chip_ioOK = [], [] + self.pwrM, self.pwrP, self.wireNotUsed, self.pwrCC = [], [], [], [] + self.io_inCC, self.io_outCC = [], [] + self.chip_out_wire, self.chip_outCC = [], [] + self.chip_in_wire = [] + self.in_outOC = [] + self.chip_out_checked = [] + self.chip_out_script = [] + + chip_select = [] + chip_out_inv = [] + chip_in_enable = [] + chip_in_enable_inv = [] + chip_in_clock = [] + chip_in_inv_reset = [] + chip_in_inv_set = [] + chip_in_inv_clock = [] + chip_in_j = [] + chip_in_k = [] + chip_in_inv_k = [] + + chip_in_ce = [] + chip_in_inv_L = [] + chip_in_inv_U = [] + chip_out_TC = [] + + self.varTempNum = 1 + self.varScript = [] + + self.show_correspondence_table(False) + for id, component in self.current_dict_circuit.items(): + if id[:6] == "_chip_": + (x, y) = component["pinUL_XY"] + numPinBR = component["pinCount"] // 2 + (real_x, real_y), (col, line) = self.sketcher.find_nearest_grid_chip(x, y) + #ioIn, ioOut = [], [] + for io in component["io"]: # [([(ce1, le1), ...], "&", [(cs1, ls1), (cs2, ls2), ...]), ...] + #io = component["io"] + # ioIN, ioOut = [], [] + ioIn = [ + # (col + (numPin % numPinBR) - 1 + (numPin // numPinBR), line + 1 - (numPin // numPinBR)) + # for numPin in io[0] + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR)) + for numPin in io[0] + ] + + ioOut = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR)) + for numPin in io[1] + ] + self.func += [(id, ioIn, component["symbScript"], ioOut)] + if ioIn: + self.chip_in += [(id, *ioIn)] + if ioOut: + self.chip_out += [(id, *ioOut)] + # print(f"ioIN = {ioIn}") + # print(f"ioOUT = {ioOut}") + # print(f"self.func= {self.func}") + # print(f"ce1-ce2, self.func, cs1:({io[0][0]}-{io[0][1]} , {chip["symbScript"]} , {io[1][0]})") + for pwr in component["pwr"]: + numPin, polarity = pwr[0], pwr[1] + col_pin = col + numPin - 1 if numPin <= numPinBR else col + (component["pinCount"] - numPin) + line_pin = line if numPin > numPinBR else line+1 + self.pwrChip[polarity] += [ + (id, col_pin, line_pin) + ] + # print(f"pwrChip= {self.pwrChip}") + ############### gestion des MUX DEMUX ################# + #### les sélecteurs ### + ioSel = component.get("io_select", []) + if ioSel: + ioS = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR)) + for numPin in ioSel[0] + ] + if ioS: + chip_select += [(id, *ioS)] + self.chip_in += [(id, *ioS)] + + #### les sorties inversées ### + ioOutInv = component.get("io_out_inv", []) + if ioOutInv: + ioOI = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR)) + for numPin in ioOutInv[0] + ] + if ioOI: + chip_out_inv += [(id, *ioOI)] + self.chip_out += [(id, *ioOI)] + + #### les entrées enable ### + ioInEnable = component.get("io_enable", []) + if ioInEnable: + ioIEn = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR)) + for numPin in ioInEnable[0] + ] + if ioIEn: + chip_in_enable += [(id, *ioIEn)] + self.chip_in += [(id, *ioIEn)] + + #### les entrées enable inverse ### + ioInEnableInv = component.get("io_enable_inv", []) + if ioInEnableInv: + ioIEnInv = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR)) + for numPin in ioInEnableInv[0] + ] + if ioIEnInv: + chip_in_enable_inv += [(id, *ioIEnInv)] + self.chip_in += [(id, *ioIEnInv)] + + #### l' entrée clock ### + ioInClock = component.get("clock_pin", []) + if ioInClock: + ioInCLK = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInClock,[]) + ] + if ioInCLK: + chip_in_clock += [(id, *ioInCLK)] + self.chip_in += [(id, *ioInCLK)] + + #### l' entrée clock Inv ### + ioInClockInv = component.get("inv_clock_pin", []) + if ioInClockInv: + ioInCLKInv = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInClockInv,[]) + ] + if ioInCLKInv: + chip_in_inv_clock += [(id, *ioInCLKInv)] + self.chip_in += [(id, *ioInCLKInv)] + + #### l' entrée Reset Inv ### + ioInResetInv = component.get("inv_reset_pin", []) + if ioInResetInv: + ioInRinv = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInResetInv, []) + ] + if ioInRinv: + chip_in_inv_reset += [(id, *ioInRinv)] + self.chip_in += [(id, *ioInRinv)] + + #### l' entrée Set Inv ### + ioInSetInv = component.get("inv_set_pin", []) + if ioInSetInv: + ioInSinv = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInSetInv, []) + ] + if ioInSinv: + chip_in_inv_set += [(id, *ioInSinv)] + self.chip_in += [(id, *ioInSinv)] + + #### l' entrée J ### + ioInJ = component.get("j_input_pin", []) + if ioInJ: + ioIJ = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInJ, []) + ] + if ioIJ: + chip_in_j += [(id, *ioIJ)] + self.chip_in += [(id, *ioIJ)] + + #### l' entrée K Inv ### + ioInKInv = component.get("inv_k_input_pin", []) + if ioInKInv: + ioIKInv = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInKInv, []) + ] + if ioIKInv: + chip_in_inv_k += [(id, *ioIKInv)] + self.chip_in += [(id, *ioIKInv)] + + #### l' entrée K ### + ioInK = component.get("k_input_pin", []) + if ioInK: + ioIK = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInK, []) + ] + if ioIK: + chip_in_k += [(id, *ioIK)] + self.chip_in += [(id, *ioIK)] + + #### l' entrée CE ### + ioInCE = component.get("count_enable_pin", []) + if ioInCE: + ioICE = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInCE, []) + ] + if ioICE: + chip_in_ce += [(id, *ioICE)] + self.chip_in += [(id, *ioICE)] + + #### l' entrée L ### + ioInInvL = component.get("inv_load_enable_pin", []) + if ioInInvL: + ioIIL = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInInvL, []) + ] + if ioIIL: + chip_in_inv_L += [(id, *ioIIL)] + self.chip_in += [(id, *ioIIL)] + + #### l' entrée U ### + ioInInvU = component.get("inv_up_down_input_pin", []) + if ioInInvU: + ioIIU = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioInInvU, []) + ] + if ioIIU: + chip_in_inv_U += [(id, *ioIIU)] + self.chip_in += [(id, *ioIIU)] + + #### l' entrée TC ### + ioOutTC = component.get("terminal_count_pin", []) + if ioOutTC: + ioOTC = [ + (col + numPin - 1 if numPin <= numPinBR else col + (numPinBR - (numPin % numPinBR) ), line + 1 - (numPin // numPinBR),n) + for (n,numPin) in sum(ioOutTC, []) + ] + if ioOTC: + chip_out_TC += [(id, *ioOTC)] + self.chip_out += [(id, *ioOTC)] + + elif id[:6] == "_wire_": # [(col1, line1,col2,line2), ...] + self.wire += [(id, *component["coord"][0])] + elif id[:4] == "_io_": # [(col1, line1,col2,line2), ...] + (col, line) = component["coord"][0][0], component["coord"][0][1] + ioZone = deepcopy(self.board.sketcher.matrix[f"{col},{line}"]["link"]) + if component["type"] == INPUT or component["type"] == CLOCK: + self.io_in += [(id, [ioZone])] + else: + self.io_out += [(id, [ioZone])] + print(f"func= {self.func}\n") + print(f"pwrChip= {self.pwrChip}\n") + print(f"wire = {self.wire}") + print(f"pwr = {self.pwrs}") + print(f"io_in = {self.io_in}") + print(f"io_out = {self.io_out}") + print(f"chip_in = {self.chip_in}") + print(f"chip_out = {self.chip_out}") + for pwr in self.pwrs: + (col, line, p) = pwr + if p == "-": + self.pwrM = deepcopy(self.board.sketcher.matrix[f"{col},{line}"]["link"]) + else: self.pwrP = deepcopy(self.board.sketcher.matrix[f"{col},{line}"]["link"]) + for w in self.wire: + id,c1,l1,c2,l2 = w + if self.is_linked_to(self.pwrM, (c1, l1)): + self.pwrM += deepcopy(self.board.sketcher.matrix[f"{c2},{l2}"]["link"]) + elif self.is_linked_to(self.pwrP, (c1, l1)): + self.pwrP += deepcopy(self.board.sketcher.matrix[f"{c2},{l2}"]["link"]) + elif w not in self.wireNotUsed: + self.wireNotUsed += [w] #deepcopy(self.board.sketcher.matrix[f"{c2},{l2}"]["link"]) + if self.is_linked_to(self.pwrM, (c2, l2)): + self.pwrM += deepcopy(self.board.sketcher.matrix[f"{c2},{l2}"]["link"]) + elif self.is_linked_to(self.pwrP, (c2, l2)): + self.pwrP += deepcopy(self.board.sketcher.matrix[f"{c2},{l2}"]["link"]) + elif w not in self.wireNotUsed: + self.wireNotUsed += [w] #deepcopy(self.board.sketcher.matrix[f"{c2},{l2}"]["link"]) + again = True + while again and len(self.wireNotUsed)>0: + again = False + for wused in self.wireNotUsed[:]: + id,cu1,lu1,cu2,lu2 = wused + if self.is_linked_to(self.pwrM, (cu1, lu1)): + self.pwrM += deepcopy(self.board.sketcher.matrix[f"{cu2},{lu2}"]["link"]) + self.wireNotUsed.remove(wused) + again = True + elif self.is_linked_to(self.pwrP, (cu1, lu1)): + self.pwrP += deepcopy(self.board.sketcher.matrix[f"{cu2},{lu2}"]["link"]) + self.wireNotUsed.remove(wused) + again = True + + if self.is_linked_to(self.pwrM, (cu2, lu2)): + self.pwrM += deepcopy(self.board.sketcher.matrix[f"{cu1},{lu1}"]["link"]) + if not again: + self.wireNotUsed.remove(wused) + again = True + elif self.is_linked_to(self.pwrP, (cu2, lu2)): + self.pwrP += deepcopy(self.board.sketcher.matrix[f"{cu1},{lu1}"]["link"]) + if not again: + self.wireNotUsed.remove(wused) + again = True + if again: + if (self.is_linked_to(self.pwrP, (cu1, lu1)) and self.is_linked_to(self.pwrM, (cu1, lu1))) or \ + (self.is_linked_to(self.pwrP, (cu2, lu2)) and self.is_linked_to(self.pwrM, (cu2, lu2))): + self.pwrCC += [wused] + #print(f"CC dans le cable {wused}") + if (self.is_linked_to(self.pwrP, (c1, l1)) and self.is_linked_to(self.pwrM, (c1, l1))) or \ + (self.is_linked_to(self.pwrP, (c2, l2)) and self.is_linked_to(self.pwrM, (c2, l2))): + self.pwrCC += [w] + #print(f"CC dans le cable {w}") + #pwrM.clear() + #pwrP.clear() + ############### Verification des chip sur pwr + ##################### + for chip in self.pwrChip["+"]: + id, col_pin, line_pin = chip + if self.is_linked_to(self.pwrP, (col_pin, line_pin)): + if id not in self.pwrChip["pwrConnected"]: + self.pwrChip["pwrConnected"].append((id,"+")) + elif self.is_linked_to(self.pwrM, (col_pin, line_pin)): + if id not in self.pwrChip["pwrMissConnected"]: + self.pwrChip["pwrMissConnected"].append((id,"+")) + elif id not in self.pwrChip["pwrNotConnected"]: + self.pwrChip["pwrNotConnected"].append((id,"+")) + ############### Verification des chip sur pwr - ##################### + for chip in self.pwrChip["-"]: + id, col_pin, line_pin = chip + if self.is_linked_to(self.pwrM, (col_pin, line_pin)): + if id not in self.pwrChip["pwrConnected"]: + self.pwrChip["pwrConnected"].append((id,"-")) + elif self.is_linked_to(self.pwrP, (col_pin, line_pin)): + if id not in self.pwrChip["pwrMissConnected"]: + self.pwrChip["pwrMissConnected"].append((id,"-")) + elif id not in self.pwrChip["pwrNotConnected"]: + self.pwrChip["pwrNotConnected"].append((id,"-")) + ############### Verification des chip_out sur pwr ##################### + for chipAllio in self.chip_out: + id = chipAllio[0] + for chipio in chipAllio[1:]: + c1,l1, *n = chipio + if self.is_linked_to(self.pwrM, (c1, l1)): + self.chip_ioCC += [(id, chipio)] + elif self.is_linked_to(self.pwrP, (c1, l1)): + self.chip_ioCC += [(id,chipio)] + else: + self.chip_ioOK += [(id,chipio)] + ############### Verification des chip_out sur io_in ##################### + for ioin in self.io_in: + id, [ioInZone] = ioin + if self.is_linked_to(ioInZone, (c1, l1)): + self.io_outCC += [ioin[0]] + + ############### Verification des io_in sur pwr ##################### + for ioin in self.io_in: + #c1, l1 = ioin[1][0], ioin[1][1] + id, ioInZone = ioin + [(c1,l1,c2,l2)] = ioInZone[0] + inChipInWire = False + if self.is_linked_to(self.pwrM, (c1, l1)): + inChipInWire = True + if ioin[0] not in self.io_outCC: + self.io_outCC += [ioin[0]] + elif self.is_linked_to(self.pwrP, (c1, l1)): + inChipInWire = True + if ioin[0] not in self.io_outCC: + self.io_outCC += [ioin[0]] + if not inChipInWire: + ciw = deepcopy(self.board.sketcher.matrix[f"{c1},{l1}"]["link"]) + again = True + while again and len(self.wireNotUsed)>0: + again = False + for wused in self.wireNotUsed[:]: + id,cu1,lu1,cu2,lu2 = wused + if self.is_linked_to(ciw, (cu1, lu1)): + ciw += deepcopy(self.board.sketcher.matrix[f"{cu2},{lu2}"]["link"]) + self.wireNotUsed.remove(wused) + again = True + elif self.is_linked_to(ciw, (cu2, lu2)): + ciw += deepcopy(self.board.sketcher.matrix[f"{cu1},{lu1}"]["link"]) + self.wireNotUsed.remove(wused) + again = True + elt = (ioin[0], ciw) + if not elt in self.chip_in_wire: + self.chip_in_wire += [elt] + + ############### Verification des self.chip_out sur chip_out ##################### + for chipAllio in self.chip_out: + id = chipAllio[0] + inChipOutWire = False + for chipio in chipAllio[1:]: + (c1,l1, *n) = chipio + for cow in self.chip_out_wire: + if self.is_linked_to(cow, (c1, l1)): + inChipOutWire = True + if chipio not in self.chip_outCC: + self.chip_outCC += [(id,chipio)] + if not inChipOutWire: + cow = deepcopy(self.board.sketcher.matrix[f"{c1},{l1}"]["link"]) + again = True + while again and len(self.wireNotUsed)>0: + again = False + for wused in self.wireNotUsed[:]: + id,cu1,lu1,cu2,lu2 = wused + if self.is_linked_to(cow, (cu1, lu1)): + cow += deepcopy(self.board.sketcher.matrix[f"{cu2},{lu2}"]["link"]) + self.wireNotUsed.remove(wused) + again = True + if not cow in self.chip_out_wire: + self.chip_out_wire += [cow] + elif self.is_linked_to(cow, (cu2, lu2)): + cow += deepcopy(self.board.sketcher.matrix[f"{cu1},{lu1}"]["link"]) + self.wireNotUsed.remove(wused) + again = True + if not cow in self.chip_out_wire: + self.chip_out_wire += [cow] + + ################# Redefinir les zones des io_out avec les cables non utilisés ############## + for n,ioOut in enumerate(self.io_out): + id, [ioOutZone] = ioOut + c1,l1,c2,l2 = ioOutZone[0] + ioOutZoneWire = [] + inIoOutZoneWire = False + for cow in self.wireNotUsed: # self.chip_out_wire + cow = [(cow[1:])] + if self.is_linked_to(cow, (c1, l1)): + inIoOutZoneWire = True + ioOutZoneWire += [cow] + if inIoOutZoneWire: + self.io_out[n] = (id,ioOutZoneWire) + + # ################ Redefinir les zones des chip_out avec les cables non utilisés ############## + # for chipO in self.chip_out: + # id = chipO[0] + # for co in chipO[1:]: + # for + + if not self.pwrCC and not self.pwrChip["pwrMissConnected"] and not self.chip_ioCC \ + and not self.io_outCC and not self.chip_outCC and not self.in_outOC: + print("vérification du circuit fermé") + self.script = "" + params ={ + "chip_select":chip_select, + "chip_out_inv":chip_out_inv, + "chip_in_enable":chip_in_enable, + "chip_in_enable_inv": chip_in_enable_inv, + "chip_in_clock" : chip_in_clock, + "chip_in_inv_reset" : chip_in_inv_reset, + "chip_in_inv_set" : chip_in_inv_set, + "chip_in_inv_clock" : chip_in_inv_clock, + "chip_in_j" : chip_in_j, + "chip_in_k" : chip_in_k, + "chip_in_inv_k" : chip_in_inv_k, + "count_enable_pin" : chip_in_ce, + "inv_load_enable_pin" : chip_in_inv_L , + "inv_up_down_input_pin" : chip_in_inv_U , + "terminal_count_pin" : chip_out_TC , + } + def io_position(io): + id,[[p]] = io + return p[0] + + # "chip_in_address_pins":chip_in_address_pins} + for no,ioOut in enumerate(sorted(self.io_out, key=lambda io: io_position(io))): + #self.script += self.mcu_pin[f"O{ioOut[0][4:]}"] + " = " # f"O{no+1}" + + circuitClose, script = self.checkCloseCircuit(ioOut,params) + if circuitClose : + print(f"le circuit est fermée sur la sortie {ioOut}") + for s in self.varScript: + self.script += s + self.varScript = [] + self.script += f"O{no+1}" + " = " + self.script += f"{script}; \n" + print(f"script temp : {self.script}") + else: print(f"le circuit est ouvert sur la sortie {ioOut}") + + + print(f"pwrChipConnected : {self.pwrChip['pwrConnected']}") + print(f"pwrChipNotConnected : {self.pwrChip['pwrNotConnected']}") + print(f"pwrChipMissConnected : {self.pwrChip['pwrMissConnected']}") + print(f"wireNotUsed : {self.wireNotUsed}") + print(f"pwrCC : {self.pwrCC}") + print(f"chip_ioCC : {self.chip_ioCC}") + print(f"chip_ioOK : {self.chip_ioOK}") + print(f"io_outCC : {self.io_outCC}") + print(f"chip_outCC : {self.chip_outCC}") + print(f"in_outOC : {self.in_outOC}") + print(f"chip_out_wire : {self.chip_out_wire}") + print(f"chip_in_wire : {self.chip_in_wire}") + print(f"chip_select : {chip_select}") + print(f"chip_out_inv : {chip_out_inv}") + print(f"chip_in_enable : {chip_in_enable}") + print(f"chip_in_enable_inv : {chip_in_enable_inv}") + print(f"map pin mcu : {self.mcu_pin}") + print(f"script final : {self.script}") + if self.script: + messagebox.showinfo("Script du circuit", f"Circuit= {self.script}") + else: + messagebox.showinfo("Script du circuit", f"Le circuit présente au moins un défaut et ne peut être téléversé.") diff --git a/object_model/chip_functions.py b/object_model/chip_functions.py index 0a97603..f68eae5 100644 --- a/object_model/chip_functions.py +++ b/object_model/chip_functions.py @@ -472,7 +472,7 @@ class Demux(ChipFunction): """ Represents an demultiplexer in a digital circuit. Attributes: - address_pins (list[int]): A tuple containing the address pins. + input_pins (list[int]): A tuple containing the address pins. output_pins (list[int]): A tuple containing the output pins. enable_pins (list[int]): A tuple containing the active HIGH enable pins. inv_enable_pins (list[int]): A tuple containing the active LOW enable pins. @@ -480,7 +480,7 @@ class Demux(ChipFunction): def __init__( self, - address_pins: list[int], + input_pins: list[int], output_pins: list[int], enable_pins: list[int], inv_enable_pins: list[int], @@ -488,7 +488,7 @@ def __init__( """ Initializes a DEMUX with the specified input and output pins. Args: - address_pins (list[int]): A tuple containing the address pins. + input_pins (list[int]): A tuple containing the address pins. output_pins (list[int]): A tuple containing the output pins. enable_pins (list[int]): A tuple containing the active HIGH enable pins. inv_enable_pins (list[int]): A tuple containing the active LOW enable pins. @@ -498,25 +498,25 @@ def __init__( ValueError: If the number of address pins is not equal to log2(num output pins). """ super().__init__() - self.address_pins: list[Pin] = [Pin(pin_num, None) for pin_num in address_pins] + self.input_pins: list[Pin] = [Pin(pin_num, None) for pin_num in input_pins] self.output_pins: list[Pin] = [Pin(pin_num, None) for pin_num in output_pins] self.enable_pins: list[Pin] = [Pin(pin_num, None) for pin_num in enable_pins] self.inv_enable_pins: list[Pin] = [Pin(pin_num, None) for pin_num in inv_enable_pins] - self.all_pins = self.address_pins + self.output_pins + self.enable_pins + self.inv_enable_pins + self.all_pins = self.input_pins + self.output_pins + self.enable_pins + self.inv_enable_pins if len(self.output_pins) < 2: raise ValueError("DEMUX must have at least two input pins.") - if len(self.address_pins) < 1: + if len(self.input_pins) < 1: raise ValueError("DEMUX must have at least one address pin.") - if len(self.address_pins) != log2(len(self.output_pins)): + if len(self.input_pins) != log2(len(self.output_pins)): raise ValueError("DEMUX must have log2(num output_pins) address pins.") if ( len(self.enable_pins) != 1 or len(self.inv_enable_pins) != 2 or len(self.output_pins) != 8 - or len(self.address_pins) != 3 + or len(self.input_pins) != 3 ): raise ValueError("Arbitrary DEMUX size not supported yet") @@ -527,7 +527,7 @@ def __str__(self): str: A string describing the DEMUX with its input and output pins. """ return ( - f"DEMUX:\n\t\tAddress Pins: {self.address_pins}," + f"DEMUX:\n\t\tAddress Pins: {self.input_pins}," f"\n\t\tOutput Pins: {self.output_pins}," f"\n\t\tEnable Pins: {self.enable_pins}," f"\n\t\tInverted Enable Pins: {self.inv_enable_pins}" @@ -540,7 +540,7 @@ def chip_internal_function(self): """ input_pin_pos = [ pin.connection_point - for pin in self.inv_enable_pins + self.enable_pins + self.address_pins + for pin in self.inv_enable_pins + self.enable_pins + self.input_pins if pin is not None and pin.connection_point is not None ] output_pin_pos = [pin.connection_point for pin in self.output_pins if pin.connection_point is not None] @@ -574,22 +574,32 @@ class DFlipFlop(ChipFunction): inv_reset_pin (Pin): The inverted reset pin (Active LOW). set_pin (Pin): The set pin. inv_set_pin (Pin): The inverted set pin (Active LOW). - data_pin (Pin): The data pin. - output_pin (Pin): The output pin. - inv_output_pin (Pin): The inverted output pin (Active LOW + input_pins (Pin): The data pin. + output_pins (Pin): The output pin. + inv_output_pins (Pin): The inverted output pin (Active LOW """ def __init__( self, - clock_pin: int, + # clock_pin: int, + # clock_type: str, + # reset_pin: int, + # inv_reset_pin: int, + # set_pin: int, + # inv_set_pin: int, + # input_pins: int, + # output_pins: int, + # inv_output_pins: int, + + clock_pin: list[int], clock_type: str, - reset_pin: int, - inv_reset_pin: int, - set_pin: int, - inv_set_pin: int, - data_pin: int, - output_pin: int, - inv_output_pin: int, + reset_pin: list[int], + inv_reset_pin: list[int], + set_pin: list[int], + inv_set_pin: list[int], + input_pins: list[int], + output_pins:list[int], + inv_output_pins:list[int], ): """ Initializes a D Flip Flop with the specified input and output pins. @@ -600,37 +610,48 @@ def __init__( inv_reset_pin (Pin): The inverted reset pin (Active LOW). set_pin (Pin): The set pin. inv_set_pin (Pin): The inverted set pin (Active LOW). - data_pin (Pin): The data pin. - output_pin (Pin): The output pin. - inv_output_pin (Pin): The inverted output pin (Active LOW). + input_pins (Pin): The data pin. + output_pins (Pin): The output pin. + inv_output_pins (Pin): The inverted output pin (Active LOW). Raises: ValueError: If the D Flip Flop does not have either set or inverted set pin. ValueError: If the D Flip Flop has both set and inverted set pins. ValueError: If the D Flip Flop does not have either reset or inverted reset pin. ValueError: If the D Flip Flop has both reset and inverted reset pins. """ - super().__init__() - self.clock_pin: Pin = Pin(clock_pin, None) + super().__init__() # + # self.clock_pin: Pin = Pin(clock_pin, None) + # self.clock_type: str = clock_type + # self.reset_pin: Pin = Pin(reset_pin, None) if reset_pin is not None else None + # self.inv_reset_pin: Pin = Pin(inv_reset_pin, None) if inv_reset_pin is not None else None + # self.set_pin: Pin = Pin(set_pin, None) if set_pin is not None else None + # self.inv_set_pin: Pin = Pin(inv_set_pin, None) if inv_set_pin is not None else None + # self.input_pins: Pin = Pin(input_pins, None) + # self.output_pins: Pin = Pin(output_pins, None) + # self.inv_output_pins: Pin = Pin(inv_output_pins, None) + + self.clock_pin: list[Pin] = [Pin(pin_num, None) for pin_num in clock_pin] self.clock_type: str = clock_type self.reset_pin: Pin = Pin(reset_pin, None) if reset_pin is not None else None - self.inv_reset_pin: Pin = Pin(inv_reset_pin, None) if inv_reset_pin is not None else None + self.inv_reset_pin: list[Pin] = [Pin(pin_num, None) for pin_num in inv_reset_pin] self.set_pin: Pin = Pin(set_pin, None) if set_pin is not None else None - self.inv_set_pin: Pin = Pin(inv_set_pin, None) if inv_set_pin is not None else None - self.data_pin: Pin = Pin(data_pin, None) - self.output_pin: Pin = Pin(output_pin, None) - self.inv_output_pin: Pin = Pin(inv_output_pin, None) - - self.all_pins = [ - self.clock_pin, - self.reset_pin, - self.inv_reset_pin, - self.set_pin, - self.inv_set_pin, - self.data_pin, - self.output_pin, - self.inv_output_pin, - ] - + self.inv_set_pin: list[Pin] = [Pin(pin_num, None) for pin_num in inv_set_pin] + self.input_pins: list[Pin] = [Pin(pin_num, None) for pin_num in input_pins] + self.output_pins: list[Pin] = [Pin(pin_num, None) for pin_num in output_pins] + self.inv_output_pins:list[Pin] = [Pin(pin_num, None) for pin_num in inv_output_pins] + + # self.all_pins = [ + # self.clock_pin, + # self.reset_pin, + # self.inv_reset_pin, + # self.set_pin, + # self.inv_set_pin, + # self.input_pins, + # self.output_pins, + # self.inv_output_pins, + # ] + self.all_pins = self.clock_pin + self.inv_reset_pin + self.inv_set_pin + \ + self.input_pins + self.output_pins + self.inv_output_pins if self.clock_type not in ["RISING_EDGE", "FALLING_EDGE"]: raise ValueError("Clock type must be either RISING_EDGE or FALLING_EDGE.") @@ -659,9 +680,9 @@ def __str__(self): f"\n\t\tInverted Reset Pin: {self.inv_reset_pin}," f"\n\t\tSet Pin: {self.set_pin}," f"\n\t\tInverted Set Pin: {self.inv_set_pin}," - f"\n\t\tData Pin: {self.data_pin}," - f"\n\t\tOutput Pin: {self.output_pin}," - f"\n\t\tInverted Output Pin: {self.inv_output_pin}" + f"\n\t\tData Pin: {self.input_pins}," + f"\n\t\tOutput Pin: {self.output_pins}," + f"\n\t\tInverted Output Pin: {self.inv_output_pins}" ) def chip_internal_function(self) -> FunctionRepresentation: @@ -672,11 +693,11 @@ def chip_internal_function(self) -> FunctionRepresentation: """ input_pin_pos = [ pin.connection_point - for pin in [self.inv_set_pin, self.inv_reset_pin, self.clock_pin, self.data_pin] + for pin in [self.inv_set_pin, self.inv_reset_pin, self.clock_pin, self.input_pins] if pin is not None and pin.connection_point is not None ] output_pin_pos = [ - pin.connection_point for pin in [self.output_pin, self.inv_output_pin] if pin.connection_point is not None + pin.connection_point for pin in [self.output_pins, self.inv_output_pins] if pin.connection_point is not None ] truth_table = TruthTable( @@ -706,8 +727,8 @@ class JKFlipFlop(ChipFunction): inv_j_input_pin (Pin): The inverted J input pin (Active LOW). k_input_pin (Pin): The K input pin. inv_k_input_pin (Pin): The inverted K input pin (Active LOW). - output_pin (Pin): The output pin. - inv_output_pin (Pin): The inverted output pin (Active LOW). + output_pins (Pin): The output pin. + inv_output_pins (Pin): The inverted output pin (Active LOW). """ def __init__( @@ -722,8 +743,8 @@ def __init__( inv_j_input_pin: int, k_input_pin: int, inv_k_input_pin: int, - output_pin: int, - inv_output_pin: int, + output_pins: int, + inv_output_pins: int, ): """ Initializes a JK Flip Flop with the specified input and output pins. @@ -738,8 +759,8 @@ def __init__( inv_j_input_pin (Pin): The inverted J input pin (Active LOW). k_input_pin (Pin): The K input pin. inv_k_input_pin (Pin): The inverted K input pin (Active LOW). - output_pin (Pin): The output pin. - inv_output_pin (Pin): The inverted output pin (Active LOW). + output_pins (Pin): The output pin. + inv_output_pins (Pin): The inverted output pin (Active LOW). Raises: ValueError: If the JK Flip Flop does not have either J or inverted J input pin. ValueError: If the JK Flip Flop has both J and inverted J input pins. @@ -751,51 +772,49 @@ def __init__( ValueError: If the JK Flip Flop has both reset and inverted reset pins. """ super().__init__() - self.clock_pin: Pin = Pin(clock_pin, None) + self.clock_pin: list[Pin] = [Pin(clock_pin, None)] self.clock_type: str = clock_type - self.reset_pin: Pin = Pin(reset_pin, None) if reset_pin is not None else None - self.inv_reset_pin: Pin = Pin(inv_reset_pin, None) if inv_reset_pin is not None else None - self.set_pin: Pin = Pin(set_pin, None) if set_pin is not None else None - self.inv_set_pin: Pin = Pin(inv_set_pin, None) if inv_set_pin is not None else None - self.j_input_pin: Pin = Pin(j_input_pin, None) if j_input_pin is not None else None - self.inv_j_input_pin: Pin = Pin(inv_j_input_pin, None) if inv_j_input_pin is not None else None - self.k_input_pin: Pin = Pin(k_input_pin, None) if k_input_pin is not None else None - self.inv_k_input_pin: Pin = Pin(inv_k_input_pin, None) if inv_k_input_pin is not None else None - self.output_pin: Pin = Pin(output_pin, None) - self.inv_output_pin: Pin = Pin(inv_output_pin, None) - - self.all_pins = [ - self.clock_pin, - self.reset_pin, - self.inv_reset_pin, - self.set_pin, - self.inv_set_pin, - self.j_input_pin, - self.inv_j_input_pin, - self.k_input_pin, - self.inv_k_input_pin, - self.output_pin, - self.inv_output_pin, - ] - - if self.clock_type not in ["RISING_EDGE", "FALLING_EDGE"]: - raise ValueError("Clock type must be either RISING_EDGE or FALLING_EDGE.") - if self.j_input_pin is None and self.inv_j_input_pin is None: - raise ValueError("JK Flip Flop must have either J or inverted J input pin.") - if self.j_input_pin is not None and self.inv_j_input_pin is not None: - raise ValueError("JK Flip Flop cannot have both J and inverted J input pins.") - if self.k_input_pin is None and self.inv_k_input_pin is None: - raise ValueError("JK Flip Flop must have either K or inverted K input pin.") - if self.k_input_pin is not None and self.inv_k_input_pin is not None: - raise ValueError("JK Flip Flop cannot have both K and inverted K input pins.") - if self.inv_set_pin is None and self.set_pin is None: - raise ValueError("JK Flip Flop must have either set or inverted set pin.") - if self.inv_set_pin is not None and self.set_pin is not None: - raise ValueError("JK Flip Flop cannot have both set and inverted set pins.") - if self.inv_reset_pin is None and self.reset_pin is None: - raise ValueError("JK Flip Flop must have either reset or inverted reset pin.") - if self.inv_reset_pin is not None and self.reset_pin is not None: - raise ValueError("JK Flip Flop cannot have both reset and inverted reset pins.") + self.reset_pin: list[Pin] = [Pin(reset_pin, None) if reset_pin is not None else None] + self.inv_reset_pin: list[Pin] = [Pin(inv_reset_pin, None) if inv_reset_pin is not None else None] + self.set_pin: list[Pin] = [Pin(set_pin, None) if set_pin is not None else None] + self.inv_set_pin: list[Pin] = [Pin(inv_set_pin, None) if inv_set_pin is not None else None] + self.j_input_pin: list[Pin] = [Pin(j_input_pin, None) if j_input_pin is not None else None] + self.inv_j_input_pin: list[Pin] = [Pin(inv_j_input_pin, None) if inv_j_input_pin is not None else None] + self.input_pins: list[Pin] = [Pin(j_input_pin, None) if j_input_pin is not None else None] # input pins = j_input_pin + self.k_input_pin: list[Pin] = [Pin(k_input_pin, None) if k_input_pin is not None else None] + self.inv_k_input_pin: list[Pin] = [Pin(inv_k_input_pin, None) if inv_k_input_pin is not None else None] + self.output_pins: list[Pin] = [Pin(output_pins, None)] + self.inv_output_pins: list[Pin] = [Pin(inv_output_pins, None)] + + self.all_pins = self.clock_pin + \ + self.reset_pin +\ + self.inv_reset_pin +\ + self.set_pin +\ + self.inv_set_pin +\ + self.input_pins +\ + self.k_input_pin +\ + self.inv_k_input_pin +\ + self.output_pins +\ + self.inv_output_pins + + # if self.clock_type not in ["RISING_EDGE", "FALLING_EDGE"]: + # raise ValueError("Clock type must be either RISING_EDGE or FALLING_EDGE.") + # if self.j_input_pin is None and self.inv_j_input_pin is None: + # raise ValueError("JK Flip Flop must have either J or inverted J input pin.") + # if self.j_input_pin is not None and self.inv_j_input_pin is not None: + # raise ValueError("JK Flip Flop cannot have both J and inverted J input pins.") + # if self.k_input_pin is None and self.inv_k_input_pin is None: + # raise ValueError("JK Flip Flop must have either K or inverted K input pin.") + # if self.k_input_pin is not None and self.inv_k_input_pin is not None: + # raise ValueError("JK Flip Flop cannot have both K and inverted K input pins.") + # if self.inv_set_pin is None and self.set_pin is None: + # raise ValueError("JK Flip Flop must have either set or inverted set pin.") + # if self.inv_set_pin is not None and self.set_pin is not None: + # raise ValueError("JK Flip Flop cannot have both set and inverted set pins.") + # if self.inv_reset_pin is None and self.reset_pin is None: + # raise ValueError("JK Flip Flop must have either reset or inverted reset pin.") + # if self.inv_reset_pin is not None and self.reset_pin is not None: + # raise ValueError("JK Flip Flop cannot have both reset and inverted reset pins.") def __str__(self): """ @@ -810,61 +829,62 @@ def __str__(self): f"\n\t\tInverted Reset Pin: {self.inv_reset_pin}," f"\n\t\tSet Pin: {self.set_pin}," f"\n\t\tInverted Set Pin: {self.inv_set_pin}," - f"\n\t\tJ Input Pin: {self.j_input_pin}," - f"\n\t\tInverted J Input Pin: {self.inv_j_input_pin}," + f"\n\t\tJ Input Pin: {self.input_pins}," + # f"\n\t\tInverted J Input Pin: {self.inv_j_input_pin}," f"\n\t\tK Input Pin: {self.k_input_pin}," f"\n\t\tInverted K Input Pin: {self.inv_k_input_pin}," - f"\n\t\tOutput Pin: {self.output_pin}," - f"\n\t\tInverted Output Pin: {self.inv_output_pin}" + f"\n\t\tOutput Pin: {self.output_pins}," + f"\n\t\tInverted Output Pin: {self.inv_output_pins}" ) def chip_internal_function(self) -> FunctionRepresentation: """ Returns a FunctionRepresentation object representing the internal function of the JK Flip Flop """ - input_pin_pos = [ - pin.connection_point - for pin in [ - self.inv_set_pin, - self.set_pin, - self.inv_reset_pin, - self.reset_pin, - self.clock_pin, - self.inv_j_input_pin, - self.j_input_pin, - self.inv_k_input_pin, - self.k_input_pin, - ] - if pin is not None and pin.connection_point is not None - ] - output_pin_pos = [ - pin.connection_point for pin in [self.output_pin, self.inv_output_pin] if pin.connection_point is not None - ] - - # Handle inverted inputs - hi_set = "H" if self.set_pin is not None else "L" - lo_set = "L" if self.set_pin is not None else "H" - hi_reset = "H" if self.reset_pin is not None else "L" - lo_reset = "L" if self.reset_pin is not None else "H" - clock_symb = "R" if self.clock_type == "RISING_EDGE" else "F" - hi_j = "H" if self.j_input_pin is not None else "L" - lo_j = "L" if self.j_input_pin is not None else "H" - hi_k = "H" if self.k_input_pin is not None else "L" - lo_k = "L" if self.k_input_pin is not None else "H" - - truth_table = TruthTable( - [ - TruthTableRow([hi_set, lo_reset, "X", "X", "X"], ["H", "L"]), - TruthTableRow([lo_set, hi_reset, "X", "X", "X"], ["L", "H"]), - TruthTableRow([hi_set, hi_reset, clock_symb, "X", "X"], ["H", "H"]), - TruthTableRow([lo_set, lo_reset, clock_symb, hi_j, hi_k], ["nQ", "Q"]), - TruthTableRow([lo_set, lo_reset, clock_symb, lo_j, hi_k], ["L", "H"]), - TruthTableRow([lo_set, lo_reset, clock_symb, hi_j, lo_k], ["H", "L"]), - TruthTableRow([lo_set, lo_reset, clock_symb, lo_j, lo_k], ["Q", "nQ"]), - ] - ) - - return FunctionRepresentation(input_pin_pos, output_pin_pos, truth_table) + # input_pin_pos = [ + # pin.connection_point + # for pin in [ + # self.inv_set_pin, + # self.set_pin, + # self.inv_reset_pin, + # self.reset_pin, + # self.clock_pin, + # self.inv_j_input_pin, + # self.j_input_pin, + # self.inv_k_input_pin, + # self.k_input_pin, + # ] + # if pin is not None and pin.connection_point is not None + # ] + # output_pin_pos = [ + # pin.connection_point for pin in [self.output_pin, self.inv_output_pin] if pin.connection_point is not None + # ] + + # # Handle inverted inputs + # hi_set = "H" if self.set_pin is not None else "L" + # lo_set = "L" if self.set_pin is not None else "H" + # hi_reset = "H" if self.reset_pin is not None else "L" + # lo_reset = "L" if self.reset_pin is not None else "H" + # clock_symb = "R" if self.clock_type == "RISING_EDGE" else "F" + # hi_j = "H" if self.j_input_pin is not None else "L" + # lo_j = "L" if self.j_input_pin is not None else "H" + # hi_k = "H" if self.k_input_pin is not None else "L" + # lo_k = "L" if self.k_input_pin is not None else "H" + + # truth_table = TruthTable( + # [ + # TruthTableRow([hi_set, lo_reset, "X", "X", "X"], ["H", "L"]), + # TruthTableRow([lo_set, hi_reset, "X", "X", "X"], ["L", "H"]), + # TruthTableRow([hi_set, hi_reset, clock_symb, "X", "X"], ["H", "H"]), + # TruthTableRow([lo_set, lo_reset, clock_symb, hi_j, hi_k], ["nQ", "Q"]), + # TruthTableRow([lo_set, lo_reset, clock_symb, lo_j, hi_k], ["L", "H"]), + # TruthTableRow([lo_set, lo_reset, clock_symb, hi_j, lo_k], ["H", "L"]), + # TruthTableRow([lo_set, lo_reset, clock_symb, lo_j, lo_k], ["Q", "nQ"]), + # ] + # ) + + # return FunctionRepresentation(input_pin_pos, output_pin_pos, truth_table) + return FunctionRepresentation([], [], TruthTable([])) class BinaryCounter(ChipFunction): @@ -892,6 +912,8 @@ def __init__( self, clock_pin: int, clock_type: str, + reset_pin: int, + inv_reset_pin: int, count_enable_pin: int, inv_count_enable_pin: int, load_enable_pin: int, @@ -909,6 +931,8 @@ def __init__( clock_pin (int): The clock pin. clock_type (str): The type of the clock signal (e.g., rising, falling, etc.). count_enable_pin (int): The count enable pin. + reset_pin (int): The reset pin. + inv_reset_pin (int): The inverted reset pin (Active LOW). inv_count_enable_pin (int): The inverted count enable pin (Active LOW). load_enable_pin (int): The load enable pin. inv_load_enable_pin (int): The inverted load enable pin (Active LOW). @@ -929,57 +953,59 @@ def __init__( ValueError: If the number of data pins is not equal to the number of output pins. """ super().__init__() - self.clock_pin: Pin = Pin(clock_pin, None) + self.clock_pin: list[Pin] = [Pin(clock_pin, None)] self.clock_type: str = clock_type - self.count_enable_pin: Pin = Pin(count_enable_pin, None) if count_enable_pin is not None else None - self.inv_count_enable_pin: Pin = Pin(inv_count_enable_pin, None) if inv_count_enable_pin is not None else None - self.load_enable_pin: Pin = Pin(load_enable_pin, None) if load_enable_pin is not None else None - self.inv_load_enable_pin: Pin = Pin(inv_load_enable_pin, None) if inv_load_enable_pin is not None else None - self.up_down_input_pin: Pin = Pin(up_down_input_pin, None) if up_down_input_pin is not None else None - self.inv_up_down_input_pin: Pin = ( + self.reset_pin: list[Pin] = [Pin(reset_pin, None) if reset_pin is not None else None] + self.inv_reset_pin: list[Pin] = [Pin(inv_reset_pin, None) if inv_reset_pin is not None else None] + self.count_enable_pin: list[Pin] = [Pin(count_enable_pin, None) if count_enable_pin is not None else None] + self.inv_count_enable_pin: list[Pin] = [Pin(inv_count_enable_pin, None) if inv_count_enable_pin is not None else None] + self.load_enable_pin: list[Pin] = [Pin(load_enable_pin, None) if load_enable_pin is not None else None] + self.inv_load_enable_pin: list[Pin] = [Pin(inv_load_enable_pin, None) if inv_load_enable_pin is not None else None] + self.up_down_input_pin: list[Pin] = [Pin(up_down_input_pin, None) if up_down_input_pin is not None else None] + self.inv_up_down_input_pin: list[Pin] = [( Pin(inv_up_down_input_pin, None) if inv_up_down_input_pin is not None else None - ) - self.terminal_count_pin: Pin = Pin(terminal_count_pin, None) - self.ripple_clock_output_pin: Pin = Pin(ripple_clock_output_pin, None) - self.data_pins: list[Pin] = [Pin(pin_num, None) for pin_num in data_pins] + )] + self.terminal_count_pin: list[Pin] = [Pin(terminal_count_pin, None)] + self.ripple_clock_output_pin: list[Pin] = [Pin(ripple_clock_output_pin, None)] + self.input_pins: list[Pin] = [Pin(pin_num, None) for pin_num in data_pins] # input pins = data pins self.output_pins: list[Pin] = [Pin(pin_num, None) for pin_num in output_pins] - self.all_pins = ( - [ - self.clock_pin, - self.count_enable_pin, - self.inv_count_enable_pin, - self.load_enable_pin, - self.inv_load_enable_pin, - self.up_down_input_pin, - self.inv_up_down_input_pin, - self.terminal_count_pin, - self.ripple_clock_output_pin, - ] - + self.data_pins - + self.output_pins - ) - - if self.count_enable_pin is not None and self.inv_count_enable_pin is not None: - raise ValueError("Binary Counter cannot have both count enable and inverted count enable pins.") - if self.load_enable_pin is not None and self.inv_load_enable_pin is not None: - raise ValueError("Binary Counter cannot have both load enable and inverted load enable pins.") - if self.up_down_input_pin is not None and self.inv_up_down_input_pin is not None: - raise ValueError("Binary Counter cannot have both up/down input and inverted up/down input pins.") - if self.inv_count_enable_pin is None and self.count_enable_pin is None: - raise ValueError("Binary Counter must have either count enable or inverted count enable pin.") - if self.inv_load_enable_pin is None and self.load_enable_pin is None: - raise ValueError("Binary Counter must have either load enable or inverted load enable pin.") - if self.inv_up_down_input_pin is None and self.up_down_input_pin is None: - raise ValueError("Binary Counter must have either up/down input or inverted up/down input pin.") - - if self.clock_type not in ["RISING_EDGE", "FALLING_EDGE"]: - raise ValueError("Clock type must be either RISING_EDGE or FALLING_EDGE.") - if len(self.data_pins) != len(self.output_pins): - raise ValueError("Number of data pins must be equal to number of output pins.") - - if len(self.data_pins) != 4: - raise ValueError("Arbitrary Binary Counter not supported yet") + # self.all_pins = ( + # [ + # self.clock_pin, + # self.count_enable_pin, + # self.inv_count_enable_pin, + # self.load_enable_pin, + # self.inv_load_enable_pin, + # self.up_down_input_pin, + # self.inv_up_down_input_pin, + # self.terminal_count_pin, + # self.ripple_clock_output_pin, + # ] + # + self.data_pins + # + self.output_pins + # ) + + # if self.count_enable_pin is not None and self.inv_count_enable_pin is not None: + # raise ValueError("Binary Counter cannot have both count enable and inverted count enable pins.") + # if self.load_enable_pin is not None and self.inv_load_enable_pin is not None: + # raise ValueError("Binary Counter cannot have both load enable and inverted load enable pins.") + # if self.up_down_input_pin is not None and self.inv_up_down_input_pin is not None: + # raise ValueError("Binary Counter cannot have both up/down input and inverted up/down input pins.") + # if self.inv_count_enable_pin is None and self.count_enable_pin is None: + # raise ValueError("Binary Counter must have either count enable or inverted count enable pin.") + # if self.inv_load_enable_pin is None and self.load_enable_pin is None: + # raise ValueError("Binary Counter must have either load enable or inverted load enable pin.") + # if self.inv_up_down_input_pin is None and self.up_down_input_pin is None: + # raise ValueError("Binary Counter must have either up/down input or inverted up/down input pin.") + + # if self.clock_type not in ["RISING_EDGE", "FALLING_EDGE"]: + # raise ValueError("Clock type must be either RISING_EDGE or FALLING_EDGE.") + # if len(self.data_pins) != len(self.output_pins): + # raise ValueError("Number of data pins must be equal to number of output pins.") + + # if len(self.data_pins) != 4: + # raise ValueError("Arbitrary Binary Counter not supported yet") def __str__(self): """ @@ -997,7 +1023,7 @@ def __str__(self): f"\n\t\tUp/Down Input Pin: {self.up_down_input_pin}," f"\n\t\tTerminal Count Pin: {self.terminal_count_pin}," f"\n\t\tRipple Clock Output Pin: {self.ripple_clock_output_pin}," - f"\n\t\tData Pins: {self.data_pins}," + f"\n\t\tData Pins: {self.input_pins}," f"\n\t\tOutput Pins: {self.output_pins}" ) @@ -1007,112 +1033,113 @@ def chip_internal_function(self) -> FunctionRepresentation: Some of the outputs are also inputs for the counter. Only supports 4 bit counter. """ - # TODO figure out a better way, I hate this - input_pin_pos = [ - pin.connection_point - for pin in [ - self.inv_load_enable_pin, - self.load_enable_pin, - self.inv_up_down_input_pin, - self.up_down_input_pin, - self.inv_count_enable_pin, - self.count_enable_pin, - self.clock_pin, - ] - + self.data_pins - + self.output_pins - if pin is not None and pin.connection_point is not None - ] - output_pin_pos = [ - pin.connection_point - for pin in self.output_pins + [self.terminal_count_pin, self.ripple_clock_output_pin] - if pin.connection_point is not None - ] - - # Handle inverted outputs - hi_load = "H" if self.load_enable_pin is not None else "L" - lo_load = "L" if self.load_enable_pin is not None else "H" - hi_up_down = "H" if self.up_down_input_pin is not None else "L" - lo_up_down = "L" if self.up_down_input_pin is not None else "H" - hi_count = "H" if self.count_enable_pin is not None else "L" - lo_count = "L" if self.count_enable_pin is not None else "H" - clock_symb = "R" if self.clock_type == "RISING_EDGE" else "F" - - x_dq = ["X"] * len(self.data_pins) # Don't care values for data pins/output pins - c00 = ["L", "L", "L", "L"] - c01 = ["L", "L", "L", "H"] - c02 = ["L", "L", "H", "L"] - c03 = ["L", "L", "H", "H"] - c04 = ["L", "H", "L", "L"] - c05 = ["L", "H", "L", "H"] - c06 = ["L", "H", "H", "L"] - c07 = ["L", "H", "H", "H"] - c08 = ["H", "L", "L", "L"] - c09 = ["H", "L", "L", "H"] - c10 = ["H", "L", "H", "L"] - c11 = ["H", "L", "H", "H"] - c12 = ["H", "H", "L", "L"] - c13 = ["H", "H", "L", "H"] - c14 = ["H", "H", "H", "L"] - c15 = ["H", "H", "H", "H"] - - - truth_table = TruthTable( - [ - # Load states - TruthTableRow([hi_load, "X", "X", "X"] + c00 + x_dq, c00 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c01 + x_dq, c01 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c02 + x_dq, c02 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c03 + x_dq, c03 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c04 + x_dq, c04 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c05 + x_dq, c05 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c06 + x_dq, c06 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c07 + x_dq, c07 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c08 + x_dq, c08 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c09 + x_dq, c09 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c10 + x_dq, c10 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c11 + x_dq, c11 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c12 + x_dq, c12 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c13 + x_dq, c13 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c14 + x_dq, c14 + ["L", "H"]), - TruthTableRow([hi_load, "X", "X", "X"] + c15 + x_dq, c15 + ["L", "H"]), - # Hold state - TruthTableRow([lo_load, "X", lo_count, "X", "X", "X", "X", "X"], ["Q", "Q", "Q", "Q", "Q", "Q"]), - # Count UP states - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c00, c01 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c01, c02 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c02, c03 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c03, c04 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c04, c05 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c05, c06 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c06, c07 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c07, c08 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c08, c09 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c09, c10 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c10, c11 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c11, c12 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c12, c13 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c13, c14 + ["L", "H"]), - TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c14, c15 + ["L", "H"]), - # TODO add limit states when terminal count is reached - # Count DOWN states - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c15, c14 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c14, c13 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c13, c12 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c12, c11 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c11, c10 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c10, c09 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c09, c08 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c08, c07 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c07, c06 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c06, c05 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c05, c04 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c04, c03 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c03, c02 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c02, c01 + ["L", "H"]), - TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c01, c00 + ["L", "H"]), - # TODO add limit states when terminal count is reached - ] - ) - - return FunctionRepresentation(input_pin_pos, output_pin_pos, truth_table) + # # TODO figure out a better way, I hate this + # input_pin_pos = [ + # pin.connection_point + # for pin in [ + # self.inv_load_enable_pin, + # self.load_enable_pin, + # self.inv_up_down_input_pin, + # self.up_down_input_pin, + # self.inv_count_enable_pin, + # self.count_enable_pin, + # self.clock_pin, + # ] + # + self.data_pins + # + self.output_pins + # if pin is not None and pin.connection_point is not None + # ] + # output_pin_pos = [ + # pin.connection_point + # for pin in self.output_pins + [self.terminal_count_pin, self.ripple_clock_output_pin] + # if pin.connection_point is not None + # ] + + # # Handle inverted outputs + # hi_load = "H" if self.load_enable_pin is not None else "L" + # lo_load = "L" if self.load_enable_pin is not None else "H" + # hi_up_down = "H" if self.up_down_input_pin is not None else "L" + # lo_up_down = "L" if self.up_down_input_pin is not None else "H" + # hi_count = "H" if self.count_enable_pin is not None else "L" + # lo_count = "L" if self.count_enable_pin is not None else "H" + # clock_symb = "R" if self.clock_type == "RISING_EDGE" else "F" + + # x_dq = ["X"] * len(self.data_pins) # Don't care values for data pins/output pins + # c00 = ["L", "L", "L", "L"] + # c01 = ["L", "L", "L", "H"] + # c02 = ["L", "L", "H", "L"] + # c03 = ["L", "L", "H", "H"] + # c04 = ["L", "H", "L", "L"] + # c05 = ["L", "H", "L", "H"] + # c06 = ["L", "H", "H", "L"] + # c07 = ["L", "H", "H", "H"] + # c08 = ["H", "L", "L", "L"] + # c09 = ["H", "L", "L", "H"] + # c10 = ["H", "L", "H", "L"] + # c11 = ["H", "L", "H", "H"] + # c12 = ["H", "H", "L", "L"] + # c13 = ["H", "H", "L", "H"] + # c14 = ["H", "H", "H", "L"] + # c15 = ["H", "H", "H", "H"] + + + # truth_table = TruthTable( + # [ + # # Load states + # TruthTableRow([hi_load, "X", "X", "X"] + c00 + x_dq, c00 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c01 + x_dq, c01 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c02 + x_dq, c02 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c03 + x_dq, c03 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c04 + x_dq, c04 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c05 + x_dq, c05 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c06 + x_dq, c06 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c07 + x_dq, c07 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c08 + x_dq, c08 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c09 + x_dq, c09 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c10 + x_dq, c10 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c11 + x_dq, c11 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c12 + x_dq, c12 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c13 + x_dq, c13 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c14 + x_dq, c14 + ["L", "H"]), + # TruthTableRow([hi_load, "X", "X", "X"] + c15 + x_dq, c15 + ["L", "H"]), + # # Hold state + # TruthTableRow([lo_load, "X", lo_count, "X", "X", "X", "X", "X"], ["Q", "Q", "Q", "Q", "Q", "Q"]), + # # Count UP states + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c00, c01 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c01, c02 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c02, c03 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c03, c04 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c04, c05 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c05, c06 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c06, c07 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c07, c08 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c08, c09 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c09, c10 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c10, c11 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c11, c12 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c12, c13 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c13, c14 + ["L", "H"]), + # TruthTableRow([lo_load, hi_up_down, hi_count, clock_symb] + x_dq + c14, c15 + ["L", "H"]), + # # TODO add limit states when terminal count is reached + # # Count DOWN states + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c15, c14 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c14, c13 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c13, c12 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c12, c11 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c11, c10 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c10, c09 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c09, c08 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c08, c07 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c07, c06 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c06, c05 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c05, c04 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c04, c03 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c03, c02 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c02, c01 + ["L", "H"]), + # TruthTableRow([lo_load, lo_up_down, hi_count, clock_symb] + x_dq + c01, c00 + ["L", "H"]), + # # TODO add limit states when terminal count is reached + # ] + # ) + + # return FunctionRepresentation(input_pin_pos, output_pin_pos, truth_table) + return FunctionRepresentation([], [], TruthTable([])) \ No newline at end of file diff --git a/object_model/circuit_object_model.py b/object_model/circuit_object_model.py index 29a099e..3bd82f8 100644 --- a/object_model/circuit_object_model.py +++ b/object_model/circuit_object_model.py @@ -184,7 +184,7 @@ def from_json(json_data: dict, package_dict: dict[str, Package] | None = None): data["inv_enable_pins"], ), "DEMUX": lambda data: Demux( - data["address_pins"], + data["input_pins"], data["output_pins"], data["enable_pins"], data["inv_enable_pins"], @@ -196,9 +196,9 @@ def from_json(json_data: dict, package_dict: dict[str, Package] | None = None): data["inv_reset_pin"], data["set_pin"], data["inv_set_pin"], - data["data_pin"], - data["output_pin"], - data["inv_output_pin"], + data["input_pins"], + data["output_pins"], + data["inv_output_pins"], ), "JK_FLIP_FLOP": lambda data: JKFlipFlop( data["clock_pin"], @@ -211,12 +211,14 @@ def from_json(json_data: dict, package_dict: dict[str, Package] | None = None): data["inv_j_input_pin"], data["k_input_pin"], data["inv_k_input_pin"], - data["output_pin"], - data["inv_output_pin"], + data["output_pins"], + data["inv_output_pins"], ), "BINARY_COUNTER": lambda data: BinaryCounter( data["clock_pin"], data["clock_type"], + data["reset_pin"], + data["inv_reset_pin"], data["count_enable_pin"], data["inv_count_enable_pin"], data["load_enable_pin"], @@ -270,10 +272,107 @@ def to_generic_dict(self) -> dict[str, Any]: if self.functions: attr_dict["logicFunctionName"] = self.functions[0].__class__.__name__ attr_dict["io"] = [ - ([pin.pin_num for pin in func.input_pins], [pin.pin_num for pin in func.output_pins]) + ( [pin.pin_num for pin in func.input_pins], [pin.pin_num for pin in func.output_pins] + \ + [pin.pin_num for pin in getattr(func, 'inv_output_pins', [])] + ) + for func in self.functions + #if isinstance(func, LogicalFunction) and not isinstance(func, Mux) and not isinstance(func, Demux) + #if isinstance(func, LogicalFunction) or isinstance(func, Mux) or isinstance(func, Demux) or isinstance(func, DFlipFlop) + ] + # if isinstance(self.functions, DFlipFlop): + # attr_dict["io"] = [([2], [5])] + attr_dict["io_select"] = [ + [pin.pin_num for pin in func.select_pins] + for func in self.functions + #if isinstance(func, LogicalFunction) and not isinstance(func, Mux) and not isinstance(func, Demux) + if isinstance(func, Mux) + ] + attr_dict["io_out_inv"] = [ + [pin.pin_num for pin in func.inv_output_pins] + for func in self.functions + #if isinstance(func, LogicalFunction) and not isinstance(func, Mux) and not isinstance(func, Demux) + if isinstance(func, Mux) or isinstance(func, DFlipFlop) + ] + attr_dict["io_enable"] = [ + [pin.pin_num for pin in func.enable_pins] + for func in self.functions + #if isinstance(func, LogicalFunction) and not isinstance(func, Mux) and not isinstance(func, Demux) + if isinstance(func, Mux) or isinstance(func, Demux) + ] + attr_dict["io_enable_inv"] = [ + [pin.pin_num for pin in func.inv_enable_pins] for func in self.functions - if isinstance(func, LogicalFunction) and not isinstance(func, Mux) and not isinstance(func, Demux) + #if isinstance(func, LogicalFunction) and not isinstance(func, Mux) and not isinstance(func, Demux) + if isinstance(func, Mux) or isinstance(func, Demux) + ] + attr_dict["clock_pin"] = [ + [(n,pin.pin_num) for pin in func.clock_pin] + for n,func in enumerate(self.functions) if getattr(func,"clock_type", "") == "RISING_EDGE" + #self.functions.clock_pin + #if isinstance(func, LogicalFunction) and not isinstance(func, Mux) and not isinstance(func, Demux) + if isinstance(func, DFlipFlop) or isinstance(func, JKFlipFlop) or isinstance(func, BinaryCounter) + ] + attr_dict["inv_clock_pin"] = [ + [(n,pin.pin_num) for pin in func.clock_pin] + for n,func in enumerate(self.functions) if getattr(func,"clock_type", "") == "FALLING_EDGE" + #self.functions.clock_pin + #if isinstance(func, LogicalFunction) and not isinstance(func, Mux) and not isinstance(func, Demux) + if isinstance(func, JKFlipFlop) + ] + attr_dict["inv_reset_pin"] = [ + [(n,pin.pin_num) for pin in func.inv_reset_pin] + for n,func in enumerate(self.functions) + + if isinstance(func, DFlipFlop) or isinstance(func, JKFlipFlop) or isinstance(func, BinaryCounter) + ] + attr_dict["inv_set_pin"] = [ + [(n,pin.pin_num)for pin in func.inv_set_pin] + for n,func in enumerate(self.functions) + + if isinstance(func, DFlipFlop) or isinstance(func, JKFlipFlop) + ] + attr_dict["j_input_pin"] = [ + [(n,pin.pin_num)for pin in func.j_input_pin] + for n,func in enumerate(self.functions) + + if isinstance(func, JKFlipFlop) + ] + attr_dict["inv_k_input_pin"] = [ + [(n,pin.pin_num)for pin in func.inv_k_input_pin if func.inv_k_input_pin[0] ] + for n,func in enumerate(self.functions) + + if isinstance(func, JKFlipFlop) ] + attr_dict["k_input_pin"] = [ + [(n,pin.pin_num)for pin in func.k_input_pin if pin] + for n,func in enumerate(self.functions) + + if isinstance(func, JKFlipFlop) + ] + attr_dict["count_enable_pin"] = [ + [(n,pin.pin_num)for pin in func.count_enable_pin if pin] + for n,func in enumerate(self.functions) + + if isinstance(func, BinaryCounter) + ] + attr_dict["inv_load_enable_pin"] = [ + [(n,pin.pin_num)for pin in func.inv_load_enable_pin if pin] + for n,func in enumerate(self.functions) + + if isinstance(func, BinaryCounter) + ] + attr_dict["inv_up_down_input_pin"] = [ + [(n,pin.pin_num)for pin in func.inv_up_down_input_pin if pin] + for n,func in enumerate(self.functions) + + if isinstance(func, BinaryCounter) + ] + attr_dict["terminal_count_pin"] = [ + [(n,pin.pin_num)for pin in func.terminal_count_pin if pin] + for n,func in enumerate(self.functions) + + if isinstance(func, BinaryCounter) + ] # return attr_dict def __str__(self): diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index d0dfd58..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pyserial==3.5 diff --git a/sidebar.py b/sidebar.py index bf65543..f5892a9 100644 --- a/sidebar.py +++ b/sidebar.py @@ -8,6 +8,7 @@ from pathlib import Path import tkinter as tk import os +import platform from typing import Callable, Tuple import subprocess import sys @@ -17,12 +18,13 @@ from dataCDLT import FREE, USED from object_model.circuit_object_model import Chip, get_all_available_chips, get_chip_modification_times -if os.name == "darwin": - from tkinter import messagebox, font - from tkmacosx import Button # type: ignore -else: - from tkinter import Button, messagebox, font +# if (os.name in ("posix", "darwin")) and "linux" not in platform.platform().lower(): +# from tkinter import messagebox, font +# from tkmacosx import Button # type: ignore +# else: +# from tkinter import Button, messagebox, font +from tkinter import Button, messagebox, font @dataclass class SidebarGrid: @@ -501,7 +503,7 @@ def manage_components(self): os.startfile(path) except AttributeError: pass - elif os.name == "posix": # For macOS and Linux # type: ignore + elif os.name == "posix" or os.name=="darwin": # For macOS and Linux # type: ignore with subprocess.Popen(["open", path] if sys.platform == "darwin" else ["xdg-open", path]): pass else: @@ -535,5 +537,5 @@ def refresh(self): self.initialize_chip_data(self.current_dict_circuit, self.chip_images_path) self.on_search(None) print("Sidebar refreshed with updated chips.") - else: - print("No changes detected. Sidebar not refreshed.") + #else: + #print("No changes detected. Sidebar not refreshed.") diff --git a/toolbar.py b/toolbar.py index 7927779..37fef84 100644 --- a/toolbar.py +++ b/toolbar.py @@ -8,6 +8,7 @@ import os from dataclasses import dataclass from pathlib import Path +import platform import tkinter as tk from idlelib.tooltip import Hovertip # type: ignore @@ -15,11 +16,11 @@ from dataCDLT import INPUT, OUTPUT, FREE, CLOCK from utils import resource_path -if os.name == "darwin": - from tkinter import messagebox, colorchooser - from tkmacosx import Button # type: ignore -else: - from tkinter import Button, messagebox, colorchooser +# if (os.name in ("posix", "darwin")) and "linux" not in platform.platform().lower(): +# from tkinter import messagebox, colorchooser +# from tkmacosx import Button # type: ignore +# else: +from tkinter import Button, messagebox, colorchooser @dataclass class WirePlacementInfo: @@ -182,6 +183,16 @@ def choose_color(self): self.canvas.itemconfig(self.cursor_indicator_id, fill=self.selected_color) # Here y_originu can add logic to apply the selected color to new connections + self.canvas.itemconfig(self.cursor_circle_id,fill=self.selected_color) + if self.wire_start_point: + color =self.hex_to_rgb(self.selected_color ) + encre = f"#{color[0]:02x}{color[1]:02x}{color[2]:02x}" + contour = f"#{color[0]//2:02x}{color[1]//2:02x}{color[2]//2:02x}" + wire_body_tag = f"{self.wire_id}_body" + wire_body_shadow_tag = f"{self.wire_id}_body_shadow" + self.canvas.itemconfig(wire_body_tag,fill=encre) + self.canvas.itemconfig(wire_body_shadow_tag,fill=contour) + def button_action(self, action_name): """ Defines the action to perform when a button is clicked.