I put instructions in comments but should have put them here.
Instructions
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).
Detailed Usage
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.
Implementation Notes
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.
Anyways, enjoy! Let me know if you find these useful, or cool, or crappy, or have any questions, or whatever. Thanks! =)
I'm reposting my reply from the comments in case somebody finds this forum thread some day:
@DCBloodHound: Putting a FILT at the intersection of two ARAYs prevents a solid BRAY from being created if they collide. Without the FILT, one BRAY may be blocked, and a solid BRAY with a long life time would be created. So, there is a FILT everywhere ARAYs cross.
@cip(View Post) i prefer put MINIMUM amount of FILT, not whole element btw awhy are they so huge for their capacity? hawe you ever heard of bray matrix? a little 100X280 px box stores 256 bytes :P
1. I did put a minimum amount of FILT but drew my initials with FILTs too. =) I guess it's kinda cheesy, though.
2. I would love to get them smaller. There's a SWCH that needs to contact 4 isolated conductors and that NTCT, plus space for the BRAYs. I'll keep trying. I'm sure I can make them smaller.
3. No I have never heard of a BRAY matrix. Do you have an example of one? It sounds cool. I tried experimenting with solid BRAYs but wasn't able to get anywhere.
I'm totally down for learning new tricks, I love this stuff.
Wow! These are brilliant! I did design mine specifically to be fast at the expense of space (I've been working on components that run as fast as possible because speed is always the problem I seem to notice in people's computers and logic here), but the density of these could definitely outweigh the speed for certain projects. Thanks a lot for sharing these. I need to take a look at them a bit more. I don't understand the behavior of solid BRAYs very well, and wasn't able to come up with a BRAY solution on my own originally. These are really great, and they look pretty cool too.
Re: Settings display - I updated your air heat and equalization display to fix some issues I noticed:
1. Lava was escaping air heat display and burning it up when gravity was set to off or radial. For some reason the lava was flowing through the single diamond layer (some kind of glitch?). I moved the clone to the center surrounded by a ring of void and it now works for all gravity modes.
2. The air heat sensor heats up the surrounding air. This was causing the NTCT inverters to malfunction in the nearby equalization sensor. I created an equalization sensor circuit that does not use PTCT/NTCT and so is not affected by ambient temperature (it's also a little smaller). To adjust the sensitivity for the spark filter, adjust the timing of the two DLAYs. The one on the left should be half the delay of the one on the right. The one on the right ends up determining max response time when equalization is turned off (currently I have it set to 150 frames = 2.5 seconds max).
3. The fluid in the equalization sensor was escaping when gravity was turned off, for the same reason as #1, so I encased it in an extra layer of diamond. The sensor still doesn't work for anything but vertical gravity, but at least the fluid won't escape.
I also added the missing "u" to "equalization", lol.
These sensors are awesome, I think I will try to work them in. But I still need to enclose them in walls, sadly, at least for my RAM, because the ambient temperature change from the air heat sensor could affect the circuits, which use NTCTs.
The updated air heat and equalization circuit are at the top of this: