wow, i totally love you dude. I support you to the fullest and please don't stop, i can predict some epicly sweet frontpage saves from you :)
Note: Comments are listed newest first, so please start with my first comment below. =)
DIRECT ACCESS NOTES:
If you look closely you will see that the core/direct access module has a small delay built in to the lower ARAY of each store ARAY pair. Originally I did not have this delay, and it was working fine. Then, at some point, it simply stopped working, and the top ARAY started firing one frame after the bottom one despite both being on the same INST line. This stinks because nondeterministic behavior is subject to change, especially in other TPT versions, and hopefully it doesn't break my circuits. The addressed and stack versions contain the original core module without the delay, for some reason they're working fine. If stores stop working completely, this is a likely cause.
4-BIT ADDRESS MODULE:
The module is integrated with the RAM exactly as shown except the STORE line is also wired to the data input buffer trigger in the RAM.
STACK ADDRESS MODULES:
The stack address module on the left is my original concept version. It is simpler than the one on the right, has separate stack pointer / load+store lines, and no reset feature. I've provided it in case anybody wants to use it. As with all the other modules, replace the ARAYs on the left with ones that suit your needs.
The stack module on the right is the one used in the RAM. It is used almost exactly as shown. The differences are:
- The store line is wired to the data input buffer trigger.
- The reset ARAYs have been moved to the bottom, so that they can be triggered by the RAM reset line's ARAY. A receiving point for the RAM reset ARAY has been added just to the right of the stack reset ARAYs.
When you fire PUSH, it fires the stack increment line first, the delays a few frames (that junk at the top left) before firing the store lines (and data input buffer trigger). This gives the switches in the stack module time to update to the new stack position before storing. Pop, on the other hand, loads first, then decrements the pointer. The load and decrement lines can be fired at the same time because decrement takes a few frames and the load ARAY will make it through before the switches change.
I chose increment then store + load then decrement, rather than store then increment + decrement then load, because load already has a high latency and I did not want to make it worse.
OTHER NOTES:
Please feel free to make improvements, but share them with me! Also let me know if there are any glitches. Some things I'd like to improve are:
- Load latency times: If I could use an INST to fire the up-facing ARAY in each memory cell, loads could happen instantly instead of propagating up through all the other cells.
- Stack address module: It works, but I was tired when I designed it, and had literally tried a dozen other approaches. I feel like this can be simplified. Basically I just need anything that fires ARAYs / lets them pass through a location that can be incremented and decremented. There must be a simpler solution than what I have.
- Memory cell size: I wouldn't mind making the memory cells smaller. There may be a way but I've been staring at it too long.
CLOSING:
Anyways, enjoy! Let me know if you find these useful, or cool, or crappy, or have any questions, or whatever. Thanks! =)
DIRECT ACCESS:
This is the core RAM module. To store data, you must fire the data input pins (spark for 1, don't spark for 0) and the store pin(s) corresponding to the location(s) you want to store in at the same time (or at least, close enough that the NTCTs are still hot - data pins heat them). You can store in multiple addresses at once.
To load data, fire the load pin corresponding to the location you want to load, and the data will come out the data out pins (all at the same time). There is latency in load depending on the address because the data has to work its way up to the top.
Load and store are independent and can thus be done asynchronously (you can load one location while storing another; the test program does this).
The reset pin will zero all memory.
To play with storage you should pause the simulation, place a spark on the data and store pins, then unpause.
ADDRESSED ACCESS:
This uses a 4-bit address module to select load/store locations. This version also includes a data input buffer. Data input does not have to arrive at the same time as the store signal; individual bits also do not have to arrive at the same time. The address lines are also inherently buffered, so you can send those at any time before load/store as well.
To set the data to store, fire the data input pins. To set the address, first fire the ADDRESS CLEAR pin then fire the address lines you want to set. After setting the data and address, fire the STORE pin. This will store the data and clear the data input buffer. This will NOT clear the address lines.
To load data, set the address in the way just described then fire the load pin. This also will not reset the address lines.
The reset pin will zero all memory, clear the data input buffer, and clear the address lines.
STACK:
This is a stack implementation. Input data is buffered in the same way as the addressed version just described.
To push a value, set the data input lines, then fire the PUSH line. This will increment the stack pointer, write the data, and reset the data input buffer.
To pop a value, fire the POP line. This will load the current value, send it to the output pins, and decrement the stack pointer.
Stack overflows/underflows will not break the module. There is currently no overflow/underflow error output, although there should be, and I will probably add it eventually (it should be straightforward).
The reset pin zeros all memory and resets the stack pointer.
See stack address module notes below for implementation details.
CORE TEST + DEMO:
This was for testing but also works as a demo. Press RUN and watch it go. I originally had it all wired with INST but had to change to WIFI to fit it in. Hopefully it's not to confusing; I labelled the rows in the program with the RAM pins they correspond to to try and clear it up. The CLS output just resets the display at the top.
If you observe any glitches please let me know, it is probably either due to INSTs arbitrarily deciding not to be instant (which they seem to do from time to time), or problems with temperature and the NTCTs.
See next comment for more implementation details.
You can use these components. This save contains the core RAM module, an addressable version, and a stack. Also the 4-bit and stack address modules are included separately in case you'd like to adapt them to other uses (hint: the ARAYs on the left are for accessing the RAM module, you can replace them with whatever you need). The stack module on the left was my initial version, it has no reset but has separate stack pointer increment/decrement pins. The module on the right combines increment+store and load+decrement. To play with any of the components spark the PSCNs. There is a test/demo program on the right, spark the RUN button.
Heat sim must be enabled. Ambient heat sim should also be enabled otherwise stores are glitchy at top speed (speed is limited by BRAY fade). The RAM uses NTCTs for stores and they must have adequate time to cool down (note: if ambient temperature is too cold stores also do not work as NTCTs don't get hot enough).
See next comment for important detailed usage info.