mirror of
https://github.com/garrettsworkshop/Warp-SE.git
synced 2024-11-28 20:52:22 +00:00
839 lines
50 KiB
HTML
839 lines
50 KiB
HTML
<html>
|
|
<head>
|
|
<title>Garrett's Workshop - Warp-SE Timing</title>
|
|
<style type="text/css">
|
|
ul {
|
|
margin-top: 0;
|
|
}
|
|
h3 {
|
|
margin-bottom: 0;
|
|
}
|
|
h2, h4 {
|
|
margin-bottom: 3px;
|
|
}
|
|
h3 + h4 {
|
|
margin-top:6px;
|
|
}
|
|
p {
|
|
margin-top:0;
|
|
}
|
|
ul li {
|
|
padding-top: 3px;
|
|
}
|
|
ul li sup {
|
|
line-height: 0;
|
|
}
|
|
</style>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/wavedrom/2.6.8/skins/default.js" type="text/javascript"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/wavedrom/2.6.8/wavedrom.min.js" type="text/javascript"></script>
|
|
</head>
|
|
|
|
<body onload="WaveDrom.ProcessAll()">
|
|
<h1>Garrett's Workshop Warp-SE 20/25 MHz 68HC000 Accelerator Documentation</h1>
|
|
|
|
<h2>System Block Diagram</h2>
|
|
<img src="CPLD.png" style="width:1000px;" />
|
|
|
|
<h2>Relevant Timing Parameters</h2>
|
|
<p>Some relevant timing parameters to which the bus timings were designed are as follows:</p>
|
|
<table>
|
|
<tr><th>Parameter</th><th>Value</th><th>Description</th></tr>
|
|
<tr><td>tPD_CPLD</td> <td>10ns</td> <td>asynchronous propagation delay</td></tr>
|
|
<tr><td>tCO_CPLD</td> <td>6ns</td> <td>clock-to-output delay</td></tr>
|
|
<tr><td>tSU_CPLD</td> <td>6ns</td> <td>global clock setup time</td></tr>
|
|
<tr><td>tRAS_DRAM</td> <td>60ns</td> <td>RAS pulse width / access time</td></tr>
|
|
<tr><td>tASR_DRAM</td> <td>0ns</td> <td>row address setup time before RAS</td></tr>
|
|
<tr><td>tRAH_DRAM</td> <td>10ns</td> <td>row address hold time after RAS</td></tr>
|
|
<tr><td>tRCD_DRAM</td> <td>20ns</td> <td>minimum RAS-to-CAS delay</td></tr>
|
|
<tr><td>tASC_DRAM</td> <td>0ns</td> <td>column address setup time before CAS</td></tr>
|
|
<tr><td>tCAH_DRAM</td> <td>10ns</td> <td>column address hold time after CAS</td></tr>
|
|
<tr><td>tCAS_DRAM</td> <td>20ns</td> <td>CAS pulse width / access time</td></tr>
|
|
<tr><td>tRP_DRAM</td> <td>40ns</td> <td>RAS precharge time</td></tr>
|
|
<tr><td>tCP_DRAM</td> <td>10ns</td> <td>CAS precharge time</td></tr>
|
|
<tr><td>tRC_DRAM</td> <td>120ns</td> <td>minimum RAS cycle time</td></tr>
|
|
<tr><td>tACC_ROM</td> <td>70ns</td> <td>ROM access time</td></tr>
|
|
<tr><td>tOE_ROM</td> <td>40ns</td> <td>ROM OE access time</td></tr>
|
|
<tr><td>tPD_573</td> <td>20ns</td> <td>74AHCT573 propagation delay after LE or D</td></tr>
|
|
<tr><td>tSU_573</td> <td>5ns</td> <td>74AHCT573 setup time before LE</td></tr>
|
|
<tr><td>tH_573</td> <td>2ns</td> <td>74AHCT573 hold time after LE</td></tr>
|
|
</table>
|
|
|
|
|
|
<h2>Timing Diagrams</h2><p>
|
|
Below I am presenting some timing diagrams showing the relevant signals for various interesting bus cycle cases. <br/>
|
|
We are beginning with the timing of the accelerated processor bus, or the front-side bus (FSB), and proceeding on to the timing of the master port on the Mac SE bus, or the I/O Bus (IOB). <br/>
|
|
The timing diagrams are scaled for a 25 MHz FSB clock frequency and the standard 7.8336 MHz Mac SE bus.
|
|
</p>
|
|
|
|
|
|
<h3 id="t0">0. Generic MC68000 bus cycle detection</h3>
|
|
<script type="WaveDrom">{signal: [
|
|
{name: 'FCLK', wave: 'p.....', phase: 0.00, period: 2},
|
|
{name: 'A', wave: 'x2..x.', phase: 0.25, period: 2},
|
|
{name: 'R/W', wave: 'x..1....x...', phase: 0.25, period: 1},
|
|
{name: '/AS', wave: '1...x0........x1....x2.', phase:-0.25, period: 0.5},
|
|
{name: '/DS (RD)', wave: '1...x0........x1....x..', phase:-0.25, period: 0.5},
|
|
{name: '/DS (WR)', wave: '1.......x0....x1....x..', phase:-0.25, period: 0.5},
|
|
{name: '/AS', wave: '1...x0........x1....x..', phase:-0.25, period: 0.5},
|
|
{name: '/ASrf', wave: '1...x.....0.......1...x', phase:-0.25, period: 0.5},
|
|
{name: 'BACT', wave: '0...x.1...........0.x.2', phase:-0.25, period: 0.5},
|
|
]}
|
|
</script><br/><p>
|
|
For starters, it is instructive to look at a generic MC68000 bus cycle. <br/>
|
|
There are some details of the MC68000 bus cycle that complicate the synchronization of a state machine to the bus cycle. <br/>
|
|
Primarily, /AS falls after a rising edge of the clock but rises after a falling edge. <br/>
|
|
Since the worst-case clock-to-output delay of MC68000 is equal to half of one clock cycle, <br/>
|
|
attempting to detect bus activity by registering /AS strictly on the rising or falling edge
|
|
might result in entrance into a metastable state. <br/>
|
|
Therefore we introduce the "bus active" BACT signal. BACT is the disjunction of the address strobe asynchronously and as registered on the previous falling edge of the FSB clock. <br/>
|
|
The key useful feature of the BACT signal is that it is always valid at the rising edge of FCLK.
|
|
</p>
|
|
|
|
|
|
<h3 id="t1">1. FSB functionality - /DTACK and Ready</h3>
|
|
<script type="WaveDrom">{signal: [
|
|
{name: 'FCLK', wave: 'p.....', phase: 0.00, period: 2},
|
|
{name: 'A', wave: 'x2..x.', phase: 0.25, period: 2},
|
|
{name: 'R/W', wave: 'x..1....x...', phase: 0.25, period: 1},
|
|
{name: '/AS', wave: '1...x0........x1....x2.', phase:-0.25, period: 0.5},
|
|
{name: '/DTACK', wave: '1.......0...........1..', phase:-0.25, period: 0.5},
|
|
{name: 'BACT', wave: '0...x.1...........0.x.2', phase:-0.25, period: 0.5},
|
|
{name: 'Ready0', wave: 'x122x.', phase:-0.20, period: 2},
|
|
{name: 'Ready1', wave: 'x122x.', phase:-0.20, period: 2},
|
|
{name: 'Ready2', wave: 'x122x.', phase:-0.20, period: 2},
|
|
{name: 'Ready', wave: 'x1...x', phase:-0.20, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
Given BACT, the FSB controller asserts either /DTACK or /VPA when BACT is true and removes both /DTACK and /VPA when BACT is false. <br/>
|
|
Because the Warp-SE is a variable-wait-state system, we also must introduce the ready signals which are input to the FSB controller. <br/>
|
|
In the Warp-SE, three functional units control the data flow on the FSB. These are the DRAM controller, the IOB slave port, and the sound rate limiter. <br/>
|
|
Therefore there are three ready signals, Ready0, Ready1, and Ready2. The three Ready signals are functionally equivalent and interchangeable. <br/>
|
|
Each ready signal is produced by one of the three functional units. The Ready signals must be valid at the rising edge of each clock where BACT is asserted. <br/>
|
|
For the FSB controller to assert /DTACK or /VPA, each of the ready signls must be active on at least one clock of the given CACT cycle. <br/>
|
|
Because all of the Ready signals are sampled by the FSB controller during each BACT cycle, functional units must gate their Ready outputs with their own select signals. <br/>
|
|
/DTACK is a registered output that changes strictly following the rising edge of FCLK. <br/>
|
|
Note that MC68000's "/AS inactive-to-/DTACK inactive" parameter of two clock cycles minus 5 nanoseconds is met here. /DTACK is negated approximately 1.5 clock cycles after /AS rises.
|
|
</p>
|
|
|
|
|
|
<h3 id="t2">2. FSB functionality - Units not immediately ready</h3>
|
|
<script type="WaveDrom">{signal: [
|
|
{name: 'FCLK', wave: 'p.......', phase: 0.00, period: 2},
|
|
{name: 'A', wave: 'x2....x.', phase: 0.25, period: 2},
|
|
{name: 'R/W', wave: 'x..1........x...', phase: 0.25, period: 1},
|
|
{name: '/AS', wave: '1...x0................x1....x2.', phase:-0.25, period: 0.5},
|
|
{name: '/DTACK', wave: '1...............0...........1..', phase:-0.25, period: 0.5},
|
|
{name: 'BACT', wave: '0...x.1...................0.x.2', phase:-0.25, period: 0.5},
|
|
{name: 'Ready0', wave: 'x10...x.', phase:-0.20, period: 2},
|
|
{name: 'Ready1', wave: 'x0.10.x.', phase:-0.20, period: 2},
|
|
{name: 'Ready2', wave: 'x010..x.', phase:-0.20, period: 2},
|
|
{name: 'Ready', wave: 'x0.1...x', phase:-0.20, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
As discussed, the Ready signals do not each need to be active all at once. The FSB controller "remembers" that each Ready signal has been asserted. <br/>
|
|
This is represented by the Ready signal. Once all three individual Ready signals have been asserted, Ready becomes true and /DTACK or /VPA is asserted. <br/>
|
|
Ready is cleared along with /DTACK and /VPA once BACT is false.
|
|
</p>
|
|
|
|
|
|
<h3 id="t3">3. FSB functionality - /VPA</h3>
|
|
<script type="WaveDrom">{signal: [
|
|
{name: 'FCLK', wave: 'p....|...', phase: 0.00, period: 2},
|
|
{name: 'A', wave: 'x2...|.x.', phase: 0.25, period: 2, data: '$FFFFXX'},
|
|
{name: 'R/W', wave: 'x..1.......|..x...', phase: 0.25, period: 1},
|
|
{name: '/AS', wave: '1...x0...............|....x1....x2.', phase:-0.25, period: 0.5},
|
|
{name: '/VPA', wave: '1...............0....|....x.1......', phase:-0.25, period: 0.5},
|
|
{name: 'BACT', wave: '0...x.1..............|........0.x.2', phase:-0.25, period: 0.5},
|
|
{name: 'Ready', wave: '1........', phase:-0.20, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
When the address is in the range $FFFFXX, the FSB controller asserts /VPA instead of /DTACK. <br/>
|
|
The "/AS inactive-to-/VPA inactive" parameter of MC68000 is more stringent than, the "/AS inactive-to-/DTACK inactive" parameter, <br/>
|
|
so /VPA is additionally gated by /AS, whereas /DTACK is not.
|
|
</p>
|
|
|
|
|
|
<h3 id="t4">4. Back-to-Back ROM Access</h3>
|
|
<script type="WaveDrom">{signal: [
|
|
{name: 'MCLK', wave: 'p.........', phase: 0.00, period: 2},
|
|
{name: 'A', wave: 'x2..x2..x.', phase: 0.25, period: 2, data:['400000-4FFFFF','400000-4FFFFF']},
|
|
{name: 'ROMCS', wave: '1..x0..........x....0..........x1......', phase:-0.25, period: 0.5},
|
|
{name: 'RW', wave: 'x..2....x..2....x...', phase: 0.25, period: 1},
|
|
{name: 'AS', wave: '1...x0........x1....x0........x1....x2.', phase:-0.25, period: 0.5},
|
|
{name: 'DS (RD)', wave: '1...x0........x1....x0........x1.......', phase:-0.25, period: 0.5},
|
|
{name: 'OE (RD)', wave: '1...x.0.......x.1...x.0.......x.1......', phase:-0.35, period: 0.5},
|
|
{name: 'DS (WR)', wave: '1.......x0....x1........x0....x1.......', phase:-0.25, period: 0.5},
|
|
{name: 'WE (WR)', wave: '1.......x.0...x.1.......x.0...x.1......', phase:-0.35, period: 0.5},
|
|
{name: 'Ready', wave: '1.........', phase:-0.25, period: 2},
|
|
{name: '/DTACK', wave: '1.0..10..1', phase:-0.20, period: 2},
|
|
{name: 'D (RD)', wave: 'z..x..2.z..x..2.z...', phase:-0.30},
|
|
{name: 'D (WR)', wave: 'z......x.2......z......x.2......z.......', phase:-0.30, period:0.5},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram introduces the simplest memory access type, a read from or write to ROM memory. ROM control is completely asynchronous.<br/>
|
|
</p><p>
|
|
The ROM /CS signal is implemented as a decode of the address bus.
|
|
Similarly, the /OE signal is an asynchronous function of LDS, UDS, and /WE. <br/>
|
|
The /OE signal is shared by the RAM and ROM, so therefore it is critical that the ROMCS signal not be tied low,
|
|
otherwise bus contention will occur during RAM reads. <br/>
|
|
The Ready signals are always high during ROM access so all ROM accesses complete with the fastest 4-cycle timing.
|
|
</p>
|
|
|
|
|
|
<h3 id="t5">5. Back-to-Back RAM Access</h3><script type="WaveDrom">{signal: [
|
|
{name: 'MCLK', wave: 'p.........', phase: 0.00, period: 2},
|
|
{name: 'A', wave: 'x2..x2..x.', phase: 0.25, period: 2, data:['000000-3FFFFF','000000-3FFFFF']},
|
|
{name: 'RW', wave: 'x..1....x..1....x...', phase: 0.25, period: 1, data:['read or write','read or write']},
|
|
{name: 'AS', wave: '1...x0........x1....x0........x1....x2.', phase:-0.25, period: 0.5},
|
|
{name: 'DS (RD)', wave: '1...x0........x1....x0........x1.......', phase:-0.25, period: 0.5},
|
|
{name: 'OE (RD)', wave: '1...x.0.......x.1...x.0.......x.1......', phase:-0.35, period: 0.5},
|
|
{name: 'DS (WR)', wave: '1.......x0....x1........x0....x1.......', phase:-0.25, period: 0.5},
|
|
{name: 'WE (WR)', wave: '1.......x.0...x.1.......x.0...x.1......', phase:-0.35, period: 0.5},
|
|
{name: 'Ready', wave: 'x10.x10.x.', phase:-0.20, period: 2},
|
|
{name: 'DTACK', wave: '1.0..10..1', phase:-0.20, period: 2},
|
|
{name: 'D (RD)', wave: 'z....x2.z....x2.z...', phase:-0.30},
|
|
{name: 'D (WR)', wave: 'z......x.2......z......x.2......z......', phase:-0.30, period:0.5},
|
|
{name: 'RS', wave: '2222222222', phase:-0.20, period: 2, data:[0,0,5,6,7,0,5,6,7,0]},
|
|
{name: 'RAS', wave: '1...x.0.......x.1...x.0.......x.1......', phase:-0.35, period: 0.5},
|
|
{name: 'RASEL', wave: '0.1.0.1.0.', phase:-0.20, period: 2},
|
|
{name: 'RA', wave: 'x...x2..x2......x....2..x2......x......', phase:-0.20, period:0.5, data:['row','col','row','col']},
|
|
{name: 'CAS', wave: '1..0.1.0.1', phase: 0.80, period: 2},
|
|
]}</script><br/><p>
|
|
This diagram introduces the DRAM access timing.
|
|
</p><p>
|
|
At 25 MHz for a 4-clock read cycle, there are only 2.5 clock cycles (100 ns) between
|
|
the MC68k's assertion of /AS and when it latches data from the bus. <br/>
|
|
Subtracting the 25ns /AS tCO and 5ns data in tSU, that leaves only 70ns during which to initiate and complete a DRAM access,
|
|
not accounting for any RAS delay in the CPLD. <br/>
|
|
Therefore to minimize RAM access latency, RAS is implemented not as a registered output
|
|
but as an asynchronous decode of the address, /AS, and the internal RAS enable signal. <br/>
|
|
With 10ns delay in the CPLD, 25 MHz operation with 60ns DRAM is just possible.
|
|
</p><p>
|
|
Similarly, the RA multiplexed DRAM address bus is an asynchronous multiplexer controlled by the RASEL signal <br/>
|
|
which outputs row addresses to the DRAM array when RASEL is low and column addresses when RASEL is high. <br/>
|
|
The /CAS signal is a function of RASEL. RASEL changes after FCLK rises. If RASEL is high at the next falling edge, /CAS is asserted.
|
|
Otherwise if RASEL is low, /CAS is deasserted at the next falling edge.
|
|
</p><p>
|
|
"RS" is the RAM state. The RS state changes after the rising edge of the clock
|
|
and can take on values 0-7. <br/>
|
|
In RS0, the RAM is considered to be idle. <br/>
|
|
At the rising edge of the clock in RS0 a RAM cycle begins if, if /AS is asserted,
|
|
a RAM address is present, and a RAM cycle has not already occurred for this /AS cycle. <br/>
|
|
In this case, we know that /RAS has been active for at least 10 nanoseconds, so RASEL is brogught high. <br/>
|
|
This switches the RA bus from row to column addresses and RS0 transitions to RS5. <br/>
|
|
At the falling edge in the middle of RS5, /CAS is brought low. RS5 always transitions to RS6. <br/>
|
|
At the end of RS6, RASEL is brought low again, switching the RA multiplexers back to row addresses
|
|
in preparation for the next DRAM access cycle. RS6 always transitions to RS7. <br/>
|
|
RS7 is the state in which a RAM access or refresh is concluded. At the falling edge in the middle of RS7, /CAS is brought high. <br/>
|
|
RS7 transitions to RS2 if a refresh request is pending, otherwise RS7 transitions to RS0. <br/>
|
|
The states RS1 and RS2-RS4 will be discussed in association with the subsequent refresh cycle diagrams. <br/>
|
|
The RS and RAMCS signals are used to generate the Ready0 ready signal input to the FSB.
|
|
Ready0 is high if and only if RS==0 and RAMCS is active.<br/>
|
|
</p><p>
|
|
Also notice how, during write cycles,
|
|
it is undefined whether the cycle is conducted as an "early write" or an "OE-controlled write" cycle. <br/>
|
|
/OE is held high at all times during write cycles,
|
|
but /LWE and /UWE are asynchronous functions of MC68k's /LDS and /UDS signals. <br/>
|
|
It is undefined during a write cycle whether /LWE and /UWE will go low before or after /CAS falls. <br/>
|
|
Since /OE is held high during write cycles, the order of the /WE signals and /CAS is of no consequence.
|
|
</p>
|
|
|
|
|
|
<h3 id="t6">6. Long-running RAM Access</h3><script type="WaveDrom">{signal: [
|
|
{name: 'MCLK', wave: 'p.........', phase: 0.00, period: 2},
|
|
{name: 'A', wave: 'x2......x.', phase: 0.25, period: 2, data:['000000-3FFFFF']},
|
|
{name: 'RW', wave: 'x..1............x...', phase: 0.25, period: 1, data:['read or write','read or write']},
|
|
{name: 'AS', wave: '1...x0........................x1.......', phase:-0.25, period: 0.5},
|
|
{name: 'Ready', wave: '0....1....', phase:-0.20, period: 2},
|
|
{name: 'DTACK', wave: '1.....0..1', phase:-0.20, period: 2},
|
|
{name: 'D (RD)', wave: 'z....x2..z..........', phase:-0.30},
|
|
{name: 'D (WR)', wave: 'z..x2...........z...', phase: 0.00},
|
|
{name: 'RS', wave: '2222222222', phase:-0.20, period: 2, data:[0,0,5,6,7,0,0,0,0,0]},
|
|
{name: 'RAS', wave: '1...x.0.......................x.1......', phase:-0.25, period: 0.5},
|
|
{name: 'RASEL', wave: '0.1.0.....', phase:-0.20, period: 2},
|
|
{name: 'RA', wave: 'x...x2..x2......2...............x........', phase:-0.20, period:0.5, data:['row','col','row']},
|
|
{name: 'CAS', wave: '1..0.1....', phase: 0.80, period: 2},
|
|
]}</script><br/><p>
|
|
This diagram shows the timing for a long-running RAM access,
|
|
in which the RAM read or write completes sooner than MC68k removes /AS. <br/>
|
|
</p><p>
|
|
There are cases in which a DRAM access completes in time for termination of a 4-clock bus cycle,
|
|
but the bus cycle is lengthened because not all of the Ready signals to the FSB controller have gone high. <br/>
|
|
If RS0 is returned to after a DRAM access but /AS remains asserted,
|
|
then the DRAM must not enter RS5-7 and thus not initiate any additional /CAS cycles. <br/>
|
|
Notice how /CAS goes high in the middle of RS7 but /RAS stays low until the end of the /AS cycle.
|
|
Using EDO DRAM allows the data bus output to be maintained while /RAS is low. <br/>
|
|
However, if FPM DRAM is used or if a refresh cycle occurs before /AS rises,
|
|
then maintenance of read data on the data bus falls to the bus capacitance and the bus hold resistors. <br/>
|
|
Therefore it is best not to prolong DRAM read cycles, even when using EDO DRAM, so that there is no possibility of
|
|
an intervening DRAM refresh cycle causing the data outputs to tristate. <br/>
|
|
Fortunately, although DRAM write cycles shadowed to main sound and video memory need to be extended
|
|
when the posted write FIFO is full, there is no need to extend DRAM read cycles. <br/>
|
|
Therefore we do not attempt to extend the /CAS pulse to fix this problem until /AS rises since the /CAS pulse
|
|
could be interrupted by a refresh cycle anyway. <br/>
|
|
To fix this problem, we could extend the /CAS pulse until /AS is high and have the
|
|
DRAM controller conform to the DRAM "hidden refresh" protocol but it is not necessary.
|
|
</p>
|
|
|
|
|
|
<h3 id="t7">7. Refresh During Idle</h3><script type="WaveDrom">{signal: [
|
|
{name: 'MCLK', wave: 'p......', phase: 0.00, period: 2},
|
|
{name: 'AS', wave: '1............', phase:-0.75},
|
|
{name: 'RS', wave: '2222222', phase:-0.2, period: 2, data:[0,0,2,3,4,7,0,0,0]},
|
|
{name: 'RefReq', wave: '01..0..', phase:-0.2, period: 2},
|
|
{name: 'RASEN', wave: '1.0...1', phase:-0.2, period: 2},
|
|
{name: 'RRAS', wave: '1.....0...1...', phase:-0.20},
|
|
{name: 'RAS', wave: '1.....0...1...', phase:-0.40},
|
|
{name: 'CAS', wave: '1..0.1.', phase: 0.80, period: 2},
|
|
]}</script><br/><p>
|
|
This diagram shows the timing of a refresh occurring after the bus and DRAM are and have been idle for at least one clock cycle.
|
|
</p><p>
|
|
RAM states RS2, RS3, RS4, and RS7 are used for refresh. <br/>
|
|
RS2-RS4 implement the main refresh behavior. <br/>
|
|
When a refresh request is pending at the rising edge ending RS0 or RS7 while /RAS is inactive,
|
|
RASEN is brought low and RS2 is entered. <br/>
|
|
With RASEN low, /AS activity does not cause a /RAS pulse and the DRAM controller uses the registered /RRAS signal
|
|
to initiate refresh cycles. <br/>
|
|
At the falling edge in the middle of RS2, /CAS is activated. Then at the rising edge concluding RS2, /RAS is activated
|
|
and RS2 transitions to RS3. <br/>
|
|
In RS3, /RAS and /CAS remain active, and RS3 transitions to RS4.
|
|
RS3 and RS4 serve to implement the requisite /RAS pulse width for a refresh. <br/>
|
|
At the falling edge in the middle of RS4, /CAS is deactivated. Then at the rising edge concluding RS4, /RAS is deactivated
|
|
and RS4 transitions to RS7. <br/>
|
|
RREQ is cleared after the first rising edge on which RefRAS is active.<br/>
|
|
In RS7, /RAS and /CAS remain inactive. RS7 serves to implement the requisite RAS precharge time between DRAM cycles.<br/>
|
|
RASEN is brought high again after the rising edge concluding RS7 and RS7 transitions to RS0 and the DRAM is considered idle again.<br/>
|
|
</p><p>
|
|
Also notice how a RASEN can only be disabled if /RAS is high or if a DRAM cycle is complete, otherwise
|
|
there may be a tRAS timing violation. This constrains the timing of a refresh.
|
|
</p>
|
|
|
|
|
|
<h3 id="t8">8. Refresh Immediately Following DRAM Access - Bus Transaction Terminated Immediately</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p...', phase: 0.00, period: 2},
|
|
{name: 'AS', wave: '0.x1....x.......', phase:-0.25, period:0.5},
|
|
{name: 'RS', wave: '2222', phase:-0.20, period: 2, data:[6,7,2,3,4]},
|
|
{name: 'RefReq', wave: '21..', phase:-0.20, period: 2},
|
|
{name: 'RASEN', wave: '1.0.', phase:-0.20, period: 2},
|
|
{name: 'RRAS', wave: '1..0', phase:-0.20, period:2},
|
|
{name: 'RAS', wave: '0.x.1.......0..', phase:-0.40, period:0.5},
|
|
{name: 'CAS', wave: '0.10', phase: 0.80, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the timing of a refresh occurring immediately after a RAM access cycle.
|
|
</p><p>
|
|
Recall that a refresh cannot begin while a DRAM access is ongoing, or else an improperly-short /RAS pulse could occur.<br/>
|
|
Imagine, however, that MC68k performs many back-to-back DRAM accesses.
|
|
In this case, there would never be an RS0 in which a /RAS pulse has not already begun. <br/>
|
|
Therefore the DRAM controller must be able to begin a refresh during RS7,
|
|
immediately after a RAM access is completed but before MC68k brings /AS low again. <br/>
|
|
The timing for this case starts out slightly differently but ends the same as the refresh during idle.
|
|
Therefore the timing is only shown through S4.<br/>
|
|
The purpose of this diagram is mainly to demonstrate that adequate /RAS and /CAS precharge time exists
|
|
after the previous DRAM access is terminated before /RAS is pulsed for refresh.
|
|
</p>
|
|
|
|
|
|
<h3 id="t9">9. Refresh Immediately Following DRAM Access - Bus Transaction Terminated While Refresh In-Progress</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p......', phase: 0.00, period: 2},
|
|
{name: 'AS', wave: '0.............x1....x......', phase:-0.25, period:0.5},
|
|
{name: 'RS', wave: '2222222', phase:-0.20, period: 2, data:[6,7,2,3,4,7,0,0,0,0]},
|
|
{name: 'RefReq', wave: '21..0..', phase:-0.20, period: 2},
|
|
{name: 'RASEN', wave: '1.0...1', phase:-0.20, period: 2},
|
|
{name: 'RRAS', wave: '1..0.1.', phase:-0.20, period:2},
|
|
{name: 'RAS', wave: '0.......1...0.......1...x..', phase:-0.40, period:0.5},
|
|
{name: 'CAS', wave: '0.10.1.', phase: 0.80, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the case where a refresh request occurs during a long-running DRAM access
|
|
and the /AS cycle terminates before the refresh ends.
|
|
</p><p>
|
|
It is possible for a DRAM access cycle to be extended for a long time, during which the DRAM may be deprived of refresh. <br/>
|
|
Therefore we must provide for the case where a DRAM access completes and a refresh begins but before /AS ever goes high. <br/>
|
|
In this case, the rising edge of RASEN causes /RAS to go inactive, as opposed to the rising edge of /AS. <br/>
|
|
Therefore, the /RAS precharge pulse width in this case is much shorter than
|
|
a refresh occurring during idle or immediately following a DRAM access. <br/>
|
|
At 25 MHz, the /RAS precharge width is only 40ns. This is the minimum tRP for 60ns DRAM and is the tightest timing parameter in the Warp-SE. <br/>
|
|
We could purpose RS1 to add additional precharge time if necessary.
|
|
</p>
|
|
|
|
|
|
<h3 id="t10">10. Refresh Immediately Following DRAM Access - Bus Transaction Terminated After Refresh Completes</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p........', phase: 0.00, period: 2},
|
|
{name: 'AS', wave: '0.........................x1....x...', phase:-0.25, period:0.5},
|
|
{name: 'RS', wave: '222222222', phase:-0.20, period: 2, data:[6,7,2,3,4,7,0,0,0]},
|
|
{name: 'RefReq', wave: '21..0....', phase:-0.20, period: 2},
|
|
{name: 'RASEN', wave: '1.0.....1', phase:-0.20, period: 2},
|
|
{name: 'RRAS', wave: '1..0.1...', phase:-0.20, period:2},
|
|
{name: 'RAS', wave: '0.......1...0.......1...........x...', phase:-0.40, period:0.5},
|
|
{name: 'CAS', wave: '0.10.1...', phase: 0.80, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the case where a refresh request occurs during a long-running DRAM access
|
|
and the /AS cycle does not terminate before the refresh ends.
|
|
</p><p>
|
|
This case is similar to the previous but there is a key difference.
|
|
/AS does not rise until after the refresh cycle completes. <br/>
|
|
Therefore if RASEN were brought high upon exit from RS7 into RS0, there may be an improperly-short /RAS pulse
|
|
terminated by the rising edge of the /AS. <br/>
|
|
Consequently RASEN enablement is held off the first rising edge during which BACT is low.
|
|
</p>
|
|
|
|
<h3 id="t11">11. Refresh in the "Middle" of DRAM Access</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p......', phase: 0.00, period: 2},
|
|
{name: 'AS', wave: '0...........................', phase:-0.25, period:0.5},
|
|
{name: 'RS', wave: '2222222', phase:-0.20, period: 2, data:[6,7,0,0,0,2,3]},
|
|
{name: 'RefReq', wave: '0...1..', phase:-0.20, period: 2},
|
|
{name: 'RASEN', wave: '1....0.', phase:-0.20, period: 2},
|
|
{name: 'RRAS', wave: '1.....0', phase:-0.20, period:2},
|
|
{name: 'RAS', wave: '0...................1...0...', phase:-0.40, period:0.5},
|
|
{name: 'CAS', wave: '0.1...0', phase: 0.80, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the case where a refresh request occurs in the "middle" of a long-running DRAM access. <br/>
|
|
The remainder of the timing is given by diagrams 9 or 10.
|
|
</p>
|
|
|
|
<h3 id="t12">12. Concurrent DRAM Access and Refresh Requests</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p.........', phase: 0.00, period: 2},
|
|
{name: 'A', wave: 'x2......x.', phase: 0.25, period: 2, data:['000000-4FFFFF']},
|
|
{name: '/AS', wave: '1..x0........................x1........', phase:-0.75, period: 0.5},
|
|
{name: 'DTACK', wave: '1.....0..1', phase:-0.30, period: 2},
|
|
{name: 'DS (RD)', wave: '1..x0........................x1.......', phase:-0.75, period: 0.5},
|
|
{name: 'OE (RD)', wave: '1...x.0......................x.1.....', phase:-0.75, period: 0.5},
|
|
{name: 'DS (WR)', wave: '1......x0....................x1.......', phase:-0.75, period: 0.5},
|
|
{name: 'WE (WR)', wave: '1.......................0....x.1......', phase:-0.75, period: 0.5},
|
|
{name: 'RS', wave: '2222222222', phase:-0.20, period: 2, data:[0,2,3,4,7,0,5,6,7,0]},
|
|
{name: 'Ready0', wave: 'x0...10.x.', phase:-0.20, period: 2},
|
|
{name: 'RefReq', wave: '1..0......', phase:-0.20, period: 2},
|
|
{name: 'RASEN', wave: '10...1....', phase:-0.20, period: 2},
|
|
{name: 'RRAS', wave: '1...0...1...........', phase:-0.20},
|
|
{name: '/RAS', wave: '1.......0.......1...0.........x.1......', phase:-0.45, period: 0.5},
|
|
{name: '/CAS', wave: '1.0.1..0.1', phase: 0.70, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the timing of a refresh starting concurrently with the beginning of a RAM access cycle.
|
|
</p><p>
|
|
Here we see the timing of refresh being entered concurrently with the start of a RAM access.
|
|
In this case, there is a little bit of a race condition. <br/>
|
|
RASEN and /AS both fall following the rising edge of FCLK. /AS causes /RAS activation asynchronously,
|
|
but RASEN gates this from occurring. <br/>
|
|
Therefore the internal RASEN feedback in the CPLD must occur sooner than /AS transitions,
|
|
otherwise an erroneous /RAS pulse will be generated. <br/>
|
|
Fortunately the CPLDs intended to be used (ispMACH4000, XC9500XL) are some 10 years newer than MC68HC000,
|
|
so their speed advantage mitigates the problem. <br/>
|
|
The negation of Ready0 causes /DTACK generation and termination of the bus cycle
|
|
to be delayed until completion of the refresh. <br/>
|
|
</p>
|
|
|
|
<p>
|
|
Before showing the timing for the I/O bus slave port on the FSB,
|
|
it's instructive to understand the timing of the I/O bus master controller.
|
|
</p>
|
|
|
|
|
|
<h3 id="t13">13. I/O Bus E State, VMA, "ETACK"</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'C16M', wave: 'p...........................', period: 1},
|
|
{name: 'C8M', wave: '0101010101010101010101010101', phase:-0.25, period: 1},
|
|
{name: 'E', wave: '10.....1...0..', phase: 0.90, period: 2},
|
|
{name: 'Er', wave: '10.....1...0..', phase:-0.40, period: 2},
|
|
{name: 'Er2', wave: '1..0...........1.......0....', phase:-0.10, period: 1},
|
|
{name: 'ES', wave: '2222222222222222222222222222', period: 1, data:[18,19,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,0,1,2,3,4,5]},
|
|
{name: 'IOACT', wave: '2........12.................', period: 1},
|
|
{name: '/VPA', wave: 'x................0..x...................................', period: 0.5},
|
|
{name: '/VMA', wave: '1.........0............1....', period: 1},
|
|
{name: 'ETACK', wave: '0..................10.......', period: 1},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the I/O bus VMA and "ETACK" timing.
|
|
<p>
|
|
Although most I/O bus accesses are terminated by /DTACK,
|
|
accesses to the VIA and interrupt acknowledge areas of memory are terminated by /VPA. <br/>
|
|
With MC68k having granted the bus to the accelerator,
|
|
it will no longer generate the /VMA chip select signal in respose to /VPA. <br/>
|
|
Therefore for /VMA, we must provide the /VMA signal timing. <br/>
|
|
In order to do this, an internal counter, the ES or "E state" is synchronized to MC68k's E clock cycle. <br/>
|
|
Synchronization of a state machine running from the C16M clock to the E clock cycle
|
|
is complicated by clock skew between the C16M, C8M, and E clocks. <br/>
|
|
The E clock changes following the falling edge of C8M, so E is registered at the falling edge of C8M as Er.
|
|
Then Er is registered at the rising edge of C16M as Er2. <br/>
|
|
Er and Er2 both have adequate setup and hold time to be used at the rising edge of C16M.
|
|
Er and Er2 are then used to synchronize the ES counter to the E clock phase. <br/>
|
|
</p><p>
|
|
In ES7, if the IO bus is active, as signified by IOACT, and /VPA has been asserted, the IO bus controller asserts /VMA
|
|
in preparation for the E clock high pulse. <br/>
|
|
Then in ES17, if /VMA is low, i.e. a /VPA cycle is ongoing, ETACK is asserted. <br/>
|
|
ETACK is analogous to /DTACK and signals the I/O controller to
|
|
terminate the /AS cycle in synchronization with the E clock going low.
|
|
</p>
|
|
|
|
|
|
<h3 id="t14">14. I/O Bus Access (Even Phase)</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'IOS', wave:'22222222222222222222|222222', period: 1,data:[0,0,0,0,0,0,1,2,3,4,5,6,7,0,1,2,3,4,5,5,5,6,7,0,0,0,0]},
|
|
{name: 'C16M', wave:'p...................|......', period: 1},
|
|
{name: 'C8M', wave:'10101010101010101010|101010', phase:-0.25, period: 1},
|
|
{name: 'C8Mr', wave:'01010101010101010101|010101', phase:-0.10, period: 1},
|
|
{name: 'AS', wave:'1.....0....1..0.....|.1....', phase:-0.60, period: 1},
|
|
{name: 'DTACK', wave:'x.........0x......1x|2x....', phase:-0.10, period: 1},
|
|
{name: 'ETACK', wave:'x.........1x......1x|2x....', phase:-0.10, period: 1},
|
|
{name: 'BERR', wave:'x.........1x......1x|1x....', phase:-0.10, period: 1},
|
|
{name: 'IOACT', wave:'0.....1....0..1.....|.0....', phase:-0.10, period: 1},
|
|
{name: 'IOREQ', wave:'0....1x......1x.....|...0..', phase:-0.60, period: 1},
|
|
{name: 'ADout0LE',wave:'1.....0.....1.0.....|..1...', phase:-0.10, period: 1},
|
|
{name: '&&ADLEEN',wave:'1....x0.....1.0.....|..1...', phase:-0.10, period: 1},
|
|
{name: 'DinLE', wave:'0........1.0.....1..|.0....', phase:-0.60, period: 1},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the timing of two I/O bus cycles, first a 4-clock cycle terminated by /DTACK,
|
|
then a longer cycle terminated by either /DTACK or /VPA.
|
|
</p><p>
|
|
The I/O bus master controller initiates a cycle when the IOREQ signal originating from the FSB domain (discussed subsequently)
|
|
is high and there is no ongoing bus cycle. <br/>
|
|
The IOS state counter tracks the progress through a M68k bus master transaction. <br/>
|
|
In IOS0, the bus is considered to be idle. In IOS0 if C8M is low and IOREQ is high,
|
|
then IOACT goes high and IOS1 is entered. Entrance into IOS1 is delayed by one clock if C8M is high.<br/>
|
|
IOS counts from 1-5 and then pauses in IOS5, only transitioning to IOS6 when C8M is high
|
|
and one of /DTACK, ETACK, /BERR, or /RESET are active. <br/>
|
|
For /DTACK, /BERR, and /RESET termination, the termination signals must be low not only at the rising edge concluding IOS5
|
|
but also at the previous falling edge and rising edge, otherwise cycle termination is held off. <br/>
|
|
In order to best match M68k's timing and meet the timing constraints of BBU, /AS is output on the falling edge of C16M. <br/>
|
|
/AS is active following the falling edge in the middle of IOS1 until the falling edge in the middle of IOS6. <br/>
|
|
The timing for /LDS and /UDS is a similarly straightforward function of IOS, R/W, and the FSB /LDS and /UDS signals. <br/>
|
|
As mentioned before, IOS5 is maintained until C8M is high and one of the cycle termination signals is active.
|
|
Once this occurs, IOS6 is entered and IOACT goes low. <br/>
|
|
IOS6 transitions to IOS7 and then around to IOS0, which is maintained until another I/O request comes in. <br/>
|
|
It is the responsibility of the FSB controller to deassert IOREQ after IOACTV goes high
|
|
in order to prevent the bus transaction from occurring twice. <br/>
|
|
However, IOREQ can be maintained high through IOACT going high, low, then high again
|
|
in order to ensure two back-to-back bus transactions occur.
|
|
</p><p>
|
|
Notice the ADout0LE and DinLE signals. <br/>
|
|
ADoutLE is the latch enable for address and write data going from the FSB to the IOB. <br/>
|
|
DinLE is the latch enable for read data going from the IOB data to the FSB. <br/>
|
|
ADoutLE is high only during IOS0 and is low during IOS1-7.
|
|
Therefore address and write data are latched for the entirety of the bus cycle. <br/>
|
|
ADoutLE0 is additionally gated by the ADLEEN signal from the FSB clock domain.
|
|
DinLE is high following the falling edges in the middle of IOS4 and IOS5, thus the input latch captures the read data. <br/>
|
|
</p>
|
|
|
|
|
|
<h3 id="t15">15. I/O Bus Access (Odd Phase)</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'IOS', wave:'2222222222222',period: 1,data:[0,0,0,0,0,0,1,2,3,4,5,6,7,0,1,2,3,4,5,5,5,6,7,0,0,0,0]},
|
|
{name: 'C16M', wave:'p............', period: 1},
|
|
{name: 'C8M', wave:'1010101010101', phase:-0.25, period: 1},
|
|
{name: 'C8Mr', wave:'0101010101010', phase:-0.10, period: 1},
|
|
{name: 'AS', wave:'1.....0....1.', phase:-0.60, period: 1},
|
|
{name: 'DTACK', wave:'x.........0x.', phase:-0.10, period: 1},
|
|
{name: 'ETACK', wave:'x.........1x.', phase:-0.10, period: 1},
|
|
{name: 'BERR', wave:'x.........1x.', phase:-0.10, period: 1},
|
|
{name: 'IOACT', wave:'0....1.....0.', phase:-0.10, period: 1},
|
|
{name: 'IOREQ', wave:'0...1x.......', phase:-0.60, period: 1},
|
|
{name: 'ADout0LE',wave:'1....0.......', phase:-0.10, period: 1},
|
|
{name: '&&ADLEEN',wave:'1...x0.......', phase:-0.10, period: 1},
|
|
{name: 'DinLE', wave:'0........1.0.', phase:-0.60, period: 1},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the timing of an I/O bus cycle beginning with C8M high.
|
|
</p><p>
|
|
This case is basically the same as the start of the previous, just the IOREQ comes in one C16M clock earlier. <br/>
|
|
Therefore although IOACTV goes high and ADoutLE goes low immediately following IOREQ detection,
|
|
entrance into IOS1 is delayed by one clock.
|
|
</p>
|
|
|
|
|
|
<h3 id="t16">16. IOREQ Synchronization from FSB to IOB</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'C16M', wave:'p..', period: 4},
|
|
{name: 'IOREQ - FSB (best case)', wave:'0..1....................', period: 0.5, phase: 0.00},
|
|
{name: 'IOREQ - IOB (best case)', wave:'0...1...................', period: 0.5, phase:-0.15},
|
|
{name: 'IOREQ - FSB (worst case)', wave:'0...1...................', period: 0.5, phase: 0.15},
|
|
{name: 'IOREQ - IOB (worst case)', wave:'0...x0......1...........', period: 0.5, phase:-0.15}
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the synchronization of IOREQ from the FSB clock domain to the I/O clock domain.
|
|
</p><p>
|
|
Because the C16M clock speed is low and because latency between the FSB and IOB is critical,
|
|
a single-state synchronizer triggered on the C16M falling edge is used. <br/>
|
|
On XC9500XL and ispMACH4000, the metastability recovery time tMET is only a few nanoseconds
|
|
for MTBF in the trillions of years. <br/>
|
|
With 30ns between the falling and rising edges of C16M, a single-stage synchronizer is adequate. <br/>
|
|
Given this arrangement, in IOS0, the delay between the FSB sending IOREQ low and the IOB responding with IOACT high <br/>
|
|
is 1.5 C16M clock cycles plus one tSU and two tCO, or approximately 110 nanoseconds.
|
|
</p>
|
|
|
|
|
|
<h3 id="t17">17. Three Consecutive Posted Writes to I/O Bus</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p..........|.....', period: 2},
|
|
{name: 'A', wave: 'x2..x2..x2.|...x.', phase:0.25, period: 2, data:['3F, 50-5F, 90-BF, D0-FF','3F, 50-5F, 90-BF, D0-FF','3F, 50-5F, 90-BF, D0-FF']},
|
|
{name: 'R/W', wave: 'x..0....x..0....x..0...|......x...', phase:0.25, period: 1},
|
|
{name: '/AS', wave: '1...x0........x1....x0........x1....x0.......|............x1....x..', phase:-0.25, period: 0.5},
|
|
{name: '/DS (WR)',wave: '1.......x0....x1........x0....x1........x0...|............x1....x..', phase:-0.25, period: 0.5},
|
|
{name: 'BACT', wave: '0...x.1...........0.x.1...........0.x.1.......................0.x.2', phase:-0.25, period: 0.5},
|
|
{name: '/DTACK', wave: '210..10..1.|.0..1', phase:-0.3, period: 2},
|
|
{name: 'D (WR)', wave: 'z...x2..z...x2..z...x2.|......z...', phase:0.00},
|
|
{name: 'Ready1', wave: 'x1..x10.x0.|1..x.', phase:-0.2, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows two consecutive posted writes to the I/O bus.
|
|
</p><p>
|
|
In order to enhance video performance, the ability to "post" up to two consecutive writes to the I/O bus is desirable.
|
|
Three such posted writes are shown here.<br/>
|
|
During IOB space write cycles, the Ready1 signal (input to the FSB controller)
|
|
is high when the FSB-to-IOB interface can accept a posted write. <br/>
|
|
Because three writes were performed consecutively here before the first had the opportunity to complete,
|
|
Ready1 goes low because the FSB-to-IOB FIFO is full and completion of the third write is delayed until the FIFO is not full.
|
|
</p>
|
|
|
|
<h3 id="t18">18. Two Consecutive Posted Writes to Video/Sound Memory with FIFO Empty</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p.........', period: 2},
|
|
{name: 'A', wave: 'x2..x2..x.', phase:0.25, period: 2, data:['3FXXXX','3FXXXX']},
|
|
{name: 'R/W', wave: 'x..0....x..0....x...', phase:0.25, period: 1},
|
|
{name: '/AS', wave: '1...x0........x1....x0........x1....x..', phase:-0.25, period: 0.5},
|
|
{name: '/DS (WR)',wave: '1.......x0....x1........x0....x1....x..', phase:-0.25, period: 0.5},
|
|
{name: 'BACT', wave: '0...x.1...........0.x.1...........0.x.1', phase:-0.25, period: 0.5},
|
|
{name: '/DTACK', wave: '210..10..1', phase:-0.3, period: 2},
|
|
{name: 'D (WR)', wave: 'z...x2..z...x2..z...', phase:0.00},
|
|
{name: 'Ready1', wave: 'x1..x10.x.', phase:-0.2, period: 2},
|
|
{name: 'RS', wave: '2222222222', phase:-0.20, period: 2, data:[0,0,5,6,7,0,5,6,7,0]},
|
|
{name: 'Ready0', wave: 'x10.x10.x.', phase:-0.20, period: 2},
|
|
{name: '/RAS', wave: '1...x.0.......x.1...x.0.......x.1......', phase:-0.35, period: 0.5},
|
|
{name: 'RASEL', wave: '0.1.0.1.0.', phase:-0.20, period: 2},
|
|
{name: 'RA', wave: 'x...x2..x2......x....2..x2......x........', phase:-0.20, period:0.5, data:['row','col','row','col']},
|
|
{name: '/CAS', wave: '1..0.1.0.1', phase: 0.80, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows two consecutive posted writes to video/sound RAM.
|
|
</p><p>
|
|
When writing to video/sound RAM, the data written must be written to the I/O bus
|
|
as well as shadowed in the accelerator's onboard RAM. <br/>
|
|
Therefore a DRAM write cycle occurs concurrently with an I/O bus write. <br/>
|
|
Here we have the case where the I/O bus FIFO starts out empty and then accepts two writes in four clock cycles each. <br/>
|
|
In this case, the acceptance of the posted write by the I/O bus slave port and the DRAM write occur simultaneously. <br/>
|
|
Of course, were the posted write FIFO full or the RAM in refresh, either unit could
|
|
delay completion of the /AS cycle via their respective Ready signals.
|
|
</p>
|
|
|
|
|
|
<h3 id="t19">19. Read from I/O Bus</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p..|.....', period: 2},
|
|
{name: 'A', wave: 'x2.|...x.', phase:0.25, period: 2, data:['50-5F, 90-BF, D0-FF','50-5F, 90-BF, D0-FF']},
|
|
{name: 'RW', wave: 'x..1...|......x...', phase:0.25, period: 1},
|
|
{name: 'AS', wave: '1...x0.......|............x1....x..', phase:-0.25, period: 0.5},
|
|
{name: 'BACT', wave: '0...x.1......|................0.x.1', phase:-0.25, period: 0.5},
|
|
{name: '/DTACK', wave: '21.|.0..1', phase:-0.3, period: 2},
|
|
{name: 'D (RD)', wave: 'z.x....|.2....z...', phase:0.00},
|
|
{name: 'Ready1', wave: 'x0.|1....', phase:-0.2, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows a read from the I/O bus.
|
|
</p><p>
|
|
From the perspective of the FSB controller, the case where data is read from the I/O bus is fairly simple. <br/>
|
|
The IOB slave port holds Ready1 low until the I/O bus transaction is completed.
|
|
</p>
|
|
|
|
|
|
<h3>20. I/O Bus Slave Port - Single Read/Write</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p...|..|...', period: 2},
|
|
{name: 'IOSTART', wave: '010.|..|...', period: 2, phase:-0.3},
|
|
{name: 'PS', wave: '2222|22|222', period: 2, data:[0,0,3,2,2,1,1,0,0], phase:-0.3},
|
|
{name: 'IOACT', wave: '0...|1.|0..', phase:-0.3, period: 2},
|
|
{name: 'IOREQ', wave: '0.1.|.0|...', phase:-0.3, period: 2},
|
|
{name: 'ALEEN0', wave: '1..0|.1|...', phase:-0.3, period: 2},
|
|
{name: 'IORW0', wave: '2.2.|..|...', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU0', wave: '2..2|..|...', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'IORDReady', wave: '0...|..|.1.', phase:-0.3, period: 2},
|
|
{name: 'IOWRReady', wave: '1...|..|...', phase:-0.3, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows the behavior of the I/O bus slave port controller under a single read/write request.
|
|
</p><p>
|
|
Here we are just showing the signals relevant to the I/O bus slave port controller rather than all of the M68k FSB signals. <br/>
|
|
IOSTART true when the I/O bus space is selected, BACT is low, and the I/O request has not been recognized this current BACT cycle.
|
|
has been submitted but not yet accepted by the I/O bus slave port controller. <br/>
|
|
If the posted write FIFO is empty then the IOB slave port controller can submit
|
|
a new access request to the master controller. <br/>
|
|
In this case the posted write FIFO is empty and IOA is active,
|
|
so the IOB slave controller enters PS2 and asserts IOREQ. <br/>
|
|
In addition, at this time, IORW0 is latched from the FSB's R/W line.
|
|
This tells the IOB master controller whether the current request a read or write.
|
|
At the end of the first PS2 state, ALEEN0 is lowered in order to latch the address and write data into the IOB interface latches.
|
|
IOLU0[1:0] is also latched from the FSB /LDS and /UDS signals. <br/>
|
|
Similar to IORW0, IOLU0 encodes which of the two bytes of the data bus are to be accessed by the IOB master controller. <br/>
|
|
</p><p>
|
|
ADLEEN0 merits some additional explanation. <br/>
|
|
Since the IOB slave controller supports a 4-clock posted write, following the first PS2 state of a posted write,
|
|
M68k will remove /AS and terminate the cycle. <br/>
|
|
Because of synchronization overhead between the FSB and IOB clock domains, the IOB master controller may not latch the address and write data into the latches between the FSB and IOB before the cycle terminates. <br/>
|
|
Therefore the ALE0 output is additionally gated by the FSB clock domain signal ADLEEN0.
|
|
ADLEEN0 stays low until a receipt of the IOB request is confirmed by the IOB master controller. <br/>
|
|
</p><p>
|
|
Following the first PS2 state, the IOB slave controller waits in PS2 until the IOB master controller signals IOACT,
|
|
indicating that it has received the IOB request. <br/>
|
|
Once IOACT is received high then the IOB slave controller removes IOREQ and ADLEEN0 and enters PS1.
|
|
</p><p>
|
|
In PS1, the IO bus controller waits for IOACT low, indicating that the cycle has completed, and then returns to PS0.
|
|
Additionally, once IOACT is low, if IORW0 indicates a read was performed, IORDRDY is brought high for one cycle.
|
|
</p><p>
|
|
The actual Ready1 output signal is a combination of IORDRDY and IOWRRDY which selects the corect one depending on the
|
|
address range accessed.
|
|
</p>
|
|
|
|
|
|
<h3>22. I/O Bus Slave Port - Two Writes, FIFO never full</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p..|..|....|..|..', period: 2},
|
|
{name: 'IOSTART', wave: '10.|..|.10.|..|..', period: 2, phase:-0.3},
|
|
{name: 'PS', wave: '222|22|2222|22|22', period: 2, data:[0,3,2,2,1,1,0,3,2,2,1,1,0], phase:-0.3},
|
|
{name: 'IOACT', wave: '0..|1.|0...|1.|0.', phase:-0.3, period: 2},
|
|
{name: 'IOREQ', wave: '01.|.0|..1.|.0|..', phase:-0.3, period: 2},
|
|
{name: 'ALE0', wave: '1.0|.1|...0|.1|..', phase:-0.3, period: 2},
|
|
{name: 'IORW0', wave: '20.|..|..0.|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU0', wave: '2.2|..|...2|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'IOWRReady', wave: '1..|..|....|..|..', phase:-0.3, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
This diagram shows two posted writes.
|
|
In this case, the posted writes are spaced out such that the FIFO is never fully utilized.
|
|
</p>
|
|
|
|
<h3>23. I/O Bus Slave Port - Two Writes, FIFO filled (0)</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p..|..|.....|..|..', period: 2},
|
|
{name: 'IOSTART', wave: '10.|..|10...|..|..', period: 2, phase:-0.3},
|
|
{name: 'PS', wave: '222|22|22222|22|22', period: 2, data:[0,3,2,2,1,1,0,3,2,2,2,1,1,0], phase:-0.3},
|
|
{name: 'IOACT', wave: '0..|1.|0....|1.|0.', phase:-0.3, period: 2},
|
|
{name: 'IOREQ', wave: '01.|.0|.1...|.0|..', phase:-0.3, period: 2},
|
|
{name: 'ALE1', wave: '1..|..|..0.1|..|..', phase:-0.3, period: 2},
|
|
{name: 'IORW1', wave: '2..|..|.0...|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU1', wave: '2..|..|..2..|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'ALE0', wave: '1.0|.1|...0.|.1|..', phase:-0.3, period: 2},
|
|
{name: 'IORW0', wave: '20.|..|..0..|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU0', wave: '2.2|..|...2.|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'IOWRReady', wave: '1..|..|.0..1|..|..', phase:-0.3, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
Here we have the case where two posted writes occur close enough in time that the FIFO is fully utilized.
|
|
</p>
|
|
|
|
|
|
<h3>24. I/O Bus Slave Port - Two Writes, FIFO filled (1)</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p..|....|.....|..|..', period: 2},
|
|
{name: 'IOSTART', wave: '10.|.10.|.....|..|..', period: 2, phase:-0.3},
|
|
{name: 'PS', wave: '222|2222|22222|22|22', period: 2, data:[0,3,2,2,1,1,1,1,0,3,2,2,2,1,1,0], phase:-0.3},
|
|
{name: 'IOACT', wave: '0..|1...|0....|1.|0.', phase:-0.3, period: 2},
|
|
{name: 'IOREQ', wave: '01.|.01.|.....|.0|..', phase:-0.3, period: 2},
|
|
{name: 'ALE1', wave: '1..|...0|....1|..|..', phase:-0.3, period: 2},
|
|
{name: 'IORW1', wave: '2..|..0.|.....|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU1', wave: '2..|...2|.....|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'ALE0', wave: '1.0|.1..|...0.|.1|..', phase:-0.3, period: 2},
|
|
{name: 'IORW0', wave: '20.|....|..0..|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU0', wave: '2.2|....|...2.|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'IOWRReady', wave: '1..|..0.|....1|..|..', phase:-0.3, period: 2},
|
|
]}
|
|
</script><br/><p>
|
|
Similar to the previous case but the writes are even closer in time.
|
|
</p>
|
|
|
|
<h3>25. I/O Bus Slave Port - Two Writes, FIFO filled (2)</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p..|....|.....|..|..', period: 2},
|
|
{name: 'IOSTART', wave: '10.|10..|.....|..|..', period: 2, phase:-0.3},
|
|
{name: 'PS', wave: '222|2222|22222|22|22', period: 2, data:[0,3,2,2,1,1,1,1,0,3,2,2,2,1,1,0], phase:-0.3},
|
|
{name: 'IOACT', wave: '0..|1...|0....|1.|0.', phase:-0.3, period: 2},
|
|
{name: 'IOREQ', wave: '01.|....|.....|.0|..', phase:-0.3, period: 2},
|
|
{name: 'ALE1', wave: '1..|..0.|....1|..|..', phase:-0.3, period: 2},
|
|
{name: 'IORW1', wave: '2..|.0..|.....|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU1', wave: '2..|..2.|.....|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'ALE0', wave: '1.0|.1..|...0.|.1|..', phase:-0.3, period: 2},
|
|
{name: 'IORW0', wave: '20.|....|..0..|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU0', wave: '2.2|....|...2.|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'IOWRReady', wave: '1..|.0..|....1|..|..', phase:-0.3, period: 2},
|
|
]}
|
|
</script><p>
|
|
Similar to the previous case (again) but here the second write has come in before
|
|
the IOBS has received indication from the IOBM that the previous write has begun.
|
|
</p>
|
|
|
|
<h3>26. I/O Bus Slave Port - Two Writes, FIFO filled (3)</h3>
|
|
<script type="WaveDrom">
|
|
{signal: [
|
|
{name: 'MCLK', wave: 'p....|..|.....|..|..', period: 2},
|
|
{name: 'IOSTART', wave: '1010.|..|.....|..|..', period: 2, phase:-0.3},
|
|
{name: 'PS', wave: '22222|22|22222|22|22', period: 2, data:[0,3,2,2,2,2,1,1,0,3,2,2,2,1,1,0], phase:-0.3},
|
|
{name: 'IOACT', wave: '0....|1.|0....|1.|0.', phase:-0.3, period: 2},
|
|
{name: 'IOREQ', wave: '01...|..|.....|.0|..', phase:-0.3, period: 2},
|
|
{name: 'ALE1', wave: '1...0|..|....1|..|..', phase:-0.3, period: 2},
|
|
{name: 'IORW1', wave: '2..0.|..|.....|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU1', wave: '2...2|..|.....|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'ALE0', wave: '1.0..|.1|...0.|.1|..', phase:-0.3, period: 2},
|
|
{name: 'IORW0', wave: '20...|..|..0..|..|..', phase:-0.3, period: 2, data:['R/W', 'R/W']},
|
|
{name: 'IOLU0', wave: '2.2..|..|...2.|..|..', phase:-0.3, period: 2, data:['LDS, UDS', 'LDS, UDS']},
|
|
{name: 'IOWRReady', wave: '1...0|..|....1|..|..', phase:-0.3, period: 2},
|
|
]}
|
|
</script><p>
|
|
Similar to the previous case (again). This is the closest write timing allowed, even faster than MC68k can do.
|
|
</p>
|
|
|
|
<script type="text/javascript">
|
|
document.querySelectorAll('script[type=wavedrom]').forEach(function(dgm) {
|
|
var dj;
|
|
eval('dj = ' + dgm.text + ';');
|
|
var lines = {};
|
|
var table = {};
|
|
dj.signal.forEach(function(line) {
|
|
lines[line.name] = '';
|
|
for (var symbol = 0; symbol < line.wave.length; symbol++) {
|
|
for (var reps = 0; reps < line.period / 0.5; reps++) {
|
|
if (line.wave.charAt(symbol) === '.' ||
|
|
line.wave.charAt(symbol) === '|') {
|
|
var previndex = lines[line.name].charAt.length-1;
|
|
|
|
if (previndex <= 0) {
|
|
lines[line.name] += '1';
|
|
} else {
|
|
lines[line.name] += lines[line.name].charAt(previndex);
|
|
}
|
|
} else {
|
|
lines[line.name] += line.wave.charAt(symbol);
|
|
}
|
|
}
|
|
}
|
|
//alert(lines[line.name]);
|
|
});
|
|
});
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|