├── docs
└── images
│ ├── Gates.png
│ ├── Examples.png
│ ├── Gates_Tab.png
│ ├── LatchTypes.png
│ ├── Latch_Tab.png
│ ├── Gates_scale.png
│ ├── InputConfig.png
│ ├── Latch_sizes.png
│ ├── SignalLines.png
│ ├── SignalTypes.png
│ ├── BooleanCommands.png
│ ├── Example_circuit.png
│ ├── Examples_white.png
│ ├── InputConfig_01.png
│ ├── SignalDirection.png
│ ├── subTabSignals.png
│ ├── Example_minterms.png
│ ├── Latch_controlGate.png
│ ├── subTabExpressions.png
│ ├── Latch_outputSuppress.png
│ ├── BooleanCommands_examples.png
│ ├── Latch_asynchronousInputs.png
│ ├── Signals_and_expressions_Tab.png
│ ├── Example_Synchonous_counter_2N.png
│ ├── Example_shift_register_4bits.png
│ ├── SignalLines.svg
│ ├── InputConfig_01.svg
│ ├── SignalDirection.svg
│ ├── Latch_outputSuppress.svg
│ ├── BooleanCommands_examples.svg
│ └── InputConfig.svg
├── 0.9x
├── CircuitSymbolsLatexPreamble.tex
├── logicGates.inx
└── logicGates.py
├── latest
├── logicGatesPreamble.tex
└── logicGates.inx
└── README.md
/docs/images/Gates.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Gates.png
--------------------------------------------------------------------------------
/docs/images/Examples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Examples.png
--------------------------------------------------------------------------------
/docs/images/Gates_Tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Gates_Tab.png
--------------------------------------------------------------------------------
/docs/images/LatchTypes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/LatchTypes.png
--------------------------------------------------------------------------------
/docs/images/Latch_Tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Latch_Tab.png
--------------------------------------------------------------------------------
/docs/images/Gates_scale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Gates_scale.png
--------------------------------------------------------------------------------
/docs/images/InputConfig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/InputConfig.png
--------------------------------------------------------------------------------
/docs/images/Latch_sizes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Latch_sizes.png
--------------------------------------------------------------------------------
/docs/images/SignalLines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/SignalLines.png
--------------------------------------------------------------------------------
/docs/images/SignalTypes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/SignalTypes.png
--------------------------------------------------------------------------------
/docs/images/BooleanCommands.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/BooleanCommands.png
--------------------------------------------------------------------------------
/docs/images/Example_circuit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Example_circuit.png
--------------------------------------------------------------------------------
/docs/images/Examples_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Examples_white.png
--------------------------------------------------------------------------------
/docs/images/InputConfig_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/InputConfig_01.png
--------------------------------------------------------------------------------
/docs/images/SignalDirection.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/SignalDirection.png
--------------------------------------------------------------------------------
/docs/images/subTabSignals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/subTabSignals.png
--------------------------------------------------------------------------------
/docs/images/Example_minterms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Example_minterms.png
--------------------------------------------------------------------------------
/docs/images/Latch_controlGate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Latch_controlGate.png
--------------------------------------------------------------------------------
/docs/images/subTabExpressions.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/subTabExpressions.png
--------------------------------------------------------------------------------
/docs/images/Latch_outputSuppress.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Latch_outputSuppress.png
--------------------------------------------------------------------------------
/docs/images/BooleanCommands_examples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/BooleanCommands_examples.png
--------------------------------------------------------------------------------
/docs/images/Latch_asynchronousInputs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Latch_asynchronousInputs.png
--------------------------------------------------------------------------------
/docs/images/Signals_and_expressions_Tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Signals_and_expressions_Tab.png
--------------------------------------------------------------------------------
/docs/images/Example_Synchonous_counter_2N.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Example_Synchonous_counter_2N.png
--------------------------------------------------------------------------------
/docs/images/Example_shift_register_4bits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fsmMLK/inkscapeLogicGates/HEAD/docs/images/Example_shift_register_4bits.png
--------------------------------------------------------------------------------
/0.9x/CircuitSymbolsLatexPreamble.tex:
--------------------------------------------------------------------------------
1 | \usepackage{amsmath,amsthm,amsbsy,amsfonts,amssymb}
2 | \usepackage[per=slash]{siunitx}
3 | \usepackage{steinmetz}
4 | \usepackage[utf8]{inputenc}
5 | %\usepackage[T1]{fontenc}
6 |
7 | \newcommand{\micro}{\ensuremath{\mu}}
8 | \newcommand{\phasorName}[1]{ \ensuremath{ \boldsymbol{\hat #1} } }
9 | \newcommand{\impedance}[1]{ \ensuremath{ \boldsymbol{#1} } }
10 | \newcommand{\complexPol}[2]{\ensuremath{#1\phase{#2}}}
11 | \newcommand{\complexPolDeg}[2]{\ensuremath{#1\phase{#2\degree}}}
12 |
13 | % new units
14 | \newunit{\Vef}{\volt_{ef}} % volt eficaz
15 | \newunit{\Vrms}{\volt_{rms}} % volt RMS
16 | \newunit{\Vpp}{\volt_{pp}} % volt peak-to-peak
17 |
18 | \newunit{\Aef}{\ampere_{ef}} % ampere eficaz
19 | \newunit{\Arms}{\ampere_{rms}} % ampere rms
20 | \newunit{\App}{\ampere_{pp}} % ampere peak-to-peak
21 |
22 | % logic Commands
23 | \newcommand{\NOT}[1]{\ensuremath{\overline{\mbox{\ensuremath{#1}}}}}
24 | \newcommand{\AND}{\ensuremath{\cdot}}
25 | \newcommand{\OR}{\ensuremath{+}}
26 | \newcommand{\XOR}{\ensuremath{\oplus}}
27 | \newcommand{\XNOR}{\ensuremath{\odot}}
--------------------------------------------------------------------------------
/latest/logicGatesPreamble.tex:
--------------------------------------------------------------------------------
1 | \usepackage{amsmath,amsthm,amsbsy,amsfonts,amssymb}
2 | \usepackage[per-mode=symbol]{siunitx}
3 | \usepackage{steinmetz}
4 | \usepackage[utf8]{inputenc}
5 | %\usepackage[T1]{fontenc}
6 |
7 | \newcommand{\micro}{\ensuremath{\mu}}
8 | \newcommand{\phasorName}[1]{ \ensuremath{ \boldsymbol{\hat #1} } }
9 | \newcommand{\impedance}[1]{ \ensuremath{ \boldsymbol{#1} } }
10 | \newcommand{\complexPol}[2]{\ensuremath{#1\phase{#2}}}
11 | \newcommand{\complexPolDeg}[2]{\ensuremath{#1\phase{#2\degree}}}
12 |
13 | % new units
14 | \DeclareSIUnit{\Vef}{\volt_{ef}} % volt eficaz
15 | \DeclareSIUnit{\Vrms}{\volt_{rms}} % volt RMS
16 | \DeclareSIUnit{\Vpp}{\volt_{pp}} % volt peak-to-peak
17 |
18 | \DeclareSIUnit{\Aef}{\ampere_{ef}} % ampere eficaz
19 | \DeclareSIUnit{\Arms}{\ampere_{rms}} % ampere rms
20 | \DeclareSIUnit{\App}{\ampere_{pp}} % ampere peak-to-peak
21 |
22 | % logic Commands
23 | \newcommand{\NOT}[1]{\ensuremath{\overline{\mbox{\ensuremath{#1}}}}}
24 | \newcommand{\AND}{\ensuremath{\cdot}}
25 | \newcommand{\OR}{\ensuremath{+}}
26 | \newcommand{\XOR}{\ensuremath{\oplus}}
27 | \newcommand{\XNOR}{\ensuremath{\odot}}
--------------------------------------------------------------------------------
/0.9x/logicGates.inx:
--------------------------------------------------------------------------------
1 |
2 |
3 | <_name>Logic Gates
4 | fsmMLK.logicGates
5 | logicGates.py
6 | inkscapeMadeEasy_Base.py
7 | inkscapeMadeEasy_Draw.py
8 | inkex.py
9 |
10 |
11 | Gate selection
12 | 1
13 | 0
14 | 0
15 | 0
16 | 0
17 | 0
18 | 0
19 |
20 | Input signal configuration (does not affect NOT gate)
21 | 2
22 | 1,1
23 | <_param name="instructions" type="description" xml:space="preserve">1: regular input
24 | 0: inverted input
25 | Ex: 0,1,1 (3 inputs)
26 | Top input is inverted, the others are regular
27 |
28 |
29 |
30 | <_option value="SRnor">SR postive (NOR)
31 | <_option value="SRnand">SR negative (NAND)
32 | <_option value="D">D
33 | <_option value="JK">JK
34 | <_option value="T">T
35 |
36 |
37 |
38 | <_option value="large">Large
39 | <_option value="medium">Medium
40 | <_option value="small">Small
41 |
42 |
43 | 0
44 | 0
45 |
46 |
47 | <_option value="none">None
48 | <_option value="level">Level (Latch)
49 | <_option value="edge">Edge (Flip-flop)
50 |
51 |
52 | <_option value="HIGH">high (or rising edge)
53 | <_option value="LOW">low (or falling edge)
54 |
55 |
56 | Asynchronous inputs
57 |
58 | <_option value="0">None
59 | <_option value="1">Active HIGH
60 | <_option value="-1">Active LOW
61 |
62 |
63 |
64 | <_option value="0">None
65 | <_option value="1">Active HIGH
66 | <_option value="-1">Active LOW
67 |
68 |
69 |
70 |
71 | Signals
72 |
73 | 0
74 |
75 | <_option value="custom">Custom
76 | <_option value="GND">GND
77 | <_option value="common">common
78 | <_option value="CLK">CLK
79 | <_option value="EN">EN
80 | <_option value="CLKi">NOT{CLK}
81 | <_option value="ENi">NOT{EN}
82 | <_option value="+vcc">+Vcc
83 | <_option value="-vcc">-Vcc
84 | <_option value="+5V">+5V
85 | <_option value="-5V">-5V
86 | <_option value="+15V">+15V
87 | <_option value="-15V">-15V
88 |
89 | A
90 |
91 | <_option value="0">North
92 | <_option value="90">West
93 | <_option value="-90">East
94 | <_option value="180">South
95 |
96 | 1
97 |
98 | Boolean expressions
99 |
100 | 0
101 | A \AND B
102 | <_param name="instructions" type="description" xml:space="preserve">
103 | Valid commands:
104 | \AND, \OR, \XOR, XNOR : no arguments needed
105 | \NOT{...} : requires one argument
106 |
107 |
108 |
109 |
110 |
111 | all
112 |
113 |
114 |
115 |
116 |
117 |
118 |
121 |
122 |
--------------------------------------------------------------------------------
/docs/images/SignalLines.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
155 |
--------------------------------------------------------------------------------
/docs/images/InputConfig_01.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
206 |
--------------------------------------------------------------------------------
/latest/logicGates.inx:
--------------------------------------------------------------------------------
1 |
2 |
3 | Logic Gates
4 | fsmMLK.logicGates
5 | logicGates.py
6 | inkscapeMadeEasy/inkscapeMadeEasy_Base.py
7 | inkscapeMadeEasy/inkscapeMadeEasy_Draw.py
8 |
9 |
10 |
11 |
12 |
13 | true
14 | false
15 |
16 |
17 |
18 | false
19 | false
20 |
21 |
22 |
23 | false
24 | false
25 |
26 |
27 |
28 | false
29 | false
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 2
38 | 1,1,0
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | false
57 | false
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | A
121 | true
122 |
123 |
124 |
125 |
126 | A \AND B
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | all
139 |
140 |
141 |
142 |
143 |
144 |
145 |
148 |
149 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # logicGates
2 |
3 | This extension will assist you creating latches, flip-flops and logic gates following the 'distinctive shape' of IEEE Std 91/91a-1991 standard in [Inkscape](https://inkscape.org/).
4 |
5 |
6 |
7 |
8 | **TIP:** If you want to create timing diagrams, please take a look at my newest project [wavedromScape](https://github.com/fsmMLK/wavedromScape)
9 |
10 |
11 | ## Main features
12 |
13 | The main features of this extension are
14 |
15 | - You can use up to six inputs for each gate (except NOT and BUFFER gates)
16 | - Each input can be set to be inverted (negated) individually
17 | - Latch and flip-flop generator, with customizable optional control gates and asynchronous Preset and Clear.
18 | - Signal labeling generator with a few pre-defined commonly used signals
19 | - Boolean expression editor, with optional LaTeX support and predefined logic operator functions.
20 |
21 | ## Current and older versions
22 |
23 | Compatibility table
24 |
25 | | Inkscape | logicGates | inkscapeMadeEasy | Receive updates?|
26 | |------------------|-----------------|------------------|-----------------|
27 | | 1.0 | 1.0 (latest) | 1.0 (latest) | YES |
28 | | 0.48, 0.91, 0.92 | 0.9x (obsolete) | 0.9x (obsolete) | NO |
29 |
30 |
31 | **Latest version:** The latest version of **logicGates** is **1.0**. This version is compatible with Inkscape 1.0 and up only. It is **incompatible** with older Inkscape versions!
32 |
33 | **Older versions:** If you have an older version of Inkscape, please use the files under the folder **0.9x** on Github.
34 |
35 | **Important: Only the latest version will receive updates, new features, and bug fixes! The usage section in this documentation describes the latest version. In older versions, the disposition of the elements in the plugin's screen might be different. Some features might not be present or have different behavior.**
36 |
37 | # Installation and requirements
38 |
39 | Installation procedures for latest and older versions are described below.
40 |
41 | ## Requirements (all versions)
42 |
43 | - You will need [inkscapeMadeEasy](https://github.com/fsmMLK/inkscapeMadeEasy) plugin installed. Check the compatibility table above to know the version you need.
44 |
45 | ## Installation procedure (v1.0 only)
46 |
47 | **logicGates** was developed using Inkscape 1.0 in Linux (Kubuntu 18.04). It should work in different OSs too as long as all requirements are met.
48 |
49 | 1. Install [inkscapeMadeEasy](https://github.com/fsmMLK/inkscapeMadeEasy), **version 1.0** (latest). Follow the instructions in the manual page. **Note:** LaTeX text is used in **logicGates** if the support is activated (nicer results), otherwise regular text elements will be used.
50 |
51 | 2. **logicGates** installation
52 |
53 | 1. Go to Inkscape's extension directory with a file browser. Your inkscape extension directory can be accessed by opening Inkscape and selecting ``Edit > Preferences > System``. Look for the item **User Extensions** field. There is a button on the right of the field that will open a file explorer window in that specific folder.
54 |
55 | 2. Create a subfolder in the extension directory with the name ``logicGates``. **Important:** Be careful with upper and lower case letters. You must write as presented above.
56 |
57 | 3. Download **logicGates** files and place them inside the directory you just created.
58 |
59 | You don't have to copy all files from Github. The files you will need are `logicGates.py`, `logicGates.inx`, and `logicGatesPreamble.tex`. **You can find these files inside the ``latest`` folder**. In the end you must have the following files and directories in your Inkscape extension directory.
60 |
61 | **LaTeX users:** the file `logicGatesPreamble.tex` contains the macros defined in this plugin. You can add your own macros to this file. You can also add macros to ``inkscapeMadeEasy/basicLatexPackages.tex``. In this case the same macros will be accessible by all plugins that employ inkscapeMadeEasy.
62 |
63 | ```
64 | inkscape
65 | ┣━━ extensions
66 | ┋ ┣━━ inkscapeMadeEasy <-- inkscapeMadeEasy folder
67 | ┃ ┣━━ inkscapeMadeEasy_Base.py
68 | ┃ ┣━━ inkscapeMadeEasy_Draw.py
69 | ┃ ┣━━ inkscapeMadeEasy_Plot.py
70 | ┃ ┗━━ basicLatexPackages.tex
71 | ┃
72 | ┣━━ textext <-- texText folder (if you installed textText)
73 | ┃ ┋
74 | ┃
75 | ┣━━ logicGates <-- logicGates folder
76 | ┋ ┣━━ logicGatesPreamble.tex
77 | ┣━━ logicGates.py
78 | ┗━━ logicGates.inx
79 |
80 | NOTE: You might have other sub folders inside the extensions directory. They don't interfere with the plugin.
81 | ```
82 |
83 | ## Installation procedure (v0.9x only)
84 |
85 | **logicGates** was developed using Inkscape 0.48 and 0.91 in Linux (Kubuntu 18.04). It should work in different OSs too as long as all requirements are met.
86 |
87 | 1. Install [inkscapeMadeEasy](https://github.com/fsmMLK/inkscapeMadeEasy), **version 1.0** (latest). Follow the instructions in the manual page. **Note:** LaTeX text is used in **logicGates** if the support is activated (nicer results), otherwise regular text elements will be used.
88 |
89 | 2. **logicGates** installation
90 |
91 | 1. Go to Inkscape's extension directory with a file browser.
92 |
93 | 2. Download **logicGates** files and place them inside the directory you just created.
94 |
95 | You don't have to copy all files from Github. The files you will need are `logicGates.py`, `logicGates.inx`, and `CircuitSymbolsLatexPreamble.tex`. **You can find these files inside the ``0.9x`` folder**. In the end you must have the following files and directories in your Inkscape extension directory.
96 |
97 | ```
98 | inkscape
99 | ┣━━ extensions
100 | ┋ ┣━━ inkscapeMadeEasy_Base.py
101 | ┣━━ inkscapeMadeEasy_Draw.py
102 | ┣━━ inkscapeMadeEasy_Plot.py
103 | ┃
104 | ┣━━ textextLib
105 | ┃ ┣━━ __init__.py
106 | ┃ ┣━━ basicLatexPackages.tex
107 | ┃ ┣━━ CircuitSymbolsLatexPreamble.tex <-- from repository folder 0.9x!
108 | ┃ ┣━━ textext.inx
109 | ┃ ┗━━ textext.py
110 | ┃
111 | ┣━━ logicGates.py <-- from repository folder 0.9x!
112 | ┣━━ logicGates.inx <-- from repository folder 0.9x!
113 | ┋
114 | ```
115 |
116 | # Usage
117 |
118 | The extension can be found under `extensions > fsmMLK > Circuit symbols` menu.
119 |
120 | This extension is presented in three tabs. The **Logic gates** and **Latch and F.F.** tabs allow you to create logic gates and latches/flip-flops respectively, while **Signals and Expressions** create boolean expressions and logic signal labels.
121 |
122 | ## Logic Gates tab
123 |
124 |
125 |
126 | **Gate checkboxes:** You can select the gates. More than one gate can be created at once, however they will share the same input configuration (see below).
127 |
128 |
129 |
130 | **Symbol size:** You can select between 2 sizes, presented below.
131 |
132 |
133 |
134 | **Number of inputs:** Number of inputs of the gate. This parameter does not affect NOT and BUFFER gates. You can choose any number between 2 and 6.
135 |
136 | **Input config:** You can select whether the inputs must be inverted. This field accepts a sequence of values `1` or `0`. You can create a sequence of 1s and 0s without any spaces, with spaces or commas.
137 |
138 | - 1 stands for regular input
139 | - 0 stands for inverted input
140 |
141 |
142 |
143 | The first element of the sequence is associated to the input at the top. If this string has less elements than the number of inputs, the remaining inputs will be set to regular inputs.
144 |
145 | Examples:
146 |
147 |
148 |
149 |
150 | ## Latch and F.F. tab
151 |
152 |
153 |
154 | **Type:** You can select the type of Latch/Flip-flop.
155 |
156 |
157 |
158 | **Symbol size:** You can select between 3 sizes, presented below.
159 |
160 |
161 |
162 | **Suppress Q and not{Q} outputs:** You can choose any output (Q and NOT{Q}) to be suppressed.
163 |
164 |
165 |
166 | **Control Gate type:** You can optionally include a control gate, by level (latch) or edge (flip-flop). Se image below.
167 |
168 | **Control Gate Activation Logic:** Here you can select the type of activation logic of the control gate. Se image below.
169 |
170 | - active on HIGH (latch) or rising edge ⮥ (flip-flop)
171 | - active on LOW (latch) or falling edge ⮧ (flip-flop)
172 |
173 |
174 |
175 | **Asynchronous Preset:** Add asynchronous Preset signal. You can select between active HIGH or LOW.
176 |
177 | **Asynchronous Clear:** Add asynchronous Clear signal. You can select between active HIGH or LOW.
178 |
179 |
180 |
181 | ## Signals and Expressions tab
182 |
183 |
184 |
185 | This tab is presented in two subtabs, *Signals* and *Expressions*. The first create signal nodes to add to your logic circuit. The second creates a text element with a boolean expression. The 'Apply' button will execute the action associated to the subtab that is on the top
186 |
187 | #### Signals subtab
188 |
189 |
190 |
191 | **Signal type:** Allows the selection of one type of signal. You can select a few commonly used signals or select ``Custom`` to customize its label. (see below)
192 |
193 |
194 |
195 | **Direction:** Direction of the signal line. This option is used only if ``Draw signal line`` option is enabled.
196 |
197 |
198 |
199 | **Custom label:** Label of the signal. This option is used only if ``Custom`` or ``Digital`` is selected in `Signal type`. If LaTeX support is enabled the text will be inserted in a mathematical environment $...$
200 |
201 |
202 | **Draw signal line:** signal line toggle.
203 |
204 |
205 |
206 | #### Expressions subtab
207 |
208 |
209 |
210 | **Boolean expression:** Boolean expression area. Predefined commands were created for the basic boolean operators:
211 |
212 |
213 |
214 | > Note: The command ``\NOT`` has one argument and **MUST** be enclosed between ``{ }``
215 |
216 | Examples:
217 |
218 |
219 |
220 |
221 | # Observations
222 |
223 | - The objects will be created in the center of your screen.
224 |
225 | # Examples
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
--------------------------------------------------------------------------------
/docs/images/SignalDirection.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
294 |
--------------------------------------------------------------------------------
/docs/images/Latch_outputSuppress.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
382 |
--------------------------------------------------------------------------------
/docs/images/BooleanCommands_examples.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
300 |
--------------------------------------------------------------------------------
/docs/images/InputConfig.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
684 |
--------------------------------------------------------------------------------
/0.9x/logicGates.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import math
4 | import os
5 |
6 | import inkscapeMadeEasy_Base as inkBase
7 | import inkscapeMadeEasy_Draw as inkDraw
8 |
9 |
10 | # ---------------------------------------------
11 | # noinspection PyUnboundLocalVariable,PyDefaultArgument,PyAttributeOutsideInit
12 | class LogicGates(inkBase.inkscapeMadeEasy):
13 | def __init__(self):
14 | inkBase.inkscapeMadeEasy.__init__(self)
15 |
16 | self.OptionParser.add_option("--tab", action="store", type="string", dest="tab", default="object")
17 |
18 | self.OptionParser.add_option("--ANDgate", action="store", type="inkbool", dest="ANDgate", default=False)
19 | self.OptionParser.add_option("--ORgate", action="store", type="inkbool", dest="ORgate", default=False)
20 | self.OptionParser.add_option("--XORgate", action="store", type="inkbool", dest="XORgate", default=False)
21 | self.OptionParser.add_option("--NOTgate", action="store", type="inkbool", dest="NOTgate", default=False)
22 | self.OptionParser.add_option("--NANDgate", action="store", type="inkbool", dest="NANDgate", default=False)
23 | self.OptionParser.add_option("--NORgate", action="store", type="inkbool", dest="NORgate", default=False)
24 | self.OptionParser.add_option("--XNORgate", action="store", type="inkbool", dest="XNORgate", default=False)
25 |
26 | self.OptionParser.add_option("--nInput", action="store", type="int", dest="nInput", default=2)
27 | self.OptionParser.add_option("--InputTypes", action="store", type="string", dest="InputTypes", default='11')
28 |
29 | self.OptionParser.add_option("--latchType", action="store", type="string", dest="latchType", default='none')
30 | self.OptionParser.add_option("--latchSize", action="store", type="string", dest="latchSize", default='large')
31 | self.OptionParser.add_option("--latchSuppressq", action="store", type="inkbool", dest="latchSuppressq", default=False)
32 | self.OptionParser.add_option("--latchSuppressNOTq", action="store", type="inkbool", dest="latchSuppressNOTq", default=False)
33 |
34 | self.OptionParser.add_option("--latchGate", action="store", type="string", dest="latchGate", default='none')
35 | self.OptionParser.add_option("--latchGateLogic", action="store", type="string", dest="latchGateLogic", default='HIGH')
36 | self.OptionParser.add_option("--latchPreset", action="store", type="string", dest="latchPreset", default='0')
37 | self.OptionParser.add_option("--latchClear", action="store", type="string", dest="latchClear", default='0')
38 |
39 | self.OptionParser.add_option("--flagSignal", action="store", type="inkbool", dest="flagSignal", default=False)
40 | self.OptionParser.add_option("--signal", action="store", type="string", dest="signal", default='GND')
41 | self.OptionParser.add_option("--signalVal", action="store", type="string", dest="signalVal", default='E')
42 | self.OptionParser.add_option("--signalRot", action="store", type="float", dest="signalRot", default=0)
43 | self.OptionParser.add_option("--signalDrawLine", action="store", type="inkbool", dest="signalDrawLine", default=True)
44 |
45 | self.OptionParser.add_option("--flagExpression", action="store", type="inkbool", dest="flagExpression", default=False)
46 | self.OptionParser.add_option("--boolExpression", action="store", type="string", dest="boolExpression", default='')
47 |
48 | self.lineStyle = inkDraw.lineStyle.setSimpleBlack()
49 | self.lineStyleBody = inkDraw.lineStyle.setSimpleBlack(1.8)
50 | self.totalHeight = 30 # total height of the logic gate
51 | self.totalWidth = 50 # total width of the logic gate, including in/output
52 | self.lengthTerm = 10 # length of the terminals
53 |
54 | def effect(self):
55 |
56 | so = self.options
57 |
58 | # sets the position to the viewport center, round to next 10.
59 | position = [self.view_center[0], self.view_center[1]]
60 | position[0] = int(math.ceil(position[0] / 10.0)) * 10
61 | position[1] = int(math.ceil(position[1] / 10.0)) * 10
62 |
63 | # root_layer = self.current_layer
64 | root_layer = self.document.getroot()
65 | # root_layer = self.getcurrentLayer()
66 |
67 | so.tab = so.tab.replace('"', '') # removes de exceding double quotes from the string
68 |
69 | # latex related preamble
70 | self.preambleFile = os.getcwd() + '/textextLib/CircuitSymbolsLatexPreamble.tex'
71 |
72 | self.fontSize = 6.0
73 | self.fontSizeSmall = self.fontSize * 0.7
74 | self.textOffset = self.fontSize / 1.5 # offset between symbol and text
75 | self.textOffsetSmall = self.fontSizeSmall / 2 # offset between symbol and text
76 | self.textStyle = inkDraw.textStyle.setSimpleBlack(self.fontSize, justification='center')
77 | self.textStyleSmall = inkDraw.textStyle.setSimpleBlack(self.fontSizeSmall, justification='center')
78 |
79 | # --------------------------
80 | # Gates
81 | # ---------------------------
82 |
83 | if so.tab == 'Gates':
84 |
85 | N_input = so.nInput
86 | inputVector = [True] * N_input
87 |
88 | # vector with type of inputs (regular or inverted)
89 | so.InputTypes = so.InputTypes.replace(' ', '').replace(',', '')
90 | for i in range(min(N_input, len(so.InputTypes))):
91 | if so.InputTypes[i] == '0':
92 | inputVector[i] = False
93 |
94 | if so.ANDgate:
95 | self.createAND(root_layer, inputVector, True, position)
96 | if so.NANDgate:
97 | self.createAND(root_layer, inputVector, False, position)
98 |
99 | if so.ORgate:
100 | self.createOR(root_layer, inputVector, True, position)
101 | if so.NORgate:
102 | self.createOR(root_layer, inputVector, False, position)
103 |
104 | if so.XORgate:
105 | self.createXOR(root_layer, inputVector, True, position)
106 | if so.XNORgate:
107 | self.createXOR(root_layer, inputVector, False, position)
108 |
109 | if so.NOTgate:
110 | self.createNOT(root_layer, position)
111 |
112 | # --------------------------
113 | # Latches and Flip-flops
114 | # ---------------------------
115 |
116 | if so.tab == 'Latches':
117 | if so.latchGateLogic == 'HIGH':
118 | logic = True
119 | else:
120 | logic = False
121 | self.createLatch(root_layer, position, type=so.latchType, controlGate=so.latchGate, controlGateLogic=logic,
122 | asynPreset=int(so.latchPreset), asynClear=int(so.latchClear), size=so.latchSize, suppressq=so.latchSuppressq,
123 | suppressNOTq=so.latchSuppressNOTq)
124 |
125 | # --------------------------
126 | # SignalsAndExpressions
127 | # ---------------------------
128 | if so.tab == 'SignalsAndExpressions':
129 |
130 | if so.flagExpression:
131 | if not inkDraw.useLatex:
132 | value = so.boolExpression.replace(' ', '').replace(r'\AND', '.').replace(r'\OR', '+').replace('\XOR', u'\u2295')
133 | value = value.replace('\XNOR', u'\u2299').replace(r'\NOT', u'\u00AC').replace('{', '(').replace('}', ')') # removes LaTeX stuff
134 | else:
135 | value = '$' + so.boolExpression + '$'
136 |
137 | inkDraw.text.latex(self, root_layer, value, [position[0], position[1]], self.fontSize, refPoint='cc', preambleFile=self.preambleFile)
138 |
139 | if so.flagSignal:
140 |
141 | if so.signal == "GND":
142 | self.drawGND(root_layer, position, angleDeg=so.signalRot)
143 | return
144 |
145 | if so.signal == "common":
146 | self.drawCommon(root_layer, position, angleDeg=so.signalRot)
147 | return
148 |
149 | if so.signal == "custom":
150 | text = so.signalVal
151 |
152 | if so.signal == "+vcc":
153 | text = '+V_{cc}'
154 |
155 | if so.signal == "-vcc":
156 | text = '-V_{cc}'
157 |
158 | if so.signal == "+5V":
159 | text = r'+5\volt'
160 |
161 | if so.signal == "-5V":
162 | text = r'-5\volt'
163 |
164 | if so.signal == "+15V":
165 | text = r'+15\volt'
166 |
167 | if so.signal == "-15V":
168 | text = r'-15\volt'
169 |
170 | if so.signal == "EN":
171 | text = r'EN'
172 |
173 | if so.signal == "CLK":
174 | text = r'CLK'
175 |
176 | if so.signal == "ENi":
177 | text = r'\NOT{EN}'
178 |
179 | if so.signal == "CLKi":
180 | text = r'\NOT{CLK}'
181 |
182 | self.drawV(root_layer, position, angleDeg=so.signalRot, nodalVal=text, drawLine=so.signalDrawLine)
183 | return
184 |
185 | def createSignal(self, flagTrue, parent, position=[0, 0], direction='E', extraLength=0.0, label='input', name=None, fontSizeFactor=1.0,
186 | isClock=False):
187 | """ Creates signals to logic Gates (inputs or outputs)
188 |
189 | flagTrue: TRUE: regular input. FALSE: NOT input
190 | parent: parent object
191 | position: position [x,y]
192 | direction: orientation of the signal. Values possible: 'N', 'S', 'W', 'E'
193 | extraLength: add extra lenght to the input line. default: 0.0
194 | label: label of the object (it can be repeated)
195 | name: Name of the signal. In ``None`` (default) no name is added
196 | fontSizeFactor: font scale factor. Default: 1.0
197 | isClock: input is clock type. Default: False
198 | """
199 |
200 | group = self.createGroup(parent, label)
201 | elem = self.createGroup(group, label)
202 |
203 | if flagTrue:
204 | inkDraw.line.relCoords(elem, [[-self.lengthTerm - extraLength, 0]], position, label, self.lineStyle)
205 |
206 | else:
207 | inkDraw.line.absCoords(elem, [[-5.5, 0], [-self.lengthTerm - extraLength, 0]], position, label, self.lineStyle)
208 | inkDraw.circle.centerRadius(elem, [-3, 0], 2, position, label, inkDraw.lineStyle.setSimpleBlack(1.2))
209 |
210 | if isClock:
211 | inkDraw.line.absCoords(elem, [[0, -4], [4, 0], [0, 4]], position, label, inkDraw.lineStyle.setSimpleBlack(0.9))
212 |
213 | if isClock:
214 | offsetText = self.textOffset * fontSizeFactor + 4
215 | else:
216 | offsetText = self.textOffset * fontSizeFactor
217 |
218 | if direction == 'N':
219 | self.rotateElement(elem, position, -90) # y direction is inverted
220 | posText = [position[0], position[1] + offsetText]
221 | justif = 'tc'
222 | if direction == 'S':
223 | self.rotateElement(elem, position, 90) # y direction is inverted
224 | posText = [position[0], position[1] - offsetText]
225 | justif = 'bc'
226 | if direction == 'E':
227 | self.rotateElement(elem, position, 180) # y direction is inverted
228 | posText = [position[0] - offsetText, position[1]]
229 | justif = 'cr'
230 | if direction == 'W':
231 | posText = [position[0] + offsetText, position[1]]
232 | justif = 'cl'
233 |
234 | if name:
235 | inkDraw.text.latex(self, group, name, position=posText, fontSize=self.fontSize * fontSizeFactor, refPoint=justif,
236 | preambleFile=self.preambleFile)
237 |
238 | # ---------------------------------------------
239 | def createInput(self, flagTrue, parent, position=[0, 0], extraLength=0.0, label='input', name=None, fontSizeFactor=1.0):
240 | """ Creates input to logic Gates
241 |
242 | flagTrue: TRUE: regular input. FALSE: NOT input
243 | parent: parent object
244 | position: position [x,y]
245 | extraLength: add extra lenght to the input line. default: 0.0
246 | label: label of the object (it can be repeated)
247 | name: Name of the signal. In ``None`` (default) no name is added
248 | fontSizeFactor: font scale factor. Default: 1.0
249 | """
250 | direction = 'W'
251 | self.createSignal(flagTrue, parent, position, direction, extraLength, label, name, fontSizeFactor)
252 |
253 | # ---------------------------------------------
254 | def createOutput(self, flagTrue, parent, position=[0, 0], extraLength=0.0, label='output', name=None, fontSizeFactor=1.0):
255 | """ Creates output to logic Gates
256 |
257 | flagTrue: TRUE: regular input. FALSE: NOT input
258 | parent: parent object
259 | position: position [x,y]
260 | extraLength: add extra lenght to the input line. default: 0.0
261 | label: label of the object (it can be repeated)
262 | name: Name of the signal. In ``None`` (default) no name is added
263 | fontSizeFactor: font scale factor. Default: 1.0
264 | """
265 | direction = 'E'
266 | if flagTrue:
267 | self.createSignal(flagTrue, parent, [position[0], position[1]], direction, extraLength, label, name, fontSizeFactor)
268 | else:
269 | self.createSignal(flagTrue, parent, [position[0] - 0.5, position[1]], direction, extraLength + 0.5, label, name, fontSizeFactor)
270 |
271 | # ---------------------------------------------
272 | def drawANDBody(self, parent, position=[0, 0], label='BodyAND'):
273 | """ Creates body of AND logic Gate
274 |
275 | parent: parent object
276 | position: position [x,y]
277 | label: label of the object (it can be repeated)
278 | """
279 |
280 | h = self.totalHeight / 2.0 # half height
281 | R = h # radius
282 | widthBase = self.totalWidth - 2 * self.lengthTerm - R # length of the straight part of AND body
283 |
284 | group = self.createGroup(parent, label)
285 |
286 | inkDraw.line.absCoords(group, [[0, h], [-widthBase, h], [-widthBase, -h], [0, -h]], position, label, self.lineStyleBody)
287 | inkDraw.arc.centerAngStartAngEnd(group, [0, 0], R, 90, -90, position, label, self.lineStyleBody, largeArc=True)
288 |
289 | # ---------------------------------------------
290 | def drawORBody(self, parent, position=[0, 0], label='BodyOR'):
291 | """ Creates body of OR logic Gate
292 |
293 | parent: parent object
294 | position: position [x,y]
295 | label: label of the object (it can be repeated)
296 | """
297 | h = self.totalHeight / 2.0 # half height
298 | x = h + 5 # x distance of the tip to the center
299 | R = math.sqrt(((x * x - h * h) / (2 * h)) ** 2 + x * x)
300 | widthBase = self.totalWidth - 2 * self.lengthTerm - 15 # length of the straight part of AND body
301 |
302 | group = self.createGroup(parent, label)
303 |
304 | inkDraw.line.absCoords(group, [[0, h], [-widthBase, h]], position, label, self.lineStyleBody)
305 | inkDraw.line.absCoords(group, [[0, -h], [-widthBase, -h]], position, label, self.lineStyleBody)
306 | inkDraw.arc.startEndRadius(group, [x, 0], [0, h], R, position, label, self.lineStyleBody, flagRightOf=False, flagOpen=True)
307 | inkDraw.arc.startEndRadius(group, [0, -h], [x, 0], R, position, label, self.lineStyleBody, flagRightOf=False, flagOpen=True)
308 | inkDraw.arc.startEndRadius(group, [-widthBase, -h], [-widthBase, h], self.totalHeight, position, label, self.lineStyleBody, flagRightOf=False,
309 | flagOpen=True)
310 |
311 | # ---------------------------------------------
312 |
313 | def drawXORBody(self, parent, position=[0, 0], label='BodyXOR'):
314 | """ Creates body of XOR logic Gate
315 |
316 | parent: parent object
317 | position: position [x,y]
318 | label: label of the object (it can be repeated)
319 | """
320 | h = self.totalHeight / 2.0 # half height
321 | x = h + 5 # x distance of the tip to the center
322 | R = math.sqrt(((x * x - h * h) / (2 * h)) ** 2 + x * x)
323 | space = 4 # space between parallel arcs
324 | widthBase = self.totalWidth - 2 * self.lengthTerm - 15 - space # length of the straight part of AND body
325 |
326 | group = self.createGroup(parent, label)
327 |
328 | inkDraw.line.absCoords(group, [[0, h], [-widthBase, h]], position, label, self.lineStyleBody)
329 | inkDraw.line.absCoords(group, [[0, -h], [-widthBase, -h]], position, label, self.lineStyleBody)
330 | inkDraw.arc.startEndRadius(group, [x, 0], [0, h], R, position, label, self.lineStyleBody, flagRightOf=False, flagOpen=True)
331 | inkDraw.arc.startEndRadius(group, [0, -h], [x, 0], R, position, label, self.lineStyleBody, flagRightOf=False, flagOpen=True)
332 | inkDraw.arc.startEndRadius(group, [-widthBase, -h], [-widthBase, h], self.totalHeight, position, label, self.lineStyleBody, flagRightOf=False,
333 | flagOpen=True)
334 | inkDraw.arc.startEndRadius(group, [-widthBase - space, -h], [-widthBase - space, h], self.totalHeight, position, label, self.lineStyleBody,
335 | flagRightOf=False, flagOpen=True)
336 |
337 | # ---------------------------------------------
338 | def drawInputOR(self, parent, vectorInput=[True, True], position=[0, 0], label='InputORGate'):
339 | """ Creates inputs to OR/NOR/XOR/XNOR logic Gates
340 |
341 | parent: parent object
342 | vectorInput: vector with booleans. Default [True,True]
343 | It's length is the number of inputs of the gate.
344 | For each input (top to bottom) True: regular input False: Negated input.
345 | position: position [x,y]
346 | label: label of the object (it can be repeated)
347 | """
348 |
349 | group = self.createGroup(parent, label)
350 |
351 | N_input = len(vectorInput)
352 | spaceBetweenInputs = 20.0 / (N_input - 1)
353 | r = self.totalHeight # radius
354 | H = self.totalHeight / 2.0 # total height
355 | h_max = 10 # maximum height of inputs
356 |
357 | for i in range(0, N_input):
358 | h = -(h_max - i * spaceBetweenInputs) # bottom to up because inkscape is upside down =(
359 | x = math.sqrt(r ** 2 - h ** 2)
360 | L0 = math.sqrt(r ** 2 - H ** 2)
361 | L = x - L0
362 |
363 | self.createInput(vectorInput[i], group, [L + position[0], h + position[1]], L - 2.5,
364 | 'input' + str(i)) # 2.5 for reducing a little the lengh so that AND and OR gates have the same width
365 |
366 | # ---------------------------------------------
367 | def drawInputAND(self, parent, vectorInput=[True, True], position=[0, 0], label='InputANDGate'):
368 | """ Creates inputs to AND,NAND logic Gates
369 |
370 | parent: parent object
371 | vectorInput: vector with booleans. Default [True,True]
372 | It's length is the number of inputs of the gate.
373 | For each input (top to bottom) True: regular input False: Negated input.
374 | position: position [x,y]
375 | label: label of the object (it can be repeated)
376 | """
377 |
378 | group = self.createGroup(parent, label)
379 |
380 | N_input = len(vectorInput)
381 | spaceBetweenInputs = 20.0 / (N_input - 1)
382 | h_max = 10 # maximum height of inputs
383 |
384 | for i in range(0, N_input):
385 | h = -(h_max - i * spaceBetweenInputs)
386 | self.createInput(vectorInput[i], group, [position[0], h + position[1]], 0, 'input' + str(i))
387 |
388 | # ---------------------------------------------
389 | def createAND(self, parent, vectorInput=[True, True], output=True, position=[0, 0], label='BodyAND'):
390 | """ Creates AND/NAND logic Gate
391 |
392 | parent: parent object
393 | vectorInput: vector with booleans. Default [True,True]
394 | It's length is the number of inputs of the gate.
395 | For each input (top to bottom) True: regular input False: Negated input.
396 | output: selects AND or NAND gate (Default True)
397 | True: AND
398 | False: NAND
399 | position: position [x,y]
400 | label: label of the object (it can be repeated)
401 | """
402 | h = self.totalHeight / 2.0 # half height
403 | R = h # radius
404 | widthBase = self.totalWidth - 2 * self.lengthTerm - R # length of the straight part of AND body
405 |
406 | group = self.createGroup(parent, label)
407 | x_output = R # x coordinate of the output
408 |
409 | self.drawANDBody(group, position)
410 | self.drawInputAND(group, vectorInput, [-widthBase + position[0], position[1]])
411 | self.createOutput(output, group, [x_output + position[0], position[1]])
412 |
413 | # ---------------------------------------------
414 | def createOR(self, parent, vectorInput=[True, True], output=True, position=[0, 0], label='ORGate'):
415 | """ Creates OR/NOR logic Gate
416 |
417 | parent: parent object
418 | vectorInput: vector with booleans. Default [True,True]
419 | It's length is the number of inputs of the gate.
420 | For each input (top to bottom) True: regular input False: Negated input.
421 | output: selects OR or NOR gate (Default True)
422 | True: OR
423 | False: NOR
424 | position: position [x,y]
425 | label: label of the object (it can be repeated)
426 | """
427 |
428 | group = self.createGroup(parent, label)
429 | x_output = self.totalHeight / 2.0 + 5 # x coordinate of the output
430 |
431 | self.drawORBody(group, position)
432 | self.drawInputOR(group, vectorInput, [position[0] - 15, position[1]])
433 | self.createOutput(output, group, [x_output + position[0], position[1]], -2.5) # 2.5 for reducing a little the lengh so that AND and
434 |
435 | # ---------------------------------------------
436 | def createXOR(self, parent, vectorInput=[True, True], output=True, position=[0, 0], label='XORGate'):
437 | """ Creates XOR/XNOR logic Gate
438 |
439 | parent: parent object
440 | vectorInput: vector with booleans. Default [True,True]
441 | It's length is the number of inputs of the gate.
442 | For each input (top to bottom) True: regular input False: Negated input.
443 | output: selects OR or NOR gate (Default True)
444 | True: XOR
445 | False: XNOR
446 | position: position [x,y]
447 | label: label of the object (it can be repeated)
448 | """
449 |
450 | group = self.createGroup(parent, label)
451 | x_output = self.totalHeight / 2.0 + 5 # x coordinate of the output
452 |
453 | self.drawXORBody(group, position)
454 | self.drawInputOR(group, vectorInput, [position[0] - 15, position[1]])
455 | self.createOutput(output, group, [x_output + position[0], position[1]], -2.5) # 2.5 for reducing a little the lengh so that AND and
456 |
457 | # ---------------------------------------------
458 |
459 | def createNOT(self, parent, position=[0, 0], label='NOTGate'):
460 | """ Creates NOT logic Gate
461 |
462 | parent: parent object
463 | vectorInput: vector with booleans. Default [True,True]
464 | It's length is the number of inputs of the gate.
465 | For each input (top to bottom) True: regular input False: Negated input.
466 | position: position [x,y]
467 | label: label of the object (it can be repeated)
468 | """
469 |
470 | triangleSide = 20
471 | triangle_height = triangleSide * math.sqrt(3) / 2
472 |
473 | group = self.createGroup(parent, label)
474 | inkDraw.line.absCoords(group, [[0, triangleSide / 2], [triangle_height, 0], [0, -triangleSide / 2], [0, triangleSide / 2]], position, 'not1',
475 | self.lineStyleBody, True)
476 |
477 | self.createInput([True], group, position)
478 | self.createOutput(False, group, [triangle_height + 0.5 + position[0], 0 + position[1]], 30 - triangle_height - 10 - 0.5)
479 |
480 | # ---------------------------------------------
481 |
482 | def drawV(self, parent, position=[0, 0], label='GND', angleDeg=0, nodalVal='V_{cc}', drawLine=True):
483 | """ draws a Voltage node
484 |
485 | parent: parent object
486 | position: position [x,y]
487 | label: label of the object (it can be repeated)
488 | angleDeg: rotation angle in degrees counter-clockwise (default 0)
489 | nodalVal: name of the node (default: 'V_{cc}')
490 | drawLine: draws line for connection (default: True)
491 | """
492 | linestyleBlackFill = inkDraw.lineStyle.set(lineWidth=0.7, fillColor=inkDraw.color.defined('black'))
493 | group = self.createGroup(parent, label)
494 | elem = self.createGroup(group, label)
495 |
496 | inkDraw.circle.centerRadius(elem, position, 1.0, offset=[0, 0], lineStyle=linestyleBlackFill)
497 | if drawLine:
498 | inkDraw.line.relCoords(elem, [[0, 10]], position)
499 |
500 | # text
501 | if abs(angleDeg) <= 90:
502 | justif = 'bc'
503 | pos_text = [position[0], position[1] - self.textOffset]
504 | else:
505 | justif = 'tc'
506 | pos_text = [position[0], position[1] + self.textOffset]
507 |
508 | if not inkDraw.useLatex:
509 | value = nodalVal.replace('_', '').replace(r'\NOT', u'\u00AC').replace('{', '').replace('}', '').replace(r'\volt',
510 | 'V') # removes LaTeX stuff
511 | else:
512 | value = '$' + nodalVal + '$'
513 | temp = inkDraw.text.latex(self, group, value, pos_text, fontSize=self.fontSize, refPoint=justif, preambleFile=self.preambleFile)
514 |
515 | self.rotateElement(temp, position, -angleDeg)
516 |
517 | if angleDeg != 0:
518 | self.rotateElement(group, position, angleDeg)
519 |
520 | return group
521 |
522 | # ---------------------------------------------
523 | def drawGND(self, parent, position=[0, 0], label='GND', angleDeg=0):
524 | """ draws a GND
525 |
526 | parent: parent object
527 | position: position [x,y]
528 | label: label of the object (it can be repeated)
529 | angleDeg: rotation angle in degrees counter-clockwise (default 0)
530 | """
531 |
532 | group = self.createGroup(parent, label)
533 | elem = self.createGroup(group, label)
534 |
535 | inkDraw.line.relCoords(elem, [[0, 10]], position)
536 | inkDraw.line.relCoords(elem, [[-14, 0]], [position[0] + 7, position[1] + 10])
537 | inkDraw.line.relCoords(elem, [[-7, 0]], [position[0] + 3.5, position[1] + 12])
538 | inkDraw.line.relCoords(elem, [[-2, 0]], [position[0] + 1, position[1] + 14])
539 |
540 | if angleDeg != 0:
541 | self.rotateElement(group, position, angleDeg)
542 |
543 | return group
544 |
545 | # ---------------------------------------------
546 | def drawCommon(self, parent, position=[0, 0], label='Common', angleDeg=0):
547 | """ draws a GND
548 |
549 | parent: parent object
550 | position: position [x,y]
551 | label: label of the object (it can be repeated)
552 | angleDeg: rotation angle in degrees counter-clockwise (default 0)
553 | """
554 |
555 | group = self.createGroup(parent, label)
556 | elem = self.createGroup(group, label)
557 |
558 | inkDraw.line.relCoords(elem, [[0, 10]], position)
559 | inkDraw.line.relCoords(elem, [[-10, 0], [5, 5], [5, -5]], [position[0] + 5, position[1] + 10])
560 |
561 | if angleDeg != 0:
562 | self.rotateElement(group, position, angleDeg)
563 |
564 | return group
565 |
566 | # ---------------------------------------------
567 | def createLatch(self, parent, position=[0, 0], label='Latch', type='SRnor', controlGate='none', controlGateLogic=True, asynPreset=0, asynClear=0,
568 | size='large', suppressq=False, suppressNOTq=False):
569 | """ draws latches
570 |
571 | parent: parent object
572 | position: position [x,y]
573 | label: label of the object (it can be repeated)
574 | type: type of latch/Flip-flop. Available values: 'SRnor','SRnand','D','JK','T'
575 | controlGate: type of the gate input: available values: 'none','level', 'edge'
576 | controlGateLogic: True: activate HIGH (or rising edge) False: activate LOW (or falling edge)
577 | asynPreset: Asyncrhonous preset
578 | asynClear: Asyncrhonous clear
579 | 1: active HIGH
580 | 0: no input
581 | -1: active LOW
582 | reducedSize: predefined size. Available values: 'large', 'medium', 'small'
583 | suppressq: suppress drawing he direct state output. Default: False
584 | suppressNOTq: suppress drawing he inverted state output. Default: False
585 | """
586 | group = self.createGroup(parent, label)
587 |
588 | if type == 'SRnor' or type == 'SRnand' or type == 'JK':
589 | if size == 'large':
590 | w = 50
591 | h = 70
592 | dist_signal = 20
593 | y_controlGate = 0
594 | if size == 'medium':
595 | w = 40
596 | h = 50
597 | dist_signal = 15
598 | y_controlGate = 0
599 | if size == 'small':
600 | w = 30
601 | h = 40
602 | dist_signal = 10
603 | y_controlGate = 0
604 |
605 | if type == 'D' or type == 'T':
606 | if size == 'large':
607 | w = 50
608 | h = 60
609 | dist_signal = 15
610 | y_controlGate = 15
611 | if size == 'medium':
612 | w = 40
613 | h = 40
614 | dist_signal = 10
615 | y_controlGate = 10
616 | if size == 'small':
617 | w = 30
618 | h = 35
619 | dist_signal = 7.5
620 | y_controlGate = 7.5
621 |
622 | if size == 'large':
623 | fontSizeFactorG = 1.2
624 | fontSizeFactorS = 0.8
625 | if size == 'medium':
626 | fontSizeFactorG = 1.0
627 | fontSizeFactorS = 0.6
628 | if size == 'small':
629 | fontSizeFactorG = 1.0
630 | fontSizeFactorS = 0.5
631 |
632 | x_min = position[0] - w / 2.0
633 | x_max = position[0] + w / 2.0
634 | y_min = position[1] + h / 2.0
635 | y_max = position[1] - h / 2.0
636 |
637 | inkDraw.rectangle.widthHeightCenter(group, centerPoint=position, width=w, height=h, lineStyle=inkDraw.lineStyle.setSimpleBlack(1.5))
638 |
639 | if not suppressq:
640 | if not inkDraw.useLatex:
641 | self.createOutput(True, group, position=[x_max, position[1] - dist_signal], extraLength=0.0, label='Q', name='Q',
642 | fontSizeFactor=fontSizeFactorG)
643 | else:
644 | self.createOutput(True, group, position=[x_max, position[1] - dist_signal], extraLength=0.0, label='Q', name='$Q$',
645 | fontSizeFactor=fontSizeFactorG)
646 |
647 | if not suppressNOTq:
648 | if not inkDraw.useLatex:
649 | self.createOutput(True, group, position=[x_max, position[1] + dist_signal], extraLength=0.0, label='notQ', name=u'\u00ACQ',
650 | fontSizeFactor=fontSizeFactorG)
651 | else:
652 | self.createOutput(True, group, position=[x_max, position[1] + dist_signal], extraLength=0.0, label='notQ', name=r'$\NOT{Q}$',
653 | fontSizeFactor=fontSizeFactorG)
654 |
655 | # Asyncronous Preset and Clear
656 | if asynPreset == 1:
657 | self.createSignal(True, group, position=[position[0], y_max], direction='N', name='PRE', fontSizeFactor=fontSizeFactorS)
658 | elif asynPreset == -1:
659 | self.createSignal(False, group, position=[position[0], y_max], direction='N', name='PRE', fontSizeFactor=fontSizeFactorS)
660 |
661 | if asynClear == 1:
662 | self.createSignal(True, group, position=[position[0], y_min], direction='S', name='CLR', fontSizeFactor=fontSizeFactorS)
663 | elif asynClear == -1:
664 | self.createSignal(False, group, position=[position[0], y_min], direction='S', name='CLR', fontSizeFactor=fontSizeFactorS)
665 |
666 | if controlGate == 'level':
667 | self.createSignal(controlGateLogic, group, position=[x_min, position[1] + y_controlGate], direction='W', name='EN', isClock=False,
668 | fontSizeFactor=fontSizeFactorS)
669 | if controlGate == 'edge':
670 | self.createSignal(controlGateLogic, group, position=[x_min, position[1] + y_controlGate], direction='W', name='CLK', isClock=True,
671 | fontSizeFactor=fontSizeFactorS)
672 |
673 | if type == 'SRnor' or type == 'JK':
674 | if not inkDraw.useLatex:
675 | self.createInput(True, group, position=[x_min, position[1] - dist_signal], extraLength=0.0, name=type[0],
676 | fontSizeFactor=fontSizeFactorG)
677 | self.createInput(True, group, position=[x_min, position[1] + dist_signal], extraLength=0.0, name=type[1],
678 | fontSizeFactor=fontSizeFactorG)
679 | else:
680 | self.createInput(True, group, position=[x_min, position[1] - dist_signal], extraLength=0.0, name='$' + type[0] + '$',
681 | fontSizeFactor=fontSizeFactorG)
682 | self.createInput(True, group, position=[x_min, position[1] + dist_signal], extraLength=0.0, name='$' + type[1] + '$',
683 | fontSizeFactor=fontSizeFactorG)
684 |
685 | elif type == 'SRnand':
686 | if not inkDraw.useLatex:
687 | input1 = u'\u00AC%s' % type[0]
688 | input2 = u'\u00AC%s' % type[1]
689 | else:
690 | input1 = r'\NOT{%s}' % type[0]
691 | input2 = r'\NOT{%s}' % type[1]
692 | self.createInput(True, group, position=[x_min, position[1] - dist_signal], extraLength=0.0, name=input1, fontSizeFactor=fontSizeFactorG)
693 | self.createInput(True, group, position=[x_min, position[1] + dist_signal], extraLength=0.0, name=input2, fontSizeFactor=fontSizeFactorG)
694 | elif type == 'D' or type == 'T':
695 | if not inkDraw.useLatex:
696 | self.createInput(True, group, position=[x_min, position[1] - dist_signal], extraLength=0.0, name=type, fontSizeFactor=fontSizeFactorG)
697 | else:
698 | self.createInput(True, group, position=[x_min, position[1] - dist_signal], extraLength=0.0, name='$' + type + '$',
699 | fontSizeFactor=fontSizeFactorG)
700 |
701 |
702 | if __name__ == '__main__':
703 | logic = LogicGates()
704 | logic.affect()
705 |
--------------------------------------------------------------------------------