The demo above allows you to create sequences of logic gates to see how they behave when connected to various inputs and outputs. Initially, you are presented with a simple on/off input and an output. To connect them, click and drag from the hollow circle on the right side of theon/off switch, and release the mouse when you are over the solid circle on the left side of the "output" block.
For each of the logic gates, outputs are hollow circles, and inputs are solid circles. Our "on/off" switch and "output block" aren't actually logic gates,but they are required because they give us the 1s and 0s needed to see how the gates behave. Click the on/off switch and see what happens. It turns yellow.This is our way of differentiating between 0 (off) and 1 (on).
To add a new logic gate, or an additional input or output block, choose from the dropdown menu and then click "add node". The new node will be placed in the top left hand corner, andyou can drag it to your desired position. To delete nodes, click the small cross in the top right corner of its enclosing box. To remove connections, you can click on theinput (solid circle) and drag away and release, or alternatively you can right click anywhere on the connection.
The NOT gate is also known as an inverter because the output is the exact opposite of the input. It has one input and one output.The two possibilities are written out in the table below. Tables listing all logical possibilities like this are known as truth tables.
The NAND gate behaves in the opposite fashion to an AND gate. You can think of it as an AND gate followed immediately by a NOT gate.Its output is 0 when the two inputs are 1, and for all other cases, its output is 1.The name NAND comes from joining NOT and AND. The symbol for NAND is the same as that for AND except for the addition of a small circle on the right side.
How do I go about doing something like this? I have a few subsheets made, with transistor circuits to act as logic gates. I want to use Eschema to simulate these logic gates, but have no idea how to do so. Can I do this, and how?
Here is where I found the circuit designs, great channel:
Is your goal to make gates out of BJTs because that seems like the most straightforward path to simulate the gates you need? Or do you actually need to simulate gates built specifically out of RTL (resistor-transistor-logic)?
ADMS is a code generator that converts electrical models written in Verilog-AMS into C code conforming to the API of spice simulators. The generated code will then be compiled into the simulator executable and the new device is ready for simulation.
Then you'd run the simulation step. This would proceed roughly the same way, but with the logic reversed. As you visit each node, you check its visited flag. If it's set, you can return immediately (and you've just detected a cycle in the graph). Otherwise, you set the flag, process the inputs for that node (etc.--your usual simulation "stuff"), then do recursive calls to do simulation on its child nodes. If any of them loops back to this one, that call will return immediately (because you've already set the flag), ending that "leg" of recursive calls.
I'm developing a digital logic simulator to build my own CPU in it later (so it's a long term project). Everything works great for circuits with no loops, for example a fulladder. Then there are circuits like an SR latch, where one of the inputs of a gate is connected to the output of another gate. So I'm in a loop, because both gates need the output of the other one, to compute their own output.
What is the best way to solve this? I implemented it in a way, that (when a loop is detected) it will return it's last output. Or, when this run is the first one (so there was no previous output) I will return zero (low). So I just assume that all the outputs were low/zero in the beginning. It works so far, but I'm sure that this is not a good way to solve the issue.
In many cases, simply modeling each gate as having a unit propagation delay is a fine approach. A slightly more sophisticated alternative is to have the "simulation-step" routine for most component check whether the simulation time has advanced by a "full step", and only update its output if so; a few components could be omit that check but instead request that they be run again on the simulation step after other components have had a chance to update. That would allow some components to pretend to have zero propagation delay provided that they weren't nested too deeply (the simulation should limit how many times it will attempt to run each component's evaluate-state routine before it decides the components aren't going to reach a stable state).
Depending upon what exactly is being simulated, I would suggest having multiple output states for your components besides "high" and "low". Even adding an "indeterminate" state can be helpful, with the behavior that when a component's input changes in a way that could affect its output, the output will become "indeterminate" after the minimum propagation time, and assume a legitimate value after the maximum propagation time following the moment that the inputs become valid. Note that as signals pass through more levels of logic, the amount of time that they are "indeterminate" will increase. The only way to simulate anything meaningfully is to have a clock which is assumed stable, and ensure that clock periods are long enough that things can fully stabilize between them.
Simulating things in this way has the advantage that while simulation will "fail" (yield "indeterminate" values) on many circuits which would work in reality, the fact that such a simulation yields deterministic results would suggest that a real circuit that was built the same way would do so as well. Unfortunately, for circuits which rely upon edge-triggered latches, the most common simulation result would be "indeterminate", even for circuits which would have a 100% chance of actually working. To ease that problem, one would often want to 'jinx' a few gates so as not to stretch the 'indeterminate' interval. Doing this would be something of a "cheat", and create the possibility that a circuit might work in simulation but fail in reality. Nonetheless, if such cheats are applied carefully, they may make simulation much more useful than it would be otherwise.
Rather than have the circuit built from the basic gates (and, or, nand, etc) I want to allow these gates to be used to make "chips" which can then be used within other circuits (eg you might want to make a 8bit register chip, or a 16bit adder).
The problem is that the number of gates increases massively with such circuits, such that if the simulation worked on each individual gate it would have 1000's of gates to simulate, so I need to simplify these components that can be placed in a circuit so they can be simulated quickly.
However it just occurred to me that in cases where the outputs link back round to the inputs, will cause a deadlock because there inputs will never all be evaluated...How can I overcome this, since the program can only evaluate one gate at a time?
Obviously I'm misusing the terminology a bit, not to mention neglecting the niceties of electronics. On the second point I recommend abstracting to wires that carry 1s and 0s like I did. I had a lot of fun drawing diagrams of gates and adders from these. When you can assemble them into circuits and draw a box round the set (with inputs and outputs) you can start building bigger things like multipliers.
Evaluating a circuit without loops should be easy - just use the BFS algorithm with "junctions" (connections between logic gates) as the items in the list. Start off with all the inputs to all the gates in an "undefined" state. As soon as a gate has all inputs "defined" (either 1 or 0), calculate its output and add its output junctions to the BFS list. This way you only have to evaluate each gate and each junction once.
You could hard code all the common ones. Then allow them to build their own out of the hard coded ones (which would include low level gates), which would be evaluated by evaluating each sub-component. Finally, if one of their "chips" has less than X inputs/outputs, you could "optimize" it into a lookup table. Maybe detect how common it is and only do this for the most used Y chips? This way you have a good speed/space tradeoff.
When I was playing around making a "digital circuit" simulation environment, I had each defined circuit (a basic gate, a mux, a demux and a couple of other primitives) associated with a transfer function (that is, a function that computes all outputs, based on the present inputs), an "agenda" structure (basically a linked list of "when to activate a specific transfer function), virtual wires and a global clock.
I arbitrarily set the wires to hard-modify the inputs whenever the output changed and the act of changing an input on any circuit to schedule a transfer function to be called after the gate delay. With this at hand, I could accommodate both clocked and unclocked circuit elements (a clocked element is set to have its transfer function run at "next clock transition, plus gate delay", any unclocked element just depends on the gate delay).
This is not available in TINA-TI, bit you can upgrade to TINA Industrial from DesignSoft to get these models. Alternately, you can create your own gates in TINA-TI using the controlled source wizard (from Sources >> Controlled Sources menu item), for example an AND gate using the following
To that end I built a tool in C# for connecting basic components together to form complicated circuits. It has the basic AND,OR,NOT and a few other gates along with wires to connect their inputs and outputs. The circuits can be saved out to files, and loaded in as individual components which can be duplicated and further connected to make more complex circuits. There is no kicking, nor is there any game to this, it is just the simulator, but it is fun to build circuits that do something.
760c119bf3