flandreas / antares

Digital circuit learning platform
49 stars 6 forks source link

Keyboard improvements #733

Closed fpw closed 5 months ago

fpw commented 5 months ago

The keyboard currently doesn't support control characters, e.g. ctrl+c or ESC. Further, it would be cool if one could choose whether enter should send CR or LF as CR was the standard on teletypes.

A PR that implements both is on the way.

fpw commented 5 months ago

Side node: This was the last required improvement to get the PDP-8/I circuit fully functional. It now passes all tests and can run original software. Here's a clip running the FOCAL programming language in the 1969 version. It's an interpreted language predating even BASIC, shown is the calculation of sqrt(2). Using it for quick calculations like this was a common use case because desktop calculators were not common at that time.

The machine has only 8 opcodes and even subtraction has to be done in software (two's complement add), yet it was used to control things from gas chromatographs to nuclear power plants. The "Multiplier / Quotient" register implies that there's a hardware multiplier / divider, but that's an expensive addon that's not used by Focal, even though it's part of my implementation in Antares for use in other software. There are also versions of COBOL, BASIC, Pascal and even FORTRAN for PDP-8 computers.

Note that on the original machine, the result was available instantly.

https://github.com/flandreas/antares/assets/5798899/c4cb356c-cc70-4541-9ab5-23265d374f6c

flandreas commented 5 months ago

This is so amazing! Congratulations to this fantastic project!

Are you planning to publish this design somehow? I can imagine it would be fascinating for some people to dive into this machine and learn about its architectural details. And of course it would be a great demonstration of what is possible to achieve with Antares :-)

So for example, I wonder how you load different programs into the machine, e.g if you want to load a compiler instead of the FOCAL interpreter. Do you load machine programs into a ROM? And if so, how do you give the user access to the ROM component if he only sees the front panel subcircuit? This is a question I've asked myself when developing my own MC designs (like Tanenbaum), and I was wondering whether Antares needs more features for loading / exchanging memory contents.

Regarding speed: I assume the example in the video runs at max. Antares speed. Do you already use Antares scripting for some simple, but central subcircuits? This could speed up the simulation dramatically. I know using scripts can feel like "cheating", but as long as the machine can run correctly with deep simulation (i.e. not using scripts), executing programs alternatively with scripting was always fine for me.

fpw commented 5 months ago

Thanks :-)

Publishing: Yes, definitely! I'll do some more cleanup and maybe implement some external peripherals like a harddisk to store more programs. Since it needs Antares 1.12, I'll wait for that until publishing it for others - but no rush!

Loading programs: Just as on the original machine, you can enter programs using the front panel switches and lamps (LEDs not available back then). The numbers on the left of the panel are actual a small bootstrap loader that you can toggle in, it's a program that can load other programs from paper tape. So to load Focal, you would toggle in this boot loader and then use that to load Focal. Luckily, the machine used magnetic core memory for RAM - it's non-volatile, so the boot loader stayed in the machine even when turning it off. But for Antares, I wrote a little helper tool that converts paper tape images to Antares' RAM import format. So the user really has to open the core memory part and click import there. I think it would help a bit if RAM and ROM were components that can be put into the circuit symbol like buttons and LEDs, that way I could make it available on the top circuit just like the console switches.

Speed: I personally prefer correctness over performance for this project. For speed, I can just use my FPGA or software implementation of the machine. The Antares version is needed to check how the real machine would have behaved in special situations; simulating it in Antares is still faster than going to the next computer museum to check something :-) I think there would be many things to make it faster, e.g. using registers instead of flipflop arrays for the registers or using inverted inputs instead of many inverter gates - but for my purposes, the circuit must really be 100% identical to the original schematic because this will become the top layer of authenticity for questions about the behavior of the machine, so to say.

Here are a few minor other things that could be improved, but there were workarounds so I didn't create tickets:

But all in all, in my opinion Antares is now in a great state where it can be used for big projects already, so thanks a lot for that! :-)

flandreas commented 5 months ago

Thank you for your suggestions.

Loading programs: Do you think it would make sense to be able to add ROM content (e.g. machine programs) as explicit objects to a project, just like the new images? That way, it would be easier to add a chooser on a ROM symbol that allows to switch memory contents without resorting to the OS file chooser. Maybe also depends on your vision about external peripherals...

Simulation speed: Yes, I see your point, perfectly fine.

Propagation delay: The "Propagation delay" property of circuits is only meant for running the simulation in shallow mode and using scripts. In that scenario, the configured "Propagation delay" (if available) is used to determine the time when the new signals produced by the scripts are published at the output pins. Since you are using "Deep mode" simulation in your project, these values have not effect. I think the feature that's still missing is "Int typed generic parameters" (unlike "Bit Width", the only implemented generic parameter type so far). With that, you could pass a "Propagation delay" parameter into a subcircuit and use it as propagation delay value for the gate in your subcircuit, such as "PD / 3" for the first AND, "PD / 5" for the inverter, and so forth. This is essentially issue #474.

Default propagation times: Yes. This needs to be a user preference, or maybe even a circuit property. Since most components store their propagation delay value, this would only take effect for new circuits.

Importing projects: Have you considered using "Workspaces"? This seems to be exactly the scenario for which workspaces were introduced with #581.

More circuit / project settings: Yes. I'll open an issue for this one.

Search function: Your requirements regarding "Project-wide search" might be special because your project is using more global things, hence the need for global tunnels. But you're right: I've also noticed that it's sometimes hard to spot the search results in large circuits. Maybe we should have a "Search tab" like in some IDE's, where search results are displayed as a list, and from there you can navigate to the corresponding element in the circuit, perhaps by applying a nice zoom-in animation, or even opening another circuit if necessary. I'll open an issue for this.

