I've looked at some techniques that were used at the beginning of the eighties to refresh the RAM (CPU-based refresh for the Z80, or the use of the video circuit for computers that shared the bus between the video and the CPU on alternate cycles), but I don't think I got all of them. Was there other techniques? (I'm mostly interested in home or office computers.)

For the end of the decade, the picture is even less clear. Did something change with the introduction of the 30-pin SIMM format?

  • The IBM PC 5150 used the 8253 timer channel 1 to trigger a DMA request for channel 0 so the DMA memory access then performed the refresh. – Justme Mar 23 at 12:04
  • Or specific hardware to perform the refresh - counter, timer + logic. The 30pin SIMM made no difference, but around that time was the introduction of sdram. With that, the finer details of the memory cycle was pushed onto the memory controller. The benefit was page mode access. – Kartman Mar 23 at 15:05
  • @Kartman: didn't page mode exist before that time? I have datasheets for old RAM chips that were capable of page mode access before SDRAM. – airman Mar 23 at 15:11
  • @Kartman 30pin SIMMs might be (fast) page mode (usually they are at 1MB or bigger). 72pin SIMMs are either (standard) fast page mode or EDO (also called "hyper page mode"). 168-pin DIMMs usually are EDO (rare, very early DIMMs only) or SDRAM. You are right that 30-pin SIMMs and FPM were introduced around the same time (late 80's), but SDRAM came around 1997. – Michael Karcher Mar 23 at 15:50
  • My memory, memory is fading! Sorry! – Kartman Mar 23 at 16:16

Basically it's all about what component do when issues a refresh. which can be seen from (at least) two points of view:

RAM side

The way RAM sees/handles refresh changed quite a bit over time.

  • Early RAM had only one kind of refresh: Access to a row would refresh it, no matter if read, write, or incomplete (RAS-only). External components had to supply row addresses and make sure that all rows were accessed within time.

  • Later, with the 4164 (IIRC), Auto-Refresh was introduced. Here each RAM already includes addressing logic to execute a refresh cycle, but the system still had to dedicate a memory cycle to execute it. It was initiated by pulling a special /REFRESH pin. Now external components only had to make sure that enough cycles were assigned within time.

    With the introduction of 256 KiBit RAM (41256) that pin was reused to provide two more address bits, so it had to be signalled with an otherwise illegal combination of CAS-before-RAS.

  • Again Later (as well EDO?) Hidden Refresh was introduced. Essentially a combination of auto-refresh and extended data out timing. After issuing a regular RAS-CAS moderated request and while CAS was still held active to extend data output, RAS was assigned again issuing a hidden refresh cycle.

  • Finally, SDRAM not only changed the behaviour completely by being clocked, but as well introduced Self-Refreshduring power down - but SDRAM is a complete different story.

(For the question marks: Assignment is from memory, so maybe not exact with each generation)

System Side

All RAM needs some system side handling for refresh. This can be differentiated by what handling is needed as well as which component does it.

Since basic refresh is simply a full (or aborted) access, any system that guarantees that all rows will be accessed within the refresh time will work. So for a classic 4116 all 128 rows had to be addressed once, in no particular order, within two milliseconds. Possible ways were:

  • Continuous Access - his means the RAM is accessed in all (used) ROWs within refresh rime due normal operation. Video memory is often designed that way. It might need some careful assignment of address bits (*1), but removes all need for refresh hard- or software.

  • Burst Refresh - here a dedicated logic will take over RAM access and issue a series of consecutive refresh cycles. For a classic 200 ns 4116-3 this meant a burst 128 cycle, each 375 ns for a total of 48 µs. The advantage is that refresh logic, as well as bus arbitrating is rather simple and overhead is small. It may be the fastest possible refresh, as it does not need to follow the time frame of other system components (*2). On the backside it will the system will be not be able to do anything during this time, which might be a problem for real time/embedded applications.

  • A special sub case might software based burst refresh. This can be done for example by calling an interrupt every two milliseconds which gurantees to access every row once before returning. While this may sound like waste of time at first, like having a longish counter loop accessing each row once, it can easy be turned into an advantage. With using the lower 7 address bits as row (*1) this only required a series of 128 NOP, places in ROM, meaning only the interrupt invocation is an additional toll to be payed, compared to hardware burst, but will save quite some hardware (at very least two multiplexers and a counter). By making the routine do something useful instead of NOPs, this drawback can even be turned into an advantage. For example by operating a real time clock in these 128 bytes.

  • Cycle Stealing is an equally common implementation. Here the refresh logic will take over RAM access only for a single access, spreading out he disruption over the whole time frame. Over all performance is like burst mode but with timing delay reduced to a single cycle. On the backside it can't operate at faster speeds, so over all performance impact is always 128 system clock cycles.

    A very prominent usage was with the original IBM PC. Here a timer let a DMA channel read from RAM in a repeated cycle. It fires every 15.1 µs i.e. every 72nd CPU-clock.

  • Hidden Refresh (not to be confused with hidden refresh within a RAM) is essentially like cycle stealing, except that only cycles are taken that are not used by other components (like CPU), thus not impacting performance. This of course only works with systems that have waste cycles.

    Essentially this is the way the Z80 offers. During M1, when the instruction is decoded a refresh cycle is provided, hidden to execution and timing.

How Does That Come Together?

Well, that depends on each system's implementation.

  • Who supplies Refresh addresses
  • Who inserts refresh cycles
  • How is this coordinated with other RAM users (most notably the CPU)
  • How it's integrated into a systems clock framework
  • and so on...

Ways to solve this are almost endless. It wouldn't make much sense to open up a list of various implementations.

*1 - Did anyone ever say that the logical (CPU) order of address bits must be the same for RAM?

*2 - For example when used in a system with a basic 2 MHz clock cycle, following the 2 MHz clock would mean that a burst would need 64 µs. With using its own clock during Refresh this can be tuned down to 48 µs.

*3 - It was also a source of early PC performance tweaking. Since memory access is two clocks every 72 clocks, refresh takes away 1/36th or 2.8%. Decreasing that (in steps of 3 clocks, as the timer is feed by 4.77 divided by 3)) increase the number of cycles the CPU could use. Going to 75 cycles is still within spec and gains 0.1%. Everything thereafter would leave the 2ms. Gains up to 1.5% could be realized with most machines. Not much, but hey, every bit counts.

Fun fact, on some (early) 286es these savings were seemingly dramatic when using Norton Index to check for system speed, A 12 MHz 286 would show up as 13-14 MHz. Except, this was an artefact of how the timing loop was interpreted no real speed gain.

  • On many machines, I would think the performance of software-based burst refresh on machines like the 6502 could be improved by placing 42 instructions of the form cmp 85 / cmp 86 / cmp 87 / ... / cmp 127 at a multiple-of-128 address and followed by a RTI. – supercat Mar 24 at 22:34
  • @supercat Except it would not do anything useful but refresh. Having a 500 Hz clock in seems rather nifty in contrast. – Raffzahn Mar 24 at 22:56
  • Executing 128 NOPs would take 128 bytes of code space and 256 cycles to execute. The 42 cmp instructions would take 84 bytes of code space and 126 cycles to execute. One could replace some of the NOPs with other code if one had something useful for it to do, but unless one has 128 bytes worth of code to be executed one would need to have some do-nothing code in there as well, and the described pattern would use two bytes of code space and three cycles for every three rows needing refresh. – supercat Mar 24 at 22:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.