hneemann / Digital

A digital logic designer and circuit simulator.
GNU General Public License v3.0
4.34k stars 439 forks source link

Feature request: bus wire splitter #197

Open benvanik opened 6 years ago

benvanik commented 6 years ago

I'd like to be able to use combined bus wires to connect multiple bus drivers. For example, the pins of two or more 74245 ICs over a single /8 bus wire instead of 8 individual wires to keep my design cleaner. As far as I can tell this isn't currently possible as the Splitter has directionality and the Bidirectional Splitter has an OE that needs to be gate-level synchronized with the 74245 (which is very tricky).

It'd be nice to have a splitter variant that had no behavior associated with it and was just a way to combine wires to keep designs clean. Think of it as a Splitter where both ends are bidirectional -- just a dumb wire splitter.

Unless I'm missing something obvious and this is already possible with some other component :)

hneemann commented 6 years ago

You're right. So far it is not possible to use a true bidirectional splitter. And that does not seem to be a significant restriction either. To my knowledge, this is only a problem with the use of 74xx chips. And this is certainly because the data bus must be split again and again to connect the bits of the data bus to the individual pins, which is not necessary under normal circumstances.

The only way to create a more clear circuit layout is to use the tunnel element:

74245

benvanik commented 5 years ago

Darn :( Do you think it'd be possible for Splitter to implement this functionality? I haven't had a chance to dig into the code but may try doing so. Does it sound reasonable for the hasChanged handlers - when a 'bidirectional' mode is enabled on the splitter - to manipulate inputs as well as outputs based on hi-z rules? (essentially: if input bit == hi-z and output bit != hi-z, inValue.set(outValue.getValue() & ...), else outValue.set(input.getValue() & ...))

hneemann commented 5 years ago

The problem with this is: If you apply this rule the first time, there is no high-z value anymore. The second evaluation will lead to wrong results. The only way to deal with this is by forming a common net, which state is calculated by evaluating the state of all connected outputs. And this net formation has to cross all connected splitters. Up to now the splitter is a logical component similar to a AND gate without a propagation delay. Implementing a bidirectional splitter means to consider the splitter during the net formation, which is a completely different story.

hneemann commented 5 years ago

Note: The consideration of real splitters must take place across sub-circuit boundaries. If a sub-circuit is used multiple times and the signals of the inputs and outputs run through different splitter configurations, this leads to different network configurations in the same sub-circuit. This means that the net formation can no longer be done independently for each circuit.

mengstr commented 5 years ago

I'd +1 the idea for a pure bidirectional splitter. In my mind I treat a bus just as a bundle of wires with a condensed representation on the screen - but from the discussion above I realize that internally it's a completely different beast.

Now I had to resort to connecting up this abomination for just splitting an 12-bit bidirectional databus into a 7- and a 5-bit bus. Luckily it was easy to generate a suitable signal for the OE.

Screen Shot 2019-09-04 at 8 04 30 AM
hneemann commented 5 years ago

@SmallRoomLabs You're right, it looks pretty ugly. But this is only because the bi-directional splitter is very limited in its capabilities. Since a bus is internally represented by a long-value, it is difficult to remove the restrictions completely. Maybe it would help in practice if the bi-directional splitter could be configured as flexible as the simple splitter. I have to think about it.

mengstr commented 5 years ago

Having the bidirectional splitter as configurable as the regular splitter would absolutely help a lot!

But for a long term solution I recon that the wire/bus handling have to be reworked into something more flexible - at least is that what I would plan for if I was maintaining this project. ;-)

Unfortunately I can't really contribute to this project, my java-fu is limited to writing bad code in Java Card edition where every line of code is sprinkled with (short) like short id = (short)((short)data1*(short)256)

hneemann commented 5 years ago

But for a long term solution I recon that the wire/bus handling have to be reworked into something more flexible - at least is that what I would plan for if I was maintaining this project. ;-)

So do I! The only problem is that I didn't have a good idea how to do this without reducing the performance too much or increasing the complexity too much. :unamused: But I still hope I can come up with something good. Therefore I find it hard to put too much work into the workarounds.

Tynach commented 3 years ago

@hneemann, if I understand correctly, the problem is that the bus splitter is a component, subcircuits are components - and components always have directional input/output pins so that when computing how wire nets are connected logically, a subcircuit can be standalone and its inputs never have to consider components outside of the subcircuit. Is this correct?

hneemann commented 3 years ago

@Tynach Not quite. A bus is something different in Digital than e.g. in a software for analog circuits. In digital the signals on a bus are treated like integer values and not like single bits. This makes e.g. a 32 bit AND operation very performant. Not 32 single bits are ANDed, but a 32 bit integer. In fact in Digital every value and every wire is a bus, but some have only one bit. If a wire is connected to a current splitter, the calculations do not have to take into account what is happening on the other side of the splitter. However, if the splitter were bidirectional, this would be necessary. The model creation would be much more complicated. It would also make the Verilog/VHDL export significantly more complex.

ghost commented 3 years ago

Would it be worth seeing how bidirectional splitters are implemented in logisim and seeing if that can be adapted to digital?

Tynach commented 3 years ago

@hneemann, that sounds like it would make things significantly slower for my own purposes... I was hoping to use Digital to try implementing an entire 16-bit CPU out of only transistor components, using busses and splitters simply to organize the wiring better.

In this scenario, you're saying that busses and splitters will essentially be constantly converting a bunch of separate values into one integer value, then back into a bunch of separate values. Why not at least provide something that lets you just bundle a bunch of separate values together into one bus, without it treating them as an integer? That would at least get rid of the performance burden of frequently converting between the two.

hneemann commented 3 years ago

@Tynach If something substantial is built from only transistors, the conversion of bits into ints and vice versa is neglectable. Optimizing something here would not have a significant impact on the performance. On the other hand, if, for example, a processor is built from somewhat more complex components such as NAND gates, this procedure brings a significant performance gain.

hneemann commented 3 years ago

@kokowadoko This could be. I am not very familiar with the simulation algorithms implemented in Logisim.

Tynach commented 3 years ago

@hneemann, I suppose so. However, while it would provide only a negligible gain in performance, it would provide a substantial gain in usability. Being able to break a wire off of a bus and then merge a wire onto a bus arbitrarily would be fantastic, and greatly improve the organization of many designs.