fpw commented 5 months ago

Loading programs: Do you think it would make sense to be able to add ROM content (e.g. machine programs) as explicit objects to a project, just like the new images?

Now that I played with the new image feature: Yes, absolutely! Including RAM / ROM dumps in the same way and then allowing the user to select them from a combobox somehow would make it really easy to play with different programs. Maybe combined with my suggestion from above to allow a RAM / ROM component to appear in the circuit symbol like switches and lamps so that the import button can be reached from the top level circuit.

PS: Using the new image feature worked perfectly! grafik

flandreas commented 5 months ago

This is just soo beautiful!

Now you could use the "Orange" light color in the LEDs instead of the yellow, and it would look even closer to what you've got on your pdp8.app site :-)

fpw commented 5 months ago

Orange has a red background that is a little confusing in my opinion - could also be a turned-on red LED. Image with both variants for comparison.

grafik

The real machine used incandescent lamps as LEDs were not available back then, so the color actually depended on how fast the bit toggled its content. See on the right side for example, the "Fetch" cycle is active in every opcode, so it's a lot lighter and more yellow than the execute lamp which is a cycle not used in all instructions, so it's both darker and more orange than yellow.

image

That's why yellow is also fine :-)

flandreas commented 5 months ago

OK, I see. Good input about the orange color, I wasn't aware of this. I've created an issue to improve it.

flandreas commented 4 months ago

@fpw Folke, I hope you are doing well.

I am working on #474 and am now trying to apply it to make the propagation delays of standard library subcircuits configurable. I'm asking you because you've suggested in this issue that it would be nice to have such a feature. You were missing it to achieve the proper timings in your project.

So, every subcircuit would now get a new generic parameter "PD", and this would be inherited to the individual gates of the subcircuit. I see two ways of how this could be done:

  1. Every gate would receive the same PD value. If you configure 20 ns on the subcircuit symbol, every inner gate would have expression "=PD" and would therefore end up with 20 ns.
  2. PD is interpreted as the total subcircuit propagation delay, e.g. 300 ns for a flip-flop, and the expressions on the inner gates would look something like "PD / 4", "PD / 3" etc, so that they add up to the flip-flops total propagation delay.

Option 1 is easier to apply on the existing standard library circuits, but I could imagine your use case would have been easier with option 2, right?

Option 2 seems to be more intuitive, but might be confusing with more complex subcircuits, as different paths from inputs to outputs could have different propagation delays, so it's unclear one is meant by the user when he specifies 300ns on the outside.

For simplicity, I think I would go with option 1. What do you think?

fpw commented 4 months ago

@flandreas thanks! Still recovering, but it's getting better.

Wouldn't 1) mean that an edge detector that consists of 3 inverters internally had a delay of at least 60 ns if I entered 20 ns in its top symbol? That sounds like it could confuse the users a lot. I was actually confused by the current solution as well because some gates allow entering an expression in the propagation delay, but it has no effect. I think you explained that this field is mainly used for the flat simulation where subcircuits are replaced by scripts.

Also, if 1) is applied to things like FlipFlops, I think they wouldn't work without random noise anymore because all gates had the same delay.

Considering this, I think if 2) is too difficult, it would be better to just make the current solution less confusing - displaying the total, actual propagation delay of a subcircuit, e.g. the longest path through the circuit or something like that. Instead of providing an editable field that neither displays the current delay nor allows an actual change of anything in the deep simulation. If that were more clear to the user, I think it's possible to go without both 1) and 2).

I think the best solution would go even one little step further than 2) but also simplifies it: Instead of only having PD as a property, allow adding arbitrary properties and use them in expressions inside the sub-circuit. For example, a FlipFlop could define several different things like "D to Q delay", "Minimum hold time", etc. while an edge detector could define "Pulse delay" and "Pulse width". That would make the circuit implementation easier, allow more flexibility and bring the properties closer to actual data sheets where circuits usually have more than just "propagation delay". The values are then used internally for different PD value calculation of gates, or passed down to similar properties of sub-sub-circuits inside the sub-circuit.

flandreas commented 4 months ago

Wouldn't 1) mean that an edge detector that consists of 3 inverters internally had a delay of at least 60 ns if I entered 20 ns in its top symbol?

Yes, it would mean that, and it would indeed be confusing. That's the disadvantage of this option.

Also, if 1) is applied to things like FlipFlops, I think they wouldn't work without random noise anymore because all gates had the same delay.

Generally yes, but I would use the approach to set the propagation delay of NAND gate 1 to "=PD" and of NAND gate 2 to "=PD + 1" or something.

...If that were more clear to the user, I think it's possible to go without both 1) and 2).

Yes, but then there wouldn't be a solution for your requirement to be able to customise propagation delays.

Instead of only having PD as a property, allow adding arbitrary properties and use them in expressions inside the sub-circuit.

Yes, this is generally possible with the "Parameter" module: You can define as many parameters as you like. However, the author of the subcircuit has then to apply the given value to the inner gates, and here he is limited to the properties of these gates, typically only the propagation delay of the gate. Even if he formulates expressions like "PD / 3 + 1", it'll be difficult to come up with emerging features like "D to Q delay". Or "Minimum hold time", which would require a new feature in Antares to support this. "Pulse with" in an edge detector however should be feasible.

I think I give option 2) a try and see how it turns out when I try to apply it to some standard library circuits